/[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 2562 by schoenebeck, Mon May 19 18:06:57 2014 UTC revision 3450 by schoenebeck, Wed Jan 2 16:39:20 2019 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2014 Andreas Persson   * Copyright (C) 2006-2017 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 "compat.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>  #if HAS_GTKMM_STOCK
31    # include <gtkmm/stock.h>
32    #endif
33  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
34  #include <gtkmm/dialog.h>  #include <gtkmm/dialog.h>
35  #include <gtkmm/comboboxtext.h>  #include <gtkmm/comboboxtext.h>
36  #include <gtkmm/spinbutton.h>  #include <gtkmm/spinbutton.h>
37  #include <gtkmm/table.h>  #include <gtkmm/label.h>
38    #if USE_GTKMM_GRID
39    # include <gtkmm/grid.h>
40    #else
41    # include <gtkmm/table.h>
42    #endif
43    
44  #include "global.h"  #include "global.h"
45  #include "compat.h"  #include "compat.h"
# Line 236  void IntSetCellRenderer::valueChanged() Line 251  void IntSetCellRenderer::valueChanged()
251  }  }
252    
253  DimensionManager::DimensionManager() :  DimensionManager::DimensionManager() :
254  addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE),  #if HAS_GTKMM_STOCK
255  allRegionsCheckBox(_("All Regions"))      addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE),
256    #else
257        addButton(_("_Add"), true), removeButton(_("_Remove"), true),
258    #endif
259        allRegionsCheckBox(_("All Regions"))
260  {  {
261        ignoreColumnClicked = true;
262    
263        if (!Settings::singleton()->autoRestoreWindowDimension) {
264            set_default_size(630, 250);
265            set_position(Gtk::WIN_POS_MOUSE);
266        }
267    
268    #if !HAS_GTKMM_STOCK
269        // see : https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
270        addButton.set_icon_name("list-add");
271        removeButton.set_icon_name("list-remove");
272    #endif
273    
274      set_title(_("Dimensions of selected Region"));      set_title(_("Dimensions of selected Region"));
275      add(vbox);      add(vbox);
276      scrolledWindow.add(treeView);      scrolledWindow.add(treeView);
# Line 246  allRegionsCheckBox(_("All Regions")) Line 278  allRegionsCheckBox(_("All Regions"))
278      scrolledWindow.show();      scrolledWindow.show();
279      vbox.pack_start(buttonBox, Gtk::PACK_SHRINK);      vbox.pack_start(buttonBox, Gtk::PACK_SHRINK);
280      buttonBox.set_layout(Gtk::BUTTONBOX_END);      buttonBox.set_layout(Gtk::BUTTONBOX_END);
281    #if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION > 24)
282        buttonBox.set_margin(5);
283    #else
284      buttonBox.set_border_width(5);      buttonBox.set_border_width(5);
285    #endif
286      buttonBox.show();      buttonBox.show();
287      buttonBox.pack_start(allRegionsCheckBox, Gtk::PACK_EXPAND_PADDING);      buttonBox.pack_start(allRegionsCheckBox, Gtk::PACK_EXPAND_PADDING);
288      buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);      buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);
# Line 271  allRegionsCheckBox(_("All Regions")) Line 307  allRegionsCheckBox(_("All Regions"))
307      treeView.get_column(2)->add_attribute(m_cellRendererIntSet.propertyValue(), tableModel.m_zones);      treeView.get_column(2)->add_attribute(m_cellRendererIntSet.propertyValue(), tableModel.m_zones);
308      treeView.show();      treeView.show();
309    
310        treeView.signal_cursor_changed().connect(
311            sigc::mem_fun(*this, &DimensionManager::onColumnClicked)
312        );
313    
314      addButton.signal_clicked().connect(      addButton.signal_clicked().connect(
315          sigc::mem_fun(*this, &DimensionManager::addDimension)          sigc::mem_fun(*this, &DimensionManager::addDimension)
316      );      );
# Line 282  allRegionsCheckBox(_("All Regions")) Line 322  allRegionsCheckBox(_("All Regions"))
322          sigc::mem_fun(*this, &DimensionManager::onAllRegionsCheckBoxToggled)          sigc::mem_fun(*this, &DimensionManager::onAllRegionsCheckBoxToggled)
323      );      );
324    
325    #if HAS_GTKMM_SHOW_ALL_CHILDREN
326      show_all_children();      show_all_children();
327        #endif
328      resize(460,300);  
329        Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
330            sigc::mem_fun(*this, &DimensionManager::on_show_tooltips_changed)
331        );
332        on_show_tooltips_changed();
333    }
334    
335    void DimensionManager::on_show_tooltips_changed() {
336        const bool b = Settings::singleton()->showTooltips;
337    
338        treeView.set_has_tooltip(b);
339        allRegionsCheckBox.set_has_tooltip(b);
340    
341        set_has_tooltip(b);
342  }  }
343    
344  bool DimensionManager::allRegions() const {  bool DimensionManager::allRegions() const {
# Line 313  struct _DimDef { Line 367  struct _DimDef {
367  };  };
368  typedef std::map<gig::dimension_t, _DimDef> _Dimensions;  typedef std::map<gig::dimension_t, _DimDef> _Dimensions;
369    
370  // update all GUI elements according to current gig::Region informations  // update all GUI elements according to current gig::Region information
371  void DimensionManager::refreshManager() {  void DimensionManager::refreshManager() {
372      set_sensitive(false);      set_sensitive(false);
373      refTableModel->clear();      refTableModel->clear();
# Line 362  void DimensionManager::refreshManager() Line 416  void DimensionManager::refreshManager()
416  }  }
417    
418  void DimensionManager::show(gig::Region* region) {  void DimensionManager::show(gig::Region* region) {
419        ignoreColumnClicked = true;
420      this->region = region;      this->region = region;
421      refreshManager();      refreshManager();
422      Gtk::Window::show();      Gtk::Window::show();
423      deiconify();      deiconify();
424        ignoreColumnClicked = false;
425  }  }
426    
427  void DimensionManager::set_region(gig::Region* region) {  void DimensionManager::set_region(gig::Region* region) {
428        ignoreColumnClicked = true;
429      this->region = region;      this->region = region;
430      refreshManager();      refreshManager();
431        ignoreColumnClicked = false;
432    }
433    
434    void DimensionManager::onColumnClicked() {
435        printf("DimensionManager::onColumnClicked()\n");
436    
437        //FIXME: BUG: this method is currently very unreliably called, it should actually be called when the user selects another column, it is ATM however also called when the table content changed programmatically causing the dialog below to popup at undesired times !
438    
439        //HACK: Prevents that onColumnClicked() gets called multiple times or at times where it is not desired
440        if (ignoreColumnClicked) {
441            ignoreColumnClicked = false;
442            return;
443        }
444    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 18) || GTKMM_MAJOR_VERSION > 2
445        // prevents app to crash if this dialog is closed
446        if (!get_visible())
447            return;
448    #else
449    # warning Your GTKMM version is too old; dimension manager dialog might crash when changing a dimension type !
450    #endif
451    
452    #if (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 8) || GTKMM_MAJOR_VERSION > 3
453        if (!is_visible()) return;
454    #endif
455    
456        Gtk::TreeModel::Path path;
457        Gtk::TreeViewColumn* focus_column;
458        treeView.get_cursor(path, focus_column);
459        //const int row = path[0];
460        if (focus_column == treeView.get_column(0)) {
461            Gtk::TreeModel::iterator it = treeView.get_model()->get_iter(path);
462            if (!it) return;
463            Gtk::TreeModel::Row row = *it;
464            gig::dimension_t oldType = row[tableModel.m_type];
465    
466            Gtk::Dialog dialog(_("Change Dimension"), true /*modal*/);
467            int oldTypeIndex = -1;
468            Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);
469            for (int i = 0x01, count = 0; i < 0xff; i++) {
470                Glib::ustring sType =
471                    dimTypeAsString(static_cast<gig::dimension_t>(i));
472                if (i == oldType) oldTypeIndex = count;
473                if (sType.find("Unknown") != 0) {
474                    Gtk::TreeModel::Row row = *(refComboModel->append());
475                    row[comboModel.m_type_id]   = i;
476                    row[comboModel.m_type_name] = sType;
477                    count++;
478                }
479            }
480    #if USE_GTKMM_GRID
481            Gtk::Grid table;
482    #else
483            Gtk::Table table(1, 2);
484    #endif
485            Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_START);
486            Gtk::ComboBox comboDimType;
487            comboDimType.set_model(refComboModel);
488            comboDimType.pack_start(comboModel.m_type_id);
489            comboDimType.pack_start(comboModel.m_type_name);
490            table.attach(labelDimType, 0, 1, 0, 1);
491            table.attach(comboDimType, 1, 2, 0, 1);
492    #if USE_GTKMM_BOX
493            dialog.get_content_area()->pack_start(table);
494    #else
495            dialog.get_vbox()->pack_start(table);
496    #endif
497    
498    #if HAS_GTKMM_STOCK
499            dialog.add_button(Gtk::Stock::OK, 0);
500            dialog.add_button(Gtk::Stock::CANCEL, 1);
501    #else
502            dialog.add_button(_("_OK"), 0);
503            dialog.add_button(_("_Cancel"), 1);
504    #endif
505    #if HAS_GTKMM_SHOW_ALL_CHILDREN
506            dialog.show_all_children();
507    #endif
508            
509            comboDimType.set_active(oldTypeIndex);
510    
511            if (!dialog.run()) { // OK selected ...
512                ignoreColumnClicked = true;
513                Gtk::TreeModel::iterator iterType = comboDimType.get_active();
514                if (!iterType) return;
515                Gtk::TreeModel::Row rowType = *iterType;
516                if (!rowType) return;
517                int iTypeID = rowType[comboModel.m_type_id];
518                gig::dimension_t newType = static_cast<gig::dimension_t>(iTypeID);
519                if (newType == oldType) return;
520                //printf("change 0x%x -> 0x%x\n", oldType, newType);
521    
522                // assemble the list of regions where the selected dimension type
523                // shall be changed
524                std::vector<gig::Region*> vRegions;
525                if (allRegions()) {
526                    gig::Instrument* instr = (gig::Instrument*)region->GetParent();
527                    for (gig::Region* rgn = instr->GetFirstRegion(); rgn; rgn = instr->GetNextRegion()) {
528                        if (rgn->GetDimensionDefinition(oldType)) vRegions.push_back(rgn);
529                    }
530                } else vRegions.push_back(region);
531    
532                std::set<Glib::ustring> errors;
533    
534                for (uint iRgn = 0; iRgn < vRegions.size(); ++iRgn) {
535                    gig::Region* region = vRegions[iRgn];
536                    try {
537                        // notify everybody that we're going to update the region
538                        region_to_be_changed_signal.emit(region);
539                        // change the dimension type on that region
540                        region->SetDimensionType(oldType, newType);
541                        // let everybody know there was a change
542                        region_changed_signal.emit(region);
543                    } catch (RIFF::Exception e) {
544                        // notify that the changes are over (i.e. to avoid dead locks)
545                        region_changed_signal.emit(region);
546                        Glib::ustring txt = _("Could not alter dimension: ") + e.Message;
547                        if (vRegions.size() == 1) {
548                            // show error message directly
549                            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
550                            msg.run();
551                        } else {
552                            // remember error, they are shown after all regions have been processed
553                            errors.insert(txt);
554                        }
555                    }
556                }
557                // update all GUI elements
558                refreshManager();
559    
560                if (!errors.empty()) {
561                    Glib::ustring txt = _(
562                        "The following errors occurred while trying to change the dimension type on all regions:"
563                    );
564                    txt += "\n\n";
565                    for (std::set<Glib::ustring>::const_iterator it = errors.begin();
566                        it != errors.end(); ++it)
567                    {
568                        txt += "-> " + *it + "\n";
569                    }
570                    txt += "\n";
571                    txt += _(
572                        "You might also want to check the console for further warnings and "
573                        "error messages."
574                    );
575                    Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
576                    msg.run();
577                }
578            }
579        } else if (focus_column == treeView.get_column(1) || focus_column == treeView.get_column(2)) {
580            Glib::ustring txt = _("Right-click on a specific dimension zone of the dimension region selector to delete or split that particular dimension zone!");
581            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_INFO);
582            msg.run();
583        }
584  }  }
585    
586  void DimensionManager::addDimension() {  void DimensionManager::addDimension() {
# Line 386  void DimensionManager::addDimension() { Line 596  void DimensionManager::addDimension() {
596              row[comboModel.m_type_name] = sType;              row[comboModel.m_type_name] = sType;
597          }          }
598      }      }
599    #if USE_GTKMM_GRID
600        Gtk::Grid table;
601    #else
602      Gtk::Table table(2, 2);      Gtk::Table table(2, 2);
603    #endif
604      Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_START);      Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_START);
605      Gtk::ComboBox comboDimType;      Gtk::ComboBox comboDimType;
606      comboDimType.set_model(refComboModel);      comboDimType.set_model(refComboModel);
607      comboDimType.pack_start(comboModel.m_type_id);      comboDimType.pack_start(comboModel.m_type_id);
608      comboDimType.pack_start(comboModel.m_type_name);      comboDimType.pack_start(comboModel.m_type_name);
609      Gtk::Label labelZones(_("Zones:"), Gtk::ALIGN_START);      Gtk::Label labelZones(_("Zones:"), Gtk::ALIGN_START);
610    #if USE_GTKMM_GRID
611        table.attach(labelDimType, 0, 0);
612        table.attach(comboDimType, 1, 0);
613        table.attach(labelZones, 0, 1);
614    #else
615      table.attach(labelDimType, 0, 1, 0, 1);      table.attach(labelDimType, 0, 1, 0, 1);
616      table.attach(comboDimType, 1, 2, 0, 1);      table.attach(comboDimType, 1, 2, 0, 1);
617      table.attach(labelZones, 0, 1, 1, 2);      table.attach(labelZones, 0, 1, 1, 2);
618    #endif
619    
620    #if USE_GTKMM_BOX
621        dialog.get_content_area()->pack_start(table);
622    #else
623      dialog.get_vbox()->pack_start(table);      dialog.get_vbox()->pack_start(table);
624    #endif
625    
626      // number of zones: use a combo box with fix values for gig      // number of zones: use a combo box with fix values for gig
627      // v2 and a spin button for v3      // v2 and a spin button for v3
# Line 426  void DimensionManager::addDimension() { Line 651  void DimensionManager::addDimension() {
651          table.attach(spinZones, 1, 2, 1, 2);          table.attach(spinZones, 1, 2, 1, 2);
652      }      }
653    
654    #if HAS_GTKMM_STOCK
655      dialog.add_button(Gtk::Stock::OK, 0);      dialog.add_button(Gtk::Stock::OK, 0);
656      dialog.add_button(Gtk::Stock::CANCEL, 1);      dialog.add_button(Gtk::Stock::CANCEL, 1);
657    #else
658        dialog.add_button(_("_OK"), 0);
659        dialog.add_button(_("_Cancel"), 1);
660    #endif
661    #if HAS_GTKMM_SHOW_ALL_CHILDREN
662      dialog.show_all_children();      dialog.show_all_children();
663    #endif
664    
665      if (!dialog.run()) { // OK selected ...      if (!dialog.run()) { // OK selected ...
666          Gtk::TreeModel::iterator iterType = comboDimType.get_active();          Gtk::TreeModel::iterator iterType = comboDimType.get_active();

Legend:
Removed from v.2562  
changed lines
  Added in v.3450

  ViewVC Help
Powered by ViewVC