/[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 2558 by schoenebeck, Sat May 17 23:55:30 2014 UTC revision 3450 by schoenebeck, Wed Jan 2 16:39:20 2019 UTC
# Line 1  Line 1 
1  /*  /*
2      Copyright (c) 2014 Christian Schoenebeck      Copyright (c) 2014-2018 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 20  Line 20 
20  #include <string.h>  #include <string.h>
21    
22  #include <glibmm/ustring.h>  #include <glibmm/ustring.h>
23  #include <gtkmm/stock.h>  #if HAS_GTKMM_STOCK
24    # include <gtkmm/stock.h>
25    #endif
26  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
27  #include <gtkmm/label.h>  #include <gtkmm/label.h>
28    #include <gtk/gtkwidget.h> // for gtk_widget_modify_*()
29    
 Glib::ustring gig_to_utf8(const gig::String& gig_string);  
30  Glib::ustring dimTypeAsString(gig::dimension_t d);  Glib::ustring dimTypeAsString(gig::dimension_t d);
31    
32  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 36  typedef std::map<DLS::range_t,RegionGrou
36  typedef std::vector<DLS::range_t> DimensionZones;  typedef std::vector<DLS::range_t> DimensionZones;
37  typedef std::map<gig::dimension_t,DimensionZones> Dimensions;  typedef std::map<gig::dimension_t,DimensionZones> Dimensions;
38    
 typedef std::map<gig::dimension_t,int> DimensionCase;  
   
39  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;
40    
41  typedef std::set<Glib::ustring> Warnings;  typedef std::set<Glib::ustring> Warnings;
# Line 97  inline int smallestOverlapPoint(const DL Line 97  inline int smallestOverlapPoint(const DL
97   *          found with a range member point >= iStart   *          found with a range member point >= iStart
98   */   */
99  static int findLowestRegionPoint(std::vector<gig::Instrument*>& instruments, int iStart) {  static int findLowestRegionPoint(std::vector<gig::Instrument*>& instruments, int iStart) {
100      DLS::range_t searchRange = { iStart, 127 };      DLS::range_t searchRange = { uint16_t(iStart), 127 };
101      int result = -1;      int result = -1;
102      for (uint i = 0; i < instruments.size(); ++i) {      for (uint i = 0; i < instruments.size(); ++i) {
103          gig::Instrument* instr = instruments[i];          gig::Instrument* instr = instruments[i];
# Line 119  static int findLowestRegionPoint(std::ve Line 119  static int findLowestRegionPoint(std::ve
119   *          with a range end >= iStart   *          with a range end >= iStart
120   */   */
121  static int findFirstRegionEnd(std::vector<gig::Instrument*>& instruments, int iStart) {  static int findFirstRegionEnd(std::vector<gig::Instrument*>& instruments, int iStart) {
122      DLS::range_t searchRange = { iStart, 127 };      DLS::range_t searchRange = { uint16_t(iStart), 127 };
123      int result = -1;      int result = -1;
124      for (uint i = 0; i < instruments.size(); ++i) {      for (uint i = 0; i < instruments.size(); ++i) {
125          gig::Instrument* instr = instruments[i];          gig::Instrument* instr = instruments[i];
# Line 195  static RegionGroups groupByRegionInterse Line 195  static RegionGroups groupByRegionInterse
195          iStart = findLowestRegionPoint(instruments, iStart);          iStart = findLowestRegionPoint(instruments, iStart);
196          if (iStart < 0) break;          if (iStart < 0) break;
197          const int iEnd = findFirstRegionEnd(instruments, iStart);          const int iEnd = findFirstRegionEnd(instruments, iStart);
198          DLS::range_t range = { iStart, iEnd };          DLS::range_t range = { uint16_t(iStart), uint16_t(iEnd) };
199          intersections.push_back(range);          intersections.push_back(range);
200          iStart = iEnd + 1;          iStart = iEnd + 1;
201      }      }
# Line 266  static Dimensions getDimensionsForRegion Line 266  static Dimensions getDimensionsForRegion
266               itNums != it->second.end(); ++itNums)               itNums != it->second.end(); ++itNums)
267          {          {
268              const int iUpperLimit = *itNums;              const int iUpperLimit = *itNums;
269              DLS::range_t range = { iLow, iUpperLimit };              DLS::range_t range = { uint16_t(iLow), uint16_t(iUpperLimit) };
270              dims[type].push_back(range);              dims[type].push_back(range);
271              iLow = iUpperLimit + 1;              iLow = iUpperLimit + 1;
272          }          }
# Line 275  static Dimensions getDimensionsForRegion Line 275  static Dimensions getDimensionsForRegion
275      return dims;      return dims;
276  }  }
277    
 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;  
 }  
   
278  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) {
279      #if DEBUG_COMBINE_INSTRUMENTS      #if DEBUG_COMBINE_INSTRUMENTS
280      printf("dimvalues = { ");      printf("dimvalues = { ");
# Line 323  static void restoreDimensionRegionUpperL Line 316  static void restoreDimensionRegionUpperL
316      }      }
317  }  }
318    
 /**  
  * 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;  
 }  
   
319  inline int dimensionRegionIndex(gig::DimensionRegion* dimRgn) {  inline int dimensionRegionIndex(gig::DimensionRegion* dimRgn) {
320      gig::Region* rgn = dimRgn->GetParent();      gig::Region* rgn = dimRgn->GetParent();
321      int sz = sizeof(rgn->pDimensionRegions) / sizeof(gig::DimensionRegion*);      int sz = sizeof(rgn->pDimensionRegions) / sizeof(gig::DimensionRegion*);
# Line 372  static DimensionZones preciseDimensionZo Line 348  static DimensionZones preciseDimensionZo
348      const gig::dimension_def_t& def = rgn->pDimensionDefinitions[iDimension];      const gig::dimension_def_t& def = rgn->pDimensionDefinitions[iDimension];
349      int iDimRgn = dimensionRegionIndex(dimRgn);      int iDimRgn = dimensionRegionIndex(dimRgn);
350      int iBaseBits = baseBits(type, rgn);      int iBaseBits = baseBits(type, rgn);
351        assert(iBaseBits >= 0);
352      int mask = ~(((1 << def.bits) - 1) << iBaseBits);      int mask = ~(((1 << def.bits) - 1) << iBaseBits);
353    
354      #if DEBUG_COMBINE_INSTRUMENTS      #if DEBUG_COMBINE_INSTRUMENTS
# Line 383  static DimensionZones preciseDimensionZo Line 360  static DimensionZones preciseDimensionZo
360          gig::DimensionRegion* dimRgn2 =          gig::DimensionRegion* dimRgn2 =
361              rgn->pDimensionRegions[ (iDimRgn & mask) | ( z << iBaseBits) ];              rgn->pDimensionRegions[ (iDimRgn & mask) | ( z << iBaseBits) ];
362          int iHigh = dimRgn2->DimensionUpperLimits[iDimension];          int iHigh = dimRgn2->DimensionUpperLimits[iDimension];
363          DLS::range_t range = { iLow, iHigh};          DLS::range_t range = { uint16_t(iLow), uint16_t(iHigh) };
364          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
365          printf("%d..%d, ", iLow, iHigh);          printf("%d..%d, ", iLow, iHigh);
366          fflush(stdout);          fflush(stdout);
# Line 469  static void scheduleCopyDimensionRegions Line 446  static void scheduleCopyDimensionRegions
446          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
447          printf("dst "); fflush(stdout);          printf("dst "); fflush(stdout);
448          #endif          #endif
449          fillDimValues(dstDimValues, dstDimCase, outRgn, true);          fillDimValues(dstDimValues, dstDimCase, outRgn, false);
450          gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);          gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);
451          gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);          gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);
452          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
# Line 505  static void scheduleCopyDimensionRegions Line 482  static void scheduleCopyDimensionRegions
482              printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]);              printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]);
483              printf("dst refilled "); fflush(stdout);              printf("dst refilled "); fflush(stdout);
484              #endif              #endif
485              fillDimValues(dstDimValues, dstDimCase, outRgn, true);              fillDimValues(dstDimValues, dstDimCase, outRgn, false);
486              dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);              dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);
487              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
488              printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn);              printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn);
# Line 660  static void combineInstruments(std::vect Line 637  static void combineInstruments(std::vect
637              iTotalZones += (def) ? def->zones : 1;              iTotalZones += (def) ? def->zones : 1;
638          }          }
639          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
640          printf("Required total zones: %d\n", iTotalZones);          printf("Required total zones: %d, vertical regions: %d\n", iTotalZones, itGroup->second.size());
641          #endif          #endif
642    
643          // create all required dimensions for this output region          // create all required dimensions for this output region
# Line 722  static void combineInstruments(std::vect Line 699  static void combineInstruments(std::vect
699              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
700              std::cout << "OK" << std::endl << std::flush;              std::cout << "OK" << std::endl << std::flush;
701              #endif              #endif
702            } else {
703                dims.erase(mainDimension);
704          }          }
705    
706          // 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 782  static void combineInstruments(std::vect
782  // class 'CombineInstrumentsDialog'  // class 'CombineInstrumentsDialog'
783    
784  CombineInstrumentsDialog::CombineInstrumentsDialog(Gtk::Window& parent, gig::File* gig)  CombineInstrumentsDialog::CombineInstrumentsDialog(Gtk::Window& parent, gig::File* gig)
785      : Gtk::Dialog(_("Combine Instruments"), parent, true),      : ManagedDialog(_("Combine Instruments"), parent, true),
786        m_gig(gig), m_fileWasChanged(false), m_newCombinedInstrument(NULL),        m_gig(gig), m_fileWasChanged(false), m_newCombinedInstrument(NULL),
787    #if HAS_GTKMM_STOCK
788        m_cancelButton(Gtk::Stock::CANCEL), m_OKButton(Gtk::Stock::OK),        m_cancelButton(Gtk::Stock::CANCEL), m_OKButton(Gtk::Stock::OK),
789        m_descriptionLabel(), m_tableDimCombo(2, 2), m_comboDimType(),  #else
790        m_labelDimType(Glib::ustring(_("Combine by Dimension:")) + "  ", Gtk::ALIGN_RIGHT)        m_cancelButton(_("_Cancel"), true), m_OKButton(_("_OK"), true),
791    #endif
792          m_descriptionLabel(),
793    #if USE_GTKMM_GRID
794          m_tableDimCombo(),
795    #else
796          m_tableDimCombo(2, 2),
797    #endif
798          m_comboDimType(),
799          m_labelDimType(Glib::ustring(_("Combine by Dimension:")) + "  ", Gtk::ALIGN_END)
800  {  {
801        if (!Settings::singleton()->autoRestoreWindowDimension) {
802            set_default_size(500, 600);
803            set_position(Gtk::WIN_POS_MOUSE);
804        }
805    
806        m_scrolledWindow.add(m_treeView);
807        m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
808    
809    #if USE_GTKMM_BOX
810        get_content_area()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK);
811        get_content_area()->pack_start(m_tableDimCombo, Gtk::PACK_SHRINK);
812        get_content_area()->pack_start(m_scrolledWindow);
813        get_content_area()->pack_start(m_labelOrder, Gtk::PACK_SHRINK);
814        get_content_area()->pack_start(m_iconView, Gtk::PACK_SHRINK);
815        get_content_area()->pack_start(m_buttonBox, Gtk::PACK_SHRINK);
816    #else
817      get_vbox()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK);      get_vbox()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK);
818      get_vbox()->pack_start(m_tableDimCombo, Gtk::PACK_SHRINK);      get_vbox()->pack_start(m_tableDimCombo, Gtk::PACK_SHRINK);
819      get_vbox()->pack_start(m_treeView);      get_vbox()->pack_start(m_scrolledWindow);
820        get_vbox()->pack_start(m_labelOrder, Gtk::PACK_SHRINK);
821        get_vbox()->pack_start(m_iconView, Gtk::PACK_SHRINK);
822      get_vbox()->pack_start(m_buttonBox, Gtk::PACK_SHRINK);      get_vbox()->pack_start(m_buttonBox, Gtk::PACK_SHRINK);
823    #endif
824    
825  #if GTKMM_MAJOR_VERSION >= 3  #if GTKMM_MAJOR_VERSION >= 3
826      description.set_line_wrap();      m_descriptionLabel.set_line_wrap();
827  #endif  #endif
828      m_descriptionLabel.set_text(_(      m_descriptionLabel.set_text(_(
829          "Select at least two instruments below that shall be combined (as "          "Select at least two instruments below that shall be combined (as "
# Line 856  CombineInstrumentsDialog::CombineInstrum Line 864  CombineInstrumentsDialog::CombineInstrum
864          "Use SHIFT + left click or CTRL + left click to select the instruments "          "Use SHIFT + left click or CTRL + left click to select the instruments "
865          "you want to combine."          "you want to combine."
866      ));      ));
867      m_treeView.append_column("Instrument", m_columns.m_col_name);      m_treeView.append_column(_("Nr"), m_columns.m_col_index);
868      m_treeView.set_headers_visible(false);      m_treeView.append_column(_("Instrument"), m_columns.m_col_name);
869        m_treeView.set_headers_visible(true);
870      m_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);      m_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
871      m_treeView.get_selection()->signal_changed().connect(      m_treeView.get_selection()->signal_changed().connect(
872          sigc::mem_fun(*this, &CombineInstrumentsDialog::onSelectionChanged)          sigc::mem_fun(*this, &CombineInstrumentsDialog::onSelectionChanged)
# Line 882  CombineInstrumentsDialog::CombineInstrum Line 891  CombineInstrumentsDialog::CombineInstrum
891          Glib::ustring name(gig_to_utf8(instr->pInfo->Name));          Glib::ustring name(gig_to_utf8(instr->pInfo->Name));
892          Gtk::TreeModel::iterator iter = m_refTreeModel->append();          Gtk::TreeModel::iterator iter = m_refTreeModel->append();
893          Gtk::TreeModel::Row row = *iter;          Gtk::TreeModel::Row row = *iter;
894            row[m_columns.m_col_index] = i;
895          row[m_columns.m_col_name] = name;          row[m_columns.m_col_name] = name;
896          row[m_columns.m_col_instr] = instr;          row[m_columns.m_col_instr] = instr;
897      }      }
898    
899        m_refOrderModel = Gtk::ListStore::create(m_orderColumns);
900        m_iconView.set_model(m_refOrderModel);
901        m_iconView.set_tooltip_text(_("Use drag & drop to change the order."));
902        m_iconView.set_markup_column(1);
903        m_iconView.set_selection_mode(Gtk::SELECTION_SINGLE);
904        // force background to retain white also on selections
905        // (this also fixes a bug with GTK 2 which often causes visibility issue
906        //  with the text of the selected item)
907        {
908    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
909            Gdk::Color white;
910    #else
911            Gdk::RGBA white;
912    #endif
913            white.set("#ffffff");
914            GtkWidget* widget = (GtkWidget*) m_iconView.gobj();
915    #if GTK_MAJOR_VERSION < 3
916            gtk_widget_modify_base(widget, GTK_STATE_SELECTED, white.gobj());
917            gtk_widget_modify_base(widget, GTK_STATE_ACTIVE, white.gobj());
918            gtk_widget_modify_bg(widget, GTK_STATE_SELECTED, white.gobj());
919            gtk_widget_modify_bg(widget, GTK_STATE_ACTIVE, white.gobj());
920    #endif
921        }
922    
923        m_labelOrder.set_text(_("Order of the instruments to be combined:"));
924    
925        // establish drag&drop within the instrument tree view, allowing to reorder
926        // the sequence of instruments within the gig file
927        {
928            std::vector<Gtk::TargetEntry> drag_target_instrument;
929            drag_target_instrument.push_back(Gtk::TargetEntry("gig::Instrument"));
930            m_iconView.drag_source_set(drag_target_instrument);
931            m_iconView.drag_dest_set(drag_target_instrument);
932            m_iconView.signal_drag_begin().connect(
933                sigc::mem_fun(*this, &CombineInstrumentsDialog::on_order_drag_begin)
934            );
935            m_iconView.signal_drag_data_get().connect(
936                sigc::mem_fun(*this, &CombineInstrumentsDialog::on_order_drag_data_get)
937            );
938            m_iconView.signal_drag_data_received().connect(
939                sigc::mem_fun(*this, &CombineInstrumentsDialog::on_order_drop_drag_data_received)
940            );
941        }
942    
943      m_buttonBox.set_layout(Gtk::BUTTONBOX_END);      m_buttonBox.set_layout(Gtk::BUTTONBOX_END);
944    #if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION > 24)
945        m_buttonBox.set_margin(5);
946    #else
947      m_buttonBox.set_border_width(5);      m_buttonBox.set_border_width(5);
948    #endif
949      m_buttonBox.pack_start(m_cancelButton, Gtk::PACK_SHRINK);      m_buttonBox.pack_start(m_cancelButton, Gtk::PACK_SHRINK);
950      m_buttonBox.pack_start(m_OKButton, Gtk::PACK_SHRINK);      m_buttonBox.pack_start(m_OKButton, Gtk::PACK_SHRINK);
951      m_buttonBox.show();      m_buttonBox.show();
# Line 904  CombineInstrumentsDialog::CombineInstrum Line 962  CombineInstrumentsDialog::CombineInstrum
962          sigc::mem_fun(*this, &CombineInstrumentsDialog::combineSelectedInstruments)          sigc::mem_fun(*this, &CombineInstrumentsDialog::combineSelectedInstruments)
963      );      );
964    
965    #if HAS_GTKMM_SHOW_ALL_CHILDREN
966      show_all_children();      show_all_children();
967    #endif
968    
969        Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
970            sigc::mem_fun(*this, &CombineInstrumentsDialog::on_show_tooltips_changed)
971        );
972        on_show_tooltips_changed();
973    
974      // show a warning to user if he uses a .gig in v2 format      // show a warning to user if he uses a .gig in v2 format
975      if (gig->pVersion->major < 3) {      if (gig->pVersion->major < 3) {
# Line 917  CombineInstrumentsDialog::CombineInstrum Line 982  CombineInstrumentsDialog::CombineInstrum
982          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_WARNING);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_WARNING);
983          msg.run();          msg.run();
984      }      }
985    
986        // OK button should have focus by default for quick combining with Return key
987        m_OKButton.grab_focus();
988    }
989    
990    void CombineInstrumentsDialog::on_order_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context)
991    {
992        printf("Drag begin\n");
993        first_call_to_drag_data_get = true;
994    }
995    
996    void CombineInstrumentsDialog::on_order_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& context,
997                                                           Gtk::SelectionData& selection_data, guint, guint)
998    {
999        printf("Drag data get\n");
1000        if (!first_call_to_drag_data_get) return;
1001        first_call_to_drag_data_get = false;
1002    
1003        // get selected source instrument
1004        gig::Instrument* src = NULL;
1005        {
1006            std::vector<Gtk::TreeModel::Path> rows = m_iconView.get_selected_items();
1007            if (!rows.empty()) {
1008                Gtk::TreeModel::iterator it = m_refOrderModel->get_iter(rows[0]);
1009                if (it) {
1010                    Gtk::TreeModel::Row row = *it;
1011                    src = row[m_orderColumns.m_col_instr];
1012                }
1013            }
1014        }
1015        if (!src) {
1016            printf("Drag data get: !src\n");
1017            return;
1018        }
1019        printf("src=%ld\n", (size_t)src);
1020    
1021        // pass the source gig::Instrument as pointer
1022        selection_data.set(selection_data.get_target(), 0/*unused*/, (const guchar*)&src,
1023                           sizeof(src)/*length of data in bytes*/);
1024    }
1025    
1026    void CombineInstrumentsDialog::on_order_drop_drag_data_received(
1027        const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
1028        const Gtk::SelectionData& selection_data, guint, guint time)
1029    {
1030        printf("Drag data received\n");
1031        if (&selection_data == NULL) {
1032            printf("!selection_data\n");
1033            return;
1034        }
1035        if (!selection_data.get_data()) {
1036            printf("selection_data.get_data() == NULL\n");
1037            return;
1038        }
1039    
1040        gig::Instrument* src = *((gig::Instrument**) selection_data.get_data());
1041        if (!src || selection_data.get_length() != sizeof(gig::Instrument*)) {
1042            printf("!src\n");
1043            return;
1044        }
1045        printf("src=%d\n", src);
1046    
1047        gig::Instrument* dst = NULL;
1048        {
1049            Gtk::TreeModel::Path path = m_iconView.get_path_at_pos(x, y);
1050            if (!path) return;
1051    
1052            Gtk::TreeModel::iterator iter = m_refOrderModel->get_iter(path);
1053            if (!iter) return;
1054            Gtk::TreeModel::Row row = *iter;
1055            dst = row[m_orderColumns.m_col_instr];
1056        }
1057        if (!dst) {
1058            printf("!dst\n");
1059            return;
1060        }
1061    
1062        printf("dragdrop received src='%s' dst='%s'\n", src->pInfo->Name.c_str(), dst->pInfo->Name.c_str());
1063    
1064        // swap the two items
1065        typedef Gtk::TreeModel::Children Children;
1066        Children children = m_refOrderModel->children();
1067        Children::iterator itSrc, itDst;
1068        int i = 0, iSrc = -1, iDst = -1;
1069        for (Children::iterator iter = children.begin();
1070             iter != children.end(); ++iter, ++i)
1071        {
1072            Gtk::TreeModel::Row row = *iter;
1073            if (row[m_orderColumns.m_col_instr] == src) {
1074                itSrc = iter;
1075                iSrc  = i;
1076            } else if (row[m_orderColumns.m_col_instr] == dst) {
1077                itDst = iter;
1078                iDst  = i;
1079            }
1080        }
1081        if (itSrc && itDst) {
1082            // swap elements
1083            m_refOrderModel->iter_swap(itSrc, itDst);
1084            // update markup
1085            Gtk::TreeModel::Row rowSrc = *itSrc;
1086            Gtk::TreeModel::Row rowDst = *itDst;
1087            {
1088                Glib::ustring name = rowSrc[m_orderColumns.m_col_name];
1089                Glib::ustring markup =
1090                    "<span foreground='black' background='white'>" + ToString(iDst+1) + ".</span>\n<span foreground='green' background='white'>" + name + "</span>";
1091                rowSrc[m_orderColumns.m_col_markup] = markup;
1092            }
1093            {
1094                Glib::ustring name = rowDst[m_orderColumns.m_col_name];
1095                Glib::ustring markup =
1096                    "<span foreground='black' background='white'>" + ToString(iSrc+1) + ".</span>\n<span foreground='green' background='white'>" + name + "</span>";
1097                rowDst[m_orderColumns.m_col_markup] = markup;
1098            }
1099        }
1100    }
1101    
1102    void CombineInstrumentsDialog::setSelectedInstruments(const std::set<int>& instrumentIndeces) {
1103        typedef Gtk::TreeModel::Children Children;
1104        Children children = m_refTreeModel->children();
1105        for (Children::iterator iter = children.begin();
1106             iter != children.end(); ++iter)
1107        {
1108            Gtk::TreeModel::Row row = *iter;
1109            int index = row[m_columns.m_col_index];
1110            if (instrumentIndeces.count(index))
1111                m_treeView.get_selection()->select(iter);
1112        }
1113        // hack: OK button lost focus after doing the above, it should have focus by default for quick combining with Return key
1114        m_OKButton.grab_focus();
1115  }  }
1116    
1117  void CombineInstrumentsDialog::combineSelectedInstruments() {  void CombineInstrumentsDialog::combineSelectedInstruments() {
1118      std::vector<gig::Instrument*> instruments;      std::vector<gig::Instrument*> instruments;
1119      std::vector<Gtk::TreeModel::Path> v = m_treeView.get_selection()->get_selected_rows();      {
1120      for (uint i = 0; i < v.size(); ++i) {          typedef Gtk::TreeModel::Children Children;
1121          Gtk::TreeModel::iterator it = m_refTreeModel->get_iter(v[i]);          int i = 0;
1122          Gtk::TreeModel::Row row = *it;          Children selection = m_refOrderModel->children();
1123          Glib::ustring name = row[m_columns.m_col_name];          for (Children::iterator it = selection.begin();
1124          gig::Instrument* instrument = row[m_columns.m_col_instr];               it != selection.end(); ++it, ++i)
1125          #if DEBUG_COMBINE_INSTRUMENTS          {
1126          printf("Selection '%s' 0x%lx\n\n", name.c_str(), int64_t((void*)instrument));              Gtk::TreeModel::Row row = *it;
1127          #endif              Glib::ustring name = row[m_orderColumns.m_col_name];
1128          instruments.push_back(instrument);              gig::Instrument* instrument = row[m_orderColumns.m_col_instr];
1129                #if DEBUG_COMBINE_INSTRUMENTS
1130                printf("Selection %d. '%s' %p\n\n", (i+1), name.c_str(), instrument));
1131                #endif
1132                instruments.push_back(instrument);
1133            }
1134      }      }
1135    
1136      g_warnings.clear();      g_warnings.clear();
# Line 947  void CombineInstrumentsDialog::combineSe Line 1147  void CombineInstrumentsDialog::combineSe
1147              mainDimension = static_cast<gig::dimension_t>(iTypeID);              mainDimension = static_cast<gig::dimension_t>(iTypeID);
1148          }          }
1149    
1150          // now start the actual cobination task ...          // now start the actual combination task ...
1151          combineInstruments(instruments, m_gig, m_newCombinedInstrument, mainDimension);          combineInstruments(instruments, m_gig, m_newCombinedInstrument, mainDimension);
1152      } catch (RIFF::Exception e) {;      } catch (RIFF::Exception e) {;
1153          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 1187  void CombineInstrumentsDialog::combineSe
1187  void CombineInstrumentsDialog::onSelectionChanged() {  void CombineInstrumentsDialog::onSelectionChanged() {
1188      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();
1189      m_OKButton.set_sensitive(v.size() >= 2);      m_OKButton.set_sensitive(v.size() >= 2);
1190    
1191        typedef Gtk::TreeModel::Children Children;
1192    
1193        // update horizontal selection list (icon view) ...
1194    
1195        // remove items which are not part of the new selection anymore
1196        {
1197            Children allOrdered = m_refOrderModel->children();
1198            for (Children::iterator itOrder = allOrdered.begin();
1199                 itOrder != allOrdered.end(); ++itOrder)
1200            {
1201                Gtk::TreeModel::Row rowOrder = *itOrder;
1202                gig::Instrument* instr = rowOrder[m_orderColumns.m_col_instr];
1203                for (uint i = 0; i < v.size(); ++i) {
1204                    Gtk::TreeModel::iterator itSel = m_refTreeModel->get_iter(v[i]);
1205                    Gtk::TreeModel::Row rowSel = *itSel;
1206                    if (rowSel[m_columns.m_col_instr] == instr)
1207                        goto nextOrderedItem;
1208                }
1209                goto removeOrderedItem;
1210            nextOrderedItem:
1211                continue;
1212            removeOrderedItem:
1213                m_refOrderModel->erase(itOrder);
1214            }
1215        }
1216    
1217        // add items newly added to the selection
1218        for (uint i = 0; i < v.size(); ++i) {
1219            Gtk::TreeModel::iterator itSel = m_refTreeModel->get_iter(v[i]);
1220            Gtk::TreeModel::Row rowSel = *itSel;
1221            gig::Instrument* instr = rowSel[m_columns.m_col_instr];
1222            Children allOrdered = m_refOrderModel->children();
1223            for (Children::iterator itOrder = allOrdered.begin();
1224                 itOrder != allOrdered.end(); ++itOrder)
1225            {
1226                Gtk::TreeModel::Row rowOrder = *itOrder;
1227                if (rowOrder[m_orderColumns.m_col_instr] == instr)
1228                    goto nextSelectionItem;
1229            }
1230            goto addNewSelectionItem;
1231        nextSelectionItem:
1232            continue;
1233        addNewSelectionItem:
1234            Glib::ustring name = gig_to_utf8(instr->pInfo->Name);
1235            Gtk::TreeModel::iterator iterOrder = m_refOrderModel->append();
1236            Gtk::TreeModel::Row rowOrder = *iterOrder;
1237            rowOrder[m_orderColumns.m_col_name] = name;
1238            rowOrder[m_orderColumns.m_col_instr] = instr;
1239        }
1240    
1241        // update markup
1242        {
1243            int i = 0;
1244            Children allOrdered = m_refOrderModel->children();
1245            for (Children::iterator itOrder = allOrdered.begin();
1246                 itOrder != allOrdered.end(); ++itOrder, ++i)
1247            {
1248                Gtk::TreeModel::Row rowOrder = *itOrder;
1249                Glib::ustring name = rowOrder[m_orderColumns.m_col_name];
1250                Glib::ustring markup =
1251                    "<span foreground='black' background='white'>" + ToString(i+1) + ".</span>\n<span foreground='green' background='white'>" + name + "</span>";
1252                rowOrder[m_orderColumns.m_col_markup] = markup;
1253            }
1254        }
1255    }
1256    
1257    void CombineInstrumentsDialog::on_show_tooltips_changed() {
1258        const bool b = Settings::singleton()->showTooltips;
1259    
1260        m_treeView.set_has_tooltip(b);
1261        m_iconView.set_has_tooltip(b);
1262    
1263        set_has_tooltip(b);
1264  }  }
1265    
1266  bool CombineInstrumentsDialog::fileWasChanged() const {  bool CombineInstrumentsDialog::fileWasChanged() const {

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

  ViewVC Help
Powered by ViewVC