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

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

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

revision 3155 by schoenebeck, Sun May 7 15:32:43 2017 UTC revision 3187 by schoenebeck, Wed May 17 16:14:20 2017 UTC
# Line 16  MacroEditor::MacroEditor() : Line 16  MacroEditor::MacroEditor() :
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    
24      set_default_size(800, 600);      set_default_size(800, 600);
25    
26        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            _("A macro is a list of parameters and corresponding values which "
32              "should be applied to the instrument editor when the macro is "
33              "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        );
39        m_vbox.pack_start(m_labelIntro, Gtk::PACK_SHRINK);
40    
41      // create Macro treeview (including its data model)      // create Macro treeview (including its data model)
42      m_treeStoreMacro = MacroTreeStore::create(m_treeModelMacro);      m_treeStoreMacro = MacroTreeStore::create(m_treeModelMacro);
43      m_treeViewMacro.set_model(m_treeStoreMacro);      m_treeViewMacro.set_model(m_treeStoreMacro);
# Line 29  MacroEditor::MacroEditor() : Line 45  MacroEditor::MacroEditor() :
45      //m_treeViewMacro.set_tooltip_text(_(""));      //m_treeViewMacro.set_tooltip_text(_(""));
46      m_treeViewMacro.append_column(_("Key"), m_treeModelMacro.m_col_name);      m_treeViewMacro.append_column(_("Key"), m_treeModelMacro.m_col_name);
47      m_treeViewMacro.append_column(_("Type"), m_treeModelMacro.m_col_type);      m_treeViewMacro.append_column(_("Type"), m_treeModelMacro.m_col_type);
48      m_treeViewMacro.append_column_editable(_("Value"), m_treeModelMacro.m_col_value);      //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        {
57            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            column->add_attribute(m_valueCellRenderer.property_has_entry(),
62                                  m_treeModelMacro.m_col_allowTextEntry);
63            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          Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(1);          Gtk::TreeViewColumn* column = m_treeViewMacro.get_column(1);
75          Gtk::CellRendererText* cellrenderer =          Gtk::CellRendererText* cellrenderer =
76              dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell());              dynamic_cast<Gtk::CellRendererText*>(column->get_first_cell());
77          cellrenderer->property_foreground().set_value("#bababa");          cellrenderer->property_foreground().set_value("#bababa");
78      }      }
     /*{  
         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  
         );  
     }*/  
