1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        MenuActionsDlg.cpp
3 // Author:      Alex Thuering
4 // Created:     13.01.2012
5 // RCS-ID:      $Id: MenuActionsDlg.cpp,v 1.6 2016/01/06 21:10:04 ntalex Exp $
6 // Copyright:   (c) Alex Thuering
7 // Licence:     GPL
8 /////////////////////////////////////////////////////////////////////////////
9 #include "MenuActionsDlg.h"
10 #include "MenuPropDlg.h"
11 #include "Utils.h"
12 #include <wxVillaLib/utils.h>
13 #include "rc/add.png.h"
14 #include "rc/remove.png.h"
15 
16 //(*InternalHeaders(MenuActionsDlg)
17 #include <wx/intl.h>
18 #include <wx/button.h>
19 #include <wx/string.h>
20 //*)
21 
22 class ActionsTable: public wxGridTableBase {
23 public:
ActionsTable(vector<DVDAction * > & actions,DVD * dvd,int tsi)24 	ActionsTable(vector<DVDAction*>& actions, DVD* dvd, int tsi): wxGridTableBase(), m_actions(actions), m_dvd(dvd), m_tsi(tsi) { }
25 
GetNumberRows()26 	int GetNumberRows() {
27 		return m_actions.size();
28 	}
29 
GetNumberCols()30 	int GetNumberCols() {
31 		return 2;
32 	}
33 
IsEmptyCell(int row,int col)34 	bool IsEmptyCell(int row, int col) {
35 		return false;
36 	}
37 
GetValue(int row,int col)38 	wxString GetValue(int row, int col) {
39 		DVDAction* action = m_actions[row];
40 		switch (col) {
41 		case 0:
42 			return action->GetId();
43 		case 1:
44 			return action->AsString(m_dvd);
45 		default:
46 			break;
47 		}
48 		return wxT("");
49 	}
50 
SetValue(int row,int col,const wxString & value)51 	void SetValue(int row, int col, const wxString& value) {
52 		DVDAction* action = m_actions[row];
53 		switch (col) {
54 		case 0:
55 			action->SetId(value);
56 			break;
57 		case 1:
58 			action->SetCustom(value);
59 			break;
60 		default:
61 			break;
62 		}
63 	}
64 
AppendRows(size_t numRows=1)65 	bool AppendRows(size_t numRows = 1) {
66 		int idx = 0;
67 		wxString id;
68 		while (true) {
69 			idx++;
70 			id = wxString::Format(wxT("action%02d"), idx);
71 			bool found = false;
72 			for (vector<DVDAction*>::const_iterator it = m_actions.begin(); it != m_actions.end(); it++) {
73 				if ((*it)->GetId() == id) {
74 					found = true;
75 					break;
76 				}
77 			}
78 			if (!found)
79 				break;
80 		}
81 		m_actions.push_back(new DVDAction(m_tsi == -1, id));
82 		if (GetView()) {
83 			wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, numRows);
84 			GetView()->ProcessTableMessage(msg);
85 		}
86 		return true;
87 	}
88 
DeleteRows(size_t pos=0,size_t numRows=1)89 	bool DeleteRows(size_t pos = 0, size_t numRows = 1) {
90 		m_actions.erase(m_actions.begin() + pos);
91 		if (GetView()) {
92 			wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, pos, 1);
93 			GetView()->ProcessTableMessage(msg);
94 		}
95 		return true;
96 	}
97 
GetRowLabelValue(int row)98 	wxString GetRowLabelValue( int row ) {
99 		return wxT("");
100 	}
101 
GetColLabelValue(int col)102 	wxString GetColLabelValue( int col ) {
103 		wxString cols[] = { _("ID"), _("Command") };
104 		return cols[col];
105 	}
106 
107 private:
108 	vector<DVDAction*>& m_actions;
109 	DVD* m_dvd;
110 	int m_tsi;
111 };
112 
113 
114 //(*IdInit(MenuActionsDlg)
115 const long MenuActionsDlg::ID_GRID = wxNewId();
116 const long MenuActionsDlg::ID_ADD_BT = wxNewId();
117 const long MenuActionsDlg::ID_DEL_BT = wxNewId();
118 //*)
119 
BEGIN_EVENT_TABLE(MenuActionsDlg,wxDialog)120 BEGIN_EVENT_TABLE(MenuActionsDlg,wxDialog)
121 	//(*EventTable(MenuActionsDlg)
122 	//*)
123 END_EVENT_TABLE()
124 
125 MenuActionsDlg::MenuActionsDlg(MenuPropDlg* parent, DVD* dvd, int tsi, int pgci, vector<DVDAction*> actions):
126 		parentDlg(parent), m_dvd(dvd), m_tsi(tsi), m_pgci(pgci) {
127 	VECTOR_COPY(actions, m_actions, DVDAction)
128 
129 	//(*Initialize(MenuActionsDlg)
130 	wxBoxSizer* boxSizer1;
131 	wxBoxSizer* boxSizer2;
132 	wxStdDialogButtonSizer* stdDialogButtonSizer;
133 	wxStaticText* staticText1;
134 	wxBoxSizer* mainSizer;
135 
136 	Create(parent, wxID_ANY, _("Menu Actions"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER, _T("wxID_ANY"));
137 	mainSizer = new wxBoxSizer(wxVERTICAL);
138 	staticText1 = new wxStaticText(this, wxID_ANY, _("Actions:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
139 	mainSizer->Add(staticText1, 0, wxALL|wxALIGN_LEFT, 5);
140 	boxSizer1 = new wxBoxSizer(wxHORIZONTAL);
141 	m_grid = new wxGrid(this, ID_GRID, wxDefaultPosition, wxSize(300,300), 0, _T("ID_GRID"));
142 	boxSizer1->Add(m_grid, 1, wxRIGHT|wxEXPAND, 6);
143 	boxSizer2 = new wxBoxSizer(wxVERTICAL);
144 	m_addBt = new wxBitmapButton(this, ID_ADD_BT, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("ID_ADD_BT"));
145 	boxSizer2->Add(m_addBt, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
146 	m_delBt = new wxBitmapButton(this, ID_DEL_BT, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("ID_DEL_BT"));
147 	boxSizer2->Add(m_delBt, 0, wxTOP|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 2);
148 	boxSizer1->Add(boxSizer2, 0, wxEXPAND, 5);
149 	mainSizer->Add(boxSizer1, 1, wxEXPAND, 5);
150 	stdDialogButtonSizer = new wxStdDialogButtonSizer();
151 	stdDialogButtonSizer->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
152 	stdDialogButtonSizer->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
153 	stdDialogButtonSizer->Realize();
154 	mainSizer->Add(stdDialogButtonSizer, 0, wxALL|wxEXPAND, 5);
155 	SetSizer(mainSizer);
156 	mainSizer->Fit(this);
157 	mainSizer->SetSizeHints(this);
158 	Center();
159 
160 	Connect(ID_ADD_BT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&MenuActionsDlg::OnAddBt);
161 	Connect(ID_DEL_BT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&MenuActionsDlg::OnDelBt);
162 	//*)
163 	Connect(wxID_OK,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&MenuActionsDlg::OnOkBt);
164 	stdDialogButtonSizer->GetAffirmativeButton()->SetDefault();
165 
166 	ActionsTable* table = new ActionsTable(m_actions, m_dvd, m_tsi);
167 	m_grid->SetTable(table);
168 	m_grid->SetRowLabelSize(10);
169 	m_grid->SetColSize(1, 190);
170 	m_grid->SetColLabelSize(m_grid->GetCharHeight() + 8);
171 	m_grid->SetDefaultRowSize(m_grid->GetCharHeight() + 8);
172 	m_grid->SetSelectionMode(wxGrid::wxGridSelectRows);
173 	for (int i = 0; i < m_grid->GetNumberRows(); i++)
174 		SetCellEditors(i);
175 
176 	m_addBt->SetBitmapLabel(wxBITMAP_FROM_MEMORY(add));
177 	m_delBt->SetBitmapLabel(wxBITMAP_FROM_MEMORY(remove));
178 
179 	m_addBt->SetFocus();
180 	mainSizer->Fit(this);
181 }
182 
~MenuActionsDlg()183 MenuActionsDlg::~MenuActionsDlg() {
184 	//(*Destroy(MenuActionsDlg)
185 	//*)
186 	VECTOR_CLEAR(m_actions, DVDAction)
187 }
188 
SetCellEditors(int row)189 void MenuActionsDlg::SetCellEditors(int row) {
190 	m_grid->SetCellEditor(row, 1, new wxGridCellChoiceEditor(parentDlg->GetCommandList(), true));
191 }
192 
OnAddBt(wxCommandEvent & event)193 void MenuActionsDlg::OnAddBt(wxCommandEvent& event) {
194 	m_grid->AppendRows(1);
195 	SetCellEditors(m_grid->GetNumberRows() - 1);
196 	m_grid->SelectRow(m_grid->GetGridCursorRow(), false);
197 	m_grid->SetFocus();
198 	m_delBt->Enable(true);
199 }
200 
OnDelBt(wxCommandEvent & event)201 void MenuActionsDlg::OnDelBt(wxCommandEvent& event) {
202 	if (!m_grid->GetSelectedRows().IsEmpty())
203 		while (m_grid->GetSelectedRows().size() > 0)
204 			m_grid->DeleteRows(m_grid->GetSelectedRows()[0]);
205 	else if (m_grid->GetGridCursorRow() >= 0)
206 		m_grid->DeleteRows(m_grid->GetGridCursorRow());
207 	if (m_grid->GetNumberRows() > 0)
208 		m_grid->SelectRow(m_grid->GetGridCursorRow(), false);
209 	m_grid->SetFocus();
210 	m_delBt->Enable(m_grid->GetNumberRows() > 0);
211 }
212 
OnOkBt(wxCommandEvent & event)213 void MenuActionsDlg::OnOkBt(wxCommandEvent& event) {
214 	// check ids
215 	int row = 0;
216 	for (vector<DVDAction*>::const_iterator it = m_actions.begin(); it != m_actions.end(); it++) {
217 		for (vector<DVDAction*>::const_iterator it2 = it + 1; it2 != m_actions.end(); it2++) {
218 			if ((*it)->GetId() == (*it2)->GetId()) {
219 				m_grid->SelectRow(row, false);
220 				wxLogError(_("Duplicated action ID '%s'."), (*it)->GetId().c_str());
221 				return;
222 			}
223 		}
224 		row++;
225 	}
226 	// check commands
227 	for (unsigned int i = 0; i < m_actions.size(); i++) {
228 		if (m_actions[i]->GetCustom().length()
229 				&& !m_actions[i]->IsValid(m_dvd, m_tsi, m_pgci, true, m_actions[i]->GetId(), true, true)) {
230 			return;
231 		}
232 	}
233 	EndModal(wxID_OK);
234 }
235