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

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

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

revision 1088 by persson, Sat Mar 10 08:16:38 2007 UTC revision 1100 by persson, Sat Mar 17 09:20:19 2007 UTC
# Line 20  Line 20 
20  #include <libintl.h>  #include <libintl.h>
21  #include <iostream>  #include <iostream>
22    
 #include "mainwindow.h"  
   
23  #include <gtkmm/filechooserdialog.h>  #include <gtkmm/filechooserdialog.h>
24    #include <gtkmm/messagedialog.h>
25  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
26    #include <gtkmm/targetentry.h>
27    
28  #if GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6  #if GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6
29  #define ABOUT_DIALOG  #define ABOUT_DIALOG
30  #include <gtkmm/aboutdialog.h>  #include <gtkmm/aboutdialog.h>
 #include <gtkmm/messagedialog.h>  
31  #endif  #endif
32    
33  #include <stdio.h>  #include <stdio.h>
34  #include <sndfile.h>  #include <sndfile.h>
35    
36    #include "mainwindow.h"
37    
38  #define _(String) gettext(String)  #define _(String) gettext(String)
39    
40  template<class T> inline std::string ToString(T o) {  template<class T> inline std::string ToString(T o) {
# Line 41  template<class T> inline std::string ToS Line 43  template<class T> inline std::string ToS
43      return ss.str();      return ss.str();
44  }  }
45    
46  bool update_gui;  MainWindow::MainWindow()
   
 uint8_t& access_UnityNote(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->UnityNote;  
 }  
 int16_t& access_FineTune(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->FineTune;  
 }  
 uint32_t& access_SampleLoops(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->SampleLoops;  
 }  
 uint8_t& access_Crossfade_in_start(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->Crossfade.in_start;  
 }  
 uint8_t& access_Crossfade_in_end(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->Crossfade.in_end;  
 }  
 uint8_t& access_Crossfade_out_start(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->Crossfade.out_start;  
 }  
 uint8_t& access_Crossfade_out_end(gig::DimensionRegion* dimreg)  
 {  
     return dimreg->Crossfade.out_end;  
 }  
   
 namespace {  
     const char* const controlChangeTexts[] = {  
         "none", "channelaftertouch", "velocity",  
         0,  
         "modwheel", // "Modulation Wheel or Lever",  
         "breath", // "Breath Controller",  
         0,  
         "foot", // "Foot Controller",  
         "portamentotime", // "Portamento Time",  
         0, 0, 0, 0, 0, 0,  
         "effect1", // "Effect Control 1",  
         "effect2", // "Effect Control 2",  
         0, 0,  
         "genpurpose1", // "General Purpose Controller 1",  
         "genpurpose2", // "General Purpose Controller 2",  
         "genpurpose3", // "General Purpose Controller 3",  
         "genpurpose4", // "General Purpose Controller 4",  
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
         0, 0, 0, 0, 0, 0,  
         "sustainpedal", // "Damper Pedal on/off (Sustain)",  
         "portamento", // "Portamento On/Off",  
         "sostenuto", // "Sustenuto On/Off",  
         "softpedal", // "Soft Pedal On/Off",  
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
         "genpurpose5", // "General Purpose Controller 5",  
         "genpurpose6", // "General Purpose Controller 6",  
         "genpurpose7", // "General Purpose Controller 7",  
         "genpurpose8", // "General Purpose Controller 8",  
         0, 0, 0, 0, 0, 0, 0,  
         "effect1depth", // "Effects 1 Depth",  
         "effect2depth", // "Effects 2 Depth",  
         "effect3depth", // "Effects 3 Depth",  
         "effect4depth", // "Effects 4 Depth",  
         "effect5depth", // "Effects 5 Depth"  
     };  
 }  
   
 void MainWindow::addString(char* labelText, Gtk::Label*& label,  
                            Gtk::Entry*& widget)  
 {  
     label = new Gtk::Label(Glib::ustring(labelText) + ":");  
     label->set_alignment(Gtk::ALIGN_LEFT);  
   
     table[pageno]->attach(*label, 1, 2, rowno, rowno + 1,  
                           Gtk::FILL, Gtk::SHRINK);  
   
     widget = new Gtk::Entry();  
   
     table[pageno]->attach(*widget, 2, 3, rowno, rowno + 1,  
                           Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);  
   
     rowno++;  
 }  
   
 LabelWidget::LabelWidget(char* labelText, Gtk::Widget& widget) :  
     label(Glib::ustring(labelText) + ":"),  
     widget(widget)  
 {  
     label.set_alignment(Gtk::ALIGN_LEFT);  
 }  
   
 void LabelWidget::set_sensitive(bool sensitive)  
 {  
     label.set_sensitive(sensitive);  
     widget.set_sensitive(sensitive);  
 }  
   
 NumEntryGain::NumEntryGain(char* labelText,  
                            double lower = 0, double upper = 127,  
                            int decimals = 0) :  
     NumEntry<gig::DimensionRegion>(labelText, lower, upper, decimals)  
 {  
     spinbutton.signal_value_changed().connect(  
         sigc::mem_fun(*this, &NumEntryGain::value_changed));  
 }  
   
 void NumEntryGain::value_changed()  
 {  
     if (dimreg && update_gui) {  
       dimreg->Gain = int32_t(spinbutton.get_value() * -655360.0);  
     }  
 }  
   
 void NumEntryGain::set_dimreg(gig::DimensionRegion* dimreg)  
 {  
     this->dimreg = 0;  
     set_value(dimreg->Gain / -655360.0);  
     this->dimreg = dimreg;  
 }  
   
   
 NumEntryPermille::NumEntryPermille(char* labelText,  
                                    uint16_t gig::DimensionRegion::* param,  
                                    double lower, double upper, int decimals) :  
     NumEntry<gig::DimensionRegion>(labelText, lower, upper, decimals),  
     param(param)  
 {  
     spinbutton.signal_value_changed().connect(  
         sigc::mem_fun(*this, &NumEntryPermille::value_changed));  
 }  
   
 void NumEntryPermille::value_changed()  
 {  
     if (dimreg && update_gui) {  
         dimreg->*param = uint16_t(spinbutton.get_value() * 10 + 0.5);  
     }  
 }  
   
 void NumEntryPermille::set_dimreg(gig::DimensionRegion* dimreg)  
 {  
     this->dimreg = 0;  
     set_value(dimreg->*param / 10.0);  
     this->dimreg = dimreg;  
 }  
   
   
 NoteEntry::NoteEntry(char* labelText, uint8_t& (*access)(gig::DimensionRegion*)) :  
     NumEntryX<uint8_t>(labelText, access)  
 {  
     spinbutton.signal_input().connect(  
         sigc::mem_fun(*this, &NoteEntry::on_input));  
     spinbutton.signal_output().connect(  
         sigc::mem_fun(*this, &NoteEntry::on_output));  
 }  
   
 const char* notes[] = {  
     "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"  
 };  
   
   
 // Convert the Entry text to a number  
 int NoteEntry::on_input(double* new_value)  
 {  
     const char* str = spinbutton.get_text().c_str();  
   
     int i;  
     for (i = 11 ; i >= 0 ; i--) {  
         if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;  
     }  
     if (i >= 0) {  
         char* endptr;  
         long x = strtol(str + strlen(notes[i]), &endptr, 10);  
         if (endptr != str + strlen(notes[i])) {  
             *new_value = i + (x + 1) * 12;  
             return true;  
         }  
     }  
     return Gtk::INPUT_ERROR;  
 }  
   
 // Convert the Adjustment position to text  
 bool NoteEntry::on_output()  
 {  
     int x = int(spinbutton.get_adjustment()->get_value());  
     char buf[10];  
     sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);  
     spinbutton.set_text(buf);  
     return true;  
 }  
   
 BoolEntry::BoolEntry(char* labelText, bool gig::DimensionRegion::* param) :  
     LabelWidget(labelText, checkbutton),  
     param(param)  
 {  
     checkbutton.signal_toggled().connect(  
         sigc::mem_fun(*this, &BoolEntry::value_changed));  
 }  
   
 void BoolEntry::value_changed()  
 {  
     if (dimreg && update_gui) {  
         dimreg->*param = checkbutton.get_active();  
     }  
 }  
   
 void BoolEntry::set_dimreg(gig::DimensionRegion* dimreg)  
 {  
     this->dimreg = 0;  
     checkbutton.set_active(dimreg->*param);  
     this->dimreg = dimreg;  
 }  
   
 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(  
     char* labelText,  
     gig::leverage_ctrl_t gig::DimensionRegion::* param) :  
     align(0, 0, 0, 0),  
     LabelWidget(labelText, align),  
     param(param)  
 {  
     for (int i = 0 ; i < 99 ; i++) {  
         if (controlChangeTexts[i]) {  
             combobox.append_text(controlChangeTexts[i]);  
         }  
     }  
     combobox.signal_changed().connect(  
         sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));  
     align.add(combobox);  
 }  
   
 void ChoiceEntryLeverageCtrl::value_changed()  
 {  
     if (dimreg && update_gui) {  
         int rowno = combobox.get_active_row_number();  
         switch (rowno)  
         {  
         case -1:  
             break;  
         case 0:  
             (dimreg->*param).type = gig::leverage_ctrl_t::type_none;  
             break;  
         case 1:  
             (dimreg->*param).type =  
                 gig::leverage_ctrl_t::type_channelaftertouch;  
             break;  
         case 2:  
             (dimreg->*param).type = gig::leverage_ctrl_t::type_velocity;  
             break;  
         default:  
             (dimreg->*param).type = gig::leverage_ctrl_t::type_controlchange;  
             int x = 3;  
             for (int cc = 0 ; cc < 96 ; cc++) {  
                 if (controlChangeTexts[cc + 3]) {  
                     if (rowno == x) {  
                         (dimreg->*param).controller_number = cc;  
                         break;  
                     }  
                     x++;  
                 }  
             }  
             break;  
         }  
     }  
 }  
   
 void ChoiceEntryLeverageCtrl::set_dimreg(gig::DimensionRegion* dimreg)  
 {  
     this->dimreg = 0;  
     gig::leverage_ctrl_t c = dimreg->*param;  
     int x;  
     switch (c.type)  
     {  
     case gig::leverage_ctrl_t::type_none:  
         x = 0;  
         break;  
     case gig::leverage_ctrl_t::type_channelaftertouch:  
         x = 1;  
         break;  
     case gig::leverage_ctrl_t::type_velocity:  
         x = 2;  
         break;  
     case gig::leverage_ctrl_t::type_controlchange:  
         x = -1;  
         for (int cc = 0 ; cc < 96 ; cc++) {  
             if (controlChangeTexts[cc + 3]) {  
                 x++;  
                 if (c.controller_number == cc) {  
                     x += 3;  
                     break;  
                 }  
             }  
         }  
         break;  
     default:  
         x = -1;  
         break;  
     }  
     combobox.set_active(x);  
     this->dimreg = dimreg;  
 }  
   
 void MainWindow::addHeader(char* text)  
 {  
     if (firstRowInBlock < rowno - 1)  
     {  
         Gtk::Label* filler = new Gtk::Label("    ");  
         table[pageno]->attach(*filler, 0, 1, firstRowInBlock, rowno,  
                               Gtk::FILL, Gtk::SHRINK);  
     }  
     Glib::ustring str = "<b>";  
     str += text;  
     str += "</b>";  
     Gtk::Label* label = new Gtk::Label(str);  
     label->set_use_markup();  
     label->set_alignment(Gtk::ALIGN_LEFT);  
     table[pageno]->attach(*label, 0, 3, rowno, rowno + 1,  
                           Gtk::FILL, Gtk::SHRINK);  
     rowno++;  
     firstRowInBlock = rowno;  
 }  
   
 void MainWindow::nextPage()  
 {  
     if (firstRowInBlock < rowno - 1)  
     {  
         Gtk::Label* filler = new Gtk::Label("    ");  
         table[pageno]->attach(*filler, 0, 1, firstRowInBlock, rowno,  
                               Gtk::FILL, Gtk::SHRINK);  
     }  
     pageno++;  
     rowno = 0;  
     firstRowInBlock = 0;  
 }  
   
 void MainWindow::addProp(LabelWidget& prop)  
 {  
     table[pageno]->attach(prop.label, 1, 2, rowno, rowno + 1,  
                           Gtk::FILL, Gtk::SHRINK);  
     table[pageno]->attach(prop.widget, 2, 3, rowno, rowno + 1,  
                           Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);  
     rowno++;  
 }  
   
   
   
   
 MainWindow::MainWindow() :  
 //    eSample("Sample", wSample),  
     eVelocityUpperLimit("VelocityUpperLimit",  
                         &gig::DimensionRegion::VelocityUpperLimit),  
     eEG1PreAttack("PreAttack", &gig::DimensionRegion::EG1PreAttack, 0, 100, 2),  
     eEG1Attack("Attack", &gig::DimensionRegion::EG1Attack, 0, 60, 3),  
     eEG1Decay1("Decay1", &gig::DimensionRegion::EG1Decay1, 0.005, 60, 3),  
     eEG1Decay2("Decay2", &gig::DimensionRegion::EG1Decay2, 0, 60, 3),  
     eEG1InfiniteSustain("InfiniteSustain",  
                         &gig::DimensionRegion::EG1InfiniteSustain),  
     eEG1Sustain("Sustain", &gig::DimensionRegion::EG1Sustain, 0, 100, 2),  
     eEG1Release("Release", &gig::DimensionRegion::EG1Release, 0, 60, 3),  
     eEG1Hold("Hold", &gig::DimensionRegion::EG1Hold),  
     eEG1Controller("Controller", &gig::DimensionRegion::EG1Controller),  
     eEG1ControllerInvert("ControllerInvert",  
                          &gig::DimensionRegion::EG1ControllerInvert),  
     eEG1ControllerAttackInfluence("ControllerAttackInfluence",  
                                   &gig::DimensionRegion::EG1ControllerAttackInfluence,  
                                   0, 3),  
     eEG1ControllerDecayInfluence("ControllerDecayInfluence",  
                                  &gig::DimensionRegion::EG1ControllerDecayInfluence,  
                                  0, 3),  
     eEG1ControllerReleaseInfluence("ControllerReleaseInfluence",  
                                    &gig::DimensionRegion::EG1ControllerReleaseInfluence,  
                                    0, 3),  
     eLFO1Frequency("Frequency", &gig::DimensionRegion::LFO1Frequency,  
                    0.1, 10, 2),  
     eLFO1InternalDepth("InternalDepth",  
                        &gig::DimensionRegion::LFO1InternalDepth, 0, 1200),  
     eLFO1ControlDepth("ControlDepth", &gig::DimensionRegion::LFO1ControlDepth,  
                       0, 1200),  
     eLFO1Controller("Controller", &gig::DimensionRegion::LFO1Controller),  
     eLFO1FlipPhase("FlipPhase", &gig::DimensionRegion::LFO1FlipPhase),  
     eLFO1Sync("Sync", &gig::DimensionRegion::LFO1Sync),  
     eEG2PreAttack("PreAttack", &gig::DimensionRegion::EG2PreAttack, 0, 100, 2),  
     eEG2Attack("Attack", &gig::DimensionRegion::EG2Attack, 0, 60, 3),  
     eEG2Decay1("Decay1", &gig::DimensionRegion::EG2Decay1, 0.005, 60, 3),  
     eEG2Decay2("Decay2", &gig::DimensionRegion::EG2Decay2, 0, 60, 3),  
     eEG2InfiniteSustain("InfiniteSustain",  
                         &gig::DimensionRegion::EG2InfiniteSustain),  
     eEG2Sustain("Sustain", &gig::DimensionRegion::EG2Sustain, 0, 100, 2),  
     eEG2Release("Release", &gig::DimensionRegion::EG2Release, 0, 60, 3),  
     eEG2Controller("Controller", &gig::DimensionRegion::EG2Controller),  
     eEG2ControllerInvert("ControllerInvert",  
                          &gig::DimensionRegion::EG2ControllerInvert),  
     eEG2ControllerAttackInfluence("ControllerAttackInfluence",  
                                   &gig::DimensionRegion::EG2ControllerAttackInfluence,  
                                   0, 3),  
     eEG2ControllerDecayInfluence("ControllerDecayInfluence",  
                                  &gig::DimensionRegion::EG2ControllerDecayInfluence,  
                                  0, 3),  
     eEG2ControllerReleaseInfluence("ControllerReleaseInfluence",  
                                    &gig::DimensionRegion::EG2ControllerReleaseInfluence,  
                                    0, 3),  
     eLFO2Frequency("Frequency", &gig::DimensionRegion::LFO2Frequency,  
                    0.1, 10, 2),  
     eLFO2InternalDepth("InternalDepth",  
                        &gig::DimensionRegion::LFO2InternalDepth, 0, 1200),  
     eLFO2ControlDepth("ControlDepth",  
                       &gig::DimensionRegion::LFO2ControlDepth, 0, 1200),  
     eLFO2Controller("Controller", &gig::DimensionRegion::LFO2Controller),  
     eLFO2FlipPhase("FlipPhase", &gig::DimensionRegion::LFO2FlipPhase),  
     eLFO2Sync("Sync", &gig::DimensionRegion::LFO2Sync),  
     eEG3Attack("Attack", &gig::DimensionRegion::EG3Attack, 0, 10, 3),  
     eEG3Depth("Depth", &gig::DimensionRegion::EG3Depth, -1200, 1200),  
     eLFO3Frequency("Frequency", &gig::DimensionRegion::LFO3Frequency,  
                    0.1, 10, 2),  
     eLFO3InternalDepth("InternalDepth",  
                        &gig::DimensionRegion::LFO3InternalDepth, 0, 1200),  
     eLFO3ControlDepth("ControlDepth", &gig::DimensionRegion::LFO3ControlDepth,  
                       0, 1200),  
     eLFO3Controller("Controller", &gig::DimensionRegion::LFO3Controller),  
     eLFO3Sync("Sync", &gig::DimensionRegion::LFO3Sync),  
     eVCFEnabled("Enabled", &gig::DimensionRegion::VCFEnabled),  
     eVCFType("Type", &gig::DimensionRegion::VCFType),  
     eVCFCutoffController("CutoffController",  
                          &gig::DimensionRegion::VCFCutoffController),  
     eVCFCutoffControllerInvert("CutoffControllerInvert",  
                                &gig::DimensionRegion::VCFCutoffControllerInvert),  
     eVCFCutoff("Cutoff", &gig::DimensionRegion::VCFCutoff),  
     eVCFVelocityCurve("VelocityCurve", &gig::DimensionRegion::VCFVelocityCurve),  
     eVCFVelocityScale("VelocityScale", &gig::DimensionRegion::VCFVelocityScale),  
     eVCFVelocityDynamicRange("VelocityDynamicRange",  
                              &gig::DimensionRegion::VCFVelocityDynamicRange,  
                              0, 4),  
     eVCFResonance("Resonance", &gig::DimensionRegion::VCFResonance),  
     eVCFResonanceDynamic("ResonanceDynamic",  
                          &gig::DimensionRegion::VCFResonanceDynamic),  
     eVCFResonanceController("ResonanceController",  
                             &gig::DimensionRegion::VCFResonanceController),  
     eVCFKeyboardTracking("KeyboardTracking",  
                          &gig::DimensionRegion::VCFKeyboardTracking),  
     eVCFKeyboardTrackingBreakpoint("KeyboardTrackingBreakpoint",  
                                    &gig::DimensionRegion::VCFKeyboardTrackingBreakpoint),  
     eVelocityResponseCurve("VelocityResponseCurve",  
                            &gig::DimensionRegion::VelocityResponseCurve),  
     eVelocityResponseDepth("VelocityResponseDepth",  
                            &gig::DimensionRegion::VelocityResponseDepth, 0, 4),  
     eVelocityResponseCurveScaling("VelocityResponseCurveScaling",  
                                   &gig::DimensionRegion::VelocityResponseCurveScaling),  
     eReleaseVelocityResponseCurve("ReleaseVelocityResponseCurve",  
                                   &gig::DimensionRegion::ReleaseVelocityResponseCurve),  
     eReleaseVelocityResponseDepth("ReleaseVelocityResponseDepth",  
                                   &gig::DimensionRegion::ReleaseVelocityResponseDepth,  
                                   0, 4),  
     eReleaseTriggerDecay("ReleaseTriggerDecay",  
                          &gig::DimensionRegion::ReleaseTriggerDecay, 0, 8),  
     eCrossfade_in_start("Crossfade.in_start", &access_Crossfade_in_start),  
     eCrossfade_in_end("Crossfade.in_end", &access_Crossfade_in_end),  
     eCrossfade_out_start("Crossfade.out_start", &access_Crossfade_out_start),  
     eCrossfade_out_end("Crossfade.out_end", &access_Crossfade_out_end),  
     ePitchTrack("PitchTrack", &gig::DimensionRegion::PitchTrack),  
     eDimensionBypass("DimensionBypass", &gig::DimensionRegion::DimensionBypass),  
     ePan("Pan", &gig::DimensionRegion::Pan, -64, 63),  
     eSelfMask("SelfMask", &gig::DimensionRegion::SelfMask),  
     eAttenuationController("AttenuationController",  
                            &gig::DimensionRegion::AttenuationController),  
     eInvertAttenuationController("InvertAttenuationController",  
                                  &gig::DimensionRegion::InvertAttenuationController),  
     eAttenuationControllerThreshold("AttenuationControllerThreshold",  
                                     &gig::DimensionRegion::AttenuationControllerThreshold),  
     eChannelOffset("ChannelOffset", &gig::DimensionRegion::ChannelOffset, 0, 9),  
     eSustainDefeat("SustainDefeat", &gig::DimensionRegion::SustainDefeat),  
     eMSDecode("MSDecode", &gig::DimensionRegion::MSDecode),  
     eSampleStartOffset("SampleStartOffset",  
                        &gig::DimensionRegion::SampleStartOffset, 0, 2000),  
     eUnityNote("UnityNote", &access_UnityNote),  
     eFineTune("FineTune", &access_FineTune, -49, 50),  
     eGain("Gain", -96, 0, 2),  
     eSampleLoops("SampleLoops", &access_SampleLoops, 0, 1)  
