diff --git a/CMakeLists.txt b/CMakeLists.txt index 0725971e..7c47fdd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ endif() # You will most likely get a message about being unable to open hunspell-1.7.lib because pkgconf forgets to add the actual path to # HUNSPELL_LIBRARIES. If so, uncomment the below line and point it to the correct vcpkg root folder/library. -set(HUNSPELL_LIBRARIES "C:\\src\\vcpkg\\installed\\${VCPKG_TARGET_TRIPLET}\\lib\\hunspell-1.7.lib") +#set(HUNSPELL_LIBRARIES "C:\\PATH\\TO\\ROOT\\vcpkg\\installed\\${VCPKG_TARGET_TRIPLET}\\lib\\hunspell-1.7.lib") message("-- Does this have a full path? If not, and it's just a file name, it's broken: Found Hunspell at ${HUNSPELL_LIBRARIES}") include_directories("${PROJECT_BINARY_DIR}/src") diff --git a/data/ch-s.mse-locale/locale b/data/ch-s.mse-locale/locale index 1476ab5e..f0cb505b 100644 --- a/data/ch-s.mse-locale/locale +++ b/data/ch-s.mse-locale/locale @@ -1143,6 +1143,10 @@ error: # error from files #TODO: Localize no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: 没有为 %s 指定游戏类型 no stylesheet specified for the set: 没有为套牌制定样式表 stylesheet and set refer to different game: diff --git a/data/ch-t.mse-locale/locale b/data/ch-t.mse-locale/locale index 8d0b3186..74963072 100644 --- a/data/ch-t.mse-locale/locale +++ b/data/ch-t.mse-locale/locale @@ -1141,6 +1141,10 @@ error: # error from files #TODO: Localize no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: 沒有為 %s 指定游戲類型 no stylesheet specified for the set: 沒有為套牌制定樣式表 stylesheet and set refer to different game: diff --git a/data/da.mse-locale/locale b/data/da.mse-locale/locale index 9f6f6dce..218e0bb8 100644 --- a/data/da.mse-locale/locale +++ b/data/da.mse-locale/locale @@ -1167,6 +1167,10 @@ error: # error from files #TODO: Localize Section no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: No game specified for the %s no stylesheet specified for the set: No stylesheet specified for the set stylesheet and set refer to different game: diff --git a/data/de.mse-locale/locale b/data/de.mse-locale/locale index d2dc0f38..89601e61 100644 --- a/data/de.mse-locale/locale +++ b/data/de.mse-locale/locale @@ -1055,6 +1055,8 @@ error: # error from files no card fields: Das Spiel '%s' hat keine Kartenfelder. Definieren Sie mindestens ein Kartenfeld. + reserved field name: '%s' ist ein reservierter Kartenfeldname. Verwenden Sie einen anderen Namen. + duplicate field name: Der alternative Kartenfeldname '%s' ist sowohl eine Alternative zu '%s' als auch zu '%s'. no game specified: Kein Spiel für %s gewählt no stylesheet specified for the set: Kein Stylesheet für diese Edition gewählt stylesheet and set refer to different game: diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index 5abf33dc..791540b1 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -1056,6 +1056,8 @@ error: # error from files no card fields: Game '%s' does not have any card fields. Define at least one card field. + reserved field name: '%s' is a reserved card field name. Use another name. + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: No game specified for the %s no stylesheet specified for the set: No stylesheet specified for the set stylesheet and set refer to different game: diff --git a/data/es.mse-locale/locale b/data/es.mse-locale/locale index ca08119f..7b476f66 100644 --- a/data/es.mse-locale/locale +++ b/data/es.mse-locale/locale @@ -1144,6 +1144,10 @@ error: # error from files #TODO: Localize no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: Ningún juego especificado para el %s no stylesheet specified for the set: Ho hay hojas de estilo (stylesheet) especificadas para el Set stylesheet and set refer to different game: diff --git a/data/fr.mse-locale/locale b/data/fr.mse-locale/locale index 7e526f2e..f338173f 100644 --- a/data/fr.mse-locale/locale +++ b/data/fr.mse-locale/locale @@ -1055,6 +1055,8 @@ error: # error from files no card fields: Le jeu '%s' ne contient aucun champ de carte. Définissez au moins un champ de carte. + reserved field name: '%s' est un nom de champ réservé. Veuillez utiliser un autre nom. + duplicate field name: Le nom de champ alternatif '%s' est un doublon : il s’agit à la fois d’un nom alternatif pour '%s' et '%s'. no game specified: Pas de jeu spécifié pour le %s no stylesheet specified for the set: Pas de Style spécifié pour le Set stylesheet and set refer to different game: diff --git a/data/it.mse-locale/locale b/data/it.mse-locale/locale index 9b88682e..7a9fbb12 100644 --- a/data/it.mse-locale/locale +++ b/data/it.mse-locale/locale @@ -1055,6 +1055,8 @@ error: # error from files no card fields: Il gioco '%s' non ha campi carta. Definisci almeno un campo carta. + reserved field name: '%s' è un nome di campo riservato per la scheda. Utilizzare un altro nome. + duplicate field name: Il nome di campo alternativo '%s' è sia un'alternativa per '%s' che per '%s'. no game specified: Nessun gioco specificato per il %s no stylesheet specified for the set: Nessuno stile specificato per il set stylesheet and set refer to different game: diff --git a/data/jp.mse-locale/locale b/data/jp.mse-locale/locale index 6aae9206..e17b2533 100644 --- a/data/jp.mse-locale/locale +++ b/data/jp.mse-locale/locale @@ -1144,6 +1144,10 @@ error: # error from files #TODO: Localize no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: のゲームに指定された %s no stylesheet specified for the set: セットのために指定されたスタイルシートはありません stylesheet and set refer to different game: diff --git a/data/ko.mse-locale/locale b/data/ko.mse-locale/locale index b192eea5..b1a1443c 100644 --- a/data/ko.mse-locale/locale +++ b/data/ko.mse-locale/locale @@ -1150,6 +1150,10 @@ error: # error from files #TODO: Localize no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: 에 지정된 게임이 없습니다 %s no stylesheet specified for the set: 세트에 지정된 스타일시트가 없습니다 stylesheet and set refer to different game: diff --git a/data/pl.mse-locale/locale b/data/pl.mse-locale/locale index fe2953ea..4aa686af 100644 --- a/data/pl.mse-locale/locale +++ b/data/pl.mse-locale/locale @@ -1200,6 +1200,10 @@ error: # error from files #TODO: Localize no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: Nie podano gry dla %s no stylesheet specified for the set: Nie podano arkusza stylu dla zestawu stylesheet and set refer to different game: diff --git a/data/pt-br.mse-locale/locale b/data/pt-br.mse-locale/locale index 5f2990b0..751e62fc 100644 --- a/data/pt-br.mse-locale/locale +++ b/data/pt-br.mse-locale/locale @@ -1056,6 +1056,8 @@ error: # error from files no card fields: O jogo '%s' não possui campos de Card. Defina pelo menos um campo de Card. + reserved field name: '%s' é um nome de campo de Card reservado. Use outro nome. + duplicate field name: Nome de campo de Card alternativo '%s' é um nome alternativo tanto para '%s' quanto para '%s'. no game specified: Não há jogo especificado para o %s no stylesheet specified for the set: Não estilo especificado para a Edição stylesheet and set refer to different game: diff --git a/data/ru.mse-locale/locale b/data/ru.mse-locale/locale index 4ccdffd8..2d5e2026 100644 --- a/data/ru.mse-locale/locale +++ b/data/ru.mse-locale/locale @@ -1195,6 +1195,10 @@ error: # error from files #TODO: Localize Section no card fields: Game '%s' does not have any card fields. Define at least one card field. + #TODO: Localize + reserved field name: '%s' is a reserved card field name. Use another name. + #TODO: Localize + duplicate field name: Duplicate alt card field name '%s' is both an alt for '%s' and '%s'. no game specified: No game specified for the %s no stylesheet specified for the set: No stylesheet specified for the set stylesheet and set refer to different game: diff --git a/src/data/action/set.cpp b/src/data/action/set.cpp index b37cc88c..2d435d98 100644 --- a/src/data/action/set.cpp +++ b/src/data/action/set.cpp @@ -71,7 +71,7 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector& } else { String relation(linked_card->getLinkedRelation(linked_index)); - card_link_actions.push_back(make_intrusive(set, linked_card, new_uid, relation, linked_index)); + card_link_actions.push_back(make_intrusive(linked_card, new_uid, relation, linked_index)); } } } @@ -115,8 +115,8 @@ void ReorderCardsAction::perform(bool to_undo) { // ----------------------------------------------------------------------------- : Link cards -OneWayLinkCardsAction::OneWayLinkCardsAction(Set& set, CardP& card, const String& uid, const String& relation, int index) - : CardListAction(set), card(card), uid(uid), relation(relation) +OneWayLinkCardsAction::OneWayLinkCardsAction(CardP& card, const String& uid, const String& relation, int index) + : card(card), uid(uid), relation(relation) { switch (index) { case 0: { diff --git a/src/data/action/set.hpp b/src/data/action/set.hpp index b5d7bba7..6d09e84e 100644 --- a/src/data/action/set.hpp +++ b/src/data/action/set.hpp @@ -67,9 +67,9 @@ public: // ----------------------------------------------------------------------------- : Link cards /// Add a link between two or more cards -class OneWayLinkCardsAction : public CardListAction { +class OneWayLinkCardsAction : public Action { public: - OneWayLinkCardsAction(Set& set, CardP& card, const String& uid, const String& relation, int index); + OneWayLinkCardsAction(CardP& card, const String& uid, const String& relation, int index); String getName(bool to_undo) const override; void perform(bool to_undo) override; diff --git a/src/data/card.cpp b/src/data/card.cpp index 01d490fe..b8972a79 100644 --- a/src/data/card.cpp +++ b/src/data/card.cpp @@ -22,19 +22,21 @@ Card::Card() // for files made before we saved these, set the time to 'yesterday', generate a uid - : time_created (wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) + : game(game_for_reading()) + , time_created (wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) , time_modified(wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) , uid(generate_uid()) , has_styling(false) { - if (!game_for_reading()) { + if (!game) { throw InternalError(_("game_for_reading not set")); } - data.init(game_for_reading()->card_fields); + data.init(game->card_fields); } -Card::Card(const Game& game) - : time_created (wxDateTime::Now()) +Card::Card(Game& game) + : game(&game) + , time_created (wxDateTime::Now()) , time_modified(wxDateTime::Now()) , uid(generate_uid()) , has_styling(false) @@ -258,7 +260,37 @@ IndexMap& Card::extraDataFor(const StyleSheet& stylesheet) { return extra_data.get(stylesheet.name(), stylesheet.extra_card_fields); } -void mark_dependency_member(const Card& card, const String& name, const Dependency& dep) { +void mark_dependency_member(const Card& card, const String& name, const Dependency& dep) { + // is it the uid? + if (name == _("uid")) { + if (card.game) { + card.game->dependent_scripts_uid.add(dep); + } + return; + } + // is it the notes? + if (name == _("notes")) { + if (card.game) { + card.game->dependent_scripts_notes.add(dep); + } + return; + } + // is it a link? + if ( + name == _("linked_card_1") || + name == _("linked_card_2") || + name == _("linked_card_3") || + name == _("linked_card_4") || + name == _("linked_relation_1") || + name == _("linked_relation_2") || + name == _("linked_relation_3") || + name == _("linked_relation_4") + ) { + if (card.game) { + card.game->dependent_scripts_links.add(dep); + } + return; + } mark_dependency_member(card.data, name, dep); } diff --git a/src/data/card.hpp b/src/data/card.hpp index 06740a0d..67b10ba1 100644 --- a/src/data/card.hpp +++ b/src/data/card.hpp @@ -34,7 +34,10 @@ public: /// Default constructor, uses game_for_new_cards to make the game Card(); /// Creates a card using the given game - Card(const Game& game); + Card(Game& game); + + /// The game this card is made for + Game* game; /// The values on the fields of the card. /** The indices should correspond to the card_fields in the Game */ @@ -73,7 +76,7 @@ public: /// Keyword usage statistics vector> keyword_usage; - + /// Get the identification of this card, an identification is something like a name, title, etc. /** May return "" */ String identification() const; diff --git a/src/data/game.cpp b/src/data/game.cpp index 614096ae..d9bb6883 100644 --- a/src/data/game.cpp +++ b/src/data/game.cpp @@ -72,7 +72,7 @@ void Game::add_alt_name_or_warn(const String& alt_name, const String& field_name String unified_name = unified_form(alt_name); if (card_fields_alt_names.count(unified_name)) { if (card_fields_alt_names[unified_name] != field_name) { - queue_message(MESSAGE_WARNING, _("Duplicate alt card field name ' ") + unified_name + _(" ' is both an alt for: ' ") + field_name + _(" ' and ' ") + card_fields_alt_names[unified_name] + _(" '.")); + queue_message(MESSAGE_WARNING, _ERROR_3_("duplicate field name", unified_name, field_name, card_fields_alt_names[unified_name])); } } else { @@ -114,6 +114,32 @@ void Game::validate(Version v) { pack->filter = OptionalScript(_("true")); pack->select = SELECT_NO_REPLACE; pack_types.push_back(pack); + } + // check for reserved names + for (auto it = card_fields.begin(); it != card_fields.end(); ++it) { + FieldP field = *it; + String& field_name = field->name; + if ( + field_name == _("data") || + field_name == _("extra_data") || + field_name == _("styling_data") || + field_name == _("has_styling") || + field_name == _("stylesheet") || + field_name == _("time_created") || + field_name == _("time_modified") || + field_name == _("notes") || + field_name == _("uid") || + field_name == _("linked_card_1") || + field_name == _("linked_card_2") || + field_name == _("linked_card_3") || + field_name == _("linked_card_4") || + field_name == _("linked_relation_1") || + field_name == _("linked_relation_2") || + field_name == _("linked_relation_3") || + field_name == _("linked_relation_4") + ) { + queue_message(MESSAGE_ERROR, _ERROR_1_("reserved field name", field_name)); + } } // alternate card field names map for (auto it = card_fields.begin(); it != card_fields.end(); ++it) { diff --git a/src/data/game.hpp b/src/data/game.hpp index 620a89a1..f2f051ca 100644 --- a/src/data/game.hpp +++ b/src/data/game.hpp @@ -62,6 +62,9 @@ public: Dependencies dependent_scripts_cards; ///< scripts that depend on the card list Dependencies dependent_scripts_keywords; ///< scripts that depend on the keywords + Dependencies dependent_scripts_uid; ///< scripts that depend on the card's uid + Dependencies dependent_scripts_notes; ///< scripts that depend on the card's notes + Dependencies dependent_scripts_links; ///< scripts that depend on the card's links Dependencies dependent_scripts_stylesheet; ///< scripts that depend on the card's stylesheet bool dependencies_initialized; ///< are the script dependencies comming from this game all initialized? diff --git a/src/data/stylesheet.cpp b/src/data/stylesheet.cpp index 1ed7010e..ad57d428 100644 --- a/src/data/stylesheet.cpp +++ b/src/data/stylesheet.cpp @@ -74,7 +74,7 @@ void StyleSheet::validate(Version ver) { if (!game) { throw Error(_ERROR_1_("no game specified",_TYPE_("stylesheet"))); } - // a stylsheet depends on the game it is made for + // a stylesheet depends on the game it is made for requireDependency(game.get()); } diff --git a/src/gui/bulk_modification_window.cpp b/src/gui/bulk_modification_window.cpp index b187b20a..69f0a459 100644 --- a/src/gui/bulk_modification_window.cpp +++ b/src/gui/bulk_modification_window.cpp @@ -379,6 +379,7 @@ void BulkModificationWindow::onOk(wxCommandEvent&) { } else { set->actions.addAction(make_unique(actions, set, card_list_window, actions.size() > 1), false); + set->actions.tellListeners(DisplayChangeAction(),true); wxMessageDialog dial = wxMessageDialog(this, _ERROR_1_("bulk modify success", String() << actions.size())); dial.ShowModal(); EndModal(wxID_OK); diff --git a/src/gui/card_link_window.cpp b/src/gui/card_link_window.cpp index 7ef163bf..9a2591f1 100644 --- a/src/gui/card_link_window.cpp +++ b/src/gui/card_link_window.cpp @@ -157,7 +157,7 @@ void CardLinkWindow::onOk(wxCommandEvent&) { vector actions; for (size_t i = 0; i < free_link_indexes.size(); ++i) { if (free_link_indexes[i] >= 0) { - actions.push_back(make_intrusive(*set, selected_card, linked_uids[i], linked_relation_string, free_link_indexes[i])); + actions.push_back(make_intrusive(selected_card, linked_uids[i], linked_relation_string, free_link_indexes[i])); } } // Find reciprocal free slots and make actions @@ -165,11 +165,12 @@ void CardLinkWindow::onOk(wxCommandEvent&) { for (size_t i = 0; i < linked_cards.size(); ++i) { int free_link_index = linked_cards[i]->findFreeLink(selected_uid, all_existing_uids); if (free_link_index >= 0) { - actions.push_back(make_intrusive(*set, linked_cards[i], selected_uid, selected_relation_string, free_link_index)); + actions.push_back(make_intrusive(linked_cards[i], selected_uid, selected_relation_string, free_link_index)); } } // Add action to set set->actions.addAction(make_unique(actions, set, card_list_window, false), false); + set->actions.tellListeners(DisplayChangeAction(),true); // Done EndModal(wxID_OK); } diff --git a/src/gui/control/card_list.cpp b/src/gui/control/card_list.cpp index 4b98fb63..86597ca6 100644 --- a/src/gui/control/card_list.cpp +++ b/src/gui/control/card_list.cpp @@ -459,8 +459,8 @@ bool CardListBase::doLink() { bool CardListBase::doUnlink(CardP linked_card) { CardP selected_card = getCard(); vector actions; - actions.emplace_back(make_intrusive(*set, selected_card, _(""), _(""), selected_card->findUIDLink(linked_card->uid))); - actions.emplace_back(make_intrusive(*set, linked_card, _(""), _(""), linked_card->findUIDLink(selected_card->uid))); + actions.emplace_back(make_intrusive(selected_card, _(""), _(""), selected_card->findUIDLink(linked_card->uid))); + actions.emplace_back(make_intrusive(linked_card, _(""), _(""), linked_card->findUIDLink(selected_card->uid))); set->actions.addAction(make_unique(actions, set, this, false), false); return true; } diff --git a/src/gui/set/cards_panel.cpp b/src/gui/set/cards_panel.cpp index ff5202a8..120438e6 100644 --- a/src/gui/set/cards_panel.cpp +++ b/src/gui/set/cards_panel.cpp @@ -556,7 +556,7 @@ bool CardsPanel::canCopy() const { CUT_COPY_PASTE(canCopy, return) } void CardsPanel::doCut() { CUT_COPY_PASTE(doCut, return (void)) } void CardsPanel::doCopy() { CUT_COPY_PASTE(doCopy, return (void)) } -// always alow pasting cards, even if something else is selected +// always allow pasting cards, even if something else is selected bool CardsPanel::canPaste() const { if (card_list->canPaste()) return true; int id = focused_control(this); diff --git a/src/script/dependency.cpp b/src/script/dependency.cpp index cac7120a..721b0b1b 100644 --- a/src/script/dependency.cpp +++ b/src/script/dependency.cpp @@ -113,7 +113,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script) // - member operator; and it signals a dependency. // - looper construction // - + for function composition - // Variable assignments are performed as normall. + // Variable assignments are performed as normal. // Jumps are tricky: // - I_LOOP: We want to prevent infinite loops, the solution is that after the first // iteration we set the looper to a dummy value, so the loop is only executed once. diff --git a/src/script/script_manager.cpp b/src/script/script_manager.cpp index 0b559722..69d7d9b0 100644 --- a/src/script/script_manager.cpp +++ b/src/script/script_manager.cpp @@ -202,11 +202,21 @@ void SetScriptManager::onAction(const Action& action, bool undone) { TYPE_CASE_(action, KeywordListAction) { updateAllDependend(set.game->dependent_scripts_keywords); return; + } + TYPE_CASE(action, OneWayLinkCardsAction) { + updateAllDependend(set.game->dependent_scripts_links, action.card); + return; } TYPE_CASE_(action, ChangeKeywordModeAction) { updateAllDependend(set.game->dependent_scripts_keywords); return; } + TYPE_CASE(action, ChangeCardNotesAction) { + updateAllDependend(set.game->dependent_scripts_notes, action.card); + } + TYPE_CASE(action, ChangeCardUIDAction) { + updateAllDependend(set.game->dependent_scripts_uid, action.card); + } TYPE_CASE(action, ChangeCardStyleAction) { updateAllDependend(set.game->dependent_scripts_stylesheet, action.card); }