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

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

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

revision 2579 by persson, Sat May 24 06:44:39 2014 UTC revision 3301 by schoenebeck, Sun Jul 9 19:00:46 2017 UTC
# Line 1  Line 1 
1  /*  /*
2      Copyright (c) 2014 Christian Schoenebeck      Copyright (c) 2014-2017 Christian Schoenebeck
3            
4      This file is part of "gigedit" and released under the terms of the      This file is part of "gigedit" and released under the terms of the
5      GNU General Public License version 2.      GNU General Public License version 2.
6  */  */
7    
8    #include "global.h"
9  #include "CombineInstrumentsDialog.h"  #include "CombineInstrumentsDialog.h"
10    
11  // enable this for debug messages being printed while combining the instruments  // enable this for debug messages being printed while combining the instruments
12  #define DEBUG_COMBINE_INSTRUMENTS 0  #define DEBUG_COMBINE_INSTRUMENTS 0
13    
 #include "global.h"  
14  #include "compat.h"  #include "compat.h"
15    
16  #include <set>  #include <set>
# Line 23  Line 23 
23  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
24  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
25  #include <gtkmm/label.h>  #include <gtkmm/label.h>
26    #include <gtk/gtkwidget.h> // for gtk_widget_modify_*()
27    
 Glib::ustring gig_to_utf8(const gig::String& gig_string);  
28  Glib::ustring dimTypeAsString(gig::dimension_t d);  Glib::ustring dimTypeAsString(gig::dimension_t d);
29    
30  typedef std::vector< std::pair<gig::Instrument*, gig::Region*> > OrderedRegionGroup;  typedef std::vector< std::pair<gig::Instrument*, gig::Region*> > OrderedRegionGroup;
# Line 34  typedef std::map<DLS::range_t,RegionGrou Line 34  typedef std::map<DLS::range_t,RegionGrou
34  typedef std::vector<DLS::range_t> DimensionZones;  typedef std::vector<DLS::range_t> DimensionZones;
35  typedef std::map<gig::dimension_t,DimensionZones> Dimensions;  typedef std::map<gig::dimension_t,DimensionZones> Dimensions;
36    
 typedef std::map<gig::dimension_t,int> DimensionCase;  
   