47  {  {
48  //    set_border_width(5);  //    set_border_width(5);
49  //    set_default_size(400, 200);  //    set_default_size(400, 200);
# Line 530  MainWindow::MainWindow() : Line 56  MainWindow::MainWindow() :
56      tree_sel_ref->signal_changed().connect(      tree_sel_ref->signal_changed().connect(
57          sigc::mem_fun(*this, &MainWindow::on_sel_change));          sigc::mem_fun(*this, &MainWindow::on_sel_change));
58    
59        // m_TreeView.set_reorderable();
60    
61      m_TreeView.signal_button_press_event().connect_notify(      m_TreeView.signal_button_press_event().connect_notify(
62          sigc::mem_fun(*this, &MainWindow::on_button_release));          sigc::mem_fun(*this, &MainWindow::on_button_release));
63    
# Line 542  MainWindow::MainWindow() : Line 70  MainWindow::MainWindow() :
70      m_ScrolledWindowSamples.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);      m_ScrolledWindowSamples.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
71    
72    
     for (int i = 0 ; i < 5 ; i++) {  
         table[i] = new Gtk::Table(3, 1);  
         table[i]->set_col_spacings(5);  
     }  
   
     pageno = 0;  
     rowno = 0;  
     firstRowInBlock = 0;  
   
     addString("Sample", lSample, wSample);  
     addProp(eVelocityUpperLimit);  
     addHeader("EG1");  
     addProp(eEG1PreAttack);  
     addProp(eEG1Attack);  
     addProp(eEG1Decay1);  
     addProp(eEG1Decay2);  
     addProp(eEG1InfiniteSustain);  
     addProp(eEG1Sustain);  
     addProp(eEG1Release);  
     addProp(eEG1Hold);  
     addProp(eEG1Controller);  
     addProp(eEG1ControllerInvert);  
     addProp(eEG1ControllerAttackInfluence);  
     addProp(eEG1ControllerDecayInfluence);  
     addProp(eEG1ControllerReleaseInfluence);  
     addHeader("LFO1");  
     addProp(eLFO1Frequency);  
     addProp(eLFO1InternalDepth);  
     addProp(eLFO1ControlDepth);  
     {  
         char* choices[] = { "internal", "modwheel", "breath",  
                             "internal+modwheel", "internal+breath", 0 };  
         static const gig::lfo1_ctrl_t values[] = {  
             gig::lfo1_ctrl_internal,  
             gig::lfo1_ctrl_modwheel,  
             gig::lfo1_ctrl_breath,  
             gig::lfo1_ctrl_internal_modwheel,  
             gig::lfo1_ctrl_internal_breath  
         };  
         eLFO1Controller.set_choices(choices, values);  
     }  
     addProp(eLFO1Controller);  
     addProp(eLFO1FlipPhase);  
     addProp(eLFO1Sync);  
   
     nextPage();  
     addHeader("EG2");  
     addProp(eEG2PreAttack);  
     addProp(eEG2Attack);  
     addProp(eEG2Decay1);  
     addProp(eEG2Decay2);  
     addProp(eEG2InfiniteSustain);  
     addProp(eEG2Sustain);  
     addProp(eEG2Release);  
     addProp(eEG2Controller);  
     addProp(eEG2ControllerInvert);  
     addProp(eEG2ControllerAttackInfluence);  
     addProp(eEG2ControllerDecayInfluence);  
     addProp(eEG2ControllerReleaseInfluence);  
     addHeader("LFO2");  
     addProp(eLFO2Frequency);  
     addProp(eLFO2InternalDepth);  
     addProp(eLFO2ControlDepth);  
     {  
         char* choices[] = { "internal", "modwheel", "foot",  
                             "internal+modwheel", "internal+foot", 0 };  
         static const gig::lfo2_ctrl_t values[] = {  
             gig::lfo2_ctrl_internal,  
             gig::lfo2_ctrl_modwheel,  
             gig::lfo2_ctrl_foot,  
             gig::lfo2_ctrl_internal_modwheel,  
             gig::lfo2_ctrl_internal_foot  
         };  
         eLFO2Controller.set_choices(choices, values);  
     }  
     addProp(eLFO2Controller);  
     addProp(eLFO2FlipPhase);  
     addProp(eLFO2Sync);  
   
     nextPage();  
   
     addHeader("EG3");  
     addProp(eEG3Attack);  
     addProp(eEG3Depth);  
     addHeader("LFO3");  
     addProp(eLFO3Frequency);  
     addProp(eLFO3InternalDepth);  
     addProp(eLFO3ControlDepth);  
     {  
         char* choices[] = { "internal", "modwheel", "aftertouch",  
                             "internal+modwheel", "internal+aftertouch", 0 };  
         static const gig::lfo3_ctrl_t values[] = {  
             gig::lfo3_ctrl_internal,  
             gig::lfo3_ctrl_modwheel,  
             gig::lfo3_ctrl_aftertouch,  
             gig::lfo3_ctrl_internal_modwheel,  
             gig::lfo3_ctrl_internal_aftertouch  
         };  
         eLFO3Controller.set_choices(choices, values);  
     }  
     addProp(eLFO3Controller);  
     addProp(eLFO3Sync);  
     addHeader("VCF");  
     addProp(eVCFEnabled);  
     {  
         char* choices[] = { "lowpass", "lowpassturbo", "bandpass",  
                             "highpass", "bandreject", 0 };  
         static const gig::vcf_type_t values[] = {  
             gig::vcf_type_lowpass,  
             gig::vcf_type_lowpassturbo,  
             gig::vcf_type_bandpass,  
             gig::vcf_type_highpass,  
             gig::vcf_type_bandreject  
         };  
         eVCFType.set_choices(choices, values);  
     }  
     addProp(eVCFType);  
     {  
         char* choices[] = { "none", "none2", "modwheel", "effect1", "effect2",  
                             "breath", "foot", "sustainpedal", "softpedal",  
                             "genpurpose7", "genpurpose8", "aftertouch", 0 };  
         static const gig::vcf_cutoff_ctrl_t values[] = {  
             gig::vcf_cutoff_ctrl_none,  
             gig::vcf_cutoff_ctrl_none2,  
             gig::vcf_cutoff_ctrl_modwheel,  
             gig::vcf_cutoff_ctrl_effect1,  
             gig::vcf_cutoff_ctrl_effect2,  
             gig::vcf_cutoff_ctrl_breath,  
             gig::vcf_cutoff_ctrl_foot,  
             gig::vcf_cutoff_ctrl_sustainpedal,  
             gig::vcf_cutoff_ctrl_softpedal,  
             gig::vcf_cutoff_ctrl_genpurpose7,  
             gig::vcf_cutoff_ctrl_genpurpose8,  
             gig::vcf_cutoff_ctrl_aftertouch  
         };  
         eVCFCutoffController.set_choices(choices, values);  
     }  
     addProp(eVCFCutoffController);  
     addProp(eVCFCutoffControllerInvert);  
     addProp(eVCFCutoff);  
     char* curve_type_texts[] = { "nonlinear", "linear", "special", 0 };  
     static const gig::curve_type_t curve_type_values[] = {  
         gig::curve_type_nonlinear,  
         gig::curve_type_linear,  
         gig::curve_type_special  
     };  
     eVCFVelocityCurve.set_choices(curve_type_texts, curve_type_values);  
     addProp(eVCFVelocityCurve);  
     addProp(eVCFVelocityScale);  
     addProp(eVCFVelocityDynamicRange);  
     addProp(eVCFResonance);  
     addProp(eVCFResonanceDynamic);  
     {  
         char* choices[] = { "none", "genpurpose3", "genpurpose4",  
                             "genpurpose5", "genpurpose6", 0 };  
         static const gig::vcf_res_ctrl_t values[] = {  
             gig::vcf_res_ctrl_none,  
             gig::vcf_res_ctrl_genpurpose3,  
             gig::vcf_res_ctrl_genpurpose4,  
             gig::vcf_res_ctrl_genpurpose5,  
             gig::vcf_res_ctrl_genpurpose6  
         };  
         eVCFResonanceController.set_choices(choices, values);  
     }  
     addProp(eVCFResonanceController);  
     addProp(eVCFKeyboardTracking);  
     addProp(eVCFKeyboardTrackingBreakpoint);  
   
     nextPage();  
   
     eVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values);  
     addProp(eVelocityResponseCurve);  
     addProp(eVelocityResponseDepth);  
     addProp(eVelocityResponseCurveScaling);  
     eReleaseVelocityResponseCurve.set_choices(curve_type_texts,  
                                               curve_type_values);  
     addProp(eReleaseVelocityResponseCurve);  
     addProp(eReleaseVelocityResponseDepth);  
     addProp(eReleaseTriggerDecay);  
     addProp(eCrossfade_in_start);  
     addProp(eCrossfade_in_end);  
     addProp(eCrossfade_out_start);  
     addProp(eCrossfade_out_end);  
     addProp(ePitchTrack);  
     {  
         char* choices[] = { "none", "effect4depth", "effect5depth", 0 };  
         static const gig::dim_bypass_ctrl_t values[] = {  
             gig::dim_bypass_ctrl_none,  
             gig::dim_bypass_ctrl_94,  
             gig::dim_bypass_ctrl_95  
         };  
         eDimensionBypass.set_choices(choices, values);  
     }  
     addProp(eDimensionBypass);  
     addProp(ePan);  
     addProp(eSelfMask);  
     addProp(eAttenuationController);  
     addProp(eInvertAttenuationController);  
     addProp(eAttenuationControllerThreshold);  
     addProp(eChannelOffset);  
     addProp(eSustainDefeat);  
   
     nextPage();  
     addProp(eMSDecode);  
     addProp(eSampleStartOffset);  
     addProp(eUnityNote);  
     addProp(eFineTune);  
     addProp(eGain);  
     addProp(eSampleLoops);  
     nextPage();  
   
     eEG1InfiniteSustain.signal_toggled().connect(  
         sigc::mem_fun(*this, &MainWindow::EG1InfiniteSustain_toggled) );  
     eEG2InfiniteSustain.signal_toggled().connect(  
         sigc::mem_fun(*this, &MainWindow::EG2InfiniteSustain_toggled) );  
     eEG1Controller.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::EG1Controller_changed) );  
     eEG2Controller.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::EG2Controller_changed) );  
     eLFO1Controller.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::LFO1Controller_changed) );  
     eLFO2Controller.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::LFO2Controller_changed) );  
     eLFO3Controller.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::LFO3Controller_changed) );  
     eAttenuationController.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::AttenuationController_changed) );  
     eVCFEnabled.signal_toggled().connect(  
         sigc::mem_fun(*this, &MainWindow::VCFEnabled_toggled) );  
     eVCFCutoffController.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::VCFCutoffController_changed) );  
     eVCFResonanceController.signal_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::VCFResonanceController_changed) );  
   
     eCrossfade_in_start.signal_value_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::crossfade1_changed));  
     eCrossfade_in_end.signal_value_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::crossfade2_changed));  
     eCrossfade_out_start.signal_value_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::crossfade3_changed));  
     eCrossfade_out_end.signal_value_changed().connect(  
         sigc::mem_fun(*this, &MainWindow::crossfade4_changed));  
   
     //m_Notebook.append_page(m_ScrolledWindow2, "Table");  
     m_Notebook.append_page(*table[0], "EG1");  
     m_Notebook.append_page(*table[1], "EG2");  
     m_Notebook.append_page(*table[2], "EG3");  
     m_Notebook.append_page(*table[3], "Velocity");  
     m_Notebook.append_page(*table[4], "Misc");  
 //    m_Notebook.set_size_request(400, 500);  
   
