/[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 3225 - (hide annotations) (download)
Fri May 26 22:10:16 2017 UTC (6 years, 11 months ago) by schoenebeck
File size: 20023 byte(s)
* Assigned more useful default dimensions (and default position) for various
  windows and dialogs (if auto-restore of user's own custom window
  dimensions is disabled).
* Bumped version (1.0.0.svn51).

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

  ViewVC Help
Powered by ViewVC