37  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;
38    
39  typedef std::set<Glib::ustring> Warnings;  typedef std::set<Glib::ustring> Warnings;
# Line 97  inline int smallestOverlapPoint(const DL Line 95  inline int smallestOverlapPoint(const DL
95   *          found with a range member point >= iStart   *          found with a range member point >= iStart
96   */   */
97  static int findLowestRegionPoint(std::vector<gig::Instrument*>& instruments, int iStart) {  static int findLowestRegionPoint(std::vector<gig::Instrument*>& instruments, int iStart) {
98      DLS::range_t searchRange = { iStart, 127 };      DLS::range_t searchRange = { uint16_t(iStart), 127 };
99      int result = -1;      int result = -1;
100      for (uint i = 0; i < instruments.size(); ++i) {      for (uint i = 0; i < instruments.size(); ++i) {
101          gig::Instrument* instr = instruments[i];          gig::Instrument* instr = instruments[i];
# Line 119  static int findLowestRegionPoint(std::ve Line 117  static int findLowestRegionPoint(std::ve
117   *          with a range end >= iStart   *          with a range end >= iStart
118   */   */
119  static int findFirstRegionEnd(std::vector<gig::Instrument*>& instruments, int iStart) {  static int findFirstRegionEnd(std::vector<gig::Instrument*>& instruments, int iStart) {
120      DLS::range_t searchRange = { iStart, 127 };      DLS::range_t searchRange = { uint16_t(iStart), 127 };
121      int result = -1;      int result = -1;
122      for (uint i = 0; i < instruments.size(); ++i) {      for (uint i = 0; i < instruments.size(); ++i) {
123          gig::Instrument* instr = instruments[i];          gig::Instrument* instr = instruments[i];
# Line 195  static RegionGroups groupByRegionInterse Line 193  static RegionGroups groupByRegionInterse
193          iStart = findLowestRegionPoint(instruments, iStart);          iStart = findLowestRegionPoint(instruments, iStart);
194          if (iStart < 0) break;          if (iStart < 0) break;
195          const int iEnd = findFirstRegionEnd(instruments, iStart);          const int iEnd = findFirstRegionEnd(instruments, iStart);
196          DLS::range_t range = { iStart, iEnd };          DLS::range_t range = { uint16_t(iStart), uint16_t(iEnd) };
197          intersections.push_back(range);          intersections.push_back(range);
198          iStart = iEnd + 1;          iStart = iEnd + 1;
199      }      }
# Line 266  static Dimensions getDimensionsForRegion Line 264  static Dimensions getDimensionsForRegion
264               itNums != it->second.end(); ++itNums)               itNums != it->second.end(); ++itNums)
265          {          {
266              const int iUpperLimit = *itNums;              const int iUpperLimit = *itNums;
267              DLS::range_t range = { iLow, iUpperLimit };              DLS::range_t range = { uint16_t(iLow), uint16_t(iUpperLimit) };
268              dims[type].push_back(range);              dims[type].push_back(range);
269              iLow = iUpperLimit + 1;              iLow = iUpperLimit + 1;
270          }          }
# Line 275  static Dimensions getDimensionsForRegion Line 273  static Dimensions getDimensionsForRegion
273      return dims;      return dims;
274  }  }
275    
 inline int getDimensionIndex(gig::dimension_t type, gig::Region* rgn) {  
     for (uint i = 0; i < rgn->Dimensions; ++i)  
         if (rgn->pDimensionDefinitions[i].dimension == type)  
             return i;  
     return -1;  
 }  
   
276  static void fillDimValues(uint* values/*[8]*/, DimensionCase dimCase, gig::Region* rgn, bool bShouldHaveAllDimensionsPassed) {  static void fillDimValues(uint* values/*[8]*/, DimensionCase dimCase, gig::Region* rgn, bool bShouldHaveAllDimensionsPassed) {
277      #if DEBUG_COMBINE_INSTRUMENTS      #if DEBUG_COMBINE_INSTRUMENTS
278      printf("dimvalues = { ");      printf("dimvalues = { ");
# Line 323  static void restoreDimensionRegionUpperL Line 314  static void restoreDimensionRegionUpperL
314      }      }
315  }  }
316    
 /**  
  * Returns the sum of all bits of all dimensions defined before the given  
  * dimensions (@a type). This allows to access cases of that particular  
  * dimension directly.  
  *  
  * @param type - dimension that shall be used  
  * @param rgn - parent region of that dimension  
  */  
 inline int baseBits(gig::dimension_t type, gig::Region* rgn) {  
     int previousBits = 0;  
     for (uint i = 0; i < rgn->Dimensions; ++i) {  
         if (rgn->pDimensionDefinitions[i].dimension == type) break;  
         previousBits += rgn->pDimensionDefinitions[i].bits;  
     }  
     return previousBits;  
 }  
   