79      m_treeViewMacro.set_headers_visible(true);      m_treeViewMacro.set_headers_visible(true);
80      m_treeViewMacro.get_selection()->signal_changed().connect(      m_treeViewMacro.get_selection()->signal_changed().connect(
81          sigc::mem_fun(*this, &MacroEditor::onTreeViewSelectionChanged)          sigc::mem_fun(*this, &MacroEditor::onTreeViewSelectionChanged)
# Line 128  MacroEditor::MacroEditor() : Line 152  MacroEditor::MacroEditor() :
152          sigc::mem_fun(*this, &MacroEditor::onKeyReleased)          sigc::mem_fun(*this, &MacroEditor::onKeyReleased)
153      );      );
154    
155        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      show_all_children();      show_all_children();
159      updateStatus();      updateStatus();
160  }  }
# Line 136  MacroEditor::~MacroEditor() { Line 163  MacroEditor::~MacroEditor() {
163      printf("MacroEditor destruct\n");      printf("MacroEditor destruct\n");
164  }  }
165    
166  void MacroEditor::setMacro(Serialization::Archive* macro) {  void MacroEditor::setMacro(Serialization::Archive* macro, bool isClipboard) {
167      m_macroOriginal = macro;      m_macroOriginal = macro;
168      if (!macro) {      if (!macro) {
169          set_title(_("No Macro"));          set_title(_("No Macro"));
170          return;          return;
171      }      }
172    
173      //set_title(std::string(_("Macro Editor:")) + " \"" + macro->name() + "\"");      if (isClipboard)
174      set_title(std::string(_("Macro Editor:")));          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    
182      // copy for non-destructive editing      // copy for non-destructive editing
183      m_macro = *macro;      m_macro = *macro;
# Line 152  void MacroEditor::setMacro(Serialization Line 185  void MacroEditor::setMacro(Serialization
185      reloadTreeView();      reloadTreeView();
186  }  }
187    
188    sigc::signal<void>& MacroEditor::signal_changes_applied() {
189        return m_changes_applied;
190    }
191    
192    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    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  void MacroEditor::buildTreeView(const Gtk::TreeModel::Row& parentRow, const Serialization::Object& parentObject) {  void MacroEditor::buildTreeView(const Gtk::TreeModel::Row& parentRow, const Serialization::Object& parentObject) {
208      for (int iMember = 0; iMember < parentObject.members().size(); ++iMember) {      for (int iMember = 0; iMember < parentObject.members().size(); ++iMember) {
209          const Serialization::Member& member = parentObject.members()[iMember];          const Serialization::Member& member = parentObject.members()[iMember];
# Line 161  void MacroEditor::buildTreeView(const Gt Line 213  void MacroEditor::buildTreeView(const Gt
213          row[m_treeModelMacro.m_col_name] = gig_to_utf8(member.name());          row[m_treeModelMacro.m_col_name] = gig_to_utf8(member.name());
214          row[m_treeModelMacro.m_col_type] = gig_to_utf8(member.type().asLongDescr());          row[m_treeModelMacro.m_col_type] = gig_to_utf8(member.type().asLongDescr());
215          row[m_treeModelMacro.m_col_uid]  = object.uid();          row[m_treeModelMacro.m_col_uid]  = object.uid();
216            row[m_treeModelMacro.m_col_allowTextEntry] = true;
217    
218          if (object.type().isClass()) {          if (object.type().isClass()) {
219              row[m_treeModelMacro.m_col_value] = "(class)";              row[m_treeModelMacro.m_col_value] = "(class)";
220                row[m_treeModelMacro.m_col_editable] = false;
221              buildTreeView(row, object);              buildTreeView(row, object);
222            } 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            } 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          } else {          } else {
240              row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object);              row[m_treeModelMacro.m_col_value] = m_macro.valueAsString(object);
241                row[m_treeModelMacro.m_col_editable] = true;
242          }          }
243      }      }
244  }  }
# Line 183  void MacroEditor::reloadTreeView() { Line 256  void MacroEditor::reloadTreeView() {
256      rowRoot[m_treeModelMacro.m_col_type]  = gig_to_utf8(rootObject.type().asLongDescr());      rowRoot[m_treeModelMacro.m_col_type]  = gig_to_utf8(rootObject.type().asLongDescr());
257      rowRoot[m_treeModelMacro.m_col_value] = "";      rowRoot[m_treeModelMacro.m_col_value] = "";
258      rowRoot[m_treeModelMacro.m_col_uid]   = rootObject.uid();      rowRoot[m_treeModelMacro.m_col_uid]   = rootObject.uid();
259        rowRoot[m_treeModelMacro.m_col_allowTextEntry] = false;
260        rowRoot[m_treeModelMacro.m_col_editable] = false;
261    
262      buildTreeView(rowRoot, rootObject);      buildTreeView(rowRoot, rootObject);
263    
# Line 200  void MacroEditor::onTreeViewSelectionCha Line 275  void MacroEditor::onTreeViewSelectionCha
275      m_inverseDeleteButton.set_sensitive(bValidSelection);      m_inverseDeleteButton.set_sensitive(bValidSelection);
276  }  }
277    
278    // 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  bool MacroEditor::onKeyPressed(GdkEventKey* key) {  bool MacroEditor::onKeyPressed(GdkEventKey* key) {
294      //printf("key down 0x%x\n", key->keyval);      //printf("key down 0x%x\n", key->keyval);
295      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)
296          m_altKeyDown = true;          m_altKeyDown = true;
297        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
298            m_primaryKeyDown = true;
299      return false;      return false;
300  }  }
301    
# Line 211  bool MacroEditor::onKeyReleased(GdkEvent Line 303  bool MacroEditor::onKeyReleased(GdkEvent
303      //printf("key up 0x%x\n", key->keyval);      //printf("key up 0x%x\n", key->keyval);
304      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)
305          m_altKeyDown = false;          m_altKeyDown = false;
306        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
307            m_primaryKeyDown = false;
308      return false;      return false;
309  }  }
310    
# Line 218  void MacroEditor::onMacroTreeViewKeyRele Line 312  void MacroEditor::onMacroTreeViewKeyRele
312      if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) {      if (key->keyval == GDK_KEY_BackSpace || key->keyval == GDK_KEY_Delete) {
313          if (m_altKeyDown)          if (m_altKeyDown)
314              inverseDeleteSelectedRows();              inverseDeleteSelectedRows();
315          else          else if (m_primaryKeyDown)
316              deleteSelectedRows();              deleteSelectedRows();
317      }      }
318  }  }
319    
320    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  void MacroEditor::onMacroTreeViewRowValueChanged(const Gtk::TreeModel::Path& path,  void MacroEditor::onMacroTreeViewRowValueChanged(const Gtk::TreeModel::Path& path,
327                                                   const Gtk::TreeModel::iterator& iter)                                                   const Gtk::TreeModel::iterator& iter)
328  {  {
329        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      if (m_ignoreTreeViewValueChange) return;      if (m_ignoreTreeViewValueChange) return;
340      if (!iter) return;      if (!iter) return;
341      Gtk::TreeModel::Row row = *iter;      Gtk::TreeModel::Row row = *iter;
     Glib::ustring value    = row[m_treeModelMacro.m_col_value];  
342      Serialization::UID uid = row[m_treeModelMacro.m_col_uid];      Serialization::UID uid = row[m_treeModelMacro.m_col_uid];
343      Serialization::String gigvalue(gig_from_utf8(value));      Serialization::String gigvalue(gig_from_utf8(value));
344      Serialization::Object& object = m_macro.objectByUID(uid);      Serialization::Object& object = m_macro.objectByUID(uid);
345      std::string errorText;      std::string errorText;
346      try {      try {
347          m_macro.setAutoValue(object, gigvalue);          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            } 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            } 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      } catch (Serialization::Exception e) {      } catch (Serialization::Exception e) {
369          errorText = e.Message;          errorText = e.Message;
370      } catch (...) {      } catch (...) {
# Line 381  void MacroEditor::onButtonApply() { Line 510  void MacroEditor::onButtonApply() {
510          msg.run();          msg.run();
511      }      }
512      updateStatus();      updateStatus();
513        m_changes_applied.emit();
514  }  }
515    
516  void MacroEditor::onWindowHide() {  void MacroEditor::onWindowHide() {

Legend:
Removed from v.3155  
changed lines
  Added in v.3187

  ViewVC Help
Powered by ViewVC