73      m_TreeViewNotebook.set_size_request(300);      m_TreeViewNotebook.set_size_request(300);
74    
75      m_HPaned.add1(m_TreeViewNotebook);      m_HPaned.add1(m_TreeViewNotebook);
76      m_HPaned.add2(m_Notebook);      m_HPaned.add2(dimreg_edit);
77    
78    
79      m_TreeViewNotebook.append_page(m_ScrolledWindowSamples, "Samples");      m_TreeViewNotebook.append_page(m_ScrolledWindowSamples, "Samples");
# Line 831  MainWindow::MainWindow() : Line 109  MainWindow::MainWindow() :
109      actionGroup->add(Gtk::Action::create("InstrProperties",      actionGroup->add(Gtk::Action::create("InstrProperties",
110                                           Gtk::Stock::PROPERTIES),                                           Gtk::Stock::PROPERTIES),
111                       sigc::mem_fun(                       sigc::mem_fun(
112                           *this, &MainWindow::on_action_file_properties));                           *this, &MainWindow::show_instr_props));
113      actionGroup->add(Gtk::Action::create("Quit", Gtk::Stock::QUIT),      actionGroup->add(Gtk::Action::create("Quit", Gtk::Stock::QUIT),
114                       sigc::mem_fun(                       sigc::mem_fun(
115                           *this, &MainWindow::hide));                           *this, &MainWindow::hide));
# Line 925  MainWindow::MainWindow() : Line 203  MainWindow::MainWindow() :
203      // Create the Tree model:      // Create the Tree model:
204      m_refTreeModel = Gtk::ListStore::create(m_Columns);      m_refTreeModel = Gtk::ListStore::create(m_Columns);
205      m_TreeView.set_model(m_refTreeModel);      m_TreeView.set_model(m_refTreeModel);
206        m_refTreeModel->signal_row_changed().connect(
207            sigc::mem_fun(*this, &MainWindow::instrument_name_changed)
208        );
209    
210      // Add the TreeView's view columns:      // Add the TreeView's view columns:
211      m_TreeView.append_column("Instrument", m_Columns.m_col_name);      m_TreeView.append_column_editable("Instrument", m_Columns.m_col_name);
212      m_TreeView.set_headers_visible(false);      m_TreeView.set_headers_visible(false);
213    
214      // create samples treeview (including its data model)      // create samples treeview (including its data model)
215      m_refSamplesTreeModel = Gtk::TreeStore::create(m_SamplesModel);      m_refSamplesTreeModel = SamplesTreeStore::create(m_SamplesModel);
216      m_TreeViewSamples.set_model(m_refSamplesTreeModel);      m_TreeViewSamples.set_model(m_refSamplesTreeModel);
217      m_TreeViewSamples.append_column("Samples", m_SamplesModel.m_col_name);      // m_TreeViewSamples.set_reorderable();
218        m_TreeViewSamples.append_column_editable("Samples", m_SamplesModel.m_col_name);
219      m_TreeViewSamples.set_headers_visible(false);      m_TreeViewSamples.set_headers_visible(false);
220      m_TreeViewSamples.signal_button_press_event().connect_notify(      m_TreeViewSamples.signal_button_press_event().connect_notify(
221          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_button_release)          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_button_release)
222      );      );
223        m_refSamplesTreeModel->signal_row_changed().connect(
224            sigc::mem_fun(*this, &MainWindow::sample_name_changed)
225        );
226    
227        // establish drag&drop between samples tree view and dimension region 'Sample' text entry
228        std::list<Gtk::TargetEntry> drag_target_gig_sample;
229        drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );
230    //drag_target_gig_sample.push_back( Gtk::TargetEntry("STRING") );
231    //drag_target_gig_sample.push_back( Gtk::TargetEntry("text/plain") );
232        m_TreeViewSamples.drag_source_set(drag_target_gig_sample);
233        m_TreeViewSamples.signal_drag_data_get().connect(
234            sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)
235        );
236        dimreg_edit.wSample->drag_dest_set(drag_target_gig_sample);
237        dimreg_edit.wSample->signal_drag_data_received().connect(
238            sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)
239        );
240    
241      file = 0;      file = 0;
242    
# Line 955  void MainWindow::region_changed() Line 254  void MainWindow::region_changed()
254    
255  void MainWindow::dimreg_changed()  void MainWindow::dimreg_changed()
256  {  {
257      set_dim_region(m_DimRegionChooser.get_dimregion());      dimreg_edit.set_dim_region(m_DimRegionChooser.get_dimregion());
258  }  }
259    
260  void MainWindow::on_sel_change()  void MainWindow::on_sel_change()
# Line 973  void MainWindow::on_sel_change() Line 272  void MainWindow::on_sel_change()
272      }      }
273  }  }
274    
 void MainWindow::set_dim_region(gig::DimensionRegion* d)  
 {  
     update_gui = false;  
     wSample->set_text(d->pSample ? d->pSample->pInfo->Name.c_str() : "NULL");  
     eVelocityUpperLimit.set_dimreg(d);  
     eEG1PreAttack.set_dimreg(d);  
     eEG1Attack.set_dimreg(d);  
     eEG1Decay1.set_dimreg(d);  
     eEG1Decay2.set_dimreg(d);  
     eEG1InfiniteSustain.set_dimreg(d);  
     eEG1Sustain.set_dimreg(d);  
     eEG1Release.set_dimreg(d);  
     eEG1Hold.set_dimreg(d);  
     eEG1Controller.set_dimreg(d);  
     eEG1ControllerInvert.set_dimreg(d);  
     eEG1ControllerAttackInfluence.set_dimreg(d);  
     eEG1ControllerDecayInfluence.set_dimreg(d);  
     eEG1ControllerReleaseInfluence.set_dimreg(d);  
     eLFO1Frequency.set_dimreg(d);  
     eLFO1InternalDepth.set_dimreg(d);  
     eLFO1ControlDepth.set_dimreg(d);  
     eLFO1Controller.set_dimreg(d);  
     eLFO1FlipPhase.set_dimreg(d);  
     eLFO1Sync.set_dimreg(d);  
     eEG2PreAttack.set_dimreg(d);  
     eEG2Attack.set_dimreg(d);  
     eEG2Decay1.set_dimreg(d);  
     eEG2Decay2.set_dimreg(d);  
     eEG2InfiniteSustain.set_dimreg(d);  
     eEG2Sustain.set_dimreg(d);  
     eEG2Release.set_dimreg(d);  
     eEG2Controller.set_dimreg(d);  
     eEG2ControllerInvert.set_dimreg(d);  
     eEG2ControllerAttackInfluence.set_dimreg(d);  
     eEG2ControllerDecayInfluence.set_dimreg(d);  
     eEG2ControllerReleaseInfluence.set_dimreg(d);  
     eLFO2Frequency.set_dimreg(d);  
     eLFO2InternalDepth.set_dimreg(d);  
     eLFO2ControlDepth.set_dimreg(d);  
     eLFO2Controller.set_dimreg(d);  
     eLFO2FlipPhase.set_dimreg(d);  
     eLFO2Sync.set_dimreg(d);  
     eEG3Attack.set_dimreg(d);  
     eEG3Depth.set_dimreg(d);  
     eLFO3Frequency.set_dimreg(d);  
     eLFO3InternalDepth.set_dimreg(d);  
     eLFO3ControlDepth.set_dimreg(d);  
     eLFO3Controller.set_dimreg(d);  
     eLFO3Sync.set_dimreg(d);  
     eVCFEnabled.set_dimreg(d);  
     eVCFType.set_dimreg(d);  
     eVCFCutoffController.set_dimreg(d);  
     eVCFCutoffControllerInvert.set_dimreg(d);  
     eVCFCutoff.set_dimreg(d);  
     eVCFVelocityCurve.set_dimreg(d);  
     eVCFVelocityScale.set_dimreg(d);  
     eVCFVelocityDynamicRange.set_dimreg(d);  
     eVCFResonance.set_dimreg(d);  
     eVCFResonanceDynamic.set_dimreg(d);  
     eVCFResonanceController.set_dimreg(d);  
     eVCFKeyboardTracking.set_dimreg(d);  
     eVCFKeyboardTrackingBreakpoint.set_dimreg(d);  
     eVelocityResponseCurve.set_dimreg(d);  
     eVelocityResponseDepth.set_dimreg(d);  
     eVelocityResponseCurveScaling.set_dimreg(d);  
     eReleaseVelocityResponseCurve.set_dimreg(d);  
     eReleaseVelocityResponseDepth.set_dimreg(d);  
     eReleaseTriggerDecay.set_dimreg(d);  
     eCrossfade_in_start.set_dimreg(d);  
     eCrossfade_in_end.set_dimreg(d);  
     eCrossfade_out_start.set_dimreg(d);  
     eCrossfade_out_end.set_dimreg(d);  
     ePitchTrack.set_dimreg(d);  
     eDimensionBypass.set_dimreg(d);  
     ePan.set_dimreg(d);  
     eSelfMask.set_dimreg(d);  
     eAttenuationController.set_dimreg(d);  
     eInvertAttenuationController.set_dimreg(d);  
     eAttenuationControllerThreshold.set_dimreg(d);  
     eChannelOffset.set_dimreg(d);  
     eSustainDefeat.set_dimreg(d);  
     eMSDecode.set_dimreg(d);  
     eSampleStartOffset.set_dimreg(d);  
     eUnityNote.set_dimreg(d);  
     eFineTune.set_dimreg(d);  
     eGain.set_dimreg(d);  
     eSampleLoops.set_dimreg(d);  
   
     VCFEnabled_toggled();  
   
     update_gui = true;  
 }  
   
 void MainWindow::VCFEnabled_toggled()  
 {  
     bool sensitive = eVCFEnabled.get_active();  
     eVCFType.set_sensitive(sensitive);  
     eVCFCutoffController.set_sensitive(sensitive);  
     eVCFVelocityCurve.set_sensitive(sensitive);  
     eVCFVelocityScale.set_sensitive(sensitive);  
     eVCFVelocityDynamicRange.set_sensitive(sensitive);  
     eVCFResonance.set_sensitive(sensitive);  
     eVCFResonanceController.set_sensitive(sensitive);  
     eVCFKeyboardTracking.set_sensitive(sensitive);  
     eVCFKeyboardTrackingBreakpoint.set_sensitive(sensitive);  
     eEG2PreAttack.set_sensitive(sensitive);  
     eEG2Attack.set_sensitive(sensitive);  
     eEG2Decay1.set_sensitive(sensitive);  
     eEG2InfiniteSustain.set_sensitive(sensitive);  
     eEG2Sustain.set_sensitive(sensitive);  
     eEG2Release.set_sensitive(sensitive);  
     eEG2Controller.set_sensitive(sensitive);  
     eEG2ControllerAttackInfluence.set_sensitive(sensitive);  
     eEG2ControllerDecayInfluence.set_sensitive(sensitive);  
     eEG2ControllerReleaseInfluence.set_sensitive(sensitive);  
     eLFO2Frequency.set_sensitive(sensitive);  
     eLFO2InternalDepth.set_sensitive(sensitive);  
     eLFO2ControlDepth.set_sensitive(sensitive);  
     eLFO2Controller.set_sensitive(sensitive);  
     eLFO2FlipPhase.set_sensitive(sensitive);  
     eLFO2Sync.set_sensitive(sensitive);  
     if (sensitive) {  
         VCFCutoffController_changed();  
         VCFResonanceController_changed();  
         EG2InfiniteSustain_toggled();  
         EG2Controller_changed();  
         LFO2Controller_changed();  
     } else {  
         eVCFCutoffControllerInvert.set_sensitive(false);  
         eVCFCutoff.set_sensitive(false);  
         eVCFResonanceDynamic.set_sensitive(false);  
         eVCFResonance.set_sensitive(false);  
         eEG2Decay2.set_sensitive(false);  
         eEG2ControllerInvert.set_sensitive(false);  
         eLFO2InternalDepth.set_sensitive(false);  
         eLFO2ControlDepth.set_sensitive(false);  
     }  
 }  
   
 void MainWindow::VCFCutoffController_changed()  
 {  
     int rowno = eVCFCutoffController.get_active_row_number();  
     bool hasController = rowno != 0 && rowno != 1;  
   
     eVCFCutoffControllerInvert.set_sensitive(hasController);  
     eVCFCutoff.set_sensitive(!hasController);  
     eVCFResonanceDynamic.set_sensitive(!hasController);  
     eVCFVelocityScale.label.set_text(hasController ? "MinimumCutoff:" :  
                                      "VelocityScale:");  
 }  
   
 void MainWindow::VCFResonanceController_changed()  
 {  
     bool hasController = eVCFResonanceController.get_active_row_number() != 0;  
     eVCFResonance.set_sensitive(!hasController);  
 }  
   
 void MainWindow::EG1InfiniteSustain_toggled()  
 {  
     bool infSus = eEG1InfiniteSustain.get_active();  
     eEG1Decay2.set_sensitive(!infSus);  
 }  
   
 void MainWindow::EG2InfiniteSustain_toggled()  
 {  
     bool infSus = eEG2InfiniteSustain.get_active();  
     eEG2Decay2.set_sensitive(!infSus);  
 }  
   
 void MainWindow::EG1Controller_changed()  
 {  
     bool hasController = eEG1Controller.get_active_row_number() != 0;  
     eEG1ControllerInvert.set_sensitive(hasController);  
 }  
   
 void MainWindow::EG2Controller_changed()  
 {  
     bool hasController = eEG2Controller.get_active_row_number() != 0;  
     eEG2ControllerInvert.set_sensitive(hasController);  
 }  
   
 void MainWindow::AttenuationController_changed()  
 {  
     bool hasController = eAttenuationController.get_active_row_number() != 0;  
     eInvertAttenuationController.set_sensitive(hasController);  
 }  
   
 void MainWindow::LFO1Controller_changed()  
 {  
     int rowno = eLFO1Controller.get_active_row_number();  
     eLFO1ControlDepth.set_sensitive(rowno != 0);  
     eLFO1InternalDepth.set_sensitive(rowno != 1 && rowno != 2);  
 }  
   
 void MainWindow::LFO2Controller_changed()  
 {  
     int rowno = eLFO2Controller.get_active_row_number();  
     eLFO2ControlDepth.set_sensitive(rowno != 0);  
     eLFO2InternalDepth.set_sensitive(rowno != 1 && rowno != 2);  
 }  
   
 void MainWindow::LFO3Controller_changed()  
 {  
     int rowno = eLFO3Controller.get_active_row_number();  
     eLFO3ControlDepth.set_sensitive(rowno != 0);  
     eLFO3InternalDepth.set_sensitive(rowno != 1 && rowno != 2);  
 }  
   
 void MainWindow::crossfade1_changed()  
 {  
     double c1 = eCrossfade_in_start.get_value();  
     double c2 = eCrossfade_in_end.get_value();  
     if (c1 > c2) eCrossfade_in_end.set_value(c1);  
 }  
   
 void MainWindow::crossfade2_changed()  
 {  
     double c1 = eCrossfade_in_start.get_value();  
     double c2 = eCrossfade_in_end.get_value();  
     double c3 = eCrossfade_out_start.get_value();  
   
     if (c2 < c1) eCrossfade_in_start.set_value(c2);  
     if (c2 > c3) eCrossfade_out_start.set_value(c2);  
 }  
   
 void MainWindow::crossfade3_changed()  
 {  
     double c2 = eCrossfade_in_end.get_value();  
     double c3 = eCrossfade_out_start.get_value();  
     double c4 = eCrossfade_out_end.get_value();  
   
     if (c3 < c2) eCrossfade_in_end.set_value(c3);  
     if (c3 > c4) eCrossfade_out_end.set_value(c3);  
 }  
   
 void MainWindow::crossfade4_changed()  
 {  
     double c3 = eCrossfade_out_start.get_value();  
     double c4 = eCrossfade_out_end.get_value();  
   
     if (c4 < c3) eCrossfade_out_start.set_value(c4);  
 }  
   
