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

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

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

revision 1831 by persson, Tue Feb 3 19:38:19 2009 UTC revision 2844 by persson, Sun Sep 20 08:49:40 2015 UTC
# Line 1  Line 1 
1  /*                                                         -*- c++ -*-  /*
2   * Copyright (C) 2006-2009 Andreas Persson   * Copyright (C) 2006-2014 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 17  Line 17 
17   * 02110-1301 USA.   * 02110-1301 USA.
18   */   */
19    
20    #include <glibmmconfig.h>
21    // threads.h must be included first to be able to build with
22    // G_DISABLE_DEPRECATED
23    #if (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION == 31 && GLIBMM_MICRO_VERSION >= 2) || \
24        (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION > 31) || GLIBMM_MAJOR_VERSION > 2
25    #include <glibmm/threads.h>
26    #endif
27    
28  #include "dimensionmanager.h"  #include "dimensionmanager.h"
29    
30  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
# Line 27  Line 35 
35  #include <gtkmm/table.h>  #include <gtkmm/table.h>
36    
37  #include "global.h"  #include "global.h"
38    #include "compat.h"
39    
40  // returns a human readable name of the given dimension type  // returns a human readable name of the given dimension type
41  static Glib::ustring __dimTypeAsString(gig::dimension_t d) {  Glib::ustring dimTypeAsString(gig::dimension_t d) {
42      char buf[32];      char buf[32];
43      switch (d) {      switch (d) {
44          case gig::dimension_none:          case gig::dimension_none:
# Line 182  static Glib::ustring __dimDescriptionAsS Line 191  static Glib::ustring __dimDescriptionAsS
191      }      }
192  }  }
193    
194    DimTypeCellRenderer::DimTypeCellRenderer() :
195        Glib::ObjectBase(typeid(DimTypeCellRenderer)),
196        Gtk::CellRendererText(),
197        m_propertyDimType(*this, "gigdimension_t", gig::dimension_none),
198        m_propertyUsageCount(*this, "intusagecount", 0),
199        m_propertyTotalRegions(*this, "inttotalregions", 0)
200    {
201        propertyDimType().signal_changed().connect(
202            sigc::mem_fun(*this, &DimTypeCellRenderer::typeChanged)
203        );
204        propertyUsageCount().signal_changed().connect(
205            sigc::mem_fun(*this, &DimTypeCellRenderer::statsChanged)
206        );
207        propertyTotalRegions().signal_changed().connect(
208            sigc::mem_fun(*this, &DimTypeCellRenderer::statsChanged)
209        );
210    }
211    
212    void DimTypeCellRenderer::typeChanged() {
213        gig::dimension_t type = propertyDimType();
214        Glib::ustring s = dimTypeAsString(type);
215        property_text() = s;
216    }
217    
218    void DimTypeCellRenderer::statsChanged() {
219        int usageCount   = propertyUsageCount();
220        int totalRegions = propertyTotalRegions();
221        bool bDimensionExistsOnAllRegions = (usageCount == totalRegions);
222        property_foreground() = ((bDimensionExistsOnAllRegions) ? "black" : "gray");
223    }
224    
225    IntSetCellRenderer::IntSetCellRenderer() :
226        Glib::ObjectBase(typeid(IntSetCellRenderer)),
227        Gtk::CellRendererText(),
228        m_propertyValue(*this, "stdintset", std::set<int>())
229    {
230        propertyValue().signal_changed().connect(
231            sigc::mem_fun(*this, &IntSetCellRenderer::valueChanged)
232        );
233    }
234    
235    void IntSetCellRenderer::valueChanged() {
236        Glib::ustring s;
237        std::set<int> v = propertyValue();
238        for (std::set<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
239            s += ToString(*it);
240            if (*it != *v.rbegin()) s += "|";
241        }
242        property_text() = s;
243        property_foreground() = (v.size() > 1) ? "gray" : "black";
244    }
245    
246  DimensionManager::DimensionManager() :  DimensionManager::DimensionManager() :
247  addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE)  addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE),
248    allRegionsCheckBox(_("All Regions"))
249  {  {
250        ignoreColumnClicked = true;
251    
252      set_title(_("Dimensions of selected Region"));      set_title(_("Dimensions of selected Region"));
253      add(vbox);      add(vbox);
254      scrolledWindow.add(treeView);      scrolledWindow.add(treeView);
# Line 194  addButton(Gtk::Stock::ADD), removeButton Line 258  addButton(Gtk::Stock::ADD), removeButton
258      buttonBox.set_layout(Gtk::BUTTONBOX_END);      buttonBox.set_layout(Gtk::BUTTONBOX_END);
259      buttonBox.set_border_width(5);      buttonBox.set_border_width(5);
260      buttonBox.show();      buttonBox.show();
261        buttonBox.pack_start(allRegionsCheckBox, Gtk::PACK_EXPAND_PADDING);
262      buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);      buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);
263      buttonBox.pack_start(removeButton, Gtk::PACK_SHRINK);      buttonBox.pack_start(removeButton, Gtk::PACK_SHRINK);
264      addButton.show();      addButton.show();
265      removeButton.show();      removeButton.show();
266        allRegionsCheckBox.set_tooltip_text(
267            _("Enable this if you want to edit dimensions of all regions simultaniously.")
268        );
269    
270      // setup the table      // setup the table
271      refTableModel = Gtk::ListStore::create(tableModel);      refTableModel = Gtk::ListStore::create(tableModel);
272      treeView.set_model(refTableModel);      treeView.set_model(refTableModel);
273      treeView.append_column(_("Dimension Type"), tableModel.m_dim_type);      treeView.append_column(_("Dimension Type"), m_cellRendererDimType);
274      treeView.append_column(_("Bits"), tableModel.m_bits);      treeView.append_column(_("Bits"), m_cellRendererIntSet);
275      treeView.append_column(_("Zones"), tableModel.m_zones);      treeView.append_column(_("Zones"), m_cellRendererIntSet);
276      treeView.append_column(_("Description"), tableModel.m_description);      treeView.append_column(_("Description"), tableModel.m_description);
277        treeView.get_column(0)->add_attribute(m_cellRendererDimType.propertyDimType(), tableModel.m_type);
278        treeView.get_column(0)->add_attribute(m_cellRendererDimType.propertyUsageCount(), tableModel.m_usageCount);
279        treeView.get_column(0)->add_attribute(m_cellRendererDimType.propertyTotalRegions(), tableModel.m_totalRegions);
280        treeView.get_column(1)->add_attribute(m_cellRendererIntSet.propertyValue(), tableModel.m_bits);
281        treeView.get_column(2)->add_attribute(m_cellRendererIntSet.propertyValue(), tableModel.m_zones);
282      treeView.show();      treeView.show();
283    
284        treeView.signal_cursor_changed().connect(
285            sigc::mem_fun(*this, &DimensionManager::onColumnClicked)
286        );
287    
288      addButton.signal_clicked().connect(      addButton.signal_clicked().connect(
289          sigc::mem_fun(*this, &DimensionManager::addDimension)          sigc::mem_fun(*this, &DimensionManager::addDimension)
290      );      );
# Line 215  addButton(Gtk::Stock::ADD), removeButton Line 292  addButton(Gtk::Stock::ADD), removeButton
292      removeButton.signal_clicked().connect(      removeButton.signal_clicked().connect(
293          sigc::mem_fun(*this, &DimensionManager::removeDimension)          sigc::mem_fun(*this, &DimensionManager::removeDimension)
294      );      );
295        allRegionsCheckBox.signal_toggled().connect(
296            sigc::mem_fun(*this, &DimensionManager::onAllRegionsCheckBoxToggled)
297        );
298    
299      show_all_children();      show_all_children();
300        
301        resize(460,300);
302  }  }
303    
304    bool DimensionManager::allRegions() const {
305        return allRegionsCheckBox.get_active();
306    }
307    
308    void DimensionManager::onAllRegionsCheckBoxToggled() {
309        set_title(
310            allRegions() ? _("Dimensions of all Regions") :  _("Dimensions of selected Region")
311        );
312        treeView.set_tooltip_text(
313            allRegions()
314                ? _("Dimensions and numbers in gray indicates a difference among the individual regions.")
315                : _("You are currently only viewing dimensions of the currently selected region.")
316        );
317        refreshManager();
318    }
319    
320    // following two data types are just used in DimensionManager::refresManager(),
321    // due to the maps template nature however, they must be declared at global
322    // space to avoid compilation errors
323    struct _DimDef {
324        std::set<int> bits;
325        std::set<int> zones;
326        int usageCount;
327    };
328    typedef std::map<gig::dimension_t, _DimDef> _Dimensions;
329    
330  // update all GUI elements according to current gig::Region informations  // update all GUI elements according to current gig::Region informations
331  void DimensionManager::refreshManager() {  void DimensionManager::refreshManager() {
332        set_sensitive(false);
333      refTableModel->clear();      refTableModel->clear();
334      if (region) {      if (allRegions()) {
335          for (int i = 0; i < region->Dimensions; i++) {          if (region) {
336              gig::dimension_def_t* dim = &region->pDimensionDefinitions[i];              _Dimensions dims;
337              Gtk::TreeModel::Row row = *(refTableModel->append());              gig::Instrument* instr = (gig::Instrument*)region->GetParent();
338              row[tableModel.m_dim_type] = __dimTypeAsString(dim->dimension);              int iRegionsCount = 0;
339              row[tableModel.m_bits] = dim->bits;              for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion(), ++iRegionsCount) {
340              row[tableModel.m_zones] = dim->zones;                  for (uint i = 0; i < rgn->Dimensions; i++) {
341              row[tableModel.m_description] = __dimDescriptionAsString(dim->dimension);                      gig::dimension_def_t* dim = &rgn->pDimensionDefinitions[i];
342              row[tableModel.m_definition] = dim;                      dims[dim->dimension].bits.insert(dim->bits);
343                        dims[dim->dimension].zones.insert(dim->zones);
344                        dims[dim->dimension].usageCount++;
345                    }
346                }
347                for (_Dimensions::const_iterator it = dims.begin(); it != dims.end(); ++it) {
348                    Gtk::TreeModel::Row row = *(refTableModel->append());
349                    row[tableModel.m_type] = it->first;
350                    row[tableModel.m_bits] = it->second.bits;
351                    row[tableModel.m_zones] = it->second.zones;
352                    row[tableModel.m_description] = __dimDescriptionAsString(it->first);
353                    row[tableModel.m_usageCount] = it->second.usageCount;
354                    row[tableModel.m_totalRegions] = iRegionsCount;
355                }
356            }
357        } else {
358            if (region) {
359                for (uint i = 0; i < region->Dimensions; i++) {
360                    gig::dimension_def_t* dim = &region->pDimensionDefinitions[i];
361                    Gtk::TreeModel::Row row = *(refTableModel->append());
362                    std::set<int> vBits;
363                    vBits.insert(dim->bits);
364                    row[tableModel.m_bits] = vBits;
365                    std::set<int> vZones;
366                    vZones.insert(dim->zones);
367                    row[tableModel.m_zones] = vZones;
368                    row[tableModel.m_description] = __dimDescriptionAsString(dim->dimension);
369                    row[tableModel.m_type] = dim->dimension;
370                    row[tableModel.m_usageCount] = 1;
371                    row[tableModel.m_totalRegions] = 1;
372                }
373          }          }
374      }      }
375      set_sensitive(region);      set_sensitive(region);
376  }  }
377    
378  void DimensionManager::show(gig::Region* region) {  void DimensionManager::show(gig::Region* region) {
379        ignoreColumnClicked = true;
380      this->region = region;      this->region = region;
381      refreshManager();      refreshManager();
382      Gtk::Window::show();      Gtk::Window::show();
383      deiconify();      deiconify();
384        ignoreColumnClicked = false;
385  }  }
386    
387  void DimensionManager::set_region(gig::Region* region) {  void DimensionManager::set_region(gig::Region* region) {
388        ignoreColumnClicked = true;
389      this->region = region;      this->region = region;
390      refreshManager();      refreshManager();
391        ignoreColumnClicked = false;
392  }  }
393    
394  void DimensionManager::addDimension() {  void DimensionManager::onColumnClicked() {
395      try {      //HACK: Prevents that onColumnClicked() gets called multiple times or at times where it is not desired
396          Gtk::Dialog dialog(_("New Dimension"), true /*modal*/);      if (ignoreColumnClicked) {
397          // add dimension type combo box to the dialog          ignoreColumnClicked = false;
398            return;
399        }
400    
401        Gtk::TreeModel::Path path;
402        Gtk::TreeViewColumn* focus_column;
403        treeView.get_cursor(path, focus_column);
404        //const int row = path[0];
405        if (focus_column == treeView.get_column(0)) {
406            Gtk::TreeModel::iterator it = treeView.get_model()->get_iter(path);
407            Gtk::TreeModel::Row row = *it;
408            gig::dimension_t oldType = row[tableModel.m_type];
409    
410            Gtk::Dialog dialog(_("Change Dimension"), true /*modal*/);
411            int oldTypeIndex = -1;
412          Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);          Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);
413          for (int i = 0x01; i < 0xff; i++) {          for (int i = 0x01, count = 0; i < 0xff; i++) {
414              Glib::ustring sType =              Glib::ustring sType =
415                  __dimTypeAsString(static_cast<gig::dimension_t>(i));                  dimTypeAsString(static_cast<gig::dimension_t>(i));
416                if (i == oldType) oldTypeIndex = count;
417              if (sType.find("Unknown") != 0) {              if (sType.find("Unknown") != 0) {
418                  Gtk::TreeModel::Row row = *(refComboModel->append());                  Gtk::TreeModel::Row row = *(refComboModel->append());
419                  row[comboModel.m_type_id]   = i;                  row[comboModel.m_type_id]   = i;
420                  row[comboModel.m_type_name] = sType;                  row[comboModel.m_type_name] = sType;
421                    count++;
422              }              }
423          }          }
424          Gtk::Table table(2, 2);          Gtk::Table table(1, 2);
425          Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_LEFT);          Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_START);
426          Gtk::ComboBox comboDimType;          Gtk::ComboBox comboDimType;
427          comboDimType.set_model(refComboModel);          comboDimType.set_model(refComboModel);
428          comboDimType.pack_start(comboModel.m_type_id);          comboDimType.pack_start(comboModel.m_type_id);
429          comboDimType.pack_start(comboModel.m_type_name);          comboDimType.pack_start(comboModel.m_type_name);
         Gtk::Label labelZones(_("Zones:"), Gtk::ALIGN_LEFT);  
