mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Strengthen paste logic
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <boost/json.hpp>
|
||||
#include <wx/filename.h>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Crop Rect Encoding
|
||||
|
||||
@@ -111,67 +112,70 @@ inline static String transformAllEncodedRects(const String& rectString, RectTran
|
||||
|
||||
// ----------------------------------------------------------------------------- : File to UTF8 Encoding
|
||||
|
||||
inline static const char Base64Alphabet[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
inline static const std::vector<int> Base64ReverseAlphabet = [] {
|
||||
std::vector<int> table(256, -1);
|
||||
for (int i = 0; i < 64; i++) table[(uint8_t)Base64Alphabet[i]] = i;
|
||||
return table;
|
||||
}();
|
||||
|
||||
/// Encode a file in a string
|
||||
inline static std::string fileToUTF8(const std::string& filepath) {
|
||||
// File to char
|
||||
// Load file
|
||||
std::ifstream file(filepath, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
std::vector<unsigned char> buffer = std::vector<unsigned char>(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||
int size = buffer.size();
|
||||
if (size < 2) {
|
||||
queue_message(MESSAGE_WARNING, _("File too small to encode"));
|
||||
if (!file) {
|
||||
queue_message(MESSAGE_WARNING, _("Could not find file: ") + String(filepath));
|
||||
return "";
|
||||
}
|
||||
// All bytes that have a highest bit of 0 are valid UTF8 characters, so:
|
||||
// Reset the highest bit of each byte, store these bits in additional bytes at the end
|
||||
const unsigned char highest_bit = 1 << 7;
|
||||
unsigned char added_byte = 0;
|
||||
for (int i = 0, b = 0 ; i < size ; ++i, ++b) {
|
||||
if (b == 7) { // Never set the highest bit of the added byte
|
||||
buffer.push_back(added_byte);
|
||||
b = 0;
|
||||
}
|
||||
unsigned char bit = 1 << b;
|
||||
if ((buffer[i] & highest_bit) != 0) { // The highest bit of the buffer is set
|
||||
buffer[i] &= ~highest_bit; // Reset the highest bit of the buffer
|
||||
added_byte |= bit; // Set the bit of the added byte
|
||||
} else {
|
||||
added_byte &= ~bit; // Reset the bit of the added byte
|
||||
size_t size = std::filesystem::file_size(filepath);
|
||||
std::vector<uint8_t> data(size);
|
||||
file.read(reinterpret_cast<char*>(data.data()), size);
|
||||
// Base64 encode
|
||||
std::string out;
|
||||
out.reserve(((size + 2) / 3) * 4);
|
||||
int val = 0;
|
||||
int valb = -6;
|
||||
for (uint8_t c : data) {
|
||||
val = (val << 8) | c;
|
||||
valb += 8;
|
||||
while (valb >= 0) {
|
||||
out.push_back(Base64Alphabet[(val >> valb) & 0x3F]);
|
||||
valb -= 6;
|
||||
}
|
||||
}
|
||||
buffer.push_back(added_byte);
|
||||
// Char to string
|
||||
return std::string(buffer.begin(), buffer.end());
|
||||
if (valb > -6) {
|
||||
out.push_back(Base64Alphabet[((val << 8) >> (valb + 8)) & 0x3F]);
|
||||
}
|
||||
// Pad
|
||||
while (out.size() % 4) {
|
||||
out.push_back('=');
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Retreive a file encoded in a string, return true if successful
|
||||
inline static bool UTF8ToFile(const std::string& filepath, std::string& string) {
|
||||
// String to char
|
||||
std::vector<unsigned char> buffer(string.begin(), string.end());
|
||||
int size = buffer.size();
|
||||
if (size < 2) {
|
||||
queue_message(MESSAGE_WARNING, _("File too small to decode"));
|
||||
return false;
|
||||
}
|
||||
// Restore the highest bit of each byte
|
||||
size = (size * 7) / 8;
|
||||
const unsigned char highest_bit = 1 << 7;
|
||||
unsigned char added_byte = buffer[size];
|
||||
for (int i = 0, j = size, b = 0 ; i < size ; ++i, ++b) {
|
||||
if (b == 7) {
|
||||
++j;
|
||||
added_byte = buffer[j];
|
||||
b = 0;
|
||||
}
|
||||
unsigned char bit = 1 << b;
|
||||
if ((added_byte & bit) != 0) { // The bit of the added byte is set
|
||||
buffer[i] |= highest_bit; // Set the highest bit of the buffer
|
||||
inline static bool UTF8ToFile(const std::string& filepath, std::string& data) {
|
||||
// Base64 decode
|
||||
std::string out;
|
||||
out.reserve(data.size() * 3 / 4);
|
||||
int val = 0;
|
||||
int valb = -8;
|
||||
for (uint8_t c : data) {
|
||||
if (c == '=') break; // padding, we're done
|
||||
val = (val << 6) | Base64ReverseAlphabet[c];
|
||||
valb += 6;
|
||||
if (valb >= 0) {
|
||||
out.push_back(static_cast<char>((val >> valb) & 0xFF));
|
||||
valb -= 8;
|
||||
}
|
||||
}
|
||||
buffer.resize(size);
|
||||
// Char to file
|
||||
std::ofstream file(filepath, std::ios::out|std::ios::binary);
|
||||
std::copy(buffer.cbegin(), buffer.cend(), std::ostream_iterator<unsigned char>(file));
|
||||
// Save file
|
||||
std::ofstream file(filepath, std::ios::binary);
|
||||
file.write(out.data(), out.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -850,14 +850,11 @@ DownloadedImage::DownloadedImage(Set* set, const String& url)
|
||||
}
|
||||
|
||||
// is the data an image?
|
||||
const String& content_type = wnd.out.GetContentType();
|
||||
if (!content_type.StartsWith(_("image"))) throw ScriptError(_ERROR_1_("download not image", loadpath));
|
||||
Image img(*wnd.out.GetStream());
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_("web request corrupted"));
|
||||
|
||||
if (!wnd.content_type.StartsWith(_("image/"))) throw ScriptError(_ERROR_1_("download not image", loadpath));
|
||||
|
||||
// add the file to the set (or overwrite it if pre-existing), save set
|
||||
auto outStream = set->openOut(savename);
|
||||
img.SaveFile(*outStream, wxBITMAP_TYPE_PNG);
|
||||
wnd.image_out.SaveFile(*outStream, wxBITMAP_TYPE_PNG);
|
||||
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", loadpath));
|
||||
outStream->Close();
|
||||
set->save(false);
|
||||
|
||||
@@ -259,7 +259,7 @@ void CardListBase::parseImageMetadata(CardP& card, const Image& image) {
|
||||
int degrees = 0;
|
||||
if (decodeRectFromString(value->filename.toStringForKey(), rect, degrees)) {
|
||||
rect = rect.intersect(RealRect(0.0, 0.0, image.GetWidth(), image.GetHeight()));
|
||||
if (rect.width > 0.0 && rect.height > 0.0) {
|
||||
if (rect.width > 0.0 && rect.height > 0.0) {
|
||||
Image img = image.GetSubImage(rect);
|
||||
img = rotate_image(img, deg_to_rad(360 - degrees));
|
||||
LocalFileName filename = set->newFileName(_("cropped_image"), _(".png")); // a new unique name in the package
|
||||
@@ -275,13 +275,13 @@ void CardListBase::parseImageMetadata(CardP& card, const Image& image) {
|
||||
}
|
||||
}
|
||||
|
||||
void CardListBase::parseImageMetadata(CardP& card) {
|
||||
void CardListBase::parseImageMetadata(CardP& card) {
|
||||
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()) {
|
||||
Image img;
|
||||
if (decodeImageFromString(value->filename.toStringForKey(), img)) {
|
||||
if (img.IsOk()) {
|
||||
if (decodeImageFromString(value->filename.toStringForKey(), img)) {
|
||||
if (img.IsOk()) {
|
||||
LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package
|
||||
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
|
||||
value->filename = filename;
|
||||
@@ -295,28 +295,21 @@ void CardListBase::parseImageMetadata(CardP& card) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::parseUrl(String& url, vector<CardP>& out) {
|
||||
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;
|
||||
|
||||
if (!url.StartsWith(_("http"))) return false;
|
||||
|
||||
WebRequestWindow wnd(url);
|
||||
if (wnd.ShowModal() == wxID_OK) {
|
||||
const String& content_type = wnd.out.GetContentType();
|
||||
if (content_type.StartsWith(_("image"))) {
|
||||
Image img(*wnd.out.GetStream());
|
||||
if (img.IsOk()) {
|
||||
parseImage(img, out);
|
||||
}
|
||||
else {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("web request corrupted"));
|
||||
}
|
||||
if (wnd.ShowModal() == wxID_OK) {
|
||||
if (wnd.content_type.StartsWith(_("image/"))) {
|
||||
parseImage(wnd.image_out, out);
|
||||
}
|
||||
else if (content_type.StartsWith(_("text"))) {
|
||||
String text = wnd.out.AsString();
|
||||
else if (wnd.content_type.StartsWith(_("text/"))) {
|
||||
String text = String(wnd.text_out.data(), wnd.text_out.size());
|
||||
parseText(text, out);
|
||||
}
|
||||
else {
|
||||
@@ -326,10 +319,10 @@ bool CardListBase::parseUrl(String& url, vector<CardP>& out) {
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
|
||||
bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
for (size_t i = 0; i < filenames.size(); i++) {
|
||||
if (wxImage::CanRead(filenames[i])) {
|
||||
if (wxImage::CanRead(filenames[i])) {
|
||||
// if it's an image file, try to get meta_data
|
||||
Image image_file;
|
||||
image_file.SetLoadFlags(image_file.GetLoadFlags() & ~wxImage::Load_Verbose);
|
||||
@@ -340,12 +333,12 @@ bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& 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;
|
||||
if (ifs.bad() || ifs.fail() || !ifs.good() || !ifs.is_open()) continue;
|
||||
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||
bool looks_like_text = std::all_of(content.begin(), content.end(), [](char c) {
|
||||
return isprint(c) || isspace(c);
|
||||
});
|
||||
if (!looks_like_text) continue;
|
||||
if (!looks_like_text) continue;
|
||||
wxString text(content);
|
||||
if (!parseUrl(text, out)) parseText(text, out);
|
||||
}
|
||||
@@ -353,7 +346,7 @@ bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
|
||||
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
if (image.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
auto text = image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION);
|
||||
@@ -368,7 +361,10 @@ bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
if (text.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
size_t j = out.size();
|
||||
size_t pos = text.find("<mse-card-data>");
|
||||
if (pos != wxString::npos) {
|
||||
@@ -376,7 +372,7 @@ bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
}
|
||||
try {
|
||||
ScriptValueP sv = json_to_mse(text, set.get());
|
||||
if (sv->type() == SCRIPT_COLLECTION) {
|
||||
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())) {
|
||||
@@ -384,11 +380,11 @@ bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(sv.get())) {
|
||||
} else if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(sv.get())) {
|
||||
out.push_back(make_intrusive<Card>(*c->getValue()));
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
} catch (...) {}
|
||||
|
||||
// decode images to populate image fields
|
||||
for (int k = j; k < out.size(); k++) {
|
||||
CardP& card = out[k];
|
||||
@@ -398,27 +394,33 @@ bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
wxBusyCursor wait;
|
||||
wxDataObjectComposite* composite = drop_target->data_object;
|
||||
wxDataFormat format = composite->GetReceivedFormat();
|
||||
vector<CardP> new_cards;
|
||||
|
||||
if (format == CardsDataObject::format) {
|
||||
if (format == CardsDataObject::format) {
|
||||
String id = ignore_cards_from_own_card_list ? drop_target->ignored_id : _("");
|
||||
size_t size = composite->GetDataSize(format);
|
||||
if (size > 0) {
|
||||
std::vector<char> buffer(size);
|
||||
if (composite->GetDataHere(format, buffer.data())) {
|
||||
CardsDataObject card_data;
|
||||
card_data.SetData(size, buffer.data());
|
||||
card_data.getCards(set, id, new_cards);
|
||||
}
|
||||
if (size < 1) {
|
||||
queue_message(MESSAGE_ERROR, _("DEBUG: CardsDataObject corrupted"));
|
||||
return false;
|
||||
}
|
||||
if (size > 10000000) { // 10Mb
|
||||
queue_message(MESSAGE_ERROR, _("Too much card data, paste less cards!"));
|
||||
return false;
|
||||
}
|
||||
std::vector<char> buffer(size);
|
||||
if (composite->GetDataHere(format, buffer.data())) {
|
||||
CardsDataObject card_data;
|
||||
card_data.SetData(size, buffer.data());
|
||||
card_data.getCards(set, id, new_cards);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wxDataObject *data = composite->GetObject(format);
|
||||
|
||||
|
||||
switch (format.GetType())
|
||||
{
|
||||
case wxDF_FILENAME:
|
||||
@@ -432,17 +434,59 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
case wxDF_PNG:
|
||||
{
|
||||
wxImageDataObject* image_data = static_cast<wxImageDataObject*>(data);
|
||||
Image image = image_data->GetImage();
|
||||
parseImage(image, new_cards);
|
||||
size_t size = image_data->GetDataSize();
|
||||
if (size < 1) {
|
||||
queue_message(MESSAGE_ERROR, _("DEBUG: ImageDataObject corrupted"));
|
||||
return false;
|
||||
}
|
||||
if (size > 50000000) { // 50Mb
|
||||
queue_message(MESSAGE_ERROR, _("Image data too large or corrupted"));
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Image image = image_data->GetImage();
|
||||
if (!image.IsOk() || image.GetWidth() > 20000 || image.GetHeight() > 20000) {
|
||||
queue_message(MESSAGE_ERROR, _("Image too large or corrupted"));
|
||||
return false;
|
||||
}
|
||||
parseImage(image, new_cards);
|
||||
} catch (const std::bad_alloc&) {
|
||||
//queue_message(MESSAGE_ERROR, _("Image couldn't be allocated"));
|
||||
return false;
|
||||
} catch (...) {
|
||||
queue_message(MESSAGE_ERROR, _("Image couldn't be processed"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case wxDF_BITMAP:
|
||||
{
|
||||
wxBitmapDataObject* bitmap_data = static_cast<wxBitmapDataObject*>(data);
|
||||
wxBitmap bitmap = bitmap_data->GetBitmap();
|
||||
Image image = bitmap.ConvertToImage();
|
||||
parseImage(image, new_cards);
|
||||
size_t size = bitmap_data->GetDataSize();
|
||||
if (size < 1) {
|
||||
queue_message(MESSAGE_ERROR, _("DEBUG: BitmapDataObject corrupted"));
|
||||
return false;
|
||||
}
|
||||
if (size > 50000000) { // 50Mb
|
||||
queue_message(MESSAGE_ERROR, _("Bitmap data too large or corrupted"));
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
wxBitmap bitmap = bitmap_data->GetBitmap();
|
||||
if (!bitmap.IsOk() || bitmap.GetWidth() > 20000 || bitmap.GetHeight() > 20000) {
|
||||
queue_message(MESSAGE_ERROR, _("Bitmap too large or corrupted"));
|
||||
return false;
|
||||
}
|
||||
Image image = bitmap.ConvertToImage();
|
||||
parseImage(image, new_cards);
|
||||
} catch (const std::bad_alloc&) {
|
||||
//queue_message(MESSAGE_ERROR, _("Bitmap or Image couldn't be allocated"));
|
||||
return false;
|
||||
} catch (...) {
|
||||
queue_message(MESSAGE_ERROR, _("Bitmap or Image couldn't be processed"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -451,6 +495,15 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
case wxDF_HTML:
|
||||
{
|
||||
wxTextDataObject* text_data = static_cast<wxTextDataObject*>(data);
|
||||
size_t size = text_data->GetDataSize();
|
||||
if (size < 1) {
|
||||
queue_message(MESSAGE_ERROR, _("DEBUG: TextDataObject corrupted"));
|
||||
return false;
|
||||
}
|
||||
if (size > 30000000) { // 30Mb
|
||||
queue_message(MESSAGE_ERROR, _("Text too large or corrupted"));
|
||||
return false;
|
||||
}
|
||||
String text = text_data->GetText();
|
||||
if (!parseUrl(text, new_cards)) parseText(text, new_cards);
|
||||
}
|
||||
@@ -774,7 +827,7 @@ CardListDropTarget::CardListDropTarget(CardListBase* card_list)
|
||||
|
||||
CardListDropTarget::~CardListDropTarget() {}
|
||||
|
||||
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
|
||||
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
|
||||
if (!GetData()) return wxDragNone;
|
||||
if (!card_list->parseData(true)) return wxDragError;
|
||||
return wxDragCopy;
|
||||
|
||||
@@ -579,7 +579,7 @@ bool CardsPanel::canPaste() const {
|
||||
else return false;
|
||||
}
|
||||
void CardsPanel::doPaste() {
|
||||
if (card_list->doPaste()) return;
|
||||
if (card_list->doPaste()) return;
|
||||
|
||||
int id = focused_control(this);
|
||||
if (id == ID_EDITOR) editor->doPaste();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <util/prec.hpp>
|
||||
#include <gui/web_request_window.hpp>
|
||||
#include <util/window_id.hpp>
|
||||
#include <wx/mstream.h>
|
||||
|
||||
// ----------------------------------------------------------------------------- : WebRequestWindow
|
||||
|
||||
@@ -76,16 +77,50 @@ void WebRequestWindow::onUpdate(wxWebRequestEvent& evt) {
|
||||
}
|
||||
|
||||
void WebRequestWindow::onComplete(wxWebRequestEvent& evt) {
|
||||
out = evt.GetResponse();
|
||||
if (out.IsOk()) {
|
||||
EndModal(wxID_OK);
|
||||
wxWebResponse response = evt.GetResponse();
|
||||
if (!response.IsOk()) {
|
||||
onFail(_ERROR_("web request corrupted"));
|
||||
return;
|
||||
}
|
||||
wxInputStream* stream = response.GetStream();
|
||||
if (!stream || !stream->IsOk()) {
|
||||
onFail(_ERROR_("web request corrupted"));
|
||||
return;
|
||||
}
|
||||
|
||||
content_type = response.GetContentType();
|
||||
if (content_type.StartsWith("image/")) {
|
||||
image_out = Image(*stream);
|
||||
if (!image_out.IsOk()) {
|
||||
onFail(_ERROR_("web request corrupted"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (content_type.StartsWith("text/") || content_type.Contains("json")) {
|
||||
wxMemoryOutputStream mem;
|
||||
char buffer[8192];
|
||||
while (true) {
|
||||
stream->Read(buffer, sizeof(buffer));
|
||||
size_t read = stream->LastRead();
|
||||
if (read > 0) mem.Write(buffer, read);
|
||||
if (stream->Eof()) break;
|
||||
if (stream->GetLastError() != wxSTREAM_NO_ERROR) {
|
||||
onFail(_ERROR_("web request corrupted"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
text_out.resize(mem.GetSize());
|
||||
mem.CopyTo(text_out.data(), mem.GetSize());
|
||||
}
|
||||
else {
|
||||
onFail(_ERROR_("web request corrupted"));
|
||||
onFail(_ERROR_("web request unsupported format"));
|
||||
return;
|
||||
}
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void WebRequestWindow::onFail(const String& message) {
|
||||
content_type.Clear();
|
||||
info->SetLabel(_ERROR_("web request failed"));
|
||||
address->SetLabel(message);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@ class WebRequestWindow : public wxDialog {
|
||||
public:
|
||||
WebRequestWindow(const String& url, bool sizer=true);
|
||||
|
||||
wxWebResponse out;
|
||||
String content_type;
|
||||
std::string text_out;
|
||||
Image image_out;
|
||||
|
||||
protected:
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
+293
-264
@@ -112,13 +112,25 @@ void pretty_print(std::ostream& os, const boost::json::value& jv, std::string* i
|
||||
String json_pretty_print(const boost::json::value& jv, std::string* indent) {
|
||||
std::ostringstream stream;
|
||||
pretty_print(stream, jv, indent);
|
||||
String string = wxString(stream.str().c_str());
|
||||
return string;
|
||||
std::string stdstring = stream.str();
|
||||
const char* data = stdstring.data();
|
||||
size_t size = stdstring.size();
|
||||
String wxstring = String::FromUTF8(data, size);
|
||||
if (wxstring.empty() && size > 0) {
|
||||
wxstring = String(data, wxConvWhateverWorks, size);
|
||||
}
|
||||
return wxstring;
|
||||
}
|
||||
|
||||
String json_ugly_print(const boost::json::value& jv) {
|
||||
String string = wxString(boost::json::serialize(jv).c_str());
|
||||
return string;
|
||||
std::string stdstring = boost::json::serialize(jv);
|
||||
const char* data = stdstring.data();
|
||||
size_t size = stdstring.size();
|
||||
String wxstring = String::FromUTF8(data, size);
|
||||
if (wxstring.empty() && size > 0) {
|
||||
wxstring = String(data, wxConvWhateverWorks, size);
|
||||
}
|
||||
return wxstring;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : JSON to MSE
|
||||
@@ -128,23 +140,33 @@ ScriptValueP json_to_mse(const boost::json::value& jv, Set* set);
|
||||
template <typename T>
|
||||
void read(T& out, boost::json::object& jv, const char value_name[]) {
|
||||
if (!jv.contains(value_name)) return;
|
||||
else {
|
||||
wxStringInputStream stream = {_("")};
|
||||
Reader reader(stream, nullptr, _(""));
|
||||
reader.setValue(wxString(jv[value_name].as_string().c_str()));
|
||||
reader.handle(out);
|
||||
boost::json::string jstring = jv[value_name].as_string();
|
||||
const char* data = jstring.data();
|
||||
size_t size = jstring.size();
|
||||
String wxstring = String::FromUTF8(data, size);
|
||||
if (wxstring.empty() && size > 0) {
|
||||
wxstring = String(data, wxConvWhateverWorks, size);
|
||||
}
|
||||
wxStringInputStream stream(wxstring);
|
||||
Reader reader(stream, nullptr, _(""), false, true);
|
||||
reader.setValue(wxstring);
|
||||
reader.handle(out);
|
||||
}
|
||||
|
||||
// templates don't work with enums? are you kidding me with this language?
|
||||
void read(PackSelectType& out, boost::json::object& jv, const char value_name[]) {
|
||||
if (!jv.contains(value_name)) return;
|
||||
else {
|
||||
wxStringInputStream stream = {_("")};
|
||||
Reader reader(stream, nullptr, _(""));
|
||||
reader.setValue(wxString(jv[value_name].as_string().c_str()));
|
||||
reader.handle(out);
|
||||
boost::json::string jstring = jv[value_name].as_string();
|
||||
const char* data = jstring.data();
|
||||
size_t size = jstring.size();
|
||||
String wxstring = String::FromUTF8(data, size);
|
||||
if (wxstring.empty() && size > 0) {
|
||||
wxstring = String(data, wxConvWhateverWorks, size);
|
||||
}
|
||||
wxStringInputStream stream(wxstring);
|
||||
Reader reader(stream, nullptr, _(""), false, true);
|
||||
reader.setValue(wxstring);
|
||||
reader.handle(out);
|
||||
}
|
||||
|
||||
PackItemP json_to_mse_pack_item(boost::json::object& jv) {
|
||||
@@ -163,7 +185,7 @@ PackTypeP json_to_mse_pack_type(boost::json::object& jv) {
|
||||
read(pack_type->summary, jv, "summary");
|
||||
read(pack_type->select, jv, "select");
|
||||
if (jv.contains("items") && jv["items"].is_array()) {
|
||||
boost::json::array pack_itemsv = jv["items"].as_array();
|
||||
boost::json::array pack_itemsv = jv["items"].get_array();
|
||||
for (size_t i = 0; i < pack_itemsv.size(); i++) {
|
||||
boost::json::object pack_itemv = pack_itemsv[i].as_object();
|
||||
pack_type->items.emplace_back(json_to_mse_pack_item(pack_itemv));
|
||||
@@ -184,38 +206,43 @@ KeywordP json_to_mse_keyword(boost::json::object& jv) {
|
||||
|
||||
CardP json_to_mse_card(boost::json::object& jv, Set* set) {
|
||||
CardP card = make_intrusive<Card>(*set->game);
|
||||
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->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");
|
||||
// card fields
|
||||
if (jv.contains("data") && jv["data"].is_object()) {
|
||||
boost::json::object datav = jv["data"].as_object();
|
||||
boost::json::object datav = jv["data"].get_object();
|
||||
for (auto it = datav.begin(); it != datav.end(); ++it) {
|
||||
String key_name = wxString(it->key_c_str());
|
||||
boost::json::string_view key_view = it->key();
|
||||
String key_name = String::FromUTF8(key_view.data(), key_view.size());
|
||||
Value* container = get_card_field_container(*set->game, card->data, key_name, false);
|
||||
ScriptValueP value = json_to_mse(it->value(), set);
|
||||
set_container(container, value, key_name);
|
||||
}
|
||||
}
|
||||
// stylesheet
|
||||
if (jv.contains("stylesheet")) card->stylesheet = StyleSheet::byGameAndName(*set->game, wxString(jv["stylesheet"].as_string().c_str()));
|
||||
if (jv.contains("stylesheet")) {
|
||||
boost::json::string stylesheet_name = jv["stylesheet"].as_string();
|
||||
card->stylesheet = StyleSheet::byGameAndName(*set->game, String::FromUTF8(stylesheet_name.data(), stylesheet_name.size()));
|
||||
}
|
||||
if (card->stylesheet) {
|
||||
// styling fields
|
||||
card->styling_data.init(card->stylesheet->styling_fields);
|
||||
if (jv.contains("styling_data") && jv["styling_data"].is_object()) {
|
||||
boost::json::object datav = jv["styling_data"].as_object();
|
||||
boost::json::object datav = jv["styling_data"].get_object();
|
||||
for (auto it = datav.begin(); it != datav.end(); ++it) {
|
||||
String key_name = wxString(it->key_c_str());
|
||||
Value* container = get_container(card->styling_data, wxString("styling"), key_name, false);
|
||||
boost::json::string_view key_view = it->key();
|
||||
String key_name = String::FromUTF8(key_view.data(), key_view.size());
|
||||
Value* container = get_container(card->styling_data, String("styling"), key_name, false);
|
||||
ScriptValueP value = json_to_mse(it->value(), set);
|
||||
set_container(container, value, key_name);
|
||||
card->has_styling = true;
|
||||
@@ -223,15 +250,17 @@ CardP json_to_mse_card(boost::json::object& jv, Set* set) {
|
||||
}
|
||||
// extra card fields
|
||||
if (jv.contains("extra_data") && jv["extra_data"].is_object()) {
|
||||
boost::json::object datav = jv["extra_data"].as_object();
|
||||
boost::json::object datav = jv["extra_data"].get_object();
|
||||
for (auto it = datav.begin(); it != datav.end(); ++it) {
|
||||
StyleSheetP stylesheet = StyleSheet::byGameAndName(*set->game, it->key_c_str());
|
||||
boost::json::string_view stylesheet_view = it->key();
|
||||
StyleSheetP stylesheet = StyleSheet::byGameAndName(*set->game, String::FromUTF8(stylesheet_view.data(), stylesheet_view.size()));
|
||||
if (!stylesheet) continue;
|
||||
IndexMap<FieldP, ValueP>& stylesheet_data = card->extraDataFor(*stylesheet);
|
||||
boost::json::object stylesheet_datav = it->value().as_object();
|
||||
for (auto stylesheet_it = stylesheet_datav.begin(); stylesheet_it != stylesheet_datav.end(); ++stylesheet_it) {
|
||||
String key_name = wxString(stylesheet_it->key_c_str());
|
||||
Value* container = get_container(stylesheet_data, wxString("extra card"), key_name, false);
|
||||
boost::json::string_view key_view = stylesheet_it->key();
|
||||
String key_name = String::FromUTF8(key_view.data(), key_view.size());
|
||||
Value* container = get_container(stylesheet_data, String("extra card"), key_name, false);
|
||||
ScriptValueP value = json_to_mse(stylesheet_it->value(), set);
|
||||
set_container(container, value, key_name);
|
||||
}
|
||||
@@ -248,30 +277,35 @@ SetP json_to_mse_set(boost::json::object& jv) {
|
||||
if (!jv.contains("stylesheet")) {
|
||||
throw ScriptError(_ERROR_("json set without stylesheet"));
|
||||
}
|
||||
GameP game = Game::byName(wxString(jv["game"].as_string().c_str()));
|
||||
StyleSheetP stylesheet = StyleSheet::byGameAndName(*game, wxString(jv["stylesheet"].as_string().c_str()));
|
||||
boost::json::string game_name = jv["game"].as_string();
|
||||
GameP game = Game::byName(String::FromUTF8(game_name.data(), game_name.size()));
|
||||
boost::json::string stylesheet_name = jv["stylesheet"].as_string();
|
||||
StyleSheetP stylesheet = StyleSheet::byGameAndName(*game, String::FromUTF8(stylesheet_name.data(), stylesheet_name.size()));
|
||||
SetP set = make_intrusive<Set>(stylesheet);
|
||||
// set fields
|
||||
if (jv.contains("set_info") && jv["set_info"].is_object()) {
|
||||
boost::json::object datav = jv["set_info"].as_object();
|
||||
boost::json::object datav = jv["set_info"].get_object();
|
||||
for (auto it = datav.begin(); it != datav.end(); ++it) {
|
||||
String key_name = wxString(it->key_c_str());
|
||||
Value* container = get_container(set->data, wxString("set"), key_name, false);
|
||||
boost::json::string_view key_view = it->key();
|
||||
String key_name = String::FromUTF8(key_view.data(), key_view.size());
|
||||
Value* container = get_container(set->data, String("set"), key_name, false);
|
||||
ScriptValueP value = json_to_mse(it->value(), set.get());
|
||||
set_container(container, value, key_name);
|
||||
}
|
||||
}
|
||||
// styling
|
||||
if (jv.contains("styling") && jv["styling"].is_object()) {
|
||||
boost::json::object datav = jv["styling"].as_object();
|
||||
boost::json::object datav = jv["styling"].get_object();
|
||||
for (auto it = datav.begin(); it != datav.end(); ++it) {
|
||||
StyleSheetP stylesheet = StyleSheet::byGameAndName(*set->game, it->key_c_str());
|
||||
boost::json::string_view stylesheet_view = it->key();
|
||||
StyleSheetP stylesheet = StyleSheet::byGameAndName(*set->game, String::FromUTF8(stylesheet_view.data(), stylesheet_view.size()));
|
||||
if (!stylesheet) continue;
|
||||
IndexMap<FieldP, ValueP>& stylesheet_data = set->stylingDataFor(*stylesheet);
|
||||
boost::json::object stylesheet_datav = it->value().as_object();
|
||||
for (auto stylesheet_it = stylesheet_datav.begin(); stylesheet_it != stylesheet_datav.end(); ++stylesheet_it) {
|
||||
String key_name = wxString(stylesheet_it->key_c_str());
|
||||
Value* container = get_container(stylesheet_data, wxString("styling"), key_name, false);
|
||||
boost::json::string_view key_view = stylesheet_it->key();
|
||||
String key_name = String::FromUTF8(key_view.data(), key_view.size());
|
||||
Value* container = get_container(stylesheet_data, String("styling"), key_name, false);
|
||||
ScriptValueP value = json_to_mse(stylesheet_it->value(), set.get());
|
||||
set_container(container, value, key_name);
|
||||
}
|
||||
@@ -279,7 +313,7 @@ SetP json_to_mse_set(boost::json::object& jv) {
|
||||
}
|
||||
// cards
|
||||
if (jv.contains("cards") && jv["cards"].is_array()) {
|
||||
boost::json::array cardsv = jv["cards"].as_array();
|
||||
boost::json::array cardsv = jv["cards"].get_array();
|
||||
for (size_t i = 0; i < cardsv.size(); i++) {
|
||||
boost::json::object cardv = cardsv[i].as_object();
|
||||
set->cards.emplace_back(json_to_mse_card(cardv, set.get()));
|
||||
@@ -287,7 +321,7 @@ SetP json_to_mse_set(boost::json::object& jv) {
|
||||
}
|
||||
// keywords
|
||||
if (jv.contains("keywords") && jv["keywords"].is_array()) {
|
||||
boost::json::array keywordsv = jv["keywords"].as_array();
|
||||
boost::json::array keywordsv = jv["keywords"].get_array();
|
||||
for (size_t i = 0; i < keywordsv.size(); i++) {
|
||||
boost::json::object keywordv = keywordsv[i].as_object();
|
||||
set->keywords.emplace_back(json_to_mse_keyword(keywordv));
|
||||
@@ -295,7 +329,7 @@ SetP json_to_mse_set(boost::json::object& jv) {
|
||||
}
|
||||
// pack types
|
||||
if (jv.contains("pack_types") && jv["pack_types"].is_array()) {
|
||||
boost::json::array pack_typesv = jv["pack_types"].as_array();
|
||||
boost::json::array pack_typesv = jv["pack_types"].get_array();
|
||||
for (size_t i = 0; i < pack_typesv.size(); i++) {
|
||||
boost::json::object pack_typev = pack_typesv[i].as_object();
|
||||
set->pack_types.emplace_back(json_to_mse_pack_type(pack_typev));
|
||||
@@ -318,17 +352,13 @@ ScriptValueP json_to_mse(const boost::json::value& jv, Set* set) {
|
||||
return to_script(integer);
|
||||
}
|
||||
else if (jv.is_string()) {
|
||||
if (jv.as_string().empty()) return to_script(String());
|
||||
std::string string = boost::json::value_to<std::string>(jv);
|
||||
const char* cstring = string.c_str();
|
||||
size_t nulpos = strlen(cstring);
|
||||
// if the string contains nul bytes, we have to use the std::string constructor, even though we can't specify the encoding
|
||||
if (nulpos < string.size()) return to_script(String(string));
|
||||
// if the string doesn't contain nul bytes, we can use the constructor that allows to specify the encoding
|
||||
String wxstring(cstring, wxConvUTF8);
|
||||
boost::json::string jstring = jv.get_string();
|
||||
if (jstring.empty()) return to_script(String());
|
||||
const char* data = jstring.data();
|
||||
size_t size = jstring.size();
|
||||
String wxstring = String::FromUTF8(data, size);
|
||||
if (!wxstring.empty()) return to_script(wxstring);
|
||||
// if all else fails, use "Whatever Works"
|
||||
return to_script(String(cstring, wxConvWhateverWorks));
|
||||
return to_script(String(data, wxConvWhateverWorks, size));
|
||||
}
|
||||
else if (jv.is_array()) {
|
||||
boost::json::array array = jv.get_array();
|
||||
@@ -349,18 +379,16 @@ ScriptValueP json_to_mse(const boost::json::value& jv, Set* set) {
|
||||
if (mse_object_type == "keyword") return make_intrusive<ScriptObject<KeywordP>> (json_to_mse_keyword(object));
|
||||
if (mse_object_type == "pack_type") return make_intrusive<ScriptObject<PackTypeP>>(json_to_mse_pack_type(object));
|
||||
if (mse_object_type == "pack_item") return make_intrusive<ScriptObject<PackItemP>>(json_to_mse_pack_item(object));
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("json unknown type") + _("(") + wxString(mse_object_type.c_str()) + _(")"));
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("json unknown type") + _("(") + String(mse_object_type.c_str()) + _(")"));
|
||||
return script_nil;
|
||||
}
|
||||
ScriptCustomCollectionP result = make_intrusive<ScriptCustomCollection>();
|
||||
for (auto it = object.begin(); it != object.end(); ++it) {
|
||||
boost::json::string_view jview = it->key();
|
||||
std::string_view stdview = std::string_view(jview.data(), jview.size());
|
||||
std::string stdstring = { stdview.begin(), stdview.end() };
|
||||
String key(stdstring.c_str(), wxConvUTF8);
|
||||
String key_name = String::FromUTF8(jview.data(), jview.size());
|
||||
boost::json::value jvalue = it->value();
|
||||
ScriptValueP value = json_to_mse(jvalue, set);
|
||||
result->key_value[key] = value;
|
||||
result->key_value[key_name] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -374,8 +402,9 @@ ScriptValueP json_to_mse(const String& string, Set* set) {
|
||||
boost::system::error_code ec;
|
||||
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());
|
||||
wxScopedCharBuffer buffer = string.ToUTF8();
|
||||
boost::json::value jv = boost::json::parse(boost::json::string_view(buffer.data(), buffer.length()), ec, {}, options);
|
||||
if(ec && buffer.length() > 0) queue_message(MESSAGE_ERROR, _ERROR_("json cant parse") + _("\n\n") + ec.message());
|
||||
if(ec) return script_nil;
|
||||
return json_to_mse(jv, set);
|
||||
}
|
||||
@@ -512,92 +541,92 @@ boost::json::object mse_to_json(const StyleP& style) {
|
||||
|
||||
boost::json::object stylev;
|
||||
stylev.emplace("mse_object_type", "style");
|
||||
stylev.emplace("z_index", wxString::Format(wxT("%i"), style->z_index));
|
||||
stylev.emplace("tab_index", wxString::Format(wxT("%i"), style->tab_index));
|
||||
stylev.emplace("left", wxString::Format(wxT("%.2f"), style->left()));
|
||||
stylev.emplace("top", wxString::Format(wxT("%.2f"), style->top()));
|
||||
stylev.emplace("right", wxString::Format(wxT("%.2f"), style->right()));
|
||||
stylev.emplace("bottom", wxString::Format(wxT("%.2f"), style->bottom()));
|
||||
stylev.emplace("width", wxString::Format(wxT("%.2f"), style->width()));
|
||||
stylev.emplace("height", wxString::Format(wxT("%.2f"), style->height()));
|
||||
stylev.emplace("angle", wxString::Format(wxT("%.2f"), style->angle()));
|
||||
stylev.emplace("visible", style->visible());
|
||||
stylev.emplace("mask", style->mask.toScriptString());
|
||||
stylev.emplace("z_index", String::Format(wxT("%i"), style->z_index));
|
||||
stylev.emplace("tab_index", String::Format(wxT("%i"), style->tab_index));
|
||||
stylev.emplace("left", String::Format(wxT("%.2f"), style->left()));
|
||||
stylev.emplace("top", String::Format(wxT("%.2f"), style->top()));
|
||||
stylev.emplace("right", String::Format(wxT("%.2f"), style->right()));
|
||||
stylev.emplace("bottom", String::Format(wxT("%.2f"), style->bottom()));
|
||||
stylev.emplace("width", String::Format(wxT("%.2f"), style->width()));
|
||||
stylev.emplace("height", String::Format(wxT("%.2f"), style->height()));
|
||||
stylev.emplace("angle", String::Format(wxT("%.2f"), style->angle()));
|
||||
stylev.emplace("visible", style->visible());
|
||||
stylev.emplace("mask", style->mask.toScriptString());
|
||||
|
||||
if (TextStyle* s = dynamic_cast<TextStyle*>(style.get())) {
|
||||
stylev.emplace("field_type", "text");
|
||||
|
||||
boost::json::object fontv;
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", wxString::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", wxString::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", wxString::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", wxString::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", wxString::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", wxString::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", wxString::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", String::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", String::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", String::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", String::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", String::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", String::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", String::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", String::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", String::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
|
||||
boost::json::object symbolfontv;
|
||||
symbolfontv.emplace("name", s->symbol_font.name());
|
||||
symbolfontv.emplace("size", wxString::Format(wxT("%.2f"), s->symbol_font.size()));
|
||||
symbolfontv.emplace("underline", s->symbol_font.underline());
|
||||
symbolfontv.emplace("strikethrough", s->symbol_font.strikethrough());
|
||||
symbolfontv.emplace("scale_down_to", wxString::Format(wxT("%.2f"), s->symbol_font.scale_down_to));
|
||||
symbolfontv.emplace("shadow_color", format_color( s->symbol_font.shadow_color()));
|
||||
symbolfontv.emplace("shadow_displacement_x", wxString::Format(wxT("%.2f"), s->symbol_font.shadow_displacement_x()));
|
||||
symbolfontv.emplace("shadow_displacement_y", wxString::Format(wxT("%.2f"), s->symbol_font.shadow_displacement_y()));
|
||||
symbolfontv.emplace("shadow_blur", wxString::Format(wxT("%.2f"), s->symbol_font.shadow_blur()));
|
||||
symbolfontv.emplace("stroke_color", format_color( s->symbol_font.stroke_color()));
|
||||
symbolfontv.emplace("stroke_radius", wxString::Format(wxT("%.2f"), s->symbol_font.stroke_radius()));
|
||||
symbolfontv.emplace("stroke_blur", wxString::Format(wxT("%.2f"), s->symbol_font.stroke_blur()));
|
||||
stylev.emplace("symbol_font", symbolfontv);
|
||||
symbolfontv.emplace("name", s->symbol_font.name());
|
||||
symbolfontv.emplace("size", String::Format(wxT("%.2f"), s->symbol_font.size()));
|
||||
symbolfontv.emplace("underline", s->symbol_font.underline());
|
||||
symbolfontv.emplace("strikethrough", s->symbol_font.strikethrough());
|
||||
symbolfontv.emplace("scale_down_to", String::Format(wxT("%.2f"), s->symbol_font.scale_down_to));
|
||||
symbolfontv.emplace("shadow_color", format_color( s->symbol_font.shadow_color()));
|
||||
symbolfontv.emplace("shadow_displacement_x", String::Format(wxT("%.2f"), s->symbol_font.shadow_displacement_x()));
|
||||
symbolfontv.emplace("shadow_displacement_y", String::Format(wxT("%.2f"), s->symbol_font.shadow_displacement_y()));
|
||||
symbolfontv.emplace("shadow_blur", String::Format(wxT("%.2f"), s->symbol_font.shadow_blur()));
|
||||
symbolfontv.emplace("stroke_color", format_color( s->symbol_font.stroke_color()));
|
||||
symbolfontv.emplace("stroke_radius", String::Format(wxT("%.2f"), s->symbol_font.stroke_radius()));
|
||||
symbolfontv.emplace("stroke_blur", String::Format(wxT("%.2f"), s->symbol_font.stroke_blur()));
|
||||
stylev.emplace("symbol_font", symbolfontv);
|
||||
|
||||
stylev.emplace("always_symbol", s->always_symbol);
|
||||
stylev.emplace("allow_formating", s->allow_formating);
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment()));
|
||||
stylev.emplace("direction", direction_to_string( s->direction));
|
||||
stylev.emplace("padding_left", wxString::Format(wxT("%.2f"), s->padding_left()));
|
||||
stylev.emplace("padding_right", wxString::Format(wxT("%.2f"), s->padding_right()));
|
||||
stylev.emplace("padding_top", wxString::Format(wxT("%.2f"), s->padding_top()));
|
||||
stylev.emplace("padding_bottom", wxString::Format(wxT("%.2f"), s->padding_bottom()));
|
||||
stylev.emplace("padding_left_min", wxString::Format(wxT("%.2f"), s->padding_left_min()));
|
||||
stylev.emplace("padding_right_min", wxString::Format(wxT("%.2f"), s->padding_right_min()));
|
||||
stylev.emplace("padding_top_min", wxString::Format(wxT("%.2f"), s->padding_top_min()));
|
||||
stylev.emplace("padding_bottom_min", wxString::Format(wxT("%.2f"), s->padding_bottom_min()));
|
||||
stylev.emplace("line_height_soft", wxString::Format(wxT("%.2f"), s->line_height_soft()));
|
||||
stylev.emplace("line_height_hard", wxString::Format(wxT("%.2f"), s->line_height_hard()));
|
||||
stylev.emplace("line_height_line", wxString::Format(wxT("%.2f"), s->line_height_line()));
|
||||
stylev.emplace("line_height_soft_max", wxString::Format(wxT("%.2f"), s->line_height_soft_max()));
|
||||
stylev.emplace("line_height_hard_max", wxString::Format(wxT("%.2f"), s->line_height_hard_max()));
|
||||
stylev.emplace("line_height_line_max", wxString::Format(wxT("%.2f"), s->line_height_line_max()));
|
||||
stylev.emplace("paragraph_height", wxString::Format(wxT("%.2f"), s->paragraph_height()));
|
||||
stylev.emplace("always_symbol", s->always_symbol);
|
||||
stylev.emplace("allow_formating", s->allow_formating);
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment()));
|
||||
stylev.emplace("direction", direction_to_string( s->direction));
|
||||
stylev.emplace("padding_left", String::Format(wxT("%.2f"), s->padding_left()));
|
||||
stylev.emplace("padding_right", String::Format(wxT("%.2f"), s->padding_right()));
|
||||
stylev.emplace("padding_top", String::Format(wxT("%.2f"), s->padding_top()));
|
||||
stylev.emplace("padding_bottom", String::Format(wxT("%.2f"), s->padding_bottom()));
|
||||
stylev.emplace("padding_left_min", String::Format(wxT("%.2f"), s->padding_left_min()));
|
||||
stylev.emplace("padding_right_min", String::Format(wxT("%.2f"), s->padding_right_min()));
|
||||
stylev.emplace("padding_top_min", String::Format(wxT("%.2f"), s->padding_top_min()));
|
||||
stylev.emplace("padding_bottom_min", String::Format(wxT("%.2f"), s->padding_bottom_min()));
|
||||
stylev.emplace("line_height_soft", String::Format(wxT("%.2f"), s->line_height_soft()));
|
||||
stylev.emplace("line_height_hard", String::Format(wxT("%.2f"), s->line_height_hard()));
|
||||
stylev.emplace("line_height_line", String::Format(wxT("%.2f"), s->line_height_line()));
|
||||
stylev.emplace("line_height_soft_max", String::Format(wxT("%.2f"), s->line_height_soft_max()));
|
||||
stylev.emplace("line_height_hard_max", String::Format(wxT("%.2f"), s->line_height_hard_max()));
|
||||
stylev.emplace("line_height_line_max", String::Format(wxT("%.2f"), s->line_height_line_max()));
|
||||
stylev.emplace("paragraph_height", String::Format(wxT("%.2f"), s->paragraph_height()));
|
||||
|
||||
boost::json::object layoutv;
|
||||
layoutv.emplace("content_top", wxString::Format(wxT("%.2f"), s->layout->top));
|
||||
layoutv.emplace("content_middle", wxString::Format(wxT("%.2f"), s->layout->middle()));
|
||||
layoutv.emplace("content_bottom", wxString::Format(wxT("%.2f"), s->layout->bottom()));
|
||||
layoutv.emplace("content_width", wxString::Format(wxT("%.2f"), s->layout->width));
|
||||
layoutv.emplace("content_height", wxString::Format(wxT("%.2f"), s->layout->height));
|
||||
layoutv.emplace("content_lines", wxString::Format(wxT("%i"), s->layout->lines.size()));
|
||||
layoutv.emplace("content_clauses", wxString::Format(wxT("%i"), s->layout->clauses.size()));
|
||||
layoutv.emplace("content_paragraphs", wxString::Format(wxT("%i"), s->layout->paragraphs.size()));
|
||||
layoutv.emplace("content_blocks", wxString::Format(wxT("%i"), s->layout->blocks.size()));
|
||||
layoutv.emplace("content_top", String::Format(wxT("%.2f"), s->layout->top));
|
||||
layoutv.emplace("content_middle", String::Format(wxT("%.2f"), s->layout->middle()));
|
||||
layoutv.emplace("content_bottom", String::Format(wxT("%.2f"), s->layout->bottom()));
|
||||
layoutv.emplace("content_width", String::Format(wxT("%.2f"), s->layout->width));
|
||||
layoutv.emplace("content_height", String::Format(wxT("%.2f"), s->layout->height));
|
||||
layoutv.emplace("content_lines", String::Format(wxT("%i"), s->layout->lines.size()));
|
||||
layoutv.emplace("content_clauses", String::Format(wxT("%i"), s->layout->clauses.size()));
|
||||
layoutv.emplace("content_paragraphs", String::Format(wxT("%i"), s->layout->paragraphs.size()));
|
||||
layoutv.emplace("content_blocks", String::Format(wxT("%i"), s->layout->blocks.size()));
|
||||
boost::json::array separatorsv;
|
||||
int size = s->layout->separators.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
separatorsv.emplace_back(wxString::Format(wxT("%.2f"), s->layout->separators[i]));
|
||||
separatorsv.emplace_back(String::Format(wxT("%.2f"), s->layout->separators[i]));
|
||||
}
|
||||
if (size > 0) layoutv.emplace("content_separators", separatorsv);
|
||||
|
||||
@@ -612,35 +641,35 @@ boost::json::object mse_to_json(const StyleP& style) {
|
||||
|
||||
else if (MultipleChoiceStyle* s = dynamic_cast<MultipleChoiceStyle*>(style.get())) {
|
||||
stylev.emplace("field_type", "multiple_choice");
|
||||
stylev.emplace("popup_style", popup_style_to_string( s->popup_style));
|
||||
stylev.emplace("render_style", render_style_to_string( s->render_style));
|
||||
stylev.emplace("image", s->image.toScriptString());
|
||||
stylev.emplace("combine", combine_to_string( s->combine));
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment));
|
||||
stylev.emplace("direction", direction_to_string( s->direction()));
|
||||
stylev.emplace("spacing", wxString::Format(wxT("%.2f"), s->spacing()));
|
||||
stylev.emplace("popup_style", popup_style_to_string( s->popup_style));
|
||||
stylev.emplace("render_style", render_style_to_string( s->render_style));
|
||||
stylev.emplace("image", s->image.toScriptString());
|
||||
stylev.emplace("combine", combine_to_string( s->combine));
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment));
|
||||
stylev.emplace("direction", direction_to_string( s->direction()));
|
||||
stylev.emplace("spacing", String::Format(wxT("%.2f"), s->spacing()));
|
||||
|
||||
boost::json::object fontv;
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", wxString::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", wxString::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", wxString::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", wxString::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", wxString::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", wxString::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", wxString::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", String::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", String::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", String::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", String::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", String::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", String::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", String::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", String::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", String::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
|
||||
boost::json::object choiceimagesv;
|
||||
for (auto choice_image : s->choice_images) {
|
||||
@@ -652,33 +681,33 @@ boost::json::object mse_to_json(const StyleP& style) {
|
||||
|
||||
else if (ChoiceStyle* s = dynamic_cast<ChoiceStyle*>(style.get())) {
|
||||
stylev.emplace("field_type", dynamic_cast<BooleanStyle*>(style.get()) ? "boolean" : "choice");
|
||||
stylev.emplace("popup_style", popup_style_to_string( s->popup_style));
|
||||
stylev.emplace("render_style", render_style_to_string( s->render_style));
|
||||
stylev.emplace("image", s->image.toScriptString());
|
||||
stylev.emplace("combine", combine_to_string( s->combine));
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment));
|
||||
stylev.emplace("popup_style", popup_style_to_string( s->popup_style));
|
||||
stylev.emplace("render_style", render_style_to_string( s->render_style));
|
||||
stylev.emplace("image", s->image.toScriptString());
|
||||
stylev.emplace("combine", combine_to_string( s->combine));
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment));
|
||||
|
||||
boost::json::object fontv;
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", wxString::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", wxString::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", wxString::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", wxString::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", wxString::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", wxString::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", wxString::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", String::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", String::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", String::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", String::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", String::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", String::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", String::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", String::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", String::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
|
||||
boost::json::object choiceimagesv;
|
||||
for (auto choice_image : s->choice_images) {
|
||||
@@ -692,71 +721,71 @@ boost::json::object mse_to_json(const StyleP& style) {
|
||||
stylev.emplace("field_type", "package_choice");
|
||||
|
||||
boost::json::object fontv;
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", wxString::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", wxString::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", wxString::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", wxString::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", wxString::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", wxString::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", wxString::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", String::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", String::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", String::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", String::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", String::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", String::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", String::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", String::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", String::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
}
|
||||
|
||||
else if (ColorStyle* s = dynamic_cast<ColorStyle*>(style.get())) {
|
||||
stylev.emplace("field_type", "color");
|
||||
stylev.emplace("radius", wxString::Format(wxT("%.2f"), s->radius()));
|
||||
stylev.emplace("left_width", wxString::Format(wxT("%.2f"), s->left_width()));
|
||||
stylev.emplace("right_width", wxString::Format(wxT("%.2f"), s->right_width()));
|
||||
stylev.emplace("top_width", wxString::Format(wxT("%.2f"), s->top_width()));
|
||||
stylev.emplace("bottom_width", wxString::Format(wxT("%.2f"), s->bottom_width()));
|
||||
stylev.emplace("combine", combine_to_string( s->combine));
|
||||
stylev.emplace("radius", String::Format(wxT("%.2f"), s->radius()));
|
||||
stylev.emplace("left_width", String::Format(wxT("%.2f"), s->left_width()));
|
||||
stylev.emplace("right_width", String::Format(wxT("%.2f"), s->right_width()));
|
||||
stylev.emplace("top_width", String::Format(wxT("%.2f"), s->top_width()));
|
||||
stylev.emplace("bottom_width", String::Format(wxT("%.2f"), s->bottom_width()));
|
||||
stylev.emplace("combine", combine_to_string( s->combine));
|
||||
}
|
||||
|
||||
else if (SymbolStyle* s = dynamic_cast<SymbolStyle*>(style.get())) {
|
||||
stylev.emplace("field_type", "symbol");
|
||||
stylev.emplace("min_aspect_ratio", wxString::Format(wxT("%.2f"), s->min_aspect_ratio));
|
||||
stylev.emplace("max_aspect_ratio", wxString::Format(wxT("%.2f"), s->max_aspect_ratio));
|
||||
stylev.emplace("min_aspect_ratio", String::Format(wxT("%.2f"), s->min_aspect_ratio));
|
||||
stylev.emplace("max_aspect_ratio", String::Format(wxT("%.2f"), s->max_aspect_ratio));
|
||||
boost::json::array variationsv;
|
||||
int size = s->variations.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
boost::json::object variationv;
|
||||
variationv.emplace("name", s->variations[i]->name);
|
||||
variationv.emplace("border_radius", wxString::Format(wxT("%.2f"), s->variations[i]->border_radius));
|
||||
variationv.emplace("name", s->variations[i]->name);
|
||||
variationv.emplace("border_radius", String::Format(wxT("%.2f"), s->variations[i]->border_radius));
|
||||
SymbolFilterP filter = s->variations[i]->filter;
|
||||
if (SolidFillSymbolFilter* f = dynamic_cast<SolidFillSymbolFilter*>(filter.get())) {
|
||||
variationv.emplace("fill_type", f->fillType());
|
||||
variationv.emplace("fill_color", format_color( f->fill_color));
|
||||
variationv.emplace("border_color", format_color( f->border_color));
|
||||
variationv.emplace("fill_type", f->fillType());
|
||||
variationv.emplace("fill_color", format_color( f->fill_color));
|
||||
variationv.emplace("border_color", format_color( f->border_color));
|
||||
}
|
||||
else if (RadialGradientSymbolFilter* f = dynamic_cast<RadialGradientSymbolFilter*>(filter.get())) {
|
||||
variationv.emplace("fill_type", f->fillType());
|
||||
variationv.emplace("fill_color_1", format_color( f->fill_color_1));
|
||||
variationv.emplace("fill_color_2", format_color( f->fill_color_2));
|
||||
variationv.emplace("border_color_1", format_color( f->border_color_1));
|
||||
variationv.emplace("border_color_2", format_color( f->border_color_2));
|
||||
variationv.emplace("fill_type", f->fillType());
|
||||
variationv.emplace("fill_color_1", format_color( f->fill_color_1));
|
||||
variationv.emplace("fill_color_2", format_color( f->fill_color_2));
|
||||
variationv.emplace("border_color_1", format_color( f->border_color_1));
|
||||
variationv.emplace("border_color_2", format_color( f->border_color_2));
|
||||
}
|
||||
else if (LinearGradientSymbolFilter* f = dynamic_cast<LinearGradientSymbolFilter*>(filter.get())) {
|
||||
variationv.emplace("fill_type", f->fillType());
|
||||
variationv.emplace("fill_color_1", format_color( f->fill_color_1));
|
||||
variationv.emplace("fill_color_2", format_color( f->fill_color_2));
|
||||
variationv.emplace("border_color_1", format_color( f->border_color_1));
|
||||
variationv.emplace("border_color_2", format_color( f->border_color_2));
|
||||
variationv.emplace("center_x", wxString::Format(wxT("%.2f"), f->center_x));
|
||||
variationv.emplace("center_y", wxString::Format(wxT("%.2f"), f->center_y));
|
||||
variationv.emplace("end_x", wxString::Format(wxT("%.2f"), f->end_x));
|
||||
variationv.emplace("end_y", wxString::Format(wxT("%.2f"), f->end_y));
|
||||
variationv.emplace("fill_type", f->fillType());
|
||||
variationv.emplace("fill_color_1", format_color( f->fill_color_1));
|
||||
variationv.emplace("fill_color_2", format_color( f->fill_color_2));
|
||||
variationv.emplace("border_color_1", format_color( f->border_color_1));
|
||||
variationv.emplace("border_color_2", format_color( f->border_color_2));
|
||||
variationv.emplace("center_x", String::Format(wxT("%.2f"), f->center_x));
|
||||
variationv.emplace("center_y", String::Format(wxT("%.2f"), f->center_y));
|
||||
variationv.emplace("end_x", String::Format(wxT("%.2f"), f->end_x));
|
||||
variationv.emplace("end_y", String::Format(wxT("%.2f"), f->end_y));
|
||||
}
|
||||
variationsv.emplace_back(variationv);
|
||||
}
|
||||
@@ -765,34 +794,34 @@ boost::json::object mse_to_json(const StyleP& style) {
|
||||
|
||||
else if (InfoStyle* s = dynamic_cast<InfoStyle*>(style.get())) {
|
||||
stylev.emplace("field_type", "info");
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment));
|
||||
stylev.emplace("padding_left", wxString::Format(wxT("%.2f"), s->padding_left));
|
||||
stylev.emplace("padding_right", wxString::Format(wxT("%.2f"), s->padding_right));
|
||||
stylev.emplace("padding_top", wxString::Format(wxT("%.2f"), s->padding_top));
|
||||
stylev.emplace("padding_bottom", wxString::Format(wxT("%.2f"), s->padding_bottom));
|
||||
stylev.emplace("background_color", format_color( s->background_color));
|
||||
stylev.emplace("alignment", alignment_to_string( s->alignment));
|
||||
stylev.emplace("padding_left", String::Format(wxT("%.2f"), s->padding_left));
|
||||
stylev.emplace("padding_right", String::Format(wxT("%.2f"), s->padding_right));
|
||||
stylev.emplace("padding_top", String::Format(wxT("%.2f"), s->padding_top));
|
||||
stylev.emplace("padding_bottom", String::Format(wxT("%.2f"), s->padding_bottom));
|
||||
stylev.emplace("background_color", format_color( s->background_color));
|
||||
|
||||
boost::json::object fontv;
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", wxString::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", wxString::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", wxString::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", wxString::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", wxString::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", wxString::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", wxString::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", wxString::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
fontv.emplace("name", s->font.name());
|
||||
fontv.emplace("italic_name", s->font.italic_name());
|
||||
fontv.emplace("size", String::Format(wxT("%.2f"), s->font.size()));
|
||||
fontv.emplace("weight", s->font.weight());
|
||||
fontv.emplace("style", s->font.style());
|
||||
fontv.emplace("underline", s->font.underline());
|
||||
fontv.emplace("strikethrough", s->font.strikethrough());
|
||||
fontv.emplace("scale_down_to", String::Format(wxT("%.2f"), s->font.scale_down_to));
|
||||
fontv.emplace("max_stretch", String::Format(wxT("%.2f"), s->font.max_stretch));
|
||||
fontv.emplace("color", format_color( s->font.color()));
|
||||
fontv.emplace("shadow_color", format_color( s->font.shadow_color()));
|
||||
fontv.emplace("shadow_displacement_x", String::Format(wxT("%.2f"), s->font.shadow_displacement_x()));
|
||||
fontv.emplace("shadow_displacement_y", String::Format(wxT("%.2f"), s->font.shadow_displacement_y()));
|
||||
fontv.emplace("shadow_blur", String::Format(wxT("%.2f"), s->font.shadow_blur()));
|
||||
fontv.emplace("stroke_color", format_color( s->font.stroke_color()));
|
||||
fontv.emplace("stroke_radius", String::Format(wxT("%.2f"), s->font.stroke_radius()));
|
||||
fontv.emplace("stroke_blur", String::Format(wxT("%.2f"), s->font.stroke_blur()));
|
||||
fontv.emplace("separator_color", format_color( s->font.separator_color));
|
||||
fontv.emplace("flags", String::Format(wxT("%i"), s->font.flags));
|
||||
stylev.emplace("font", fontv);
|
||||
}
|
||||
|
||||
return stylev;
|
||||
|
||||
@@ -18,9 +18,9 @@ using boost::tribool;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Reader
|
||||
|
||||
Reader::Reader(wxInputStream& input, Packaged* package, const String& filename, bool ignore_invalid)
|
||||
Reader::Reader(wxInputStream& input, Packaged* package, const String& filename, bool ignore_invalid, bool suppress_warnings)
|
||||
: indent(0), expected_indent(0), state(OUTSIDE)
|
||||
, ignore_invalid(ignore_invalid)
|
||||
, ignore_invalid(ignore_invalid), suppress_warnings(suppress_warnings)
|
||||
, filename(filename), package(package), line_number(0), previous_line_number(0)
|
||||
, input(input)
|
||||
{
|
||||
@@ -53,7 +53,7 @@ void Reader::warning(const String& msg, int line_number_delta, bool warn_on_prev
|
||||
}
|
||||
|
||||
void Reader::showWarnings() {
|
||||
if (!warnings.empty()) {
|
||||
if (!suppress_warnings && !warnings.empty()) {
|
||||
queue_message(MESSAGE_WARNING, _("Warnings while reading file:\n") + filename + _("\n") + warnings);
|
||||
warnings.clear();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,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 = _(""), bool ignore_invalid = false);
|
||||
Reader(wxInputStream& input, Packaged* package = nullptr, const String& filename = _(""), bool ignore_invalid = false, bool suppress_warnings = false);
|
||||
|
||||
~Reader() { showWarnings(); }
|
||||
|
||||
@@ -148,7 +148,9 @@ private:
|
||||
} state;
|
||||
/// Should all invalid keys be ignored?
|
||||
bool ignore_invalid;
|
||||
|
||||
/// Should warnings be emitted?
|
||||
bool suppress_warnings;
|
||||
|
||||
/// Filename for error messages
|
||||
String filename;
|
||||
/// Package this file is from, if any
|
||||
|
||||
Reference in New Issue
Block a user