275  void loader_progress_callback(gig::progress_t* progress)  void loader_progress_callback(gig::progress_t* progress)
276  {  {
277      Loader* loader = static_cast<Loader*>(progress->custom);      Loader* loader = static_cast<Loader*>(progress->custom);
# Line 1277  Glib::Dispatcher& Loader::signal_finishe Line 333  Glib::Dispatcher& Loader::signal_finishe
333      return finished_dispatcher;      return finished_dispatcher;
334  }  }
335    
336  LoadDialog::LoadDialog()  LoadDialog::LoadDialog(const Glib::ustring& title, Gtk::Window& parent)
337        : Gtk::Dialog(title, parent, true)
338  {  {
339      get_vbox()->pack_start(progressBar);      get_vbox()->pack_start(progressBar);
340      show_all_children();      show_all_children();
# Line 1313  void MainWindow::on_action_file_open() Line 370  void MainWindow::on_action_file_open()
370          m_refSamplesTreeModel->clear();          m_refSamplesTreeModel->clear();
371          if (file) delete file;          if (file) delete file;
372    
         // getInfo(dialog.get_filename().c_str(), *this);  
   
373          printf("on_action_file_open self=%x\n", Glib::Thread::self());          printf("on_action_file_open self=%x\n", Glib::Thread::self());
374          load_dialog = new LoadDialog(); // Gtk::Dialog("Loading...", *this, true);          load_file(dialog.get_filename().c_str());
         load_dialog->show_all();  
         loader = new Loader(strdup(dialog.get_filename().c_str()));  
         loader->signal_progress().connect(  
             sigc::mem_fun(*this, &MainWindow::on_loader_progress));  
         loader->signal_finished().connect(  
             sigc::mem_fun(*this, &MainWindow::on_loader_finished));  
   
         loader->launch();  
375      }      }
376  }  }
377    
378    void MainWindow::load_file(const char* name)
379    {
380        load_dialog = new LoadDialog("Loading...", *this);
381        load_dialog->show_all();
382        loader = new Loader(strdup(name));
383        loader->signal_progress().connect(
384            sigc::mem_fun(*this, &MainWindow::on_loader_progress));
385        loader->signal_finished().connect(
386            sigc::mem_fun(*this, &MainWindow::on_loader_finished));
387        loader->launch();
388    }
389    
390  void MainWindow::on_loader_progress()  void MainWindow::on_loader_progress()
391  {  {
392      load_dialog->set_fraction(loader->get_progress());      load_dialog->set_fraction(loader->get_progress());
# Line 1349  void MainWindow::on_loader_finished() Line 408  void MainWindow::on_loader_finished()
408  void MainWindow::on_action_file_save()  void MainWindow::on_action_file_save()
409  {  {
410      if (!file) return;      if (!file) return;
411      file->Save();      std::cout << "Saving file\n" << std::flush;
412        try {
413            file->Save();
414        } catch (RIFF::Exception e) {
415            Glib::ustring txt = "Could not save file: " + e.Message;
416            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
417            msg.run();
418            return;
419        }
420        std::cout << "Saving file done\n" << std::flush;
421      __import_queued_samples();      __import_queued_samples();
422  }  }
423    
# Line 1364  void MainWindow::on_action_file_save_as( Line 432  void MainWindow::on_action_file_save_as(
432      dialog.set_filter(filter);      dialog.set_filter(filter);
433      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
434          printf("filename=%s\n", dialog.get_filename().c_str());          printf("filename=%s\n", dialog.get_filename().c_str());
435          file->Save(dialog.get_filename());          try {
436                file->Save(dialog.get_filename());
437            } catch (RIFF::Exception e) {
438                Glib::ustring txt = "Could not save file: " + e.Message;
439                Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
440                msg.run();
441                return;
442            }
443          __import_queued_samples();          __import_queued_samples();
444      }      }
445  }  }
446    
447  // actually write the sample(s)' data to the gig file  // actually write the sample(s)' data to the gig file
448  void MainWindow::__import_queued_samples() {  void MainWindow::__import_queued_samples() {
449        std::cout << "Starting sample import\n" << std::flush;
450      Glib::ustring error_files;      Glib::ustring error_files;
451      for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin(); iter != m_SampleImportQueue.end(); ++iter) {      printf("Samples to import: %d\n", m_SampleImportQueue.size());
452        for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
453             iter != m_SampleImportQueue.end(); ) {
454          printf("Importing sample %s\n",(*iter).sample_path.c_str());          printf("Importing sample %s\n",(*iter).sample_path.c_str());
455          SF_INFO info;          SF_INFO info;
456          info.format = 0;          info.format = 0;
# Line 1407  void MainWindow::__import_queued_samples Line 485  void MainWindow::__import_queued_samples
485                      sf_close(hFile); // close sound file                      sf_close(hFile); // close sound file
486                      throw std::string("format not supported"); // unsupported subformat (yet?)                      throw std::string("format not supported"); // unsupported subformat (yet?)
487              }              }
488              // allocate appropriate copy buffer (TODO: for now we copy it in one piece, might be tough for very long samples)              // allocate appropriate copy buffer (TODO: for now we copy
489                // it in one piece, might be tough for very long samples)
490              // and copy sample data into buffer              // and copy sample data into buffer
491              int8_t* buffer = NULL;              int8_t* buffer = NULL;
492              switch (bitdepth) {              switch (bitdepth) {
493                  case 16:                  case 16:
494                      buffer = new int8_t[2 * info.channels * info.frames];                      buffer = new int8_t[2 * info.channels * info.frames];
495                      sf_readf_short(hFile, (short*) buffer, info.frames); // libsndfile does the conversion for us (if needed)                      // libsndfile does the conversion for us (if needed)
496                        sf_readf_short(hFile, (short*) buffer, info.frames);
497                      break;                      break;
498                  case 32:                  case 32:
499                      buffer = new int8_t[4 * info.channels * info.frames];                      buffer = new int8_t[4 * info.channels * info.frames];
500                      sf_readf_int(hFile, (int*) buffer, info.frames); // libsndfile does the conversion for us (if needed)                      // libsndfile does the conversion for us (if needed)
501                        sf_readf_int(hFile, (int*) buffer, info.frames);
502                      break;                      break;
503              }              }
504              // write from buffer directly (physically) into .gig file              // write from buffer directly (physically) into .gig file
# Line 1425  void MainWindow::__import_queued_samples Line 506  void MainWindow::__import_queued_samples
506              // cleanup              // cleanup
507              sf_close(hFile);              sf_close(hFile);
508              delete buffer;              delete buffer;
509              // on success we remove the sample from the import queue, otherwise keep it, maybe it works the next time ?              // on success we remove the sample from the import queue,
510              m_SampleImportQueue.erase(iter);              // otherwise keep it, maybe it works the next time ?
511          } catch (std::string what) { // remember the files that made trouble (and their cause)              std::list<SampleImportItem>::iterator cur = iter;
512                ++iter;
513                m_SampleImportQueue.erase(cur);
514            } catch (std::string what) {
515                // remember the files that made trouble (and their cause)
516              if (error_files.size()) error_files += "\n";              if (error_files.size()) error_files += "\n";
517              error_files += (*iter).sample_path += " (" + what + ")";              error_files += (*iter).sample_path += " (" + what + ")";
518                ++iter;
519          }          }
520      }      }
521      // show error message box when some sample(s) could not be imported      // show error message box when some sample(s) could not be imported
# Line 1568  InstrumentProps::InstrumentProps() Line 654  InstrumentProps::InstrumentProps()
654      show_all_children();      show_all_children();
655  }  }
656    
657    extern char* notes[];
658    
659  void InstrumentProps::set_instrument(gig::Instrument* instrument)  void InstrumentProps::set_instrument(gig::Instrument* instrument)
660  {  {
# Line 1599  void InstrumentProps::set_instrument(gig Line 686  void InstrumentProps::set_instrument(gig
686      entry[entryIdx].set_text(buf);      entry[entryIdx].set_text(buf);
687  }  }
688    
 void MainWindow::getInfo(const char *filename)  
 {  
     RIFF::File* riff = new RIFF::File(filename);  
     gig::File* gig = new gig::File(riff);  
   
     load_gig(gig, filename);  
 }  
   