430          table.attach(labelDimType, 0, 1, 0, 1);          table.attach(labelDimType, 0, 1, 0, 1);
431          table.attach(comboDimType, 1, 2, 0, 1);          table.attach(comboDimType, 1, 2, 0, 1);
         table.attach(labelZones, 0, 1, 1, 2);  
432          dialog.get_vbox()->pack_start(table);          dialog.get_vbox()->pack_start(table);
433    
         // number of zones: use a combo box with fix values for gig  
         // v2 and a spin button for v3  
         Gtk::ComboBoxText comboZones;  
         Gtk::SpinButton spinZones;  
         bool version2 = false;  
         if (region) {  
             gig::File* file = (gig::File*)region->GetParent()->GetParent();  
             version2 = file->pVersion && file->pVersion->major == 2;  
         }  
         if (version2) {  
             for (int i = 1; i <= 5; i++) {  
                 char buf[3];  
                 sprintf(buf, "%d", 1 << i);  
                 comboZones.append_text(buf);  
             }  
             table.attach(comboZones, 1, 2, 1, 2);  
         } else {  
             spinZones.set_increments(1, 8);  
             spinZones.set_numeric(true);  
             spinZones.set_range(2, 128);  
             spinZones.set_value(2);  
             table.attach(spinZones, 1, 2, 1, 2);  
         }  
   
434          dialog.add_button(Gtk::Stock::OK, 0);          dialog.add_button(Gtk::Stock::OK, 0);
435          dialog.add_button(Gtk::Stock::CANCEL, 1);          dialog.add_button(Gtk::Stock::CANCEL, 1);
436          dialog.show_all_children();          dialog.show_all_children();
437            
438            comboDimType.set_active(oldTypeIndex);
439    
440          if (!dialog.run()) { // OK selected ...          if (!dialog.run()) { // OK selected ...
441              Gtk::TreeModel::iterator iterType = comboDimType.get_active();              Gtk::TreeModel::iterator iterType = comboDimType.get_active();
442              if (!iterType) return;              if (!iterType) return;
443              Gtk::TreeModel::Row rowType = *iterType;              Gtk::TreeModel::Row rowType = *iterType;
444              if (!rowType) return;              if (!rowType) return;
             gig::dimension_def_t dim;  
445              int iTypeID = rowType[comboModel.m_type_id];              int iTypeID = rowType[comboModel.m_type_id];
446              dim.dimension = static_cast<gig::dimension_t>(iTypeID);              gig::dimension_t newType = static_cast<gig::dimension_t>(iTypeID);
447                if (newType == oldType) return;
448              if (version2) {              //printf("change 0x%x -> 0x%x\n", oldType, newType);
449                  if (comboZones.get_active_row_number() < 0) return;              ignoreColumnClicked = true;
450                  dim.bits = comboZones.get_active_row_number() + 1;  
451                  dim.zones = 1 << dim.bits;              // assemble the list of regions where the selected dimension type
452              } else {              // shall be changed
453                  dim.zones = spinZones.get_value_as_int();              std::vector<gig::Region*> vRegions;
454                  // Find the number of bits required to hold the              if (allRegions()) {
455                  // specified amount of zones.                  gig::Instrument* instr = (gig::Instrument*)region->GetParent();
456                  int zoneBits = dim.zones - 1;                  for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion()) {
457                  for (dim.bits = 0; zoneBits > 1; dim.bits += 2, zoneBits >>= 2);                      if (rgn->GetDimensionDefinition(oldType)) vRegions.push_back(rgn);
458                  dim.bits += zoneBits;                  }
459              }              } else vRegions.push_back(region);
460              printf(  
461                  "Adding dimension (type=0x%x, bits=%d, zones=%d)\n",              std::set<Glib::ustring> errors;
462                  dim.dimension, dim.bits, dim.zones  
463              );              for (uint iRgn = 0; iRgn < vRegions.size(); ++iRgn) {
464              // notify everybody that we're going to update the region                  gig::Region* region = vRegions[iRgn];
465              region_to_be_changed_signal.emit(region);                  try {
466              // add the new dimension to the region                      // notify everybody that we're going to update the region
467              // (implicitly creates new dimension regions)                      region_to_be_changed_signal.emit(region);
468              region->AddDimension(&dim);                      // change the dimension type on that region
469              // let everybody know there was a change                      region->SetDimensionType(oldType, newType);
470              region_changed_signal.emit(region);                      // let everybody know there was a change
471                        region_changed_signal.emit(region);
472                    } catch (RIFF::Exception e) {
473                        // notify that the changes are over (i.e. to avoid dead locks)
474                        region_changed_signal.emit(region);
475                        Glib::ustring txt = _("Could not alter dimension: ") + e.Message;
476                        if (vRegions.size() == 1) {
477                            // show error message directly
478                            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
479                            msg.run();
480                        } else {
481                            // remember error, they are shown after all regions have been processed
482                            errors.insert(txt);
483                        }
484                    }
485                }
486              // update all GUI elements              // update all GUI elements
487              refreshManager();              refreshManager();
488    
489                if (!errors.empty()) {
490                    Glib::ustring txt = _(
491                        "The following errors occurred while trying to change the dimension type on all regions:"
492                    );
493                    txt += "\n\n";
494                    for (std::set<Glib::ustring>::const_iterator it = errors.begin();
495                        it != errors.end(); ++it)
496                    {
497                        txt += "-> " + *it + "\n";
498                    }
499                    txt += "\n";
500                    txt += _(
501                        "You might also want to check the console for further warnings and "
502                        "error messages."
503                    );
504                    Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
505                    msg.run();
506                }
507            }
508        }
509    }
510    
511    void DimensionManager::addDimension() {
512        Gtk::Dialog dialog(_("New Dimension"), true /*modal*/);
513        // add dimension type combo box to the dialog
514        Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);
515        for (int i = 0x01; i < 0xff; i++) {
516            Glib::ustring sType =
517                dimTypeAsString(static_cast<gig::dimension_t>(i));
518            if (sType.find("Unknown") != 0) {
519                Gtk::TreeModel::Row row = *(refComboModel->append());
520                row[comboModel.m_type_id]   = i;
521                row[comboModel.m_type_name] = sType;
522            }
523        }
524        Gtk::Table table(2, 2);
525        Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_START);
526        Gtk::ComboBox comboDimType;
527        comboDimType.set_model(refComboModel);
528        comboDimType.pack_start(comboModel.m_type_id);
529        comboDimType.pack_start(comboModel.m_type_name);
530        Gtk::Label labelZones(_("Zones:"), Gtk::ALIGN_START);
531        table.attach(labelDimType, 0, 1, 0, 1);
532        table.attach(comboDimType, 1, 2, 0, 1);
533        table.attach(labelZones, 0, 1, 1, 2);
534        dialog.get_vbox()->pack_start(table);
535    
536        // number of zones: use a combo box with fix values for gig
537        // v2 and a spin button for v3
538        Gtk::ComboBoxText comboZones;
539        Gtk::SpinButton spinZones;
540        bool version2 = false;
541        if (region) {
542            gig::File* file = (gig::File*)region->GetParent()->GetParent();
543            version2 = file->pVersion && file->pVersion->major == 2;
544        }
545        if (version2) {
546            for (int i = 1; i <= 5; i++) {
547                char buf[3];
548                sprintf(buf, "%d", 1 << i);
549    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
550                comboZones.append_text(buf);
551    #else
552                comboZones.append(buf);
553    #endif
554            }
555            table.attach(comboZones, 1, 2, 1, 2);
556        } else {
557            spinZones.set_increments(1, 8);
558            spinZones.set_numeric(true);
559            spinZones.set_range(2, 128);
560            spinZones.set_value(2);
561            table.attach(spinZones, 1, 2, 1, 2);
562        }
563    
564        dialog.add_button(Gtk::Stock::OK, 0);
565        dialog.add_button(Gtk::Stock::CANCEL, 1);
566        dialog.show_all_children();
567    
568        if (!dialog.run()) { // OK selected ...
569            Gtk::TreeModel::iterator iterType = comboDimType.get_active();
570            if (!iterType) return;
571            Gtk::TreeModel::Row rowType = *iterType;
572            if (!rowType) return;
573            int iTypeID = rowType[comboModel.m_type_id];
574            gig::dimension_t type = static_cast<gig::dimension_t>(iTypeID);
575            gig::dimension_def_t dim;
576            dim.dimension = type;
577    
578            if (version2) {
579                if (comboZones.get_active_row_number() < 0) return;
580                dim.bits = comboZones.get_active_row_number() + 1;
581                dim.zones = 1 << dim.bits;
582            } else {
583                dim.zones = spinZones.get_value_as_int();
584                dim.bits = zoneCountToBits(dim.zones);
585            }
586    
587            // assemble the list of regions where the selected dimension shall be
588            // added to
589            std::vector<gig::Region*> vRegions;
590            if (allRegions()) {
591                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
592                for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion()) {
593                    if (!rgn->GetDimensionDefinition(type)) vRegions.push_back(rgn);
594                }
595            } else vRegions.push_back(region);
596                
597            std::set<Glib::ustring> errors;
598    
599            for (uint iRgn = 0; iRgn < vRegions.size(); ++iRgn) {
600                gig::Region* region = vRegions[iRgn];
601                try {
602                    printf(
603                        "Adding dimension (type=0x%x, bits=%d, zones=%d)\n",
604                        dim.dimension, dim.bits, dim.zones
605                    );
606                    // notify everybody that we're going to update the region
607                    region_to_be_changed_signal.emit(region);
608                    // add the new dimension to the region
609                    // (implicitly creates new dimension regions)
610                    region->AddDimension(&dim);
611                    // let everybody know there was a change
612                    region_changed_signal.emit(region);
613                } catch (RIFF::Exception e) {
614                    // notify that the changes are over (i.e. to avoid dead locks)
615                    region_changed_signal.emit(region);
616                    Glib::ustring txt = _("Could not add dimension: ") + e.Message;
617                    if (vRegions.size() == 1) {
618                        // show error message directly
619                        Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
620                        msg.run();
621                    } else {
622                        // remember error, they are shown after all regions have been processed
623                        errors.insert(txt);
624                    }
625                }
626            }
627            // update all GUI elements
628            refreshManager();
629    
630            if (!errors.empty()) {
631                Glib::ustring txt = _(
632                    "The following errors occurred while trying to create the dimension on all regions:"
633                );
634                txt += "\n\n";
635                for (std::set<Glib::ustring>::const_iterator it = errors.begin();
636                     it != errors.end(); ++it)
637                {
638                    txt += "-> " + *it + "\n";
639                }
640                txt += "\n";
641                txt += _(
642                    "You might also want to check the console for further warnings and "
643                    "error messages."
644                );
645                Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
646                msg.run();
647          }          }
     } catch (RIFF::Exception e) {  
         // notify that the changes are over (i.e. to avoid dead locks)  
         region_changed_signal.emit(region);  
         // show error message  
         Glib::ustring txt = _("Could not add dimension: ") + e.Message;  
         Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);  
         msg.run();  
648      }      }
649  }  }
650    
651  void DimensionManager::removeDimension() {  void DimensionManager::removeDimension() {        
652      Glib::RefPtr<Gtk::TreeSelection> sel = treeView.get_selection();      Glib::RefPtr<Gtk::TreeSelection> sel = treeView.get_selection();
653      Gtk::TreeModel::iterator it = sel->get_selected();      Gtk::TreeModel::iterator it = sel->get_selected();
654      if (it) {      if (it) {
655          try {          Gtk::TreeModel::Row row = *it;
656              // notify everybody that we're going to update the region          gig::dimension_t type = row[tableModel.m_type];
657              region_to_be_changed_signal.emit(region);  
658              // remove selected dimension          // assemble the list of regions where the selected dimension shall be
659              Gtk::TreeModel::Row row = *it;          // added to
660              gig::dimension_def_t* dim = row[tableModel.m_definition];          std::vector<gig::Region*> vRegions;
661              region->DeleteDimension(dim);          if (allRegions()) {
662              // let everybody know there was a change              gig::Instrument* instr = (gig::Instrument*)region->GetParent();
663              region_changed_signal.emit(region);              for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion()) {
664              // update all GUI elements                  if (rgn->GetDimensionDefinition(type)) vRegions.push_back(rgn);
665              refreshManager();              }
666          } catch (RIFF::Exception e) {          } else vRegions.push_back(region);
667              // notify that the changes are over (i.e. to avoid dead locks)  
668              region_changed_signal.emit(region);          std::set<Glib::ustring> errors;
669              // show error message  
670              Glib::ustring txt = _("Could not remove dimension: ") + e.Message;          for (uint iRgn = 0; iRgn < vRegions.size(); ++iRgn) {
671                gig::Region* region = vRegions[iRgn];
672                gig::dimension_def_t* dim = region->GetDimensionDefinition(type);
673                try {
674                    // notify everybody that we're going to update the region
675                    region_to_be_changed_signal.emit(region);
676                    // remove selected dimension    
677                    region->DeleteDimension(dim);
678                    // let everybody know there was a change
679                    region_changed_signal.emit(region);
680                } catch (RIFF::Exception e) {
681                    // notify that the changes are over (i.e. to avoid dead locks)
682                    region_changed_signal.emit(region);
683                    Glib::ustring txt = _("Could not remove dimension: ") + e.Message;
684                    if (vRegions.size() == 1) {
685                        // show error message directly
686                        Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
687                        msg.run();
688                    } else {
689                        // remember error, they are shown after all regions have been processed
690                        errors.insert(txt);
691                    }
692                }
693            }
694            // update all GUI elements
695            refreshManager();
696    
697            if (!errors.empty()) {
698                Glib::ustring txt = _(
699                    "The following errors occurred while trying to remove the dimension from all regions:"
700                );
701                txt += "\n\n";
702                for (std::set<Glib::ustring>::const_iterator it = errors.begin();
703                     it != errors.end(); ++it)
704                {
705                    txt += "-> " + *it + "\n";
706                }
707                txt += "\n";
708                txt += _(
709                    "You might also want to check the console for further warnings and "
710                    "error messages."
711                );
712              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
713              msg.run();              msg.run();
714          }          }

Legend:
Removed from v.1831  
changed lines
  Added in v.2844

  ViewVC Help
Powered by ViewVC