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

Diff of /gigedit/trunk/src/gigedit/MacrosSetup.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3157 by schoenebeck, Mon May 8 17:30:10 2017 UTC revision 3162 by schoenebeck, Tue May 9 14:35:23 2017 UTC
# Line 9  Line 9 
9  #include "global.h"  #include "global.h"
10  #include <assert.h>  #include <assert.h>
11  #include <set>  #include <set>
12    #include <math.h>
13    #include <gtkmm/stock.h>
14    #include "MacroEditor.h"
15    
16  MacrosSetup::MacrosSetup() :  MacrosSetup::MacrosSetup() :
17        m_modified(false),
18        m_clipboardContent(NULL),
19        m_addFromClipboardButton("  " + Glib::ustring(_("From Clipboard")) + "  " + UNICODE_PRIMARY_KEY_SYMBOL + "B"),
20        m_addFromSelectionButton("  " + Glib::ustring(_("From Selection")) + "  " + UNICODE_PRIMARY_KEY_SYMBOL + "S"),
21        m_buttonUp(Gtk::Stock::GO_UP),
22        m_buttonDown(Gtk::Stock::GO_DOWN),
23        m_buttonEdit(Gtk::Stock::EDIT),
24      m_statusLabel("",  Gtk::ALIGN_START),      m_statusLabel("",  Gtk::ALIGN_START),
25      m_deleteButton(Glib::ustring(_("Delete")) + " " + UNICODE_PRIMARY_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL),      m_labelComment(_("Comment"), Gtk::ALIGN_START),
26      m_inverseDeleteButton(Glib::ustring(_("Inverse Delete")) + " " + UNICODE_ALT_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL),      m_deleteButton("  " + Glib::ustring(_("Delete")) + "  " + UNICODE_PRIMARY_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL),
27      m_applyButton(_("_Apply"), true),      m_inverseDeleteButton("  " + Glib::ustring(_("Inverse Delete")) + "  " + UNICODE_ALT_KEY_SYMBOL + UNICODE_ERASE_KEY_SYMBOL),
28      m_cancelButton(_("_Cancel"), true),      m_applyButton(Gtk::Stock::APPLY),
29      m_altKeyDown(false)      m_cancelButton(Gtk::Stock::CANCEL),
30        m_altKeyDown(false),
31        m_primaryKeyDown(false)
32  {  {
33      add(m_vbox);      add(m_vbox);
34    
35      set_title(_("Setup Macros"));      set_title(_("Setup Macros"));
36    
37      set_default_size(800, 600);      set_default_size(680, 500);
38    
39        m_addFromClipboardButton.set_image(
40            *new Gtk::Image(Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON)
41        );
42        m_addFromSelectionButton.set_image(
43            *new Gtk::Image(Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON)
44        );
45        m_deleteButton.set_image(
46            *new Gtk::Image(Gtk::Stock::DELETE, Gtk::ICON_SIZE_BUTTON)
47        );
48        m_inverseDeleteButton.set_image(
49            *new Gtk::Image(Gtk::Stock::DELETE, Gtk::ICON_SIZE_BUTTON)
50        );
51        m_addFromClipboardButton.set_tooltip_text(_("Create a new macro from the content currently available on the clipboard."));
52        m_addFromSelectionButton.set_tooltip_text(_("Create a new macro from the currently selected dimension region's parameters currently shown on the main window."));
53        m_addHBox.pack_start(m_addFromClipboardButton, Gtk::PACK_EXPAND_WIDGET/*, 15*/);
54        m_addHBox.pack_start(m_addFromSelectionButton, Gtk::PACK_EXPAND_WIDGET/*, 15*/);
55        m_vbox.pack_start(m_addHBox, Gtk::PACK_SHRINK);
56    
57        m_vbox.pack_start(m_mainHBox);
58        m_vbox.set_spacing(5);
59    
60      // create Macro list treeview (including its data model)      // create Macro list treeview (including its data model)
61      m_treeStoreMacros = MacroListTreeStore::create(m_treeModelMacros);      m_treeStoreMacros = MacroListTreeStore::create(m_treeModelMacros);
# Line 30  MacrosSetup::MacrosSetup() : Line 63  MacrosSetup::MacrosSetup() :
63      m_treeViewMacros.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);      m_treeViewMacros.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
64      //m_treeViewMacro.set_tooltip_text(_(""));      //m_treeViewMacro.set_tooltip_text(_(""));
65      m_treeViewMacros.append_column(_("Key"), m_treeModelMacros.m_col_key);      m_treeViewMacros.append_column(_("Key"), m_treeModelMacros.m_col_key);
66      m_treeViewMacros.append_column_editable(_("Name"), m_treeModelMacros.m_col_name);      m_treeViewMacros.append_column_editable(_("Macro Name"), m_treeModelMacros.m_col_name);
67      m_treeViewMacros.append_column(_("Created"), m_treeModelMacros.m_col_created);      m_treeViewMacros.append_column(_("Created"), m_treeModelMacros.m_col_created);
68      m_treeViewMacros.append_column(_("Modified"), m_treeModelMacros.m_col_modified);      m_treeViewMacros.append_column(_("Modified"), m_treeModelMacros.m_col_modified);
69      m_treeViewMacros.set_tooltip_column(m_treeModelMacros.m_col_comment.index());      m_treeViewMacros.set_tooltip_column(m_treeModelMacros.m_col_comment.index());
# Line 63  MacrosSetup::MacrosSetup() : Line 96  MacrosSetup::MacrosSetup() :
96      m_treeViewMacros.get_selection()->signal_changed().connect(      m_treeViewMacros.get_selection()->signal_changed().connect(
97          sigc::mem_fun(*this, &MacrosSetup::onTreeViewSelectionChanged)          sigc::mem_fun(*this, &MacrosSetup::onTreeViewSelectionChanged)
98      );      );
99      /*m_treeViewMacros.signal_key_release_event().connect_notify(      m_treeViewMacros.signal_key_release_event().connect_notify(
100          sigc::mem_fun(*this, &MacrosSetup::onMacroTreeViewKeyRelease)          sigc::mem_fun(*this, &MacrosSetup::onMacroTreeViewKeyRelease)
101      );*/      );
102      m_treeStoreMacros->signal_row_changed().connect(      m_treeStoreMacros->signal_row_changed().connect(
103          sigc::mem_fun(*this, &MacrosSetup::onMacroTreeViewRowValueChanged)          sigc::mem_fun(*this, &MacrosSetup::onMacroTreeViewRowValueChanged)
104      );      );
105      m_ignoreTreeViewValueChange = false;      m_ignoreTreeViewValueChange = false;
106        m_ignoreCommentTextViewChange = false;
107    
108      m_scrolledWindow.add(m_treeViewMacros);      m_scrolledWindow.add(m_treeViewMacros);
109      m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);      m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
110      m_vbox.pack_start(m_scrolledWindow);      m_mainHBox.pack_start(m_scrolledWindow);
111    
112        m_rvbox.set_spacing(5);
113    
114        m_mainHBox.pack_start(m_rvbox, Gtk::PACK_SHRINK);
115        m_mainHBox.set_spacing(5),
116        m_rvbox.set_spacing(5);
117        m_rvbox.pack_start(m_detailsButtonBox, Gtk::PACK_SHRINK);
118    
119        //m_textViewComment.set_left_margin(3);
120        //m_textViewComment.set_right_margin(3);
121        m_textViewComment.set_indent(2);
122        m_scrolledWindowComment.add(m_textViewComment);
123        m_scrolledWindowComment.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
124        m_labelComment.set_markup(
125            "<b>" + m_labelComment.get_text() + "</b>"
126        );
127        m_rvbox.pack_start(m_labelComment, Gtk::PACK_SHRINK);
128        m_rvbox.pack_start(m_scrolledWindowComment);
129    
130        m_detailsButtonBox.pack_start(m_buttonUp);
131        m_detailsButtonBox.pack_start(m_buttonDown);
132        m_detailsButtonBox.pack_start(m_buttonEdit);
133    
134      m_buttonBoxL.set_layout(Gtk::BUTTONBOX_START);      m_buttonBoxL.set_layout(Gtk::BUTTONBOX_START);
135      m_buttonBoxL.pack_start(m_deleteButton);      m_buttonBoxL.pack_start(m_deleteButton);
# Line 104  MacrosSetup::MacrosSetup() : Line 160  MacrosSetup::MacrosSetup() :
160    
161      m_vbox.pack_start(m_footerHBox, Gtk::PACK_SHRINK);      m_vbox.pack_start(m_footerHBox, Gtk::PACK_SHRINK);
162    
163        m_addFromClipboardButton.signal_clicked().connect(
164            sigc::mem_fun(*this, &MacrosSetup::onButtonAddFromClipboard)
165        );
166    
167        m_addFromSelectionButton.signal_clicked().connect(
168            sigc::mem_fun(*this, &MacrosSetup::onButtonAddFromSelection)
169        );
170    
171        m_buttonUp.signal_clicked().connect(
172            sigc::mem_fun(*this, &MacrosSetup::onButtonUp)
173        );
174    
175        m_buttonDown.signal_clicked().connect(
176            sigc::mem_fun(*this, &MacrosSetup::onButtonDown)
177        );
178    
179        m_buttonEdit.signal_clicked().connect(
180            sigc::mem_fun(*this, &MacrosSetup::onButtonEdit)
181        );
182    
183        m_textViewComment.get_buffer()->signal_changed().connect(
184            sigc::mem_fun(*this, &MacrosSetup::onCommentTextViewChanged)
185        );
186    
187      m_applyButton.signal_clicked().connect(      m_applyButton.signal_clicked().connect(
188          sigc::mem_fun(*this, &MacrosSetup::onButtonApply)          sigc::mem_fun(*this, &MacrosSetup::onButtonApply)
189      );      );
# Line 143  MacrosSetup::~MacrosSetup() { Line 223  MacrosSetup::~MacrosSetup() {
223      printf("MacrosSetup destruct\n");      printf("MacrosSetup destruct\n");
224  }  }
225    
226  void MacrosSetup::setMacros(const std::vector<Serialization::Archive>& macros) {  void MacrosSetup::setMacros(const std::vector<Serialization::Archive>& macros,
227                                Serialization::Archive* pClipboardContent,
228                                gig::DimensionRegion* pSelectedDimRgn)
229    {
230      // copy for non-destructive editing      // copy for non-destructive editing
231      m_macros = macros;      m_macros = macros;
232    
233        m_clipboardContent = pClipboardContent;
234        m_selectedDimRgn = pSelectedDimRgn;
235    
236      reloadTreeView();      reloadTreeView();
237  }  }
238    
239    void MacrosSetup::onButtonAddFromClipboard() {
240        printf("+fromClipboard\n");
241        if (!m_clipboardContent) return;
242        if (!m_clipboardContent->rootObject()) return;
243        m_macros.push_back(*m_clipboardContent);
244        m_modified = true;
245        reloadTreeView();
246    }
247    
248    void MacrosSetup::onButtonAddFromSelection() {
249        printf("+fromSelection\n");
250        if (!m_selectedDimRgn) return;
251        std::string errorText;
252        try {
253            Serialization::Archive archive;
254            archive.serialize(m_selectedDimRgn);
255            //archive.setName("Unnamed Macro");
256            m_macros.push_back(archive);
257            m_modified = true;
258            reloadTreeView();
259        } catch (Serialization::Exception e) {
260            errorText = e.Message;
261        } catch (...) {
262            errorText = _("Unknown exception while creating macro");
263        }
264        if (!errorText.empty()) {
265            Glib::ustring txt = _("Couldn't create macro:\n") + errorText;
266            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
267            msg.run();
268        }
269    }
270    
271    void MacrosSetup::moveByDir(int d) {
272        if (d < -1 || d > 1) return;
273        int index = getSelectedMacroIndex();
274        if (index < 0) return;
275        if (d == -1 && index == 0) return;
276        if (d == +1 && index >= m_macros.size() - 1) return;
277    
278        // swap macros
279        std::swap(m_macros[index + d], m_macros[index]);
280    
281        // swap tree view rows
282        Gtk::TreePath p1(ToString(index + d));
283        Gtk::TreePath p2(ToString(index));
284        Gtk::TreeModel::iterator it1 = m_treeStoreMacros->get_iter(p1);
285        Gtk::TreeModel::iterator it2 = m_treeStoreMacros->get_iter(p2);
286        m_treeStoreMacros->iter_swap(it1, it2);
287        int idx1 = (*it1)[m_treeModelMacros.m_col_index];
288        int idx2 = (*it2)[m_treeModelMacros.m_col_index];
289        (*it1)[m_treeModelMacros.m_col_index] = idx2;
290        (*it2)[m_treeModelMacros.m_col_index] = idx1;
291        Glib::ustring s1 = (*it1)[m_treeModelMacros.m_col_key];
292        Glib::ustring s2 = (*it2)[m_treeModelMacros.m_col_key];
293        (*it1)[m_treeModelMacros.m_col_key] = s2;
294        (*it2)[m_treeModelMacros.m_col_key] = s1;
295    
296        m_modified = true;
297    }
298    
299    void MacrosSetup::onButtonUp() {
300        moveByDir(-1);
301    }
302    
303    void MacrosSetup::onButtonDown() {
304        moveByDir(+1);
305    }
306    
307    void MacrosSetup::onButtonEdit() {
308        Serialization::Archive* macro = getSelectedMacro();
309        if (!macro) return;
310    
311        m_modifiedBeforeMacroEditor = isModified();
312    
313        MacroEditor* editor = new MacroEditor();
314        editor->setMacro(macro, false);
315        editor->signal_changes_applied().connect(
316            sigc::mem_fun(*this, &MacrosSetup::onMacroEditorAppliedChanges)
317        );
318        editor->show();
319    }
320    
321    void MacrosSetup::onMacroEditorAppliedChanges() {
322        // so that the user does not need to click on a Apply buttons twice
323        if (!m_modifiedBeforeMacroEditor)
324            onButtonApply();
325        updateStatus();
326    }
327    
328    void MacrosSetup::onCommentTextViewChanged() {
329        if (m_ignoreCommentTextViewChange) return;
330        //printf("textChanged\n");
331        Serialization::Archive* macro = getSelectedMacro();
332        if (!macro) return;
333        macro->setComment(
334            m_textViewComment.get_buffer()->get_text()
335        );
336        updateStatus();
337    }
338    
339    int MacrosSetup::getSelectedMacroIndex() const {
340        std::vector<Gtk::TreeModel::Path> v = m_treeViewMacros.get_selection()->get_selected_rows();
341        if (v.empty()) return -1;
342        Gtk::TreeModel::iterator it = m_treeStoreMacros->get_iter(v[0]);
343        if (!it) return -1;
344        const Gtk::TreeModel::Row& row = *it;
345        int index = row[m_treeModelMacros.m_col_index];
346        if (index < 0 || index >= m_macros.size()) return -1;
347        return index;
348    }
349    
350    Serialization::Archive* MacrosSetup::getSelectedMacro() {
351        int index = getSelectedMacroIndex();
352        if (index < 0) return NULL;
353        return &m_macros[index];
354    }
355    
356  static Glib::ustring indexToAccKey(uint index) {  static Glib::ustring indexToAccKey(uint index) {
357      if (index >= 12) return "";      if (index >= 12) return "";
358      return "F" + ToString(index+1);      return "F" + ToString(index+1);
359  }  }
360    
361    static int daysAgo(const tm& t) {
362        time_t now;
363        time(&now);
364        tm* pNow = localtime(&now);
365        if (!pNow) return 0;
366        if (pNow->tm_year == t.tm_year &&
367            pNow->tm_mon  == t.tm_mon &&
368            pNow->tm_mday == t.tm_mday) return 0;
369        time_t past = mktime((tm*)&t);
370        return ceil(difftime(now, past) / 60.0 / 60.0 / 24.0);
371    }
372    
373  static Glib::ustring humanShortStr(const tm& t) {  static Glib::ustring humanShortStr(const tm& t) {
374        int iDaysAgo = daysAgo(t);
375      char buf[70];      char buf[70];
376      int daysAgo;      if (iDaysAgo == 0) {
     if (daysAgo = 0) {  
377          // C-Time specification for a time somewhere today (see 'man strftime()').          // C-Time specification for a time somewhere today (see 'man strftime()').
378          if (strftime(buf, sizeof buf, _("%R"), &t))          if (strftime(buf, sizeof buf, _("%R"), &t))
379              return buf;              return buf;
380      } else if (daysAgo = 1) {      } else if (iDaysAgo == 1) {
381          // C-Time specification for a time somewhere yesterday (see 'man strftime()').          // C-Time specification for a time somewhere yesterday (see 'man strftime()').
382          if (strftime(buf, sizeof buf, _("Yesterday %R"), &t))          if (strftime(buf, sizeof buf, _("Yesterday %R"), &t))
383              return buf;              return buf;
384      } else if (daysAgo = 2) {      } else if (iDaysAgo == 2) {
385          // C-Time specification for a time somewhere 2 days ago (see 'man strftime()').          // C-Time specification for a time somewhere 2 days ago (see 'man strftime()').
386          if (strftime(buf, sizeof buf, _("2 days ago %R"), &t))          if (strftime(buf, sizeof buf, _("2 days ago %R"), &t))
387              return buf;              return buf;
# Line 189  void MacrosSetup::reloadTreeView() { Line 404  void MacrosSetup::reloadTreeView() {
404          Gtk::TreeModel::iterator iter = m_treeStoreMacros->append();          Gtk::TreeModel::iterator iter = m_treeStoreMacros->append();
405          Gtk::TreeModel::Row row = *iter;          Gtk::TreeModel::Row row = *iter;
406          row[m_treeModelMacros.m_col_key] = indexToAccKey(iMacro);          row[m_treeModelMacros.m_col_key] = indexToAccKey(iMacro);
407          row[m_treeModelMacros.m_col_name] = gig_to_utf8(macro.name());          row[m_treeModelMacros.m_col_name] = macro.name().empty() ? _("Unnamed Macro") : gig_to_utf8(macro.name());
408          row[m_treeModelMacros.m_col_comment] = gig_to_utf8(macro.comment());          row[m_treeModelMacros.m_col_comment] = macro.comment().empty() ? _("No comment assigned yet.") : gig_to_utf8(macro.comment());
409          row[m_treeModelMacros.m_col_created] = humanShortStr(macro.dateTimeCreated());          row[m_treeModelMacros.m_col_created] = humanShortStr(macro.dateTimeCreated());
410          row[m_treeModelMacros.m_col_modified] = humanShortStr(macro.dateTimeModified());          row[m_treeModelMacros.m_col_modified] = humanShortStr(macro.dateTimeModified());
411          row[m_treeModelMacros.m_col_index] = iMacro;          row[m_treeModelMacros.m_col_index] = iMacro;
# Line 208  void MacrosSetup::onTreeViewSelectionCha Line 423  void MacrosSetup::onTreeViewSelectionCha
423      const bool bValidSelection = !v.empty();      const bool bValidSelection = !v.empty();
424      m_deleteButton.set_sensitive(bValidSelection);      m_deleteButton.set_sensitive(bValidSelection);
425      m_inverseDeleteButton.set_sensitive(bValidSelection);      m_inverseDeleteButton.set_sensitive(bValidSelection);
426  }      m_buttonEdit.set_sensitive(bValidSelection);
427    
428        // update comment text view
429        std::string sComment;
430        Serialization::Archive* macro = getSelectedMacro();
431        if (macro)
432            sComment = macro->comment();
433        m_ignoreCommentTextViewChange = true;
434        m_textViewComment.get_buffer()->set_text(sComment);
435        m_ignoreCommentTextViewChange = false;
436        m_textViewComment.set_sensitive(bValidSelection);
437    }
438    
439    // Cmd key on Mac, Ctrl key on all other OSs
440    static const guint primaryKeyL =
441        #if defined(__APPLE__)
442        GDK_KEY_Meta_L;
443        #else
444        GDK_KEY_Control_L;
445        #endif
446    
447    static const guint primaryKeyR =
448        #if defined(__APPLE__)
449        GDK_KEY_Meta_R;
450        #else
451        GDK_KEY_Control_R;
452        #endif
453    
454  bool MacrosSetup::onKeyPressed(GdkEventKey* key) {  bool MacrosSetup::onKeyPressed(GdkEventKey* key) {
455      //printf("key down 0x%x\n", key->keyval);      //printf("key down 0x%x\n", key->keyval);
456      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)
457          m_altKeyDown = true;          m_altKeyDown = true;
458        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
459            m_primaryKeyDown = true;
460      return false;      return false;
461  }  }
462    
# Line 221  bool MacrosSetup::onKeyReleased(GdkEvent Line 464  bool MacrosSetup::onKeyReleased(GdkEvent
464      //printf("key up 0x%x\n", key->keyval);      //printf("key up 0x%x\n", key->keyval);
465      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)
466          m_altKeyDown = false;          m_altKeyDown = false;
467        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
468            m_primaryKeyDown = false;
469        if (m_primaryKeyDown && key->keyval == GDK_KEY_b)
470            onButtonAddFromClipboard();
471        if (m_primaryKeyDown && key->keyval == GDK_KEY_s)
472            onButtonAddFromSelection();
473      return false;      return false;
474  }  }
475    
# Line 228  void MacrosSetup::onMacroTreeViewKeyRele Line 477  void MacrosSetup::onMacroTreeViewKeyRele
477      if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) {      if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) {
478          if (m_altKeyDown)          if (m_altKeyDown)
479              inverseDeleteSelectedRows();              inverseDeleteSelectedRows();
480          else          else if (m_primaryKeyDown)
481              deleteSelectedRows();              deleteSelectedRows();
482      }      }
483  }  }
# Line 243  void MacrosSetup::onMacroTreeViewRowValu Line 492  void MacrosSetup::onMacroTreeViewRowValu
492      int index = row[m_treeModelMacros.m_col_index];      int index = row[m_treeModelMacros.m_col_index];
493      m_macros[index].setName(name);      m_macros[index].setName(name);
494      //reloadTreeView();      //reloadTreeView();
495        m_modified = true;
496        updateStatus();
497  }  }
498    
499  void MacrosSetup::deleteSelectedRows() {  void MacrosSetup::deleteSelectedRows() {
# Line 252  void MacrosSetup::deleteSelectedRows() { Line 503  void MacrosSetup::deleteSelectedRows() {
503  }  }
504    
505  void MacrosSetup::deleteRows(const std::vector<Gtk::TreeModel::Path>& rows) {  void MacrosSetup::deleteRows(const std::vector<Gtk::TreeModel::Path>& rows) {
506        m_modified = !rows.empty();
507      std::set<int> macros;      std::set<int> macros;
508      for (int r = rows.size() - 1; r >= 0; --r) {      for (int r = rows.size() - 1; r >= 0; --r) {
509          Gtk::TreeModel::iterator it = m_treeStoreMacros->get_iter(rows[r]);          Gtk::TreeModel::iterator it = m_treeStoreMacros->get_iter(rows[r]);
# Line 298  void MacrosSetup::inverseDeleteSelectedR Line 550  void MacrosSetup::inverseDeleteSelectedR
550  }  }
551    
552  void MacrosSetup::updateStatus() {  void MacrosSetup::updateStatus() {
553        bool bValidSelection = !m_treeViewMacros.get_selection()->get_selected_rows().empty();
554        m_addFromClipboardButton.set_sensitive(
555            m_clipboardContent && m_clipboardContent->rootObject()
556        );
557        m_addFromSelectionButton.set_sensitive(m_selectedDimRgn);
558        m_buttonEdit.set_sensitive(bValidSelection);
559      m_applyButton.set_sensitive(isModified());      m_applyButton.set_sensitive(isModified());
560        m_textViewComment.set_sensitive(bValidSelection);
561      updateStatusBar();      updateStatusBar();
562  }  }
563    
# Line 320  bool MacrosSetup::onWindowDelete(GdkEven Line 579  bool MacrosSetup::onWindowDelete(GdkEven
579    
580      //gchar* msg = g_strdup_printf(_("Apply changes to macro \"%s\" before closing?"),      //gchar* msg = g_strdup_printf(_("Apply changes to macro \"%s\" before closing?"),
581      //                             m_macroOriginal->Name.c_str());      //                             m_macroOriginal->Name.c_str());
582      gchar* msg = g_strdup_printf(_("Apply changes to macro before closing?"));      gchar* msg = g_strdup_printf(_("Apply changes to macro list before closing?"));
583      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
584      g_free(msg);      g_free(msg);
585      dialog.set_secondary_text(_("If you close without applying, your changes will be lost."));      dialog.set_secondary_text(_("If you close without applying, your changes will be lost."));
# Line 352  bool MacrosSetup::onWindowDelete(GdkEven Line 611  bool MacrosSetup::onWindowDelete(GdkEven
611  }  }
612    
613  bool MacrosSetup::isModified() const {  bool MacrosSetup::isModified() const {
614        if (m_modified) return true;
615      bool bModified = false;      bool bModified = false;
616      for (int i = 0; i < m_macros.size(); ++i) {      for (int i = 0; i < m_macros.size(); ++i) {
617          if (m_macros[i].isModified()) {          if (m_macros[i].isModified()) {
# Line 377  void MacrosSetup::onButtonApply() { Line 637  void MacrosSetup::onButtonApply() {
637              // 'modified' state              // 'modified' state
638              m_macros[i].rawData();              m_macros[i].rawData();
639          }          }
640            m_modified = false;
641      } catch (Serialization::Exception e) {      } catch (Serialization::Exception e) {
642          errorText = e.Message;          errorText = e.Message;
643      } catch (...) {      } catch (...) {

Legend:
Removed from v.3157  
changed lines
  Added in v.3162

  ViewVC Help
Powered by ViewVC