mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
refactor card copy pasting
This commit is contained in:
@@ -63,7 +63,9 @@ IMPLEMENT_REFLECTION(WrappedCards) {
|
|||||||
|
|
||||||
wxDataFormat CardsDataObject::format(wxString("application/x-mse-cards"));
|
wxDataFormat CardsDataObject::format(wxString("application/x-mse-cards"));
|
||||||
|
|
||||||
CardsDataObject::CardsDataObject(const SetP& set, const String id, const vector<CardP>& cards) {
|
CardsDataObject::CardsDataObject(const SetP& set, const String& id, const vector<CardP>& cards)
|
||||||
|
: wxCustomDataObject(format)
|
||||||
|
{
|
||||||
// set the stylesheet, so when deserializing we know whos style options we are reading
|
// set the stylesheet, so when deserializing we know whos style options we are reading
|
||||||
vector<bool> has_styling;
|
vector<bool> has_styling;
|
||||||
for (size_t i = 0 ; i < cards.size() ; ++i) {
|
for (size_t i = 0 ; i < cards.size() ; ++i) {
|
||||||
@@ -72,9 +74,15 @@ CardsDataObject::CardsDataObject(const SetP& set, const String id, const vector<
|
|||||||
cards[i]->stylesheet = set->stylesheet;
|
cards[i]->stylesheet = set->stylesheet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store as raw bytes
|
||||||
WrappedCards data = { set->game.get(), set->game->name(), id, cards };
|
WrappedCards data = { set->game.get(), set->game->name(), id, cards };
|
||||||
SetText(serialize_for_clipboard(*set, data));
|
String serialized = serialize_for_clipboard(*set, data);
|
||||||
// restore cards
|
wxScopedCharBuffer utf8 = serialized.utf8_str();
|
||||||
|
buffer.assign(utf8.data(), utf8.length());
|
||||||
|
SetData(buffer.size(), buffer.data());
|
||||||
|
|
||||||
|
// restore styling
|
||||||
for (size_t i = 0 ; i < cards.size() ; ++i) {
|
for (size_t i = 0 ; i < cards.size() ; ++i) {
|
||||||
if (has_styling[i]) {
|
if (has_styling[i]) {
|
||||||
cards[i]->stylesheet = StyleSheetP();
|
cards[i]->stylesheet = StyleSheetP();
|
||||||
@@ -83,22 +91,31 @@ CardsDataObject::CardsDataObject(const SetP& set, const String id, const vector<
|
|||||||
SetFormat(format);
|
SetFormat(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
CardsDataObject::CardsDataObject() {
|
CardsDataObject::CardsDataObject()
|
||||||
SetFormat(format);
|
: wxCustomDataObject(format)
|
||||||
}
|
{}
|
||||||
|
|
||||||
bool CardsDataObject::getCards(const SetP& set, const String id, vector<CardP>& out) {
|
bool CardsDataObject::getCards(const SetP& set, const String& id, vector<CardP>& out) {
|
||||||
|
size_t size = GetSize();
|
||||||
|
if (size == 0) return false;
|
||||||
|
const void* raw = GetData();
|
||||||
|
if (!raw) return false;
|
||||||
|
|
||||||
|
String text(wxString::FromUTF8(static_cast<const char*>(raw), size));
|
||||||
WrappedCards data = { set->game.get(), set->game->name() };
|
WrappedCards data = { set->game.get(), set->game->name() };
|
||||||
deserialize_from_clipboard(data, *set, GetText());
|
try {
|
||||||
|
deserialize_from_clipboard(data, *set, text);
|
||||||
|
} catch (...) {
|
||||||
|
queue_message(MESSAGE_ERROR, _("DEBUG: Card deserialization failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (data.cards.empty()) return false;
|
if (data.cards.empty()) return false;
|
||||||
if (!id.empty() && data.id == id) return false;
|
if (!id.empty() && data.id == id) return false;
|
||||||
if (data.game_name == set->game->name()) {
|
if (data.game_name != set->game->name()) return false;
|
||||||
// Cards are from the same game
|
// Cards are from the same game
|
||||||
out = data.cards;
|
out = data.cards;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : KeywordDataObject
|
// ----------------------------------------------------------------------------- : KeywordDataObject
|
||||||
|
|||||||
@@ -18,19 +18,22 @@ DECLARE_POINTER_TYPE(Keyword);
|
|||||||
// ----------------------------------------------------------------------------- : CardDataObject
|
// ----------------------------------------------------------------------------- : CardDataObject
|
||||||
|
|
||||||
/// The data format for cards on the clipboard
|
/// The data format for cards on the clipboard
|
||||||
class CardsDataObject : public wxTextDataObject {
|
class CardsDataObject : public wxCustomDataObject {
|
||||||
public:
|
public:
|
||||||
/// Name of the format of MSE cards
|
/// Name of the format of MSE cards
|
||||||
static wxDataFormat format;
|
static wxDataFormat format;
|
||||||
|
|
||||||
CardsDataObject();
|
CardsDataObject();
|
||||||
/// Store a card
|
/// Store a card
|
||||||
CardsDataObject(const SetP& set, const String id, const vector<CardP>& cards);
|
CardsDataObject(const SetP& set, const String& id, const vector<CardP>& cards);
|
||||||
|
|
||||||
/// Retrieve the cards, only if this is made with the same game as set
|
/// Retrieve the cards, only if this is made with the same game as set
|
||||||
/// And if this is NOT of the same id as the given one
|
/// And if this is NOT of the same id as the given one
|
||||||
/** Return true if the cards are correctly retrieved, and there is at least one card */
|
/** Return true if the cards are correctly retrieved, and there is at least one card */
|
||||||
bool getCards(const SetP& set, const String id, vector<CardP>& out);
|
bool getCards(const SetP& set, const String& id, vector<CardP>& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string buffer; // keep data alive for wx
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : KeywordDataObject
|
// ----------------------------------------------------------------------------- : KeywordDataObject
|
||||||
|
|||||||
@@ -333,6 +333,10 @@ bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
|
|||||||
std::ifstream ifs(filenames[i].ToStdString());
|
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>()));
|
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;
|
||||||
wxString text(content);
|
wxString text(content);
|
||||||
if (!parseUrl(text, out)) parseText(text, out);
|
if (!parseUrl(text, out)) parseText(text, out);
|
||||||
}
|
}
|
||||||
@@ -357,8 +361,9 @@ bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
|
|||||||
|
|
||||||
bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||||
size_t j = out.size();
|
size_t j = out.size();
|
||||||
if (size_t pos = text.find("<mse-card-data>") != wxString::npos) {
|
size_t pos = text.find("<mse-card-data>");
|
||||||
text = text.substr(pos + 14, text.find("</mse-card-data>") - pos - 14);
|
if (pos != wxString::npos) {
|
||||||
|
text = text.substr(pos + 15, text.find("</mse-card-data>") - pos - 15);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ScriptValueP sv = json_to_mse(text, set.get());
|
ScriptValueP sv = json_to_mse(text, set.get());
|
||||||
@@ -386,15 +391,26 @@ bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
|||||||
|
|
||||||
bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||||
wxBusyCursor wait;
|
wxBusyCursor wait;
|
||||||
wxDataFormat format = drop_target->data_object->GetReceivedFormat();
|
wxDataObjectComposite* composite = drop_target->data_object;
|
||||||
wxDataObject *data = drop_target->data_object->GetObject(format);
|
wxDataFormat format = composite->GetReceivedFormat();
|
||||||
vector<CardP> new_cards;
|
vector<CardP> new_cards;
|
||||||
|
|
||||||
if (CardsDataObject* card_data = dynamic_cast<CardsDataObject*>(data)) {
|
if (format == CardsDataObject::format) {
|
||||||
String id = ignore_cards_from_own_card_list ? drop_target->ignored_id : _("");
|
String id = ignore_cards_from_own_card_list ? drop_target->ignored_id : _("");
|
||||||
card_data->getCards(set, id, new_cards);
|
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);
|
||||||
}
|
}
|
||||||
else switch (format.GetType())
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wxDataObject *data = composite->GetObject(format);
|
||||||
|
|
||||||
|
switch (format.GetType())
|
||||||
{
|
{
|
||||||
case wxDF_FILENAME:
|
case wxDF_FILENAME:
|
||||||
{
|
{
|
||||||
@@ -436,6 +452,7 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
|||||||
queue_message(MESSAGE_ERROR, _ERROR_("unknown data format"));
|
queue_message(MESSAGE_ERROR, _ERROR_("unknown data format"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (new_cards.size() > 0) {
|
if (new_cards.size() > 0) {
|
||||||
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
|
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
|
||||||
|
|||||||
Reference in New Issue
Block a user