317  inline int dimensionRegionIndex(gig::DimensionRegion* dimRgn) {  inline int dimensionRegionIndex(gig::DimensionRegion* dimRgn) {
318      gig::Region* rgn = dimRgn->GetParent();      gig::Region* rgn = dimRgn->GetParent();
319      int sz = sizeof(rgn->pDimensionRegions) / sizeof(gig::DimensionRegion*);      int sz = sizeof(rgn->pDimensionRegions) / sizeof(gig::DimensionRegion*);
# Line 372  static DimensionZones preciseDimensionZo Line 346  static DimensionZones preciseDimensionZo
346      const gig::dimension_def_t& def = rgn->pDimensionDefinitions[iDimension];      const gig::dimension_def_t& def = rgn->pDimensionDefinitions[iDimension];
347      int iDimRgn = dimensionRegionIndex(dimRgn);      int iDimRgn = dimensionRegionIndex(dimRgn);
348      int iBaseBits = baseBits(type, rgn);      int iBaseBits = baseBits(type, rgn);
349        assert(iBaseBits >= 0);
350      int mask = ~(((1 << def.bits) - 1) << iBaseBits);      int mask = ~(((1 << def.bits) - 1) << iBaseBits);
351    
352      #if DEBUG_COMBINE_INSTRUMENTS      #if DEBUG_COMBINE_INSTRUMENTS
# Line 383  static DimensionZones preciseDimensionZo Line 358  static DimensionZones preciseDimensionZo
358          gig::DimensionRegion* dimRgn2 =          gig::DimensionRegion* dimRgn2 =
359              rgn->pDimensionRegions[ (iDimRgn & mask) | ( z << iBaseBits) ];              rgn->pDimensionRegions[ (iDimRgn & mask) | ( z << iBaseBits) ];
360          int iHigh = dimRgn2->DimensionUpperLimits[iDimension];          int iHigh = dimRgn2->DimensionUpperLimits[iDimension];
361          DLS::range_t range = { iLow, iHigh};          DLS::range_t range = { uint16_t(iLow), uint16_t(iHigh) };
362          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
363          printf("%d..%d, ", iLow, iHigh);          printf("%d..%d, ", iLow, iHigh);
364          fflush(stdout);          fflush(stdout);
# Line 469  static void scheduleCopyDimensionRegions Line 444  static void scheduleCopyDimensionRegions
444          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
445          printf("dst "); fflush(stdout);          printf("dst "); fflush(stdout);
446          #endif          #endif
447          fillDimValues(dstDimValues, dstDimCase, outRgn, true);          fillDimValues(dstDimValues, dstDimCase, outRgn, false);
448          gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);          gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);
449          gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);          gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);
450          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
# Line 505  static void scheduleCopyDimensionRegions Line 480  static void scheduleCopyDimensionRegions
480              printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]);              printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]);
481              printf("dst refilled "); fflush(stdout);              printf("dst refilled "); fflush(stdout);
482              #endif              #endif
483              fillDimValues(dstDimValues, dstDimCase, outRgn, true);              fillDimValues(dstDimValues, dstDimCase, outRgn, false);
484              dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);              dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);
485              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
486              printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn);              printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn);
# Line 660  static void combineInstruments(std::vect Line 635  static void combineInstruments(std::vect
635              iTotalZones += (def) ? def->zones : 1;              iTotalZones += (def) ? def->zones : 1;
636          }          }
637          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
638          printf("Required total zones: %d\n", iTotalZones);          printf("Required total zones: %d, vertical regions: %d\n", iTotalZones, itGroup->second.size());
639          #endif          #endif
640    
641          // create all required dimensions for this output region          // create all required dimensions for this output region
# Line 722  static void combineInstruments(std::vect Line 697  static void combineInstruments(std::vect
697              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
698              std::cout << "OK" << std::endl << std::flush;              std::cout << "OK" << std::endl << std::flush;
699              #endif              #endif
700            } else {
701                dims.erase(mainDimension);
702          }          }
703    
704          // for the next task we need to have the current RegionGroup to be          // for the next task we need to have the current RegionGroup to be
# Line 803  static void combineInstruments(std::vect Line 780  static void combineInstruments(std::vect
780  // class 'CombineInstrumentsDialog'  // class 'CombineInstrumentsDialog'
781    
782  CombineInstrumentsDialog::CombineInstrumentsDialog(Gtk::Window& parent, gig::File* gig)  CombineInstrumentsDialog::CombineInstrumentsDialog(Gtk::Window& parent, gig::File* gig)
783      : Gtk::Dialog(_("Combine Instruments"), parent, true),      : ManagedDialog(_("Combine Instruments"), parent, true),
784        m_gig(gig), m_fileWasChanged(false), m_newCombinedInstrument(NULL),        m_gig(gig), m_fileWasChanged(false), m_newCombinedInstrument(NULL),
785        m_cancelButton(Gtk::Stock::CANCEL), m_OKButton(Gtk::Stock::OK),        m_cancelButton(Gtk::Stock::CANCEL), m_OKButton(Gtk::Stock::OK),
786        m_descriptionLabel(), m_tableDimCombo(2, 2), m_comboDimType(),        m_descriptionLabel(), m_tableDimCombo(2, 2), m_comboDimType(),
787        m_labelDimType(Glib::ustring(_("Combine by Dimension:")) + "  ", Gtk::ALIGN_END)        m_labelDimType(Glib::ustring(_("Combine by Dimension:")) + "  ", Gtk::ALIGN_END)
788  {  {
789        if (!Settings::singleton()->autoRestoreWindowDimension) {
790            set_default_size(500, 600);
791            set_position(Gtk::WIN_POS_MOUSE);
792        }
793    
794        m_scrolledWindow.add(m_treeView);
795        m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
796    
797      get_vbox()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK);      get_vbox()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK);
798      get_vbox()->pack_start(m_tableDimCombo, Gtk::PACK_SHRINK);      get_vbox()->pack_start(m_tableDimCombo, Gtk::PACK_SHRINK);
799      get_vbox()->pack_start(m_treeView);      get_vbox()->pack_start(m_scrolledWindow);
800        get_vbox()->pack_start(m_labelOrder, Gtk::PACK_SHRINK);
801        get_vbox()->pack_start(m_iconView, Gtk::PACK_SHRINK);
802      get_vbox()->pack_start(m_buttonBox, Gtk::PACK_SHRINK);      get_vbox()->pack_start(m_buttonBox, Gtk::PACK_SHRINK);
803    
804  #if GTKMM_MAJOR_VERSION >= 3  #if GTKMM_MAJOR_VERSION >= 3
# Line 856  CombineInstrumentsDialog::CombineInstrum Line 843  CombineInstrumentsDialog::CombineInstrum
843          "Use SHIFT + left click or CTRL + left click to select the instruments "          "Use SHIFT + left click or CTRL + left click to select the instruments "
844          "you want to combine."          "you want to combine."
845      ));      ));
846      m_treeView.append_column("Instrument", m_columns.m_col_name);      m_treeView.append_column(_("Nr"), m_columns.m_col_index);
847      m_treeView.set_headers_visible(false);      m_treeView.append_column(_("Instrument"), m_columns.m_col_name);
848        m_treeView.set_headers_visible(true);
849      m_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);      m_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
850      m_treeView.get_selection()->signal_changed().connect(      m_treeView.get_selection()->signal_changed().connect(
851          sigc::mem_fun(*this, &CombineInstrumentsDialog::onSelectionChanged)          sigc::mem_fun(*this, &CombineInstrumentsDialog::onSelectionChanged)
# Line 882  CombineInstrumentsDialog::CombineInstrum Line 870  CombineInstrumentsDialog::CombineInstrum
870          Glib::ustring name(gig_to_utf8(instr->pInfo->Name));          Glib::ustring name(gig_to_utf8(instr->pInfo->Name));
871          Gtk::TreeModel::iterator iter = m_refTreeModel->append();          Gtk::TreeModel::iterator iter = m_refTreeModel->append();
872          Gtk::TreeModel::Row row = *iter;          Gtk::TreeModel::Row row = *iter;
873            row[m_columns.m_col_index] = i;
874          row[m_columns.m_col_name] = name;          row[m_columns.m_col_name] = name;
875          row[m_columns.m_col_instr] = instr;          row[m_columns.m_col_instr] = instr;
876      }      }
877    
878        m_refOrderModel = Gtk::ListStore::create(m_orderColumns);
879        m_iconView.set_model(m_refOrderModel);
880        m_iconView.set_tooltip_text(_("Use drag & drop to change the order."));
881        m_iconView.set_markup_column(1);
882        m_iconView.set_selection_mode(Gtk::SELECTION_SINGLE);
883        // force background to retain white also on selections
884        // (this also fixes a bug with GTK 2 which often causes visibility issue
885        //  with the text of the selected item)
886        {
887            Gdk::Color white;
888            white.set("#ffffff");
889            GtkWidget* widget = (GtkWidget*) m_iconView.gobj();
890            gtk_widget_modify_base(widget, GTK_STATE_SELECTED, white.gobj());
891            gtk_widget_modify_base(widget, GTK_STATE_ACTIVE, white.gobj());
892            gtk_widget_modify_bg(widget, GTK_STATE_SELECTED, white.gobj());
893            gtk_widget_modify_bg(widget, GTK_STATE_ACTIVE, white.gobj());
894        }
895    
896        m_labelOrder.set_text(_("Order of the instruments to be combined:"));
897    
898        // establish drag&drop within the instrument tree view, allowing to reorder
899        // the sequence of instruments within the gig file
900        {
901            std::vector<Gtk::TargetEntry> drag_target_instrument;
902            drag_target_instrument.push_back(Gtk::TargetEntry("gig::Instrument"));
903            m_iconView.drag_source_set(drag_target_instrument);
904            m_iconView.drag_dest_set(drag_target_instrument);
905            m_iconView.signal_drag_begin().connect(
906                sigc::mem_fun(*this, &CombineInstrumentsDialog::on_order_drag_begin)
907            );
908            m_iconView.signal_drag_data_get().connect(
909                sigc::mem_fun(*this, &CombineInstrumentsDialog::on_order_drag_data_get)
910            );
911            m_iconView.signal_drag_data_received().connect(
912                sigc::mem_fun(*this, &CombineInstrumentsDialog::on_order_drop_drag_data_received)
913            );
914        }
915    
916      m_buttonBox.set_layout(Gtk::BUTTONBOX_END);      m_buttonBox.set_layout(Gtk::BUTTONBOX_END);
917      m_buttonBox.set_border_width(5);      m_buttonBox.set_border_width(5);
918      m_buttonBox.pack_start(m_cancelButton, Gtk::PACK_SHRINK);      m_buttonBox.pack_start(m_cancelButton, Gtk::PACK_SHRINK);
# Line 919  CombineInstrumentsDialog::CombineInstrum Line 946  CombineInstrumentsDialog::CombineInstrum
946      }      }
947  }  }
948    
949    void CombineInstrumentsDialog::on_order_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context)
950    {
951        printf("Drag begin\n");
952        first_call_to_drag_data_get = true;
953    }
954    
955    void CombineInstrumentsDialog::on_order_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& context,
956                                                           Gtk::SelectionData& selection_data, guint, guint)
957    {
958        printf("Drag data get\n");
959        if (!first_call_to_drag_data_get) return;
960        first_call_to_drag_data_get = false;
961    
962        // get selected source instrument
963        gig::Instrument* src = NULL;
964        {
965            std::vector<Gtk::TreeModel::Path> rows = m_iconView.get_selected_items();
966            if (!rows.empty()) {
967                Gtk::TreeModel::iterator it = m_refOrderModel->get_iter(rows[0]);
968                if (it) {
969                    Gtk::TreeModel::Row row = *it;
970                    src = row[m_orderColumns.m_col_instr];
971                }
972            }
973        }
974        if (!src) {
975            printf("Drag data get: !src\n");
976            return;
977        }
978        printf("src=%ld\n", (size_t)src);
979    
980        // pass the source gig::Instrument as pointer
981        selection_data.set(selection_data.get_target(), 0/*unused*/, (const guchar*)&src,
982                           sizeof(src)/*length of data in bytes*/);
983    }
984    
985    void CombineInstrumentsDialog::on_order_drop_drag_data_received(
986        const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
987        const Gtk::SelectionData& selection_data, guint, guint time)
988    {
989        printf("Drag data received\n");
990        if (&selection_data == NULL) {
991            printf("!selection_data\n");
992            return;
993        }
994        if (!selection_data.get_data()) {
995            printf("selection_data.get_data() == NULL\n");
996            return;
997        }
998    
999        gig::Instrument* src = *((gig::Instrument**) selection_data.get_data());
1000        if (!src || selection_data.get_length() != sizeof(gig::Instrument*)) {
1001            printf("!src\n");
1002            return;
1003        }
1004        printf("src=%d\n", src);
1005    
1006        gig::Instrument* dst = NULL;
1007        {
1008            Gtk::TreeModel::Path path = m_iconView.get_path_at_pos(x, y);
1009            if (!path) return;
1010    
1011            Gtk::TreeModel::iterator iter = m_refOrderModel->get_iter(path);
1012            if (!iter) return;
1013            Gtk::TreeModel::Row row = *iter;
1014            dst = row[m_orderColumns.m_col_instr];
1015        }
1016        if (!dst) {
1017            printf("!dst\n");
1018            return;
1019        }
1020    
1021        printf("dragdrop received src='%s' dst='%s'\n", src->pInfo->Name.c_str(), dst->pInfo->Name.c_str());
1022    
1023        // swap the two items
1024        typedef Gtk::TreeModel::Children Children;
1025        Children children = m_refOrderModel->children();
1026        Children::iterator itSrc, itDst;
1027        int i = 0, iSrc = -1, iDst = -1;
1028        for (Children::iterator iter = children.begin();
1029             iter != children.end(); ++iter, ++i)
1030        {
1031            Gtk::TreeModel::Row row = *iter;
1032            if (row[m_orderColumns.m_col_instr] == src) {
1033                itSrc = iter;
1034                iSrc  = i;
1035            } else if (row[m_orderColumns.m_col_instr] == dst) {
1036                itDst = iter;
1037                iDst  = i;
1038            }
1039        }
1040        if (itSrc && itDst) {
1041            // swap elements
1042            m_refOrderModel->iter_swap(itSrc, itDst);
1043            // update markup
1044            Gtk::TreeModel::Row rowSrc = *itSrc;
1045            Gtk::TreeModel::Row rowDst = *itDst;
1046            {
1047                Glib::ustring name = rowSrc[m_orderColumns.m_col_name];
1048                Glib::ustring markup =
1049                    "<span foreground='black' background='white'>" + ToString(iDst+1) + ".</span>\n<span foreground='green' background='white'>" + name + "</span>";
1050                rowSrc[m_orderColumns.m_col_markup] = markup;
1051            }
1052            {
1053                Glib::ustring name = rowDst[m_orderColumns.m_col_name];
1054                Glib::ustring markup =
1055                    "<span foreground='black' background='white'>" + ToString(iSrc+1) + ".</span>\n<span foreground='green' background='white'>" + name + "</span>";
1056                rowDst[m_orderColumns.m_col_markup] = markup;
1057            }
1058        }
1059    }
1060    
1061    void CombineInstrumentsDialog::setSelectedInstruments(const std::set<int>& instrumentIndeces) {
1062        typedef Gtk::TreeModel::Children Children;
1063        Children children = m_refTreeModel->children();
1064        for (Children::iterator iter = children.begin();
1065             iter != children.end(); ++iter)
1066        {
1067            Gtk::TreeModel::Row row = *iter;
1068            int index = row[m_columns.m_col_index];
1069            if (instrumentIndeces.count(index))
1070                m_treeView.get_selection()->select(iter);
1071        }
1072    }
1073    
1074  void CombineInstrumentsDialog::combineSelectedInstruments() {  void CombineInstrumentsDialog::combineSelectedInstruments() {
1075      std::vector<gig::Instrument*> instruments;      std::vector<gig::Instrument*> instruments;
1076      std::vector<Gtk::TreeModel::Path> v = m_treeView.get_selection()->get_selected_rows();      {
1077      for (uint i = 0; i < v.size(); ++i) {          typedef Gtk::TreeModel::Children Children;
1078          Gtk::TreeModel::iterator it = m_refTreeModel->get_iter(v[i]);          int i = 0;
1079          Gtk::TreeModel::Row row = *it;          Children selection = m_refOrderModel->children();
1080          Glib::ustring name = row[m_columns.m_col_name];          for (Children::iterator it = selection.begin();
1081          gig::Instrument* instrument = row[m_columns.m_col_instr];               it != selection.end(); ++it, ++i)
1082          #if DEBUG_COMBINE_INSTRUMENTS          {
1083          printf("Selection '%s' 0x%lx\n\n", name.c_str(), int64_t((void*)instrument));              Gtk::TreeModel::Row row = *it;
1084          #endif              Glib::ustring name = row[m_orderColumns.m_col_name];
1085          instruments.push_back(instrument);              gig::Instrument* instrument = row[m_orderColumns.m_col_instr];
1086                #if DEBUG_COMBINE_INSTRUMENTS
1087                printf("Selection %d. '%s' %p\n\n", (i+1), name.c_str(), instrument));
1088                #endif
1089                instruments.push_back(instrument);
1090            }
1091      }      }
1092    
1093      g_warnings.clear();      g_warnings.clear();
# Line 947  void CombineInstrumentsDialog::combineSe Line 1104  void CombineInstrumentsDialog::combineSe
1104              mainDimension = static_cast<gig::dimension_t>(iTypeID);              mainDimension = static_cast<gig::dimension_t>(iTypeID);
1105          }          }
1106    
1107          // now start the actual cobination task ...          // now start the actual combination task ...
1108          combineInstruments(instruments, m_gig, m_newCombinedInstrument, mainDimension);          combineInstruments(instruments, m_gig, m_newCombinedInstrument, mainDimension);
1109      } catch (RIFF::Exception e) {;      } catch (RIFF::Exception e) {;
1110          Gtk::MessageDialog msg(*this, e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, e.Message, false, Gtk::MESSAGE_ERROR);
# Line 987  void CombineInstrumentsDialog::combineSe Line 1144  void CombineInstrumentsDialog::combineSe
1144  void CombineInstrumentsDialog::onSelectionChanged() {  void CombineInstrumentsDialog::onSelectionChanged() {
1145      std::vector<Gtk::TreeModel::Path> v = m_treeView.get_selection()->get_selected_rows();      std::vector<Gtk::TreeModel::Path> v = m_treeView.get_selection()->get_selected_rows();
1146      m_OKButton.set_sensitive(v.size() >= 2);      m_OKButton.set_sensitive(v.size() >= 2);
1147    
1148        typedef Gtk::TreeModel::Children Children;
1149    
1150        // update horizontal selection list (icon view) ...
1151    
1152        // remove items which are not part of the new selection anymore
1153        {
1154            Children allOrdered = m_refOrderModel->children();
1155            for (Children::iterator itOrder = allOrdered.begin();
1156                 itOrder != allOrdered.end(); ++itOrder)
1157            {
1158                Gtk::TreeModel::Row rowOrder = *itOrder;
1159                gig::Instrument* instr = rowOrder[m_orderColumns.m_col_instr];
1160                for (uint i = 0; i < v.size(); ++i) {
1161                    Gtk::TreeModel::iterator itSel = m_refTreeModel->get_iter(v[i]);
1162                    Gtk::TreeModel::Row rowSel = *itSel;
1163                    if (rowSel[m_columns.m_col_instr] == instr)
1164                        goto nextOrderedItem;
1165                }
1166                goto removeOrderedItem;
1167            nextOrderedItem:
1168                continue;
1169            removeOrderedItem:
1170                m_refOrderModel->erase(itOrder);
1171            }
1172        }
1173    
1174        // add items newly added to the selection
1175        for (uint i = 0; i < v.size(); ++i) {
1176            Gtk::TreeModel::iterator itSel = m_refTreeModel->get_iter(v[i]);
1177            Gtk::TreeModel::Row rowSel = *itSel;
1178            gig::Instrument* instr = rowSel[m_columns.m_col_instr];
1179            Children allOrdered = m_refOrderModel->children();
1180            for (Children::iterator itOrder = allOrdered.begin();
1181                 itOrder != allOrdered.end(); ++itOrder)
1182            {
1183                Gtk::TreeModel::Row rowOrder = *itOrder;
1184                if (rowOrder[m_orderColumns.m_col_instr] == instr)
1185                    goto nextSelectionItem;
1186            }
1187            goto addNewSelectionItem;
1188        nextSelectionItem:
1189            continue;
1190        addNewSelectionItem:
1191            Glib::ustring name = gig_to_utf8(instr->pInfo->Name);
1192            Gtk::TreeModel::iterator iterOrder = m_refOrderModel->append();
1193            Gtk::TreeModel::Row rowOrder = *iterOrder;
1194            rowOrder[m_orderColumns.m_col_name] = name;
1195            rowOrder[m_orderColumns.m_col_instr] = instr;
1196        }
1197    
1198        // update markup
1199        {
1200            int i = 0;
1201            Children allOrdered = m_refOrderModel->children();
1202            for (Children::iterator itOrder = allOrdered.begin();
1203                 itOrder != allOrdered.end(); ++itOrder, ++i)
1204            {
1205                Gtk::TreeModel::Row rowOrder = *itOrder;
1206                Glib::ustring name = rowOrder[m_orderColumns.m_col_name];
1207                Glib::ustring markup =
1208                    "<span foreground='black' background='white'>" + ToString(i+1) + ".</span>\n<span foreground='green' background='white'>" + name + "</span>";
1209                rowOrder[m_orderColumns.m_col_markup] = markup;
1210            }
1211        }
1212  }  }
1213    
1214  bool CombineInstrumentsDialog::fileWasChanged() const {  bool CombineInstrumentsDialog::fileWasChanged() const {

Legend:
Removed from v.2579  
changed lines
  Added in v.3301

  ViewVC Help
Powered by ViewVC