/[svn]/gigedit/trunk/src/gigedit/MacroEditor.cpp
ViewVC logotype

Annotation of /gigedit/trunk/src/gigedit/MacroEditor.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3187 - (hide annotations) (download)
Wed May 17 16:14:20 2017 UTC (6 years, 11 months ago) by schoenebeck
File size: 19909 byte(s)
* Macro Editor: Handle boolean parameter types appropriately, i.e. show
  'Yes' or 'NO' instead of '1' or '0'.
* Bumped version (1.0.0.svn47).

1 schoenebeck 3151 /*
2     Copyright (c) MMXVII Christian Schoenebeck
3    
4     This file is part of "gigedit" and released under the terms of the
5     GNU General Public License version 2.
6     */
7    
8     #include "MacroEditor.h"
9     #include "global.h"
10     #include <assert.h>
11    
12     MacroEditor::MacroEditor() :
13     m_macroOriginal(NULL),
14     m_statusLabel("", Gtk::ALIGN_START),
15 schoenebeck 3155 m_deleteButton(Glib::ustring(_("Delete")) + " " + UNICODE_PRIMARY_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL),
16     m_inverseDeleteButton(Glib::ustring(_("Inverse Delete")) + " " + UNICODE_ALT_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL),
17 schoenebeck 3151 m_applyButton(_("_Apply"), true),
18 schoenebeck 3155 m_cancelButton(_("_Cancel"), true),
19 schoenebeck 3170 m_altKeyDown(false),
20     m_primaryKeyDown(false)
21 schoenebeck 3151 {
22     add(m_vbox);
23    
24     set_default_size(800, 600);
25    
26 schoenebeck 3184 m_labelIntro.set_padding(10, 10);
27     #if GTKMM_MAJOR_VERSION >= 3
28     m_labelIntro.set_line_wrap();
29     #endif
30     m_labelIntro.set_text(
31 schoenebeck 3162 _("A macro is a list of parameters and corresponding values which "
32     "should be applied to the instrument editor when the macro is "
33 schoenebeck 3184 "triggered by the user. Only the parameters listed here will be "
34     "applied to the instrument editor when this macro is triggered, all "
35     "other ones remain untouched. So simply delete parameters here which "
36     "you don't want to be modified by this macro. Double click on a "
37     "value to change it.")
38 schoenebeck 3162 );
39 schoenebeck 3184 m_vbox.pack_start(m_labelIntro, Gtk::PACK_SHRINK);
40 schoenebeck 3162
41 schoenebeck 3151 // create Macro treeview (including its data model)
42     m_treeStoreMacro = MacroTreeStore::create(m_treeModelMacro);
43     m_treeViewMacro.set_model(m_treeStoreMacro);
44     m_treeViewMacro.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
45     //m_treeViewMacro.set_tooltip_text(_(""));
46     m_treeViewMacro.append_column(_("Key"), m_treeModelMacro.m_col_name);
47     m_treeViewMacro.append_column(_("Type"), m_treeModelMacro.m_col_type);
48 schoenebeck 3170 //m_treeViewMacro.append_column_editable(_("Value"), m_treeModelMacro.m_col_value);
49     //m_treeViewMacro.append_column(_("Value"), m_valueCellRenderer);
50     Gtk::TreeViewColumn* valueColumn = new Gtk::TreeViewColumn(_("Value"));
51     valueColumn->pack_start(m_valueCellRenderer);
52     m_treeViewMacro.append_column(*valueColumn);
53     // m_valueCellRenderer.property_model() = m_comboBoxModel;
54     // m_valueCellRenderer.property_text_column() = 0;
55     //m_valueCellRenderer.property_editable() = true;
56 schoenebeck 3154 {
57 schoenebeck 3170 Gtk::TreeView::Column* column = valueColumn;// m_treeViewMacro.get_column(2);
58     //column->set_renderer(m_valueCellRenderer, m_treeModelMacro.m_col_value);
59     column->add_attribute(m_valueCellRenderer.property_text(),
60     m_treeModelMacro.m_col_value);
61 schoenebeck 3187 column->add_attribute(m_valueCellRenderer.property_has_entry(),
62     m_treeModelMacro.m_col_allowTextEntry);
63 schoenebeck 3170 column->add_attribute(m_valueCellRenderer.property_editable(),
64     m_treeModelMacro.m_col_editable);
65     column->add_attribute(m_valueCellRenderer.property_model(),
66     m_treeModelMacro.m_col_options);
67     }
68     m_valueCellRenderer.property_text_column() = 0;
69     m_valueCellRenderer.signal_edited().connect(
70     sigc::mem_fun(*this, &MacroEditor::onValueCellEdited)
71     );
72    
73     {
74 schoenebeck 3154 Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(1);
75     Gtk::CellRendererText* cellrenderer =
76     dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell());
77     cellrenderer->property_foreground().set_value("#bababa");
78     }
79 schoenebeck 3151 m_treeViewMacro.set_headers_visible(true);
80 schoenebeck 3154 m_treeViewMacro.get_selection()->signal_changed().connect(
81     sigc::mem_fun(*this, &MacroEditor::onTreeViewSelectionChanged)
82     );
83     m_treeViewMacro.signal_key_release_event().connect_notify(
84     sigc::mem_fun(*this, &MacroEditor::onMacroTreeViewKeyRelease)
85     );
86     m_treeStoreMacro->signal_row_changed().connect(
87     sigc::mem_fun(*this, &MacroEditor::onMacroTreeViewRowValueChanged)
88     );
89     m_ignoreTreeViewValueChange = false;
90 schoenebeck 3151
91     m_scrolledWindow.add(m_treeViewMacro);
92     m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
93     m_vbox.pack_start(m_scrolledWindow);
94    
95 schoenebeck 3154 m_buttonBoxL.set_layout(Gtk::BUTTONBOX_START);
96     m_buttonBoxL.pack_start(m_deleteButton);
97     m_buttonBoxL.pack_start(m_inverseDeleteButton);
98     m_deleteButton.set_sensitive(false);
99     m_inverseDeleteButton.set_sensitive(false);
100    
101 schoenebeck 3151 m_buttonBox.set_layout(Gtk::BUTTONBOX_END);
102     m_buttonBox.pack_start(m_applyButton);
103     m_buttonBox.pack_start(m_cancelButton);
104     m_applyButton.set_can_default();
105     m_applyButton.set_sensitive(false);
106     m_applyButton.grab_focus();
107    
108     #if GTKMM_MAJOR_VERSION >= 3
109     m_statusLabel.set_margin_left(6);
110     m_statusLabel.set_margin_right(6);
111     #else
112     m_statusHBox.set_spacing(6);
113     #endif
114    
115     m_statusHBox.pack_start(m_statusLabel);
116     m_statusHBox.show_all_children();
117    
118 schoenebeck 3154 m_footerHBox.pack_start(m_buttonBoxL, Gtk::PACK_SHRINK);
119 schoenebeck 3151 m_footerHBox.pack_start(m_statusHBox);
120     m_footerHBox.pack_start(m_buttonBox, Gtk::PACK_SHRINK);
121    
122     m_vbox.pack_start(m_footerHBox, Gtk::PACK_SHRINK);
123    
124     m_applyButton.signal_clicked().connect(
125     sigc::mem_fun(*this, &MacroEditor::onButtonApply)
126     );
127    
128     m_cancelButton.signal_clicked().connect(
129     sigc::mem_fun(*this, &MacroEditor::onButtonCancel)
130     );
131    
132 schoenebeck 3154 m_deleteButton.signal_clicked().connect(
133     sigc::mem_fun(*this, &MacroEditor::deleteSelectedRows)
134     );
135    
136     m_inverseDeleteButton.signal_clicked().connect(
137     sigc::mem_fun(*this, &MacroEditor::inverseDeleteSelectedRows)
138     );
139    
140 schoenebeck 3151 signal_hide().connect(
141     sigc::mem_fun(*this, &MacroEditor::onWindowHide)
142     );
143    
144     signal_delete_event().connect(
145     sigc::mem_fun(*this, &MacroEditor::onWindowDelete)
146     );
147    
148 schoenebeck 3155 signal_key_press_event().connect(
149     sigc::mem_fun(*this, &MacroEditor::onKeyPressed)
150     );
151     signal_key_release_event().connect(
152     sigc::mem_fun(*this, &MacroEditor::onKeyReleased)
153     );
154    
155 schoenebeck 3184 m_deleteButton.set_tooltip_text(_("Delete the selected parameters from this macro."));
156     m_inverseDeleteButton.set_tooltip_text(_("Delete all parameters from this macro except the selected ones."));
157    
158 schoenebeck 3151 show_all_children();
159     updateStatus();
160     }
161    
162     MacroEditor::~MacroEditor() {
163     printf("MacroEditor destruct\n");
164     }
165    
166 schoenebeck 3162 void MacroEditor::setMacro(Serialization::Archive* macro, bool isClipboard) {
167 schoenebeck 3151 m_macroOriginal = macro;
168     if (!macro) {
169     set_title(_("No Macro"));
170     return;
171     }
172    
173 schoenebeck 3162 if (isClipboard)
174     set_title(std::string(_("Macro Editor:")) + " " + _("Clipboard Content"));
175     else {
176     if (macro->name().empty())
177     set_title(std::string(_("Macro Editor:")) + " " + _("Unnamed Macro"));
178     else
179     set_title(std::string(_("Macro Editor:")) + " \"" + macro->name() + "\"");
180     }
181 schoenebeck 3151
182     // copy for non-destructive editing
183     m_macro = *macro;
184    
185     reloadTreeView();
186     }
187    
188 schoenebeck 3162 sigc::signal<void>& MacroEditor::signal_changes_applied() {
189     return m_changes_applied;
190     }
191    
192 schoenebeck 3170 Glib::RefPtr<Gtk::ListStore> MacroEditor::createComboOptions(const char** options) {
193     Glib::RefPtr<Gtk::ListStore> refOptions = Gtk::ListStore::create(m_comboOptionsModel);
194     for (size_t i = 0; options[i]; ++i)
195     (*refOptions->append())[m_comboOptionsModel.m_col_choice] = options[i];
196     return refOptions;
197     }
198    
199 schoenebeck 3187 inline static Serialization::String _boolToStr(bool b) {
200     // 'NO' intentional all uper case in contrast to 'Yes', simply because I
201     // find them easier distinguishable that way on quick readings
202     return b ? "Yes" : "NO";
203     }
204    
205     static const char* _boolOptions[] = { "Yes", "NO", NULL };
206    
207 schoenebeck 3151 void MacroEditor::buildTreeView(const Gtk::TreeModel::Row& parentRow, const Serialization::Object& parentObject) {
208     for (int iMember = 0; iMember < parentObject.members().size(); ++iMember) {
209     const Serialization::Member& member = parentObject.members()[iMember];
210     const Serialization::Object& object = m_macro.objectByUID(member.uid());
211     Gtk::TreeModel::iterator iterRow = m_treeStoreMacro->append(parentRow.children());
212     Gtk::TreeModel::Row row = *iterRow;
213     row[m_treeModelMacro.m_col_name] = gig_to_utf8(member.name());
214     row[m_treeModelMacro.m_col_type] = gig_to_utf8(member.type().asLongDescr());
215     row[m_treeModelMacro.m_col_uid] = object.uid();
216 schoenebeck 3187 row[m_treeModelMacro.m_col_allowTextEntry] = true;
217 schoenebeck 3170
218 schoenebeck 3151 if (object.type().isClass()) {
219     row[m_treeModelMacro.m_col_value] = "(class)";
220 schoenebeck 3170 row[m_treeModelMacro.m_col_editable] = false;
221 schoenebeck 3151 buildTreeView(row, object);
222 schoenebeck 3170 } else if (object.type().isEnum()) {
223     const char* key = gig::enumKey(
224     object.type().customTypeName(), m_macro.valueAsInt(object)
225     );
226     row[m_treeModelMacro.m_col_value] = key ? key : m_macro.valueAsString(object);
227     row[m_treeModelMacro.m_col_editable] = true;
228     const char** allKeys = gig::enumKeys(object.type().customTypeName());
229     if (allKeys) {
230     Glib::RefPtr<Gtk::ListStore> refOptions = createComboOptions(allKeys);
231     row[m_treeModelMacro.m_col_options] = refOptions;
232     }
233 schoenebeck 3187 } else if (object.type().isBool()) {
234     row[m_treeModelMacro.m_col_value] = _boolToStr( m_macro.valueAsBool(object) );
235     row[m_treeModelMacro.m_col_editable] = true;
236     Glib::RefPtr<Gtk::ListStore> refOptions = createComboOptions(_boolOptions);
237     row[m_treeModelMacro.m_col_options] = refOptions;
238     row[m_treeModelMacro.m_col_allowTextEntry] = false;
239 schoenebeck 3151 } else {
240     row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object);
241 schoenebeck 3170 row[m_treeModelMacro.m_col_editable] = true;
242 schoenebeck 3151 }
243     }
244     }
245    
246     void MacroEditor::reloadTreeView() {
247 schoenebeck 3154 m_ignoreTreeViewValueChange = true;
248    
249 schoenebeck 3151 m_treeStoreMacro->clear();
250    
251     const Serialization::Object& rootObject = m_macro.rootObject();
252    
253     Gtk::TreeModel::iterator iterRoot = m_treeStoreMacro->append();
254     Gtk::TreeModel::Row rowRoot = *iterRoot;
255     rowRoot[m_treeModelMacro.m_col_name] = "(Root)";
256     rowRoot[m_treeModelMacro.m_col_type] = gig_to_utf8(rootObject.type().asLongDescr());
257     rowRoot[m_treeModelMacro.m_col_value] = "";
258     rowRoot[m_treeModelMacro.m_col_uid] = rootObject.uid();
259 schoenebeck 3170 rowRoot[m_treeModelMacro.m_col_allowTextEntry] = false;
260     rowRoot[m_treeModelMacro.m_col_editable] = false;
261 schoenebeck 3151
262     buildTreeView(rowRoot, rootObject);
263    
264     m_treeViewMacro.expand_all();
265    
266     updateStatus();
267 schoenebeck 3154
268     m_ignoreTreeViewValueChange = false;
269 schoenebeck 3151 }
270    
271 schoenebeck 3154 void MacroEditor::onTreeViewSelectionChanged() {
272     std::vector<Gtk::TreeModel::Path> v = m_treeViewMacro.get_selection()->get_selected_rows();
273     const bool bValidSelection = !v.empty();
274     m_deleteButton.set_sensitive(bValidSelection);
275     m_inverseDeleteButton.set_sensitive(bValidSelection);
276     }
277    
278 schoenebeck 3170 // Cmd key on Mac, Ctrl key on all other OSs
279     static const guint primaryKeyL =
280     #if defined(__APPLE__)
281     GDK_KEY_Meta_L;
282     #else
283     GDK_KEY_Control_L;
284     #endif
285    
286     static const guint primaryKeyR =
287     #if defined(__APPLE__)
288     GDK_KEY_Meta_R;
289     #else
290     GDK_KEY_Control_R;
291     #endif
292    
293 schoenebeck 3155 bool MacroEditor::onKeyPressed(GdkEventKey* key) {
294     //printf("key down 0x%x\n", key->keyval);
295     if (key->keyval == GDK_KEY_Alt_L || key->keyval == GDK_KEY_Alt_R)
296     m_altKeyDown = true;
297 schoenebeck 3170 if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
298     m_primaryKeyDown = true;
299 schoenebeck 3155 return false;
300     }
301    
302     bool MacroEditor::onKeyReleased(GdkEventKey* key) {
303     //printf("key up 0x%x\n", key->keyval);
304     if (key->keyval == GDK_KEY_Alt_L || key->keyval == GDK_KEY_Alt_R)
305     m_altKeyDown = false;
306 schoenebeck 3170 if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
307     m_primaryKeyDown = false;
308 schoenebeck 3155 return false;
309     }
310    
311 schoenebeck 3154 void MacroEditor::onMacroTreeViewKeyRelease(GdkEventKey* key) {
312 schoenebeck 3155 if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) {
313     if (m_altKeyDown)
314     inverseDeleteSelectedRows();
315 schoenebeck 3170 else if (m_primaryKeyDown)
316 schoenebeck 3155 deleteSelectedRows();
317     }
318 schoenebeck 3154 }
319    
320 schoenebeck 3170 void MacroEditor::onValueCellEdited(const Glib::ustring& sPath, const Glib::ustring& text) {
321     Gtk::TreePath path(sPath);
322     Gtk::TreeModel::iterator iter = m_treeStoreMacro->get_iter(path);
323     onMacroTreeViewRowValueChangedImpl(path, iter, text);
324     }
325    
326 schoenebeck 3154 void MacroEditor::onMacroTreeViewRowValueChanged(const Gtk::TreeModel::Path& path,
327     const Gtk::TreeModel::iterator& iter)
328     {
329 schoenebeck 3170 if (!iter) return;
330     Gtk::TreeModel::Row row = *iter;
331     Glib::ustring value = row[m_treeModelMacro.m_col_value];
332     onMacroTreeViewRowValueChangedImpl(path, iter, value);
333     }
334    
335     void MacroEditor::onMacroTreeViewRowValueChangedImpl(const Gtk::TreeModel::Path& path,
336     const Gtk::TreeModel::iterator& iter,
337     const Glib::ustring& value)
338     {
339 schoenebeck 3154 if (m_ignoreTreeViewValueChange) return;
340     if (!iter) return;
341     Gtk::TreeModel::Row row = *iter;
342     Serialization::UID uid = row[m_treeModelMacro.m_col_uid];
343     Serialization::String gigvalue(gig_from_utf8(value));
344     Serialization::Object& object = m_macro.objectByUID(uid);
345     std::string errorText;
346     try {
347 schoenebeck 3170 if (object.type().isEnum() &&
348     gig::enumKey(object.type().customTypeName(), gigvalue))
349     {
350     size_t iValue = gig::enumValue(gigvalue);
351     m_macro.setAutoValue(object, ToString(iValue));
352     // no auto correct here yet (due to numeric vs. textual values)
353     if (row[m_treeModelMacro.m_col_value] != value)
354     row[m_treeModelMacro.m_col_value] = value;
355 schoenebeck 3187 } else if (object.type().isBool()) {
356     m_macro.setAutoValue(object, gigvalue);
357     Serialization::String sBoolean = _boolToStr( m_macro.valueAsBool(object) );
358     // potentially auto correct (i.e. when type is bool, user entered '5' -> yields 'Yes')
359     if (row[m_treeModelMacro.m_col_value] != sBoolean)
360     row[m_treeModelMacro.m_col_value] = sBoolean;
361 schoenebeck 3170 } else {
362     m_macro.setAutoValue(object, gigvalue);
363     // potentially auto correct (i.e. when type is bool, user entered 5 -> yields 1)
364     if (row[m_treeModelMacro.m_col_value] != m_macro.valueAsString(object))
365     row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object);
366     }
367     updateStatus();
368 schoenebeck 3154 } catch (Serialization::Exception e) {
369     errorText = e.Message;
370     } catch (...) {
371     errorText = _("Unknown exception during object value change");
372     }
373     if (!errorText.empty()) {
374     Glib::ustring txt = _("Couldn't change value:\n") + errorText;
375     Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
376     msg.run();
377     }
378     }
379    
380     void MacroEditor::deleteSelectedRows() {
381     Glib::RefPtr<Gtk::TreeSelection> sel = m_treeViewMacro.get_selection();
382     std::vector<Gtk::TreeModel::Path> rows = sel->get_selected_rows();
383 schoenebeck 3155 deleteRows(rows);
384     }
385    
386     void MacroEditor::deleteRows(const std::vector<Gtk::TreeModel::Path>& rows) {
387 schoenebeck 3154 for (int r = rows.size() - 1; r >= 0; --r) {
388     Gtk::TreeModel::iterator it = m_treeStoreMacro->get_iter(rows[r]);
389     if (!it) continue;
390     Gtk::TreeModel::Row row = *it;
391     Serialization::UID uid = row[m_treeModelMacro.m_col_uid];
392     if (uid == m_macro.rootObject().uid()) continue; // prohibit deleting root object
393     Gtk::TreeModel::iterator itParent = row.parent();
394     if (!itParent) continue;
395     Gtk::TreeModel::Row rowParent = *itParent;
396     Serialization::UID uidParent = rowParent[m_treeModelMacro.m_col_uid];
397     //Serialization::Object& object = m_macro.objectByUID(uid);
398     Serialization::Object& parentObject = m_macro.objectByUID(uidParent);
399     const Serialization::Member& member = parentObject.memberByUID(uid);
400     m_macro.removeMember(parentObject, member);
401     //m_macro.remove(object);
402     }
403     reloadTreeView();
404     }
405    
406 schoenebeck 3155 static bool _onEachTreeRow(const Gtk::TreeModel::Path& input, std::vector<Gtk::TreeModel::Path>* output) {
407     output->push_back(input);
408     return false; // continue walking the tree
409     }
410    
411 schoenebeck 3154 void MacroEditor::inverseDeleteSelectedRows() {
412 schoenebeck 3155 // get all rows of tree view
413     std::vector<Gtk::TreeModel::Path> rows;
414     m_treeViewMacro.get_model()->foreach_path(
415     sigc::bind(
416     sigc::ptr_fun(&_onEachTreeRow),
417     &rows
418     )
419     );
420    
421     // erase all entries from "rows" which are currently selected
422     std::vector<Gtk::TreeModel::Path> vSelected = m_treeViewMacro.get_selection()->get_selected_rows();
423     for (int i = rows.size() - 1; i >= 0; --i) {
424     bool bIsSelected = std::find(vSelected.begin(), vSelected.end(),
425     rows[i]) != vSelected.end();
426     if (bIsSelected)
427     rows.erase(rows.begin() + i);
428     }
429    
430     // delete those 'inverse' selected rows
431     deleteRows(rows);
432 schoenebeck 3154 }
433    
434 schoenebeck 3151 void MacroEditor::updateStatus() {
435     m_applyButton.set_sensitive(isModified());
436     updateStatusBar();
437     }
438    
439     void MacroEditor::updateStatusBar() {
440     // update status text
441     std::string txt;
442     m_statusLabel.set_markup(txt);
443     }
444    
445     bool MacroEditor::onWindowDelete(GdkEventAny* e) {
446     //printf("onWindowDelete\n");
447    
448     if (!isModified()) return false; // propagate event further (which will close this window)
449    
450     //gchar* msg = g_strdup_printf(_("Apply changes to macro \"%s\" before closing?"),
451     // m_macroOriginal->Name.c_str());
452     gchar* msg = g_strdup_printf(_("Apply changes to macro before closing?"));
453     Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
454     g_free(msg);
455     dialog.set_secondary_text(_("If you close without applying, your changes will be lost."));
456     dialog.add_button(_("Close _Without Applying"), Gtk::RESPONSE_NO);
457     dialog.add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
458     dialog.add_button(_("_Apply"), Gtk::RESPONSE_YES);
459     dialog.set_default_response(Gtk::RESPONSE_YES);
460     int response = dialog.run();
461     dialog.hide();
462    
463     // user decided to close macro editor without saving
464     if (response == Gtk::RESPONSE_NO)
465     return false; // propagate event further (which will close this window)
466    
467     // user cancelled dialog, thus don't close macro editor
468     if (response == Gtk::RESPONSE_CANCEL) {
469     show();
470     return true; // drop event (prevents closing this window)
471     }
472    
473     // user wants to apply the changes, afterwards close window
474     if (response == Gtk::RESPONSE_YES) {
475     onButtonApply();
476     return false; // propagate event further (which will close this window)
477     }
478    
479     // should never ever make it to this point actually
480     return false;
481     }
482    
483     bool MacroEditor::isModified() const {
484     return m_macro.isModified();
485     }
486    
487     void MacroEditor::onButtonCancel() {
488     bool dropEvent = onWindowDelete(NULL);
489     if (dropEvent) return;
490     hide();
491     }
492    
493     void MacroEditor::onButtonApply() {
494 schoenebeck 3155 std::string errorText;
495     try {
496     // enforce re-encoding the abstract object model and resetting the
497     // 'modified' state
498     m_macro.rawData();
499     // replace actual effective Archive object which is effectively used
500     // for macro apply operations
501     *m_macroOriginal = m_macro;
502     } catch (Serialization::Exception e) {
503     errorText = e.Message;
504     } catch (...) {
505     errorText = _("Unknown exception while applying macro changes");
506     }
507     if (!errorText.empty()) {
508     Glib::ustring txt = _("Couldn't apply macro changes:\n") + errorText;
509     Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
510     msg.run();
511     }
512     updateStatus();
513 schoenebeck 3162 m_changes_applied.emit();
514 schoenebeck 3151 }
515    
516     void MacroEditor::onWindowHide() {
517     delete this; // this is the end, my friend
518     }

  ViewVC Help
Powered by ViewVC