689  void MainWindow::load_gig(gig::File* gig, const char* filename)  void MainWindow::load_gig(gig::File* gig, const char* filename)
690  {  {
691      file = gig;      file = gig;
# Line 1630  void MainWindow::load_gig(gig::File* gig Line 709  void MainWindow::load_gig(gig::File* gig
709          row[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();          row[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();
710          row[m_Columns.m_col_instr] = instrument;          row[m_Columns.m_col_instr] = instrument;
711          // create a menu item for this instrument          // create a menu item for this instrument
712          Gtk::RadioMenuItem* item= new Gtk::RadioMenuItem(instrument_group, instrument->pInfo->Name.c_str());          Gtk::RadioMenuItem* item =
713                new Gtk::RadioMenuItem(instrument_group, instrument->pInfo->Name.c_str());
714          instrument_menu->get_submenu()->append(*item);          instrument_menu->get_submenu()->append(*item);
715          item->signal_activate().connect(          item->signal_activate().connect(
716              sigc::bind(              sigc::bind(
# Line 1650  void MainWindow::load_gig(gig::File* gig Line 730  void MainWindow::load_gig(gig::File* gig
730              rowGroup[m_SamplesModel.m_col_name]   = group->Name.c_str();              rowGroup[m_SamplesModel.m_col_name]   = group->Name.c_str();
731              rowGroup[m_SamplesModel.m_col_group]  = group;              rowGroup[m_SamplesModel.m_col_group]  = group;
732              rowGroup[m_SamplesModel.m_col_sample] = NULL;              rowGroup[m_SamplesModel.m_col_sample] = NULL;
733              for (gig::Sample* sample = group->GetFirstSample(); sample; sample = group->GetNextSample()) {              for (gig::Sample* sample = group->GetFirstSample();
734                  Gtk::TreeModel::iterator iterSample = m_refSamplesTreeModel->append(rowGroup.children());                   sample; sample = group->GetNextSample()) {
735                    Gtk::TreeModel::iterator iterSample =
736                        m_refSamplesTreeModel->append(rowGroup.children());
737                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
738                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();
739                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
# Line 1661  void MainWindow::load_gig(gig::File* gig Line 743  void MainWindow::load_gig(gig::File* gig
743      }      }
744  }  }
745    
746  void MainWindow::on_button_release(GdkEventButton* button)  void MainWindow::show_instr_props()
747  {  {
748      if (button->type == GDK_2BUTTON_PRESS) {      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
749          Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();      Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
750          Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();      if (it)
751          if (it)      {
752            Gtk::TreeModel::Row row = *it;
753            if (row[m_Columns.m_col_instr])
754          {          {
755              Gtk::TreeModel::Row row = *it;              instrumentProps.set_instrument(row[m_Columns.m_col_instr]);
756              if (row[m_Columns.m_col_instr])              instrumentProps.show();
757              {              instrumentProps.deiconify();
                 instrumentProps.set_instrument(row[m_Columns.m_col_instr]);  
                 instrumentProps.show();  
                 instrumentProps.deiconify();  
             }  
758          }          }
759        }
760    }
761    
762    void MainWindow::on_button_release(GdkEventButton* button)
763    {
764        if (button->type == GDK_2BUTTON_PRESS) {
765            show_instr_props();
766      } else if (button->type == GDK_BUTTON_PRESS && button->button == 3) {      } else if (button->type == GDK_BUTTON_PRESS && button->button == 3) {
767          popup_menu->popup(button->button, button->time);          popup_menu->popup(button->button, button->time);
768      }      }
# Line 1699  void MainWindow::on_sample_treeview_butt Line 786  void MainWindow::on_sample_treeview_butt
786              group_selected  = row[m_SamplesModel.m_col_group];              group_selected  = row[m_SamplesModel.m_col_group];
787              sample_selected = row[m_SamplesModel.m_col_sample];              sample_selected = row[m_SamplesModel.m_col_sample];
788          }          }
789          dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/SampleProperties"))->set_sensitive(group_selected || sample_selected);          dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/SampleProperties"))->
790          dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/AddSample"))->set_sensitive(group_selected || sample_selected);              set_sensitive(group_selected || sample_selected);
791          dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/AddGroup"))->set_sensitive(file);          dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/AddSample"))->
792          dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/RemoveSample"))->set_sensitive(group_selected || sample_selected);              set_sensitive(group_selected || sample_selected);
793            dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/AddGroup"))->
794                set_sensitive(file);
795            dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/RemoveSample"))->
796                set_sensitive(group_selected || sample_selected);
797          // show sample popup          // show sample popup
798          sample_popup->popup(button->button, button->time);          sample_popup->popup(button->button, button->time);
799      }      }
# Line 1749  void MainWindow::on_action_add_sample() Line 840  void MainWindow::on_action_add_sample()
840      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
841      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
842      dialog.set_select_multiple(true);      dialog.set_select_multiple(true);
843      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile (yet to do ;-)      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile
844      soundfilter.add_pattern("*.wav");      const char* supportedFileTypes[] = {
845            "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",
846            "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",
847            "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",
848            "*.W64", "*.pvf", "*.PVF", "*.xi", "*.XI", "*.htk", "*.HTK",
849            "*.caf", "*.CAF", NULL
850        };
851        for (int i = 0; supportedFileTypes[i]; i++)
852            soundfilter.add_pattern(supportedFileTypes[i]);
853      soundfilter.set_name("Sound Files");      soundfilter.set_name("Sound Files");
854      Gtk::FileFilter allpassfilter; // matches every file      Gtk::FileFilter allpassfilter; // matches every file
855      allpassfilter.add_pattern("*.*");      allpassfilter.add_pattern("*.*");
# Line 1760  void MainWindow::on_action_add_sample() Line 859  void MainWindow::on_action_add_sample()
859      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
860          Glib::ustring error_files;          Glib::ustring error_files;
861          Glib::SListHandle<Glib::ustring> filenames = dialog.get_filenames();          Glib::SListHandle<Glib::ustring> filenames = dialog.get_filenames();
862          for (Glib::SListHandle<Glib::ustring>::iterator iter = filenames.begin(); iter != filenames.end(); ++iter) {          for (Glib::SListHandle<Glib::ustring>::iterator iter = filenames.begin();
863                 iter != filenames.end(); ++iter) {
864              printf("Adding sample %s\n",(*iter).c_str());              printf("Adding sample %s\n",(*iter).c_str());
865              // use libsndfile to retrieve file informations              // use libsndfile to retrieve file informations
866              SF_INFO info;              SF_INFO info;
# Line 1797  void MainWindow::on_action_add_sample() Line 897  void MainWindow::on_action_add_sample()
897                  }                  }
898                  // add a new sample to the .gig file                  // add a new sample to the .gig file
899                  gig::Sample* sample = file->AddSample();                  gig::Sample* sample = file->AddSample();
900                  sample->pInfo->Name = (*iter).substr((*iter).rfind('/') + 1).raw(); // file name without path                  // file name without path
901                    sample->pInfo->Name = (*iter).substr((*iter).rfind('/') + 1).raw();
902                  sample->Channels = info.channels;                  sample->Channels = info.channels;
903                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
904                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
905                  sample->SamplesPerSecond = info.samplerate;                  sample->SamplesPerSecond = info.samplerate;
906                  // schedule resizing the sample (which will be done physically when File::Save() is called)                  // schedule resizing the sample (which will be done
907                    // physically when File::Save() is called)
908                  sample->Resize(info.frames);                  sample->Resize(info.frames);
909                  // schedule that physical resize and sample import (data copying), performed when "Save" is requested                  // make sure sample is part of the selected group
910                    group->AddSample(sample);
911                    // schedule that physical resize and sample import
912                    // (data copying), performed when "Save" is requested
913                  SampleImportItem sched_item;                  SampleImportItem sched_item;
914                  sched_item.gig_sample  = sample;                  sched_item.gig_sample  = sample;
915                  sched_item.sample_path = *iter;                  sched_item.sample_path = *iter;
916                  m_SampleImportQueue.push_back(sched_item);                  m_SampleImportQueue.push_back(sched_item);
917                  // add sample to the tree view                  // add sample to the tree view
918                  Gtk::TreeModel::iterator iterSample = m_refSamplesTreeModel->append(row.children());                  Gtk::TreeModel::iterator iterSample =
919                        m_refSamplesTreeModel->append(row.children());
920                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
921                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();
922                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
# Line 1839  void MainWindow::on_action_remove_sample Line 945  void MainWindow::on_action_remove_sample
945          Gtk::TreeModel::Row row = *it;          Gtk::TreeModel::Row row = *it;
946          gig::Group* group   = row[m_SamplesModel.m_col_group];          gig::Group* group   = row[m_SamplesModel.m_col_group];
947          gig::Sample* sample = row[m_SamplesModel.m_col_sample];          gig::Sample* sample = row[m_SamplesModel.m_col_sample];
948            Glib::ustring name  = row[m_SamplesModel.m_col_name];
949          try {          try {
950              // remove group or sample from the gig file              // remove group or sample from the gig file
951              if (group) {              if (group) {
952                    // temporarily remember the samples that bolong to
953                    // that group (we need that to clean the queue)
954                    std::list<gig::Sample*> members;
955                    for (gig::Sample* pSample = group->GetFirstSample();
956                         pSample; pSample = group->GetNextSample()) {
957                        members.push_back(pSample);
958                    }
959                    // delete the group in the .gig file including the
960                    // samples that belong to the group
961                  file->DeleteGroup(group);                  file->DeleteGroup(group);
962                    // if sample(s) were just previously added, remove
963                    // them from the import queue
964                    for (std::list<gig::Sample*>::iterator member = members.begin();
965                         member != members.end(); ++member) {
966                        for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
967                             iter != m_SampleImportQueue.end(); ++iter) {
968                            if ((*iter).gig_sample == *member) {
969                                printf("Removing previously added sample '%s' from group '%s'\n",
970                                       (*iter).sample_path.c_str(), name.c_str());
971                                m_SampleImportQueue.erase(iter);
972                                break;
973                            }
974                        }
975                    }
976              } else if (sample) {              } else if (sample) {
977                    // remove sample from the .gig file
978                  file->DeleteSample(sample);                  file->DeleteSample(sample);
979              }                  // if sample was just previously added, remove it from
980              // if sample was just previously added, remove it from the import queue                  // the import queue
981              if (sample) {                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
982                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin(); iter != m_SampleImportQueue.end(); ++iter) {                       iter != m_SampleImportQueue.end(); ++iter) {
983                      if ((*iter).gig_sample == sample) {                      if ((*iter).gig_sample == sample) {
984                            printf("Removing previously added sample '%s'\n",
985                                   (*iter).sample_path.c_str());
986                          m_SampleImportQueue.erase(iter);                          m_SampleImportQueue.erase(iter);
987                          break;                          break;
988                      }                      }
# Line 1863  void MainWindow::on_action_remove_sample Line 996  void MainWindow::on_action_remove_sample
996          }          }
997      }      }
998  }  }
999    
1000    void MainWindow::on_sample_treeview_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&,
1001                                                      Gtk::SelectionData& selection_data, guint, guint)
1002    {
1003        // get selected sample
1004        gig::Sample* sample = NULL;
1005        Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
1006        Gtk::TreeModel::iterator it = sel->get_selected();
1007        if (it) {
1008            Gtk::TreeModel::Row row = *it;
1009            sample = row[m_SamplesModel.m_col_sample];
1010        }
1011        // pass the gig::Sample as pointer
1012        selection_data.set(selection_data.get_target(), 0/*unused*/, (const guchar*)&sample,
1013                           sizeof(sample)/*length of data in bytes*/);
1014    }
1015    
1016    void MainWindow::on_sample_label_drop_drag_data_received(
1017        const Glib::RefPtr<Gdk::DragContext>& context, int, int,
1018        const Gtk::SelectionData& selection_data, guint, guint time)
1019    {
1020        gig::DimensionRegion* dimregion = m_DimRegionChooser.get_dimregion();
1021        gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1022    
1023        if (sample && dimregion && selection_data.get_length() == sizeof(gig::Sample*)) {
1024            if (sample != dimregion->pSample) {
1025                dimregion->pSample = sample;
1026                dimreg_edit.wSample->set_text(dimregion->pSample->pInfo->Name.c_str());
1027                std::cout << "Drop received sample \"" <<
1028                    dimregion->pSample->pInfo->Name.c_str() << "\"" << std::endl;
1029                // drop success
1030                context->drop_reply(true, time);
1031                return;
1032            }
1033        }
1034        // drop failed
1035        context->drop_reply(false, time);
1036    }
1037    
1038    void MainWindow::sample_name_changed(const Gtk::TreeModel::Path& path,
1039                                         const Gtk::TreeModel::iterator& iter) {
1040        if (!iter) return;
1041        Gtk::TreeModel::Row row = *iter;
1042        Glib::ustring name  = row[m_SamplesModel.m_col_name];
1043        gig::Group* group   = row[m_SamplesModel.m_col_group];
1044        gig::Sample* sample = row[m_SamplesModel.m_col_sample];
1045        if (group) {
1046            group->Name = name;
1047            std::cout << "Group name changed\n" << std::flush;
1048        } else if (sample) {
1049            sample->pInfo->Name = name.raw();
1050            std::cout << "Sample name changed\n" << std::flush;
1051        }
1052    }
1053    
1054    void MainWindow::instrument_name_changed(const Gtk::TreeModel::Path& path,
1055                                             const Gtk::TreeModel::iterator& iter) {
1056        std::cout << "Instrument name changed\n" << std::flush;
1057        if (!iter) return;
1058        Gtk::TreeModel::Row row = *iter;
1059        Glib::ustring name = row[m_Columns.m_col_name];
1060        gig::Instrument* instrument = row[m_Columns.m_col_instr];
1061        if (instrument) instrument->pInfo->Name = name.raw();
1062    }

Legend:
Removed from v.1088  
changed lines
  Added in v.1100

  ViewVC Help
Powered by ViewVC