diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index 7ab18988..289798b4 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -396,6 +396,10 @@ label: game type: &Game type: style type: &Card style: + stylesheet not found: + The set you are trying to open uses the stylesheet "%s". + This stylesheet is not found on your system, please select an alternative. + # Preferences language: Language app language: Language of the user interface: @@ -510,11 +514,13 @@ title: about: About Magic Set Editor symbol editor: Symbol Editor # dialogs + new set: New Set open set: Open Set save set: Save Set As save image: Save Image - updates availible: Updates Availible + updates available: Updates Available save changes: Save Changes? + select stylesheet: Select Stylesheet #preferences preferences: Preferences global: Global diff --git a/src/data/stylesheet.cpp b/src/data/stylesheet.cpp index adc28c39..968642fd 100644 --- a/src/data/stylesheet.cpp +++ b/src/data/stylesheet.cpp @@ -10,6 +10,7 @@ #include #include #include +#include // for selecting stylesheets on load error DECLARE_TYPEOF_COLLECTION(StyleSheet*); DECLARE_TYPEOF_COLLECTION(FieldP); @@ -25,7 +26,30 @@ StyleSheet::StyleSheet() {} StyleSheetP StyleSheet::byGameAndName(const Game& game, const String& name) { - return packages.open(game.name() + _("-") + name + _(".mse-style")); + /// Alternative stylesheets for game + static map stylesheet_alternatives; + String full_name = game.name() + _("-") + name + _(".mse-style"); + try { + map::const_iterator it = stylesheet_alternatives.find(full_name); + if (it != stylesheet_alternatives.end()) { + return packages.open(it->second); + } else { + return packages.open(full_name); + } + } catch (PackageNotFoundError& e) { + if (stylesheet_for_reading()) { + // we already have a stylesheet higher up, so just return a null pointer + return StyleSheetP(); + } + // load an alternative stylesheet + StyleSheetP ss = select_stylesheet(game, name); + if (ss) { + stylesheet_alternatives[full_name] = ss->relativeFilename(); + return ss; + } else { + throw e; + } + } } String StyleSheet::stylesheetName() const { String sn = name(), gn = game->name(); diff --git a/src/gui/new_window.cpp b/src/gui/new_window.cpp index f66c4d0a..acf313e8 100644 --- a/src/gui/new_window.cpp +++ b/src/gui/new_window.cpp @@ -25,14 +25,14 @@ SetP new_set_window(Window* parent) { } NewSetWindow::NewSetWindow(Window* parent) - : wxDialog(parent, wxID_ANY, _("New set"), wxDefaultPosition, wxSize(530,320), wxDEFAULT_DIALOG_STYLE) + : wxDialog(parent, wxID_ANY, _TITLE_("new set"), wxDefaultPosition, wxSize(530,320), wxDEFAULT_DIALOG_STYLE) { wxBusyCursor wait; // init controls game_list = new PackageList (this, ID_GAME_LIST); stylesheet_list = new PackageList (this, ID_STYLESHEET_LIST); - game_text = new wxStaticText(this, ID_GAME_LIST, _LABEL_("game type")); - stylesheet_text = new wxStaticText(this, ID_STYLESHEET_LIST, _LABEL_("style type")); + wxStaticText* game_text = new wxStaticText(this, ID_GAME_LIST, _LABEL_("game type")); + wxStaticText* stylesheet_text = new wxStaticText(this, ID_STYLESHEET_LIST, _LABEL_("style type")); // init sizer wxSizer* s = new wxBoxSizer(wxVERTICAL); s->Add(game_text, 0, wxALL, 4); @@ -126,3 +126,84 @@ BEGIN_EVENT_TABLE(NewSetWindow, wxDialog) EVT_UPDATE_UI (wxID_ANY, NewSetWindow::onUpdateUI) EVT_IDLE ( NewSetWindow::onIdle) END_EVENT_TABLE () + +// ----------------------------------------------------------------------------- : SelectStyleSheetWindow + + +StyleSheetP select_stylesheet(const Game& game, const String& failed_name) { + SelectStyleSheetWindow wnd(nullptr, game, failed_name); + wnd.ShowModal(); + return wnd.stylesheet; +} + +SelectStyleSheetWindow::SelectStyleSheetWindow(Window* parent, const Game& game, const String& failed_name) + : wxDialog(parent, wxID_ANY, _TITLE_("select stylesheet"), wxDefaultPosition, wxSize(530,320), wxDEFAULT_DIALOG_STYLE) + , game(game) +{ + wxBusyCursor wait; + // init controls + stylesheet_list = new PackageList (this, ID_STYLESHEET_LIST); + wxStaticText* description = new wxStaticText(this, ID_GAME_LIST, _LABEL_1_("stylesheet not found", failed_name)); + wxStaticText* stylesheet_text = new wxStaticText(this, ID_STYLESHEET_LIST, _LABEL_("style type")); + // init sizer + wxSizer* s = new wxBoxSizer(wxVERTICAL); + s->Add(description, 0, wxALL, 4); + s->Add(stylesheet_text, 0, wxALL, 4); + s->Add(stylesheet_list, 0, wxEXPAND | wxALL & ~wxTOP, 4); + s->Add(CreateButtonSizer(wxOK | wxCANCEL) , 0, wxEXPAND | wxALL, 8); + s->SetSizeHints(this); + SetSizer(s); + // init list + stylesheet_list->showData(game.name() + _("-*")); + stylesheet_list->select(settings.gameSettingsFor(game).default_stylesheet); + // Resize + SetSize(630,-1); + Layout(); + GetSizer()->SetSizeHints(this); + SetSize(630,-1); + UpdateWindowUI(wxUPDATE_UI_RECURSE); +} + +void SelectStyleSheetWindow::onStyleSheetSelect(wxCommandEvent&) { + handle_pending_errors(); + UpdateWindowUI(wxUPDATE_UI_RECURSE); +} +void SelectStyleSheetWindow::onStyleSheetActivate(wxCommandEvent&) { + done(); +} + +void SelectStyleSheetWindow::OnOK(wxCommandEvent&) { + done(); +} + +void SelectStyleSheetWindow::done() { + try { + stylesheet = stylesheet_list->getSelection(); + EndModal(wxID_OK); + } catch (const Error& e) { + handle_error(e); + EndModal(wxID_CANCEL); + } +} + +void SelectStyleSheetWindow::onUpdateUI(wxUpdateUIEvent& ev) { + switch (ev.GetId()) { + case wxID_OK: + ev.Enable(stylesheet_list->hasSelection()); + break; + } +} + +void SelectStyleSheetWindow::onIdle(wxIdleEvent& ev) { + // Stuff that must be done in the main thread + handle_pending_errors(); +} + +BEGIN_EVENT_TABLE(SelectStyleSheetWindow, wxDialog) + EVT_GALLERY_SELECT (ID_STYLESHEET_LIST, SelectStyleSheetWindow::onStyleSheetSelect) + EVT_GALLERY_ACTIVATE(ID_STYLESHEET_LIST, SelectStyleSheetWindow::onStyleSheetActivate) + EVT_BUTTON (wxID_OK, SelectStyleSheetWindow::OnOK) + EVT_UPDATE_UI (wxID_ANY, SelectStyleSheetWindow::onUpdateUI) + EVT_IDLE ( SelectStyleSheetWindow::onIdle) +END_EVENT_TABLE () + diff --git a/src/gui/new_window.hpp b/src/gui/new_window.hpp index 37508ed4..fc2603d6 100644 --- a/src/gui/new_window.hpp +++ b/src/gui/new_window.hpp @@ -12,7 +12,9 @@ #include class PackageList; +class Game; DECLARE_POINTER_TYPE(Set); +DECLARE_POINTER_TYPE(StyleSheet); // ----------------------------------------------------------------------------- : NewSetWindow @@ -33,8 +35,6 @@ class NewSetWindow : public wxDialog { // gui items PackageList* game_list, *stylesheet_list; - wxStaticText* game_text, *stylesheet_text; - Window* ok_button; // --------------------------------------------------- : events @@ -52,5 +52,42 @@ class NewSetWindow : public wxDialog { void done(); }; +// ----------------------------------------------------------------------------- : SelectStyleSheetWindow +// very similair, so in the same file + +/// Show the select stylesheet window, return the selected stylesheet, if any +StyleSheetP select_stylesheet(const Game& game, const String& failed_name); + +/// "Create a new set" dialog. First select game, then matching style. +class SelectStyleSheetWindow : public wxDialog { + public: + /// The selected stylesheet, if any + StyleSheetP stylesheet; + + SelectStyleSheetWindow(Window* parent, const Game& game, const String& failed_name); + + // --------------------------------------------------- : data + private: + DECLARE_EVENT_TABLE(); + + const Game& game; + + // gui items + PackageList* stylesheet_list; + + // --------------------------------------------------- : events + + void onStyleSheetSelect (wxCommandEvent&); + void onStyleSheetActivate(wxCommandEvent&); + + virtual void OnOK(wxCommandEvent&); + + void onUpdateUI(wxUpdateUIEvent&); + void onIdle(wxIdleEvent&); + + // we are done, close the window + void done(); +}; + // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/resource/common/expected_locale_keys b/src/resource/common/expected_locale_keys index d4184a60..50968587 100644 --- a/src/resource/common/expected_locale_keys +++ b/src/resource/common/expected_locale_keys @@ -1,6 +1,6 @@ # This file contains the keys expected to be in MSE locales # It was automatically generated by tools/locale/locale.pl -# Generated on Sun Aug 26 21:17:38 2007 +# Generated on Sat Sep 1 23:06:46 2007 action: add control point: 0 @@ -261,6 +261,7 @@ label: size: 0 standard keyword: 1 style type: 0 + stylesheet not found: 1 styling options: 0 uses: 0 zoom: 0 @@ -355,6 +356,7 @@ title: global: 0 locate apprentice: 0 magic set editor: 0 + new set: 0 new status: 0 open set: 0 package list: 0 @@ -369,6 +371,7 @@ title: select cards: 0 select cards export: 0 select columns: 0 + select stylesheet: 0 slice image: 0 symbol editor: 0 untitled: 0 diff --git a/src/util/error.hpp b/src/util/error.hpp index 235bd14a..b1675dcd 100644 --- a/src/util/error.hpp +++ b/src/util/error.hpp @@ -48,6 +48,12 @@ class PackageError : public Error { inline PackageError(const String& str) : Error(str) {} }; +/// A package is not found +class PackageNotFoundError : public PackageError { + public: + inline PackageNotFoundError(const String& str) : PackageError(str) {} +}; + /// A file is not found class FileNotFoundError : public PackageError { public: diff --git a/src/util/io/package.cpp b/src/util/io/package.cpp index 1b85fe4b..584c5869 100644 --- a/src/util/io/package.cpp +++ b/src/util/io/package.cpp @@ -82,7 +82,7 @@ void Package::open(const String& n) { } else if (wxFileExists(filename)) { openZipfile(); } else { - throw PackageError(_("Package not found: '") + filename + _("'")); + throw PackageNotFoundError(_("Package not found: '") + filename + _("'")); } } diff --git a/src/util/locale.hpp b/src/util/locale.hpp index 6e8f2c84..f35cdf3a 100644 --- a/src/util/locale.hpp +++ b/src/util/locale.hpp @@ -92,6 +92,9 @@ String tr(const SymbolFont&, const String& key, const String& def); /// A localized string for tooltip text, with 1 argument (printf style) #define _TOOLTIP_1_(s,a) format_string(_TOOLTIP_(s), a) +/// A localized string for tooltip labels, with 1 argument (printf style) +#define _LABEL_1_(s,a) format_string(_LABEL_(s), a) + /// A localized string for button text, with 1 argument (printf style) #define _BUTTON_1_(s,a) format_string(_BUTTON_(s), a)