16 |
m_inverseDeleteButton(Glib::ustring(_("Inverse Delete")) + " " + UNICODE_ALT_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL), |
m_inverseDeleteButton(Glib::ustring(_("Inverse Delete")) + " " + UNICODE_ALT_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL), |
17 |
m_applyButton(_("_Apply"), true), |
m_applyButton(_("_Apply"), true), |
18 |
m_cancelButton(_("_Cancel"), true), |
m_cancelButton(_("_Cancel"), true), |
19 |
m_altKeyDown(false) |
m_altKeyDown(false), |
20 |
|
m_primaryKeyDown(false) |
21 |
{ |
{ |
22 |
add(m_vbox); |
add(m_vbox); |
23 |
|
|
41 |
//m_treeViewMacro.set_tooltip_text(_("")); |
//m_treeViewMacro.set_tooltip_text(_("")); |
42 |
m_treeViewMacro.append_column(_("Key"), m_treeModelMacro.m_col_name); |
m_treeViewMacro.append_column(_("Key"), m_treeModelMacro.m_col_name); |
43 |
m_treeViewMacro.append_column(_("Type"), m_treeModelMacro.m_col_type); |
m_treeViewMacro.append_column(_("Type"), m_treeModelMacro.m_col_type); |
44 |
m_treeViewMacro.append_column_editable(_("Value"), m_treeModelMacro.m_col_value); |
//m_treeViewMacro.append_column_editable(_("Value"), m_treeModelMacro.m_col_value); |
45 |
|
//m_treeViewMacro.append_column(_("Value"), m_valueCellRenderer); |
46 |
|
Gtk::TreeViewColumn* valueColumn = new Gtk::TreeViewColumn(_("Value")); |
47 |
|
valueColumn->pack_start(m_valueCellRenderer); |
48 |
|
m_treeViewMacro.append_column(*valueColumn); |
49 |
|
// m_valueCellRenderer.property_model() = m_comboBoxModel; |
50 |
|
// m_valueCellRenderer.property_text_column() = 0; |
51 |
|
//m_valueCellRenderer.property_editable() = true; |
52 |
|
{ |
53 |
|
Gtk::TreeView::Column* column = valueColumn;// m_treeViewMacro.get_column(2); |
54 |
|
//column->set_renderer(m_valueCellRenderer, m_treeModelMacro.m_col_value); |
55 |
|
column->add_attribute(m_valueCellRenderer.property_text(), |
56 |
|
m_treeModelMacro.m_col_value); |
57 |
|
//column->add_attribute(m_valueCellRenderer.property_has_entry(), |
58 |
|
// m_treeModelMacro.m_col_allowTextEntry); |
59 |
|
column->add_attribute(m_valueCellRenderer.property_editable(), |
60 |
|
m_treeModelMacro.m_col_editable); |
61 |
|
column->add_attribute(m_valueCellRenderer.property_model(), |
62 |
|
m_treeModelMacro.m_col_options); |
63 |
|
} |
64 |
|
m_valueCellRenderer.property_text_column() = 0; |
65 |
|
m_valueCellRenderer.signal_edited().connect( |
66 |
|
sigc::mem_fun(*this, &MacroEditor::onValueCellEdited) |
67 |
|
); |
68 |
|
|
69 |
{ |
{ |
70 |
Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(1); |
Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(1); |
71 |
Gtk::CellRendererText* cellrenderer = |
Gtk::CellRendererText* cellrenderer = |
72 |
dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell()); |
dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell()); |
73 |
cellrenderer->property_foreground().set_value("#bababa"); |
cellrenderer->property_foreground().set_value("#bababa"); |
74 |
} |
} |
|
/*{ |
|
|
Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(0); |
|
|
Gtk::CellRendererText* cellrenderer = |
|
|
dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell()); |
|
|
column->add_attribute( |
|
|
cellrenderer->property_foreground(), m_SamplesModel.m_color |
|
|
); |
|
|
}*/ |
|
|
/*{ |
|
|
Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(1); |
|
|
Gtk::CellRendererText* cellrenderer = |
|
|
dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell()); |
|
|
column->add_attribute( |
|
|
cellrenderer->property_foreground(), m_SamplesModel.m_color |
|
|
); |
|
|
}*/ |
|
75 |
m_treeViewMacro.set_headers_visible(true); |
m_treeViewMacro.set_headers_visible(true); |
76 |
m_treeViewMacro.get_selection()->signal_changed().connect( |
m_treeViewMacro.get_selection()->signal_changed().connect( |
77 |
sigc::mem_fun(*this, &MacroEditor::onTreeViewSelectionChanged) |
sigc::mem_fun(*this, &MacroEditor::onTreeViewSelectionChanged) |
182 |
return m_changes_applied; |
return m_changes_applied; |
183 |
} |
} |
184 |
|
|
185 |
|
Glib::RefPtr<Gtk::ListStore> MacroEditor::createComboOptions(const char** options) { |
186 |
|
Glib::RefPtr<Gtk::ListStore> refOptions = Gtk::ListStore::create(m_comboOptionsModel); |
187 |
|
for (size_t i = 0; options[i]; ++i) |
188 |
|
(*refOptions->append())[m_comboOptionsModel.m_col_choice] = options[i]; |
189 |
|
return refOptions; |
190 |
|
} |
191 |
|
|
192 |
void MacroEditor::buildTreeView(const Gtk::TreeModel::Row& parentRow, const Serialization::Object& parentObject) { |
void MacroEditor::buildTreeView(const Gtk::TreeModel::Row& parentRow, const Serialization::Object& parentObject) { |
193 |
for (int iMember = 0; iMember < parentObject.members().size(); ++iMember) { |
for (int iMember = 0; iMember < parentObject.members().size(); ++iMember) { |
194 |
const Serialization::Member& member = parentObject.members()[iMember]; |
const Serialization::Member& member = parentObject.members()[iMember]; |
198 |
row[m_treeModelMacro.m_col_name] = gig_to_utf8(member.name()); |
row[m_treeModelMacro.m_col_name] = gig_to_utf8(member.name()); |
199 |
row[m_treeModelMacro.m_col_type] = gig_to_utf8(member.type().asLongDescr()); |
row[m_treeModelMacro.m_col_type] = gig_to_utf8(member.type().asLongDescr()); |
200 |
row[m_treeModelMacro.m_col_uid] = object.uid(); |
row[m_treeModelMacro.m_col_uid] = object.uid(); |
201 |
|
row[m_treeModelMacro.m_col_allowTextEntry] = false; |
202 |
|
|
203 |
if (object.type().isClass()) { |
if (object.type().isClass()) { |
204 |
row[m_treeModelMacro.m_col_value] = "(class)"; |
row[m_treeModelMacro.m_col_value] = "(class)"; |
205 |
|
row[m_treeModelMacro.m_col_editable] = false; |
206 |
buildTreeView(row, object); |
buildTreeView(row, object); |
207 |
|
} else if (object.type().isEnum()) { |
208 |
|
const char* key = gig::enumKey( |
209 |
|
object.type().customTypeName(), m_macro.valueAsInt(object) |
210 |
|
); |
211 |
|
row[m_treeModelMacro.m_col_value] = key ? key : m_macro.valueAsString(object); |
212 |
|
row[m_treeModelMacro.m_col_editable] = true; |
213 |
|
const char** allKeys = gig::enumKeys(object.type().customTypeName()); |
214 |
|
if (allKeys) { |
215 |
|
Glib::RefPtr<Gtk::ListStore> refOptions = createComboOptions(allKeys); |
216 |
|
row[m_treeModelMacro.m_col_options] = refOptions; |
217 |
|
} |
218 |
} else { |
} else { |
219 |
row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object); |
row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object); |
220 |
|
row[m_treeModelMacro.m_col_editable] = true; |
221 |
} |
} |
222 |
} |
} |
223 |
} |
} |
235 |
rowRoot[m_treeModelMacro.m_col_type] = gig_to_utf8(rootObject.type().asLongDescr()); |
rowRoot[m_treeModelMacro.m_col_type] = gig_to_utf8(rootObject.type().asLongDescr()); |
236 |
rowRoot[m_treeModelMacro.m_col_value] = ""; |
rowRoot[m_treeModelMacro.m_col_value] = ""; |
237 |
rowRoot[m_treeModelMacro.m_col_uid] = rootObject.uid(); |
rowRoot[m_treeModelMacro.m_col_uid] = rootObject.uid(); |
238 |
|
rowRoot[m_treeModelMacro.m_col_allowTextEntry] = false; |
239 |
|
rowRoot[m_treeModelMacro.m_col_editable] = false; |
240 |
|
|
241 |
buildTreeView(rowRoot, rootObject); |
buildTreeView(rowRoot, rootObject); |
242 |
|
|
254 |
m_inverseDeleteButton.set_sensitive(bValidSelection); |
m_inverseDeleteButton.set_sensitive(bValidSelection); |
255 |
} |
} |
256 |
|
|
257 |
|
// Cmd key on Mac, Ctrl key on all other OSs |
258 |
|
static const guint primaryKeyL = |
259 |
|
#if defined(__APPLE__) |
260 |
|
GDK_KEY_Meta_L; |
261 |
|
#else |
262 |
|
GDK_KEY_Control_L; |
263 |
|
#endif |
264 |
|
|
265 |
|
static const guint primaryKeyR = |
266 |
|
#if defined(__APPLE__) |
267 |
|
GDK_KEY_Meta_R; |
268 |
|
#else |
269 |
|
GDK_KEY_Control_R; |
270 |
|
#endif |
271 |
|
|
272 |
bool MacroEditor::onKeyPressed(GdkEventKey* key) { |
bool MacroEditor::onKeyPressed(GdkEventKey* key) { |
273 |
//printf("key down 0x%x\n", key->keyval); |
//printf("key down 0x%x\n", key->keyval); |
274 |
if (key->keyval == GDK_KEY_Alt_L || key->keyval == GDK_KEY_Alt_R) |
if (key->keyval == GDK_KEY_Alt_L || key->keyval == GDK_KEY_Alt_R) |
275 |
m_altKeyDown = true; |
m_altKeyDown = true; |
276 |
|
if (key->keyval == primaryKeyL || key->keyval == primaryKeyR) |
277 |
|
m_primaryKeyDown = true; |
278 |
return false; |
return false; |
279 |
} |
} |
280 |
|
|
282 |
//printf("key up 0x%x\n", key->keyval); |
//printf("key up 0x%x\n", key->keyval); |
283 |
if (key->keyval == GDK_KEY_Alt_L || key->keyval == GDK_KEY_Alt_R) |
if (key->keyval == GDK_KEY_Alt_L || key->keyval == GDK_KEY_Alt_R) |
284 |
m_altKeyDown = false; |
m_altKeyDown = false; |
285 |
|
if (key->keyval == primaryKeyL || key->keyval == primaryKeyR) |
286 |
|
m_primaryKeyDown = false; |
287 |
return false; |
return false; |
288 |
} |
} |
289 |
|
|
291 |
if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) { |
if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) { |
292 |
if (m_altKeyDown) |
if (m_altKeyDown) |
293 |
inverseDeleteSelectedRows(); |
inverseDeleteSelectedRows(); |
294 |
else |
else if (m_primaryKeyDown) |
295 |
deleteSelectedRows(); |
deleteSelectedRows(); |
296 |
} |
} |
297 |
} |
} |
298 |
|
|
299 |
|
void MacroEditor::onValueCellEdited(const Glib::ustring& sPath, const Glib::ustring& text) { |
300 |
|
printf("asdf\n"); |
301 |
|
Gtk::TreePath path(sPath); |
302 |
|
Gtk::TreeModel::iterator iter = m_treeStoreMacro->get_iter(path); |
303 |
|
onMacroTreeViewRowValueChangedImpl(path, iter, text); |
304 |
|
} |
305 |
|
|
306 |
void MacroEditor::onMacroTreeViewRowValueChanged(const Gtk::TreeModel::Path& path, |
void MacroEditor::onMacroTreeViewRowValueChanged(const Gtk::TreeModel::Path& path, |
307 |
const Gtk::TreeModel::iterator& iter) |
const Gtk::TreeModel::iterator& iter) |
308 |
{ |
{ |
309 |
|
if (!iter) return; |
310 |
|
Gtk::TreeModel::Row row = *iter; |
311 |
|
Glib::ustring value = row[m_treeModelMacro.m_col_value]; |
312 |
|
onMacroTreeViewRowValueChangedImpl(path, iter, value); |
313 |
|
} |
314 |
|
|
315 |
|
void MacroEditor::onMacroTreeViewRowValueChangedImpl(const Gtk::TreeModel::Path& path, |
316 |
|
const Gtk::TreeModel::iterator& iter, |
317 |
|
const Glib::ustring& value) |
318 |
|
{ |
319 |
if (m_ignoreTreeViewValueChange) return; |
if (m_ignoreTreeViewValueChange) return; |
320 |
if (!iter) return; |
if (!iter) return; |
321 |
Gtk::TreeModel::Row row = *iter; |
Gtk::TreeModel::Row row = *iter; |
|
Glib::ustring value = row[m_treeModelMacro.m_col_value]; |
|
322 |
Serialization::UID uid = row[m_treeModelMacro.m_col_uid]; |
Serialization::UID uid = row[m_treeModelMacro.m_col_uid]; |
323 |
Serialization::String gigvalue(gig_from_utf8(value)); |
Serialization::String gigvalue(gig_from_utf8(value)); |
324 |
Serialization::Object& object = m_macro.objectByUID(uid); |
Serialization::Object& object = m_macro.objectByUID(uid); |
325 |
std::string errorText; |
std::string errorText; |
326 |
try { |
try { |
327 |
m_macro.setAutoValue(object, gigvalue); |
if (object.type().isEnum() && |
328 |
|
gig::enumKey(object.type().customTypeName(), gigvalue)) |
329 |
|
{ |
330 |
|
size_t iValue = gig::enumValue(gigvalue); |
331 |
|
m_macro.setAutoValue(object, ToString(iValue)); |
332 |
|
// no auto correct here yet (due to numeric vs. textual values) |
333 |
|
if (row[m_treeModelMacro.m_col_value] != value) |
334 |
|
row[m_treeModelMacro.m_col_value] = value; |
335 |
|
} else { |
336 |
|
m_macro.setAutoValue(object, gigvalue); |
337 |
|
// potentially auto correct (i.e. when type is bool, user entered 5 -> yields 1) |
338 |
|
if (row[m_treeModelMacro.m_col_value] != m_macro.valueAsString(object)) |
339 |
|
row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object); |
340 |
|
} |
341 |
|
updateStatus(); |
342 |
} catch (Serialization::Exception e) { |
} catch (Serialization::Exception e) { |
343 |
errorText = e.Message; |
errorText = e.Message; |
344 |
} catch (...) { |
} catch (...) { |