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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2562 - (hide annotations) (download)
Mon May 19 18:06:57 2014 UTC (9 years, 11 months ago) by schoenebeck
File size: 23257 byte(s)
* 'Dimension Manager' dialog: added support for viewing and editing
  dimensions of all regions simultaniously.

1 persson 2169 /*
2 persson 2507 * Copyright (C) 2006-2014 Andreas Persson
3 schoenebeck 1225 *
4     * This program is free software; you can redistribute it and/or
5     * modify it under the terms of the GNU General Public License as
6     * published by the Free Software Foundation; either version 2, or (at
7     * your option) any later version.
8     *
9     * This program is distributed in the hope that it will be useful, but
10     * WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12     * General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with program; see the file COPYING. If not, write to the Free
16     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17     * 02110-1301 USA.
18     */
19    
20     #include "dimensionmanager.h"
21    
22     #include <gtkmm/stock.h>
23     #include <gtkmm/messagedialog.h>
24     #include <gtkmm/dialog.h>
25     #include <gtkmm/comboboxtext.h>
26 persson 1733 #include <gtkmm/spinbutton.h>
27     #include <gtkmm/table.h>
28 schoenebeck 1225
29 persson 1831 #include "global.h"
30 persson 2169 #include "compat.h"
31 persson 1831
32 schoenebeck 1225 // returns a human readable name of the given dimension type
33 schoenebeck 2558 Glib::ustring dimTypeAsString(gig::dimension_t d) {
34 schoenebeck 1225 char buf[32];
35     switch (d) {
36     case gig::dimension_none:
37 persson 1831 return _("None");
38 schoenebeck 1225 case gig::dimension_samplechannel:
39 persson 1831 return _("Sample Channel");
40 schoenebeck 1225 case gig::dimension_layer:
41 persson 1831 return _("Layer");
42 schoenebeck 1225 case gig::dimension_velocity:
43 persson 1831 return _("Velocity");
44 schoenebeck 1225 case gig::dimension_channelaftertouch:
45 persson 1831 return _("Aftertouch");
46 schoenebeck 1225 case gig::dimension_releasetrigger:
47 persson 1831 return _("Release Trigger");
48 schoenebeck 1225 case gig::dimension_keyboard:
49 persson 1831 return _("Keyswitching");
50 schoenebeck 1225 case gig::dimension_roundrobin:
51 persson 1831 return _("Round Robin");
52 schoenebeck 1225 case gig::dimension_random:
53 persson 1831 return _("Random Generator");
54 schoenebeck 1225 case gig::dimension_smartmidi:
55 persson 1831 return _("Smart MIDI");
56 schoenebeck 1225 case gig::dimension_roundrobinkeyboard:
57 persson 1831 return _("Keyboard Round Robin");
58 schoenebeck 1225 case gig::dimension_modwheel:
59 persson 1831 return _("Modulation Wheel");
60 schoenebeck 1225 case gig::dimension_breath:
61 persson 1831 return _("Breath Ctrl.");
62 schoenebeck 1225 case gig::dimension_foot:
63 persson 1831 return _("Foot Ctrl.");
64 schoenebeck 1225 case gig::dimension_portamentotime:
65 persson 1831 return _("Portamento Time Ctrl.");
66 schoenebeck 1225 case gig::dimension_effect1:
67 persson 1831 return _("Effect Ctrl. 1");
68 schoenebeck 1225 case gig::dimension_effect2:
69 persson 1831 return _("Effect Ctrl. 2");
70 schoenebeck 1225 case gig::dimension_genpurpose1:
71 persson 1831 return _("General Purpose Ctrl. 1");
72 schoenebeck 1225 case gig::dimension_genpurpose2:
73 persson 1831 return _("General Purpose Ctrl. 2");
74 schoenebeck 1225 case gig::dimension_genpurpose3:
75 persson 1831 return _("General Purpose Ctrl. 3");
76 schoenebeck 1225 case gig::dimension_genpurpose4:
77 persson 1831 return _("General Purpose Ctrl. 4");
78 schoenebeck 1225 case gig::dimension_sustainpedal:
79 persson 1831 return _("Sustain Pedal");
80 schoenebeck 1225 case gig::dimension_portamento:
81 persson 1831 return _("Portamento Ctrl.");
82 schoenebeck 1225 case gig::dimension_sostenutopedal:
83 persson 1831 return _("Sostenuto Pedal");
84 schoenebeck 1225 case gig::dimension_softpedal:
85 persson 1831 return _("Soft Pedal");
86 schoenebeck 1225 case gig::dimension_genpurpose5:
87 persson 1831 return _("General Purpose Ctrl. 5");
88 schoenebeck 1225 case gig::dimension_genpurpose6:
89 persson 1831 return _("General Purpose Ctrl. 6");
90 schoenebeck 1225 case gig::dimension_genpurpose7:
91 persson 1831 return _("General Purpose Ctrl. 7");
92 schoenebeck 1225 case gig::dimension_genpurpose8:
93 persson 1831 return _("General Purpose Ctrl. 8");
94 schoenebeck 1225 case gig::dimension_effect1depth:
95 persson 1831 return _("Effect 1 Depth");
96 schoenebeck 1225 case gig::dimension_effect2depth:
97 persson 1831 return _("Effect 2 Depth");
98 schoenebeck 1225 case gig::dimension_effect3depth:
99 persson 1831 return _("Effect 3 Depth");
100 schoenebeck 1225 case gig::dimension_effect4depth:
101 persson 1831 return _("Effect 4 Depth");
102 schoenebeck 1225 case gig::dimension_effect5depth:
103 persson 1831 return _("Effect 5 Depth");
104 schoenebeck 1225 default:
105     sprintf(buf, "Unknown Type (0x%x) !!!", d);
106     return buf;
107     }
108     }
109    
110     // returns a human readable description of the given dimension
111     static Glib::ustring __dimDescriptionAsString(gig::dimension_t d) {
112     switch (d) {
113     case gig::dimension_none:
114 persson 1831 return _("Dimension not in use");
115 schoenebeck 1225 case gig::dimension_samplechannel:
116 persson 1831 return _("If used sample has more than one channel (thus is not mono)");
117 schoenebeck 1225 case gig::dimension_layer:
118 persson 1831 return _("For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers");
119 schoenebeck 1225 case gig::dimension_velocity:
120 persson 1831 return _("Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined)");
121 schoenebeck 1225 case gig::dimension_channelaftertouch:
122 persson 1831 return _("Channel Key Pressure");
123 schoenebeck 1225 case gig::dimension_releasetrigger:
124 persson 1831 return _("Special dimension for triggering samples on releasing a key");
125 schoenebeck 1225 case gig::dimension_keyboard:
126 persson 1831 return _("Dimension for keyswitching (keyboard)");
127 schoenebeck 1225 case gig::dimension_roundrobin:
128 persson 1831 return _("Different samples triggered each time a note is played, dimension regions selected in sequence");
129 schoenebeck 1225 case gig::dimension_random:
130 persson 1831 return _("Different samples triggered each time a note is played, random order");
131 schoenebeck 1225 case gig::dimension_smartmidi:
132 persson 1831 return _("For MIDI tools like legato and repetition mode");
133 schoenebeck 1225 case gig::dimension_roundrobinkeyboard:
134 persson 1831 return _("Different samples triggered each time a note is played, any key advances the counter");
135 schoenebeck 1225 case gig::dimension_modwheel:
136 persson 1831 return _("MIDI Controller 1");
137 schoenebeck 1225 case gig::dimension_breath:
138 persson 1831 return _("MIDI Controller 2");
139 schoenebeck 1225 case gig::dimension_foot:
140 persson 1831 return _("MIDI Controller 4");
141 schoenebeck 1225 case gig::dimension_portamentotime:
142 persson 1831 return _("MIDI Controller 5");
143 schoenebeck 1225 case gig::dimension_effect1:
144 persson 1831 return _("MIDI Controller 12");
145 schoenebeck 1225 case gig::dimension_effect2:
146 persson 1831 return _("MIDI Controller 13");
147 schoenebeck 1225 case gig::dimension_genpurpose1:
148 persson 1831 return _("Slider, MIDI Controller 16");
149 schoenebeck 1225 case gig::dimension_genpurpose2:
150 persson 1831 return _("Slider, MIDI Controller 17");
151 schoenebeck 1225 case gig::dimension_genpurpose3:
152 persson 1831 return _("Slider, MIDI Controller 18");
153 schoenebeck 1225 case gig::dimension_genpurpose4:
154 persson 1831 return _("Slider, MIDI Controller 19");
155 schoenebeck 1225 case gig::dimension_sustainpedal:
156 persson 1831 return _("MIDI Controller 64");
157 schoenebeck 1225 case gig::dimension_portamento:
158 persson 1831 return _("MIDI Controller 65");
159 schoenebeck 1225 case gig::dimension_sostenutopedal:
160 persson 1831 return _("MIDI Controller 66");
161 schoenebeck 1225 case gig::dimension_softpedal:
162 persson 1831 return _("MIDI Controller 67");
163 schoenebeck 1225 case gig::dimension_genpurpose5:
164 persson 1831 return _("Button, MIDI Controller 80");
165 schoenebeck 1225 case gig::dimension_genpurpose6:
166 persson 1831 return _("Button, MIDI Controller 81");
167 schoenebeck 1225 case gig::dimension_genpurpose7:
168 persson 1831 return _("Button, MIDI Controller 82");
169 schoenebeck 1225 case gig::dimension_genpurpose8:
170 persson 1831 return _("Button, MIDI Controller 83");
171 schoenebeck 1225 case gig::dimension_effect1depth:
172 persson 1831 return _("MIDI Controller 91");
173 schoenebeck 1225 case gig::dimension_effect2depth:
174 persson 1831 return _("MIDI Controller 92");
175 schoenebeck 1225 case gig::dimension_effect3depth:
176 persson 1831 return _("MIDI Controller 93");
177 schoenebeck 1225 case gig::dimension_effect4depth:
178 persson 1831 return _("MIDI Controller 94");
179 schoenebeck 1225 case gig::dimension_effect5depth:
180 persson 1831 return _("MIDI Controller 95");
181 schoenebeck 1225 default:
182 persson 1831 return _("Please report this !!!");
183 schoenebeck 1225 }
184     }
185    
186 schoenebeck 2562 DimTypeCellRenderer::DimTypeCellRenderer() :
187     Glib::ObjectBase(typeid(DimTypeCellRenderer)),
188     Gtk::CellRendererText(),
189     m_propertyDimType(*this, "gigdimension_t", gig::dimension_none),
190     m_propertyUsageCount(*this, "intusagecount", 0),
191     m_propertyTotalRegions(*this, "inttotalregions", 0)
192     {
193     propertyDimType().signal_changed().connect(
194     sigc::mem_fun(*this, &DimTypeCellRenderer::typeChanged)
195     );
196     propertyUsageCount().signal_changed().connect(
197     sigc::mem_fun(*this, &DimTypeCellRenderer::statsChanged)
198     );
199     propertyTotalRegions().signal_changed().connect(
200     sigc::mem_fun(*this, &DimTypeCellRenderer::statsChanged)
201     );
202     }
203    
204     void DimTypeCellRenderer::typeChanged() {
205     gig::dimension_t type = propertyDimType();
206     Glib::ustring s = dimTypeAsString(type);
207     property_text() = s;
208     }
209    
210     void DimTypeCellRenderer::statsChanged() {
211     int usageCount = propertyUsageCount();
212     int totalRegions = propertyTotalRegions();
213     bool bDimensionExistsOnAllRegions = (usageCount == totalRegions);
214     property_foreground() = ((bDimensionExistsOnAllRegions) ? "black" : "gray");
215     }
216    
217     IntSetCellRenderer::IntSetCellRenderer() :
218     Glib::ObjectBase(typeid(IntSetCellRenderer)),
219     Gtk::CellRendererText(),
220     m_propertyValue(*this, "stdintset", std::set<int>())
221     {
222     propertyValue().signal_changed().connect(
223     sigc::mem_fun(*this, &IntSetCellRenderer::valueChanged)
224     );
225     }
226    
227     void IntSetCellRenderer::valueChanged() {
228     Glib::ustring s;
229     std::set<int> v = propertyValue();
230     for (std::set<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
231     s += ToString(*it);
232     if (*it != *v.rbegin()) s += "|";
233     }
234     property_text() = s;
235     property_foreground() = (v.size() > 1) ? "gray" : "black";
236     }
237    
238 schoenebeck 1225 DimensionManager::DimensionManager() :
239 schoenebeck 2562 addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE),
240     allRegionsCheckBox(_("All Regions"))
241 schoenebeck 1225 {
242 persson 1831 set_title(_("Dimensions of selected Region"));
243 schoenebeck 1225 add(vbox);
244     scrolledWindow.add(treeView);
245     vbox.pack_start(scrolledWindow);
246     scrolledWindow.show();
247 schoenebeck 1411 vbox.pack_start(buttonBox, Gtk::PACK_SHRINK);
248 schoenebeck 1225 buttonBox.set_layout(Gtk::BUTTONBOX_END);
249     buttonBox.set_border_width(5);
250     buttonBox.show();
251 schoenebeck 2562 buttonBox.pack_start(allRegionsCheckBox, Gtk::PACK_EXPAND_PADDING);
252 schoenebeck 1411 buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);
253     buttonBox.pack_start(removeButton, Gtk::PACK_SHRINK);
254 schoenebeck 1225 addButton.show();
255     removeButton.show();
256 schoenebeck 2562 allRegionsCheckBox.set_tooltip_text(
257     _("Enable this if you want to edit dimensions of all regions simultaniously.")
258     );
259 schoenebeck 1225
260     // setup the table
261     refTableModel = Gtk::ListStore::create(tableModel);
262     treeView.set_model(refTableModel);
263 schoenebeck 2562 treeView.append_column(_("Dimension Type"), m_cellRendererDimType);
264     treeView.append_column(_("Bits"), m_cellRendererIntSet);
265     treeView.append_column(_("Zones"), m_cellRendererIntSet);
266 persson 1831 treeView.append_column(_("Description"), tableModel.m_description);
267 schoenebeck 2562 treeView.get_column(0)->add_attribute(m_cellRendererDimType.propertyDimType(), tableModel.m_type);
268     treeView.get_column(0)->add_attribute(m_cellRendererDimType.propertyUsageCount(), tableModel.m_usageCount);
269     treeView.get_column(0)->add_attribute(m_cellRendererDimType.propertyTotalRegions(), tableModel.m_totalRegions);
270     treeView.get_column(1)->add_attribute(m_cellRendererIntSet.propertyValue(), tableModel.m_bits);
271     treeView.get_column(2)->add_attribute(m_cellRendererIntSet.propertyValue(), tableModel.m_zones);
272 schoenebeck 1225 treeView.show();
273    
274     addButton.signal_clicked().connect(
275     sigc::mem_fun(*this, &DimensionManager::addDimension)
276     );
277    
278     removeButton.signal_clicked().connect(
279     sigc::mem_fun(*this, &DimensionManager::removeDimension)
280     );
281 schoenebeck 2562 allRegionsCheckBox.signal_toggled().connect(
282     sigc::mem_fun(*this, &DimensionManager::onAllRegionsCheckBoxToggled)
283     );
284 schoenebeck 1225
285     show_all_children();
286 schoenebeck 2558
287     resize(460,300);
288 schoenebeck 1225 }
289    
290 schoenebeck 2562 bool DimensionManager::allRegions() const {
291     return allRegionsCheckBox.get_active();
292     }
293    
294     void DimensionManager::onAllRegionsCheckBoxToggled() {
295     set_title(
296     allRegions() ? _("Dimensions of all Regions") : _("Dimensions of selected Region")
297     );
298     treeView.set_tooltip_text(
299     allRegions()
300     ? _("Dimensions and numbers in gray indicates a difference among the individual regions.")
301     : _("You are currently only viewing dimensions of the currently selected region.")
302     );
303     refreshManager();
304     }
305    
306     // following two data types are just used in DimensionManager::refresManager(),
307     // due to the maps template nature however, they must be declared at global
308     // space to avoid compilation errors
309     struct _DimDef {
310     std::set<int> bits;
311     std::set<int> zones;
312     int usageCount;
313     };
314     typedef std::map<gig::dimension_t, _DimDef> _Dimensions;
315    
316 schoenebeck 1225 // update all GUI elements according to current gig::Region informations
317     void DimensionManager::refreshManager() {
318 schoenebeck 2562 set_sensitive(false);
319 schoenebeck 1225 refTableModel->clear();
320 schoenebeck 2562 if (allRegions()) {
321     if (region) {
322     _Dimensions dims;
323     gig::Instrument* instr = (gig::Instrument*)region->GetParent();
324     int iRegionsCount = 0;
325     for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion(), ++iRegionsCount) {
326     for (uint i = 0; i < rgn->Dimensions; i++) {
327     gig::dimension_def_t* dim = &rgn->pDimensionDefinitions[i];
328     dims[dim->dimension].bits.insert(dim->bits);
329     dims[dim->dimension].zones.insert(dim->zones);
330     dims[dim->dimension].usageCount++;
331     }
332     }
333     for (_Dimensions::const_iterator it = dims.begin(); it != dims.end(); ++it) {
334     Gtk::TreeModel::Row row = *(refTableModel->append());
335     row[tableModel.m_type] = it->first;
336     row[tableModel.m_bits] = it->second.bits;
337     row[tableModel.m_zones] = it->second.zones;
338     row[tableModel.m_description] = __dimDescriptionAsString(it->first);
339     row[tableModel.m_usageCount] = it->second.usageCount;
340     row[tableModel.m_totalRegions] = iRegionsCount;
341     }
342 persson 1677 }
343 schoenebeck 2562 } else {
344     if (region) {
345     for (uint i = 0; i < region->Dimensions; i++) {
346     gig::dimension_def_t* dim = &region->pDimensionDefinitions[i];
347     Gtk::TreeModel::Row row = *(refTableModel->append());
348     std::set<int> vBits;
349     vBits.insert(dim->bits);
350     row[tableModel.m_bits] = vBits;
351     std::set<int> vZones;
352     vZones.insert(dim->zones);
353     row[tableModel.m_zones] = vZones;
354     row[tableModel.m_description] = __dimDescriptionAsString(dim->dimension);
355     row[tableModel.m_type] = dim->dimension;
356     row[tableModel.m_usageCount] = 1;
357     row[tableModel.m_totalRegions] = 1;
358     }
359     }
360 schoenebeck 1225 }
361 persson 1677 set_sensitive(region);
362 schoenebeck 1225 }
363    
364     void DimensionManager::show(gig::Region* region) {
365     this->region = region;
366     refreshManager();
367     Gtk::Window::show();
368     deiconify();
369     }
370    
371 persson 1677 void DimensionManager::set_region(gig::Region* region) {
372     this->region = region;
373     refreshManager();
374     }
375    
376 schoenebeck 1225 void DimensionManager::addDimension() {
377 schoenebeck 2562 Gtk::Dialog dialog(_("New Dimension"), true /*modal*/);
378     // add dimension type combo box to the dialog
379     Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);
380     for (int i = 0x01; i < 0xff; i++) {
381     Glib::ustring sType =
382     dimTypeAsString(static_cast<gig::dimension_t>(i));
383     if (sType.find("Unknown") != 0) {
384     Gtk::TreeModel::Row row = *(refComboModel->append());
385     row[comboModel.m_type_id] = i;
386     row[comboModel.m_type_name] = sType;
387 schoenebeck 1225 }
388 schoenebeck 2562 }
389     Gtk::Table table(2, 2);
390     Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_START);
391     Gtk::ComboBox comboDimType;
392     comboDimType.set_model(refComboModel);
393     comboDimType.pack_start(comboModel.m_type_id);
394     comboDimType.pack_start(comboModel.m_type_name);
395     Gtk::Label labelZones(_("Zones:"), Gtk::ALIGN_START);
396     table.attach(labelDimType, 0, 1, 0, 1);
397     table.attach(comboDimType, 1, 2, 0, 1);
398     table.attach(labelZones, 0, 1, 1, 2);
399     dialog.get_vbox()->pack_start(table);
400 persson 1733
401 schoenebeck 2562 // number of zones: use a combo box with fix values for gig
402     // v2 and a spin button for v3
403     Gtk::ComboBoxText comboZones;
404     Gtk::SpinButton spinZones;
405     bool version2 = false;
406     if (region) {
407     gig::File* file = (gig::File*)region->GetParent()->GetParent();
408     version2 = file->pVersion && file->pVersion->major == 2;
409     }
410     if (version2) {
411     for (int i = 1; i <= 5; i++) {
412     char buf[3];
413     sprintf(buf, "%d", 1 << i);
414 persson 2507 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
415 schoenebeck 2562 comboZones.append_text(buf);
416 persson 2169 #else
417 schoenebeck 2562 comboZones.append(buf);
418 persson 2169 #endif
419 schoenebeck 2562 }
420     table.attach(comboZones, 1, 2, 1, 2);
421     } else {
422     spinZones.set_increments(1, 8);
423     spinZones.set_numeric(true);
424     spinZones.set_range(2, 128);
425     spinZones.set_value(2);
426     table.attach(spinZones, 1, 2, 1, 2);
427     }
428    
429     dialog.add_button(Gtk::Stock::OK, 0);
430     dialog.add_button(Gtk::Stock::CANCEL, 1);
431     dialog.show_all_children();
432    
433     if (!dialog.run()) { // OK selected ...
434     Gtk::TreeModel::iterator iterType = comboDimType.get_active();
435     if (!iterType) return;
436     Gtk::TreeModel::Row rowType = *iterType;
437     if (!rowType) return;
438     int iTypeID = rowType[comboModel.m_type_id];
439     gig::dimension_t type = static_cast<gig::dimension_t>(iTypeID);
440     gig::dimension_def_t dim;
441     dim.dimension = type;
442    
443     if (version2) {
444     if (comboZones.get_active_row_number() < 0) return;
445     dim.bits = comboZones.get_active_row_number() + 1;
446     dim.zones = 1 << dim.bits;
447 persson 1733 } else {
448 schoenebeck 2562 dim.zones = spinZones.get_value_as_int();
449     dim.bits = zoneCountToBits(dim.zones);
450 persson 1733 }
451    
452 schoenebeck 2562 // assemble the list of regions where the selected dimension shall be
453     // added to
454     std::vector<gig::Region*> vRegions;
455     if (allRegions()) {
456     gig::Instrument* instr = (gig::Instrument*)region->GetParent();
457     for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion()) {
458     if (!rgn->GetDimensionDefinition(type)) vRegions.push_back(rgn);
459     }
460     } else vRegions.push_back(region);
461    
462     std::set<Glib::ustring> errors;
463 persson 1733
464 schoenebeck 2562 for (uint iRgn = 0; iRgn < vRegions.size(); ++iRgn) {
465     gig::Region* region = vRegions[iRgn];
466     try {
467     printf(
468     "Adding dimension (type=0x%x, bits=%d, zones=%d)\n",
469     dim.dimension, dim.bits, dim.zones
470     );
471     // notify everybody that we're going to update the region
472     region_to_be_changed_signal.emit(region);
473     // add the new dimension to the region
474     // (implicitly creates new dimension regions)
475     region->AddDimension(&dim);
476     // let everybody know there was a change
477     region_changed_signal.emit(region);
478     } catch (RIFF::Exception e) {
479     // notify that the changes are over (i.e. to avoid dead locks)
480     region_changed_signal.emit(region);
481     Glib::ustring txt = _("Could not add dimension: ") + e.Message;
482     if (vRegions.size() == 1) {
483     // show error message directly
484     Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
485     msg.run();
486     } else {
487     // remember error, they are shown after all regions have been processed
488     errors.insert(txt);
489     }
490     }
491     }
492     // update all GUI elements
493     refreshManager();
494 persson 1733
495 schoenebeck 2562 if (!errors.empty()) {
496     Glib::ustring txt = _(
497     "The following errors occurred while trying to create the dimension on all regions:"
498     );
499     txt += "\n\n";
500     for (std::set<Glib::ustring>::const_iterator it = errors.begin();
501     it != errors.end(); ++it)
502     {
503     txt += "-> " + *it + "\n";
504 persson 1733 }
505 schoenebeck 2562 txt += "\n";
506     txt += _(
507     "You might also want to check the console for further warnings and "
508     "error messages."
509 schoenebeck 1225 );
510 schoenebeck 2562 Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
511     msg.run();
512 schoenebeck 1225 }
513     }
514     }
515    
516 schoenebeck 2562 void DimensionManager::removeDimension() {
517 schoenebeck 1225 Glib::RefPtr<Gtk::TreeSelection> sel = treeView.get_selection();
518     Gtk::TreeModel::iterator it = sel->get_selected();
519     if (it) {
520 schoenebeck 2562 Gtk::TreeModel::Row row = *it;
521     gig::dimension_t type = row[tableModel.m_type];
522    
523     // assemble the list of regions where the selected dimension shall be
524     // added to
525     std::vector<gig::Region*> vRegions;
526     if (allRegions()) {
527     gig::Instrument* instr = (gig::Instrument*)region->GetParent();
528     for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion()) {
529     if (rgn->GetDimensionDefinition(type)) vRegions.push_back(rgn);
530     }
531     } else vRegions.push_back(region);
532    
533     std::set<Glib::ustring> errors;
534    
535     for (uint iRgn = 0; iRgn < vRegions.size(); ++iRgn) {
536     gig::Region* region = vRegions[iRgn];
537     gig::dimension_def_t* dim = region->GetDimensionDefinition(type);
538     try {
539     // notify everybody that we're going to update the region
540     region_to_be_changed_signal.emit(region);
541     // remove selected dimension
542     region->DeleteDimension(dim);
543     // let everybody know there was a change
544     region_changed_signal.emit(region);
545     } catch (RIFF::Exception e) {
546     // notify that the changes are over (i.e. to avoid dead locks)
547     region_changed_signal.emit(region);
548     Glib::ustring txt = _("Could not remove dimension: ") + e.Message;
549     if (vRegions.size() == 1) {
550     // show error message directly
551     Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
552     msg.run();
553     } else {
554     // remember error, they are shown after all regions have been processed
555     errors.insert(txt);
556     }
557     }
558     }
559     // update all GUI elements
560     refreshManager();
561    
562     if (!errors.empty()) {
563     Glib::ustring txt = _(
564     "The following errors occurred while trying to remove the dimension from all regions:"
565     );
566     txt += "\n\n";
567     for (std::set<Glib::ustring>::const_iterator it = errors.begin();
568     it != errors.end(); ++it)
569     {
570     txt += "-> " + *it + "\n";
571     }
572     txt += "\n";
573     txt += _(
574     "You might also want to check the console for further warnings and "
575     "error messages."
576     );
577 schoenebeck 1225 Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
578     msg.run();
579     }
580     }
581     }

  ViewVC Help
Powered by ViewVC