Fix crash if text containing \n is printed at nonzero x
[lsnes.git] / src / platform / wxwidgets / editor-conflict.cpp
blob60541f7bf4e0a679289fb9314f953731532a3284
1 #include <wx/wx.h>
2 #include <wx/event.h>
3 #include <wx/control.h>
4 #include <wx/combobox.h>
5 #include <wx/scrolwin.h>
7 #include "interface/romtype.hpp"
8 #include "library/string.hpp"
9 #include "core/romimage.hpp"
11 #include "platform/wxwidgets/platform.hpp"
13 class wxeditor_conflict : public wxDialog
15 public:
16 wxeditor_conflict(wxWindow* parent);
17 bool ShouldPreventAppExit() const;
18 void on_ok(wxCommandEvent& e);
19 void on_cancel(wxCommandEvent& e);
20 private:
21 void add_options(wxWindow* win, wxSizer* sizer);
22 void add_option(wxWindow* win, wxSizer* sizer, const std::string& key, const std::string& name);
23 std::map<std::string, wxComboBox*> choices;
24 std::map<std::pair<std::string, std::string>, core_type*> rchoices;
25 std::set<std::string> bad_defaults;
26 wxScrolledWindow* scrollwin;
27 wxButton* btnok;
28 wxButton* btncancel;
31 wxeditor_conflict::wxeditor_conflict(wxWindow* parent)
32 : wxDialog(parent, wxID_ANY, wxT("lsnes: Edit conflicts"), wxDefaultPosition, wxSize(-1, -1))
34 CHECK_UI_THREAD;
35 Centre();
36 wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
37 SetSizer(top_s);
39 scrollwin = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxVSCROLL);
40 scrollwin->SetMinSize(wxSize(-1, 500));
42 wxFlexGridSizer* t_s = new wxFlexGridSizer(0, 2, 0, 0);
43 add_options(scrollwin, t_s);
44 scrollwin->SetSizer(t_s);
45 top_s->Add(scrollwin);
46 scrollwin->SetScrollRate(0, 20);
48 wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
49 pbutton_s->AddStretchSpacer();
50 pbutton_s->Add(btnok = new wxButton(this, wxID_CANCEL, wxT("OK")), 0, wxGROW);
51 btnok->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
52 wxCommandEventHandler(wxeditor_conflict::on_ok), NULL, this);
53 pbutton_s->Add(btncancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW);
54 btncancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
55 wxCommandEventHandler(wxeditor_conflict::on_cancel), NULL, this);
56 top_s->Add(pbutton_s, 0, wxGROW);
58 t_s->SetSizeHints(this);
59 top_s->SetSizeHints(this);
60 t_s->Layout();
61 top_s->Layout();
62 Fit();
65 void wxeditor_conflict::add_options(wxWindow* win, wxSizer* sizer)
67 std::map<std::string, std::string> classes;
68 for(auto i : core_type::get_core_types()) {
69 if(i->is_hidden())
70 continue;
71 classes["type:" + i->get_iname()] = "Type " + i->get_iname();
72 for(auto j : i->get_extensions())
73 classes["ext:" + j] = "Extension " + j;
75 for(auto i : classes)
76 add_option(win, sizer, i.first, i.second);
79 void wxeditor_conflict::add_option(wxWindow* win, wxSizer* sizer, const std::string& key, const std::string& name)
81 CHECK_UI_THREAD;
82 sizer->Add(new wxStaticText(win, wxID_ANY, towxstring(name)));
83 std::vector<wxString> v;
84 size_t dfltidx = 0;
85 v.push_back(wxT("(unspecified)"));
86 regex_results r;
87 if(r = regex("ext:(.*)", key)) {
88 for(auto i : core_type::get_core_types()) {
89 if(i->is_hidden())
90 continue;
91 for(auto j : i->get_extensions())
92 if(j == r[1]) {
93 std::string val = i->get_hname() + " / " + i->get_core_identifier();
94 rchoices[std::make_pair(key, val)] = i;
95 if(core_selections.count(key) && i == preferred_core[key])
96 dfltidx = v.size();
97 v.push_back(towxstring(val));
100 } else if(r = regex("type:(.*)", key)) {
101 for(auto i : core_type::get_core_types()) {
102 if(i->is_hidden())
103 continue;
104 if(i->get_iname() == r[1]) {
105 std::string val = i->get_hname() + " / " + i->get_core_identifier();
106 rchoices[std::make_pair(key, val)] = i;
107 if(core_selections.count(key) && i == preferred_core[key])
108 dfltidx = v.size();
109 v.push_back(towxstring(val));
113 if(core_selections.count(key) && !dfltidx) {
114 bad_defaults.insert(key);
115 dfltidx = v.size();
116 v.push_back(towxstring("bad default [" + core_selections[key] + "]"));
119 sizer->Add(choices[key] = new wxComboBox(win, wxID_ANY, v[dfltidx], wxDefaultPosition, wxDefaultSize,
120 v.size(), &v[0], wxCB_READONLY), 1, wxGROW);
123 bool wxeditor_conflict::ShouldPreventAppExit() const { return false; }
125 void wxeditor_conflict::on_ok(wxCommandEvent& e)
127 CHECK_UI_THREAD;
128 for(auto i : choices) {
129 if(i.second->GetSelection() == 0) {
130 //Reset to unspecified.
131 preferred_core.erase(i.first);
132 core_selections.erase(i.first);
133 } else if(bad_defaults.count(i.first) && i.second->GetSelection() ==
134 (int)(i.second->GetCount() - 1)) {
135 //Preserve the previous, reset real setting to unspecified.
136 preferred_core.erase(i.first);
137 } else {
138 //Chose a setting.
139 std::string val = tostdstring(i.second->GetStringSelection());
140 core_selections[i.first] = val;
141 preferred_core[i.first] = rchoices[std::make_pair(i.first, val)];
144 EndModal(wxID_OK);
147 void wxeditor_conflict::on_cancel(wxCommandEvent& e)
149 CHECK_UI_THREAD;
150 EndModal(wxID_CANCEL);
153 void show_conflictwindow(wxWindow* parent)
155 CHECK_UI_THREAD;
156 modal_pause_holder hld;
157 wxDialog* editor;
158 try {
159 editor = new wxeditor_conflict(parent);
160 editor->ShowModal();
161 } catch(...) {
162 return;
164 editor->Destroy();
165 do_save_configuration();
168 std::map<std::string, std::string> core_selections;