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

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

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

revision 1261 by persson, Thu Jul 5 17:12:20 2007 UTC revision 1322 by schoenebeck, Tue Sep 4 11:04:56 2007 UTC
# Line 31  Line 31 
31  #include <gtkmm/aboutdialog.h>  #include <gtkmm/aboutdialog.h>
32  #endif  #endif
33    
34    #if (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION < 6) || GLIBMM_MAJOR_VERSION < 2
35    namespace Glib {
36    Glib::ustring filename_display_basename(const std::string& filename)
37    {
38        gchar* gstr = g_path_get_basename(filename.c_str());
39        Glib::ustring str(gstr);
40        g_free(gstr);
41        return Glib::filename_to_utf8(str);
42    }
43    }
44    #endif
45    
46  #include <stdio.h>  #include <stdio.h>
47  #include <sndfile.h>  #include <sndfile.h>
48    
# Line 234  MainWindow::MainWindow() Line 246  MainWindow::MainWindow()
246      std::list<Gtk::TargetEntry> drag_target_gig_sample;      std::list<Gtk::TargetEntry> drag_target_gig_sample;
247      drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );      drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );
248      m_TreeViewSamples.drag_source_set(drag_target_gig_sample);      m_TreeViewSamples.drag_source_set(drag_target_gig_sample);
249        m_TreeViewSamples.signal_drag_begin().connect(
250            sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_begin)
251        );
252      m_TreeViewSamples.signal_drag_data_get().connect(      m_TreeViewSamples.signal_drag_data_get().connect(
253          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)
254      );      );
# Line 242  MainWindow::MainWindow() Line 257  MainWindow::MainWindow()
257          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)
258      );      );
259      dimreg_edit.signal_dimreg_changed().connect(      dimreg_edit.signal_dimreg_changed().connect(
260          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::hide(sigc::mem_fun(*this, &MainWindow::file_changed)));
261      m_RegionChooser.signal_instrument_changed().connect(      m_RegionChooser.signal_instrument_changed().connect(
262          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
263      m_DimRegionChooser.signal_region_changed().connect(      m_DimRegionChooser.signal_region_changed().connect(
264          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
265      instrumentProps.signal_instrument_changed().connect(      instrumentProps.signal_instrument_changed().connect(
266          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
267    
268        dimreg_edit.signal_dimreg_to_be_changed().connect(
269            dimreg_to_be_changed_signal.make_slot());
270        dimreg_edit.signal_dimreg_changed().connect(
271            dimreg_changed_signal.make_slot());
272        dimreg_edit.signal_sample_ref_changed().connect(
273            sample_ref_changed_signal.make_slot());
274    
275        m_RegionChooser.signal_instrument_struct_to_be_changed().connect(
276            sigc::hide(
277                sigc::bind(
278                    file_structure_to_be_changed_signal.make_slot(),
279                    sigc::ref(this->file)
280                )
281            )
282        );
283        m_RegionChooser.signal_instrument_struct_changed().connect(
284            sigc::hide(
285                sigc::bind(
286                    file_structure_changed_signal.make_slot(),
287                    sigc::ref(this->file)
288                )
289            )
290        );
291        m_RegionChooser.signal_region_to_be_changed().connect(
292            region_to_be_changed_signal.make_slot());
293        m_RegionChooser.signal_region_changed_signal().connect(
294            region_changed_signal.make_slot());
295    
296      file = 0;      file = 0;
297      file_is_changed = false;      file_is_changed = false;
298    
299      show_all_children();      show_all_children();
300    
301        // start with a new gig file by default
302        on_action_file_new();
303  }  }
304    
305  MainWindow::~MainWindow()  MainWindow::~MainWindow()
# Line 407  bool MainWindow::close_confirmation_dial Line 454  bool MainWindow::close_confirmation_dial
454                                   Glib::filename_display_basename(filename).c_str());                                   Glib::filename_display_basename(filename).c_str());
455      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
456      g_free(msg);      g_free(msg);
457    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2
458      dialog.set_secondary_text(_("If you close without saving, your changes will be lost."));      dialog.set_secondary_text(_("If you close without saving, your changes will be lost."));
459    #endif
460      dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);      dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);
461      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
462      dialog.add_button(file_has_name ? Gtk::Stock::SAVE : Gtk::Stock::SAVE_AS, Gtk::RESPONSE_YES);      dialog.add_button(file_has_name ? Gtk::Stock::SAVE : Gtk::Stock::SAVE_AS, Gtk::RESPONSE_YES);
463      dialog.set_default_response(Gtk::RESPONSE_YES);      dialog.set_default_response(Gtk::RESPONSE_YES);
464      int response = dialog.run();      int response = dialog.run();
465        dialog.hide();
466      if (response == Gtk::RESPONSE_YES) return file_save();      if (response == Gtk::RESPONSE_YES) return file_save();
467      return response != Gtk::RESPONSE_CANCEL;      return response != Gtk::RESPONSE_CANCEL;
468  }  }
# Line 434  void MainWindow::on_action_file_open() Line 484  void MainWindow::on_action_file_open()
484      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
485          std::string filename = dialog.get_filename();          std::string filename = dialog.get_filename();
486          printf("filename=%s\n", filename.c_str());          printf("filename=%s\n", filename.c_str());
         __clear();  
487          printf("on_action_file_open self=%x\n", Glib::Thread::self());          printf("on_action_file_open self=%x\n", Glib::Thread::self());
488          load_file(filename.c_str());          load_file(filename.c_str());
489          current_dir = Glib::path_get_dirname(filename);          current_dir = Glib::path_get_dirname(filename);
# Line 443  void MainWindow::on_action_file_open() Line 492  void MainWindow::on_action_file_open()
492    
493  void MainWindow::load_file(const char* name)  void MainWindow::load_file(const char* name)
494  {  {
495        __clear();
496      load_dialog = new LoadDialog("Loading...", *this);      load_dialog = new LoadDialog("Loading...", *this);
497      load_dialog->show_all();      load_dialog->show_all();
498      loader = new Loader(strdup(name));      loader = new Loader(strdup(name));
# Line 483  void MainWindow::on_action_file_save() Line 533  void MainWindow::on_action_file_save()
533      file_save();      file_save();
534  }  }
535    
536  bool MainWindow::file_save()  bool MainWindow::check_if_savable()
537  {  {
538      if (!file) return false;      if (!file) return false;
539    
540        if (!file->GetFirstSample()) {
541            Gtk::MessageDialog(*this, _("The file could not be saved "
542                                        "because it contains no samples"),
543                               false, Gtk::MESSAGE_ERROR).run();
544            return false;
545        }
546    
547        for (gig::Instrument* instrument = file->GetFirstInstrument() ; instrument ;
548             instrument = file->GetNextInstrument()) {
549            if (!instrument->GetFirstRegion()) {
550                Gtk::MessageDialog(*this, _("The file could not be saved "
551                                            "because there are instruments "
552                                            "that have no regions"),
553                                   false, Gtk::MESSAGE_ERROR).run();
554                return false;
555            }
556        }
557        return true;
558    }
559    
560    bool MainWindow::file_save()
561    {
562        if (!check_if_savable()) return false;
563      if (!file_has_name) return file_save_as();      if (!file_has_name) return file_save_as();
564    
565      std::cout << "Saving file\n" << std::flush;      std::cout << "Saving file\n" << std::flush;
566        file_structure_to_be_changed_signal.emit(this->file);
567      try {      try {
568          file->Save();          file->Save();
569          if (file_is_changed) {          if (file_is_changed) {
# Line 496  bool MainWindow::file_save() Line 571  bool MainWindow::file_save()
571              file_is_changed = false;              file_is_changed = false;
572          }          }
573      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
574            file_structure_changed_signal.emit(this->file);
575          Glib::ustring txt = "Could not save file: " + e.Message;          Glib::ustring txt = "Could not save file: " + e.Message;
576          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
577          msg.run();          msg.run();
# Line 503  bool MainWindow::file_save() Line 579  bool MainWindow::file_save()
579      }      }
580      std::cout << "Saving file done\n" << std::flush;      std::cout << "Saving file done\n" << std::flush;
581      __import_queued_samples();      __import_queued_samples();
582        file_structure_changed_signal.emit(this->file);
583      return true;      return true;
584  }  }
585    
586  void MainWindow::on_action_file_save_as()  void MainWindow::on_action_file_save_as()
587  {  {
588        if (!check_if_savable()) return;
589      file_save_as();      file_save_as();
590  }  }
591    
592  bool MainWindow::file_save_as()  bool MainWindow::file_save_as()
593  {  {
     if (!file) return false;  
594      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);
595      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
596      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
# Line 535  bool MainWindow::file_save_as() Line 612  bool MainWindow::file_save_as()
612      dialog.set_current_name(Glib::filename_display_basename(filename));      dialog.set_current_name(Glib::filename_display_basename(filename));
613    
614      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
615            file_structure_to_be_changed_signal.emit(this->file);
616          try {          try {
617              std::string filename = dialog.get_filename();              std::string filename = dialog.get_filename();
618              if (!Glib::str_has_suffix(filename, ".gig")) {              if (!Glib::str_has_suffix(filename, ".gig")) {
# Line 548  bool MainWindow::file_save_as() Line 626  bool MainWindow::file_save_as()
626              file_has_name = true;              file_has_name = true;
627              file_is_changed = false;              file_is_changed = false;
628          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
629                file_structure_changed_signal.emit(this->file);
630              Glib::ustring txt = "Could not save file: " + e.Message;              Glib::ustring txt = "Could not save file: " + e.Message;
631              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
632              msg.run();              msg.run();
633              return false;              return false;
634          }          }
635          __import_queued_samples();          __import_queued_samples();
636            file_structure_changed_signal.emit(this->file);
637          return true;          return true;
638      }      }
639      return false;      return false;
# Line 576  void MainWindow::__import_queued_samples Line 656  void MainWindow::__import_queued_samples
656              int bitdepth;              int bitdepth;
657              switch (info.format & 0xff) {              switch (info.format & 0xff) {
658                  case SF_FORMAT_PCM_S8:                  case SF_FORMAT_PCM_S8:
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
659                  case SF_FORMAT_PCM_16:                  case SF_FORMAT_PCM_16:
660                    case SF_FORMAT_PCM_U8:
661                      bitdepth = 16;                      bitdepth = 16;
662                      break;                      break;
663                  case SF_FORMAT_PCM_24:                  case SF_FORMAT_PCM_24:
                     bitdepth = 32; // we simply convert to 32 bit for now  
                     break;  
664                  case SF_FORMAT_PCM_32:                  case SF_FORMAT_PCM_32:
                     bitdepth = 32;  
                     break;  
                 case SF_FORMAT_PCM_U8:  
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
665                  case SF_FORMAT_FLOAT:                  case SF_FORMAT_FLOAT:
                     bitdepth = 32;  
                     break;  
666                  case SF_FORMAT_DOUBLE:                  case SF_FORMAT_DOUBLE:
667                      bitdepth = 32; // I guess we will always truncate this to 32 bit                      bitdepth = 24;
668                      break;                      break;
669                  default:                  default:
670                      sf_close(hFile); // close sound file                      sf_close(hFile); // close sound file
671                      throw std::string("format not supported"); // unsupported subformat (yet?)                      throw std::string("format not supported"); // unsupported subformat (yet?)
672              }              }
673              // allocate appropriate copy buffer (TODO: for now we copy  
674              // it in one piece, might be tough for very long samples)              const int bufsize = 10000;
             // and copy sample data into buffer  
             int8_t* buffer = NULL;  
675              switch (bitdepth) {              switch (bitdepth) {
676                  case 16:                  case 16: {
677                      buffer = new int8_t[2 * info.channels * info.frames];                      short* buffer = new short[bufsize * info.channels];
678                      // libsndfile does the conversion for us (if needed)                      sf_count_t cnt = info.frames;
679                      sf_readf_short(hFile, (short*) buffer, info.frames);                      while (cnt) {
680                            // libsndfile does the conversion for us (if needed)
681                            int n = sf_readf_short(hFile, buffer, bufsize);
682                            // write from buffer directly (physically) into .gig file
683                            iter->gig_sample->Write(buffer, n);
684                            cnt -= n;
685                        }
686                        delete[] buffer;
687                      break;                      break;
688                  case 32:                  }
689                      buffer = new int8_t[4 * info.channels * info.frames];                  case 24: {
690                      // libsndfile does the conversion for us (if needed)                      int* srcbuf = new int[bufsize * info.channels];
691                      sf_readf_int(hFile, (int*) buffer, info.frames);                      uint8_t* dstbuf = new uint8_t[bufsize * 3 * info.channels];
692                        sf_count_t cnt = info.frames;
693                        while (cnt) {
694                            // libsndfile returns 32 bits, convert to 24
695                            int n = sf_readf_int(hFile, srcbuf, bufsize);
696                            int j = 0;
697                            for (int i = 0 ; i < n * info.channels ; i++) {
698                                dstbuf[j++] = srcbuf[i] >> 8;
699                                dstbuf[j++] = srcbuf[i] >> 16;
700                                dstbuf[j++] = srcbuf[i] >> 24;
701                            }
702                            // write from buffer directly (physically) into .gig file
703                            iter->gig_sample->Write(dstbuf, n);
704                            cnt -= n;
705                        }
706                        delete[] srcbuf;
707                        delete[] dstbuf;
708                      break;                      break;
709                    }
710              }              }
             // write from buffer directly (physically) into .gig file  
             (*iter).gig_sample->Write(buffer, info.frames);  
711              // cleanup              // cleanup
712              sf_close(hFile);              sf_close(hFile);
             delete[] buffer;  
713              // on success we remove the sample from the import queue,              // on success we remove the sample from the import queue,
714              // otherwise keep it, maybe it works the next time ?              // otherwise keep it, maybe it works the next time ?
715              std::list<SampleImportItem>::iterator cur = iter;              std::list<SampleImportItem>::iterator cur = iter;
# Line 712  void PropDialog::set_info(DLS::Info* inf Line 801  void PropDialog::set_info(DLS::Info* inf
801      entry[15].set_text(info->Subject);      entry[15].set_text(info->Subject);
802  }  }
803    
804    void InstrumentProps::add_prop(BoolEntry& boolentry)
805    {
806        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
807                     Gtk::FILL, Gtk::SHRINK);
808        rowno++;
809        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
810    }
811    
812    void InstrumentProps::add_prop(BoolEntryPlus6& boolentry)
813    {
814        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
815                     Gtk::FILL, Gtk::SHRINK);
816        rowno++;
817        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
818    }
819    
820  void InstrumentProps::add_prop(LabelWidget& prop)  void InstrumentProps::add_prop(LabelWidget& prop)
821  {  {
822      table.attach(prop.label, 0, 1, rowno, rowno + 1,      table.attach(prop.label, 0, 1, rowno, rowno + 1,
# Line 726  InstrumentProps::InstrumentProps() Line 831  InstrumentProps::InstrumentProps()
831      : table(2,1),      : table(2,1),
832        quitButton(Gtk::Stock::CLOSE),        quitButton(Gtk::Stock::CLOSE),
833        eName("Name"),        eName("Name"),
834        eIsDrum("IsDrum"),        eIsDrum("Is drum"),
835        eMIDIBank("MIDIBank", 0, 16383),        eMIDIBank("MIDI bank", 0, 16383),
836        eMIDIProgram("MIDIProgram"),        eMIDIProgram("MIDI program"),
837        eAttenuation("Attenuation", 0, 96, 0, 1),        eAttenuation("Attenuation", 0, 96, 0, 1),
838        eGainPlus6("Gain +6dB", eAttenuation, -6),        eGainPlus6("Gain +6dB", eAttenuation, -6),
839        eEffectSend("EffectSend", 0, 65535),        eEffectSend("Effect send", 0, 65535),
840        eFineTune("FineTune", -8400, 8400),        eFineTune("Fine tune", -8400, 8400),
841        ePitchbendRange("PitchbendRange", 0, 12),        ePitchbendRange("Pitchbend range", 0, 12),
842        ePianoReleaseMode("PianoReleaseMode"),        ePianoReleaseMode("Piano release mode"),
843        eDimensionKeyRangeLow("DimensionKeyRangeLow"),        eDimensionKeyRangeLow("Dimension key range low"),
844        eDimensionKeyRangeHigh("DimensionKeyRangeHigh")        eDimensionKeyRangeHigh("Dimension key range high")
845  {  {
846      set_title("Instrument properties");      set_title("Instrument properties");
847    
# Line 1027  void MainWindow::on_action_add_sample() Line 1132  void MainWindow::on_action_add_sample()
1132      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1133      dialog.set_select_multiple(true);      dialog.set_select_multiple(true);
1134      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile
1135      const char* supportedFileTypes[] = {      const char* const supportedFileTypes[] = {
1136          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",
1137          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",
1138          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",
# Line 1057  void MainWindow::on_action_add_sample() Line 1162  void MainWindow::on_action_add_sample()
1162                  int bitdepth;                  int bitdepth;
1163                  switch (info.format & 0xff) {                  switch (info.format & 0xff) {
1164                      case SF_FORMAT_PCM_S8:                      case SF_FORMAT_PCM_S8:
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1165                      case SF_FORMAT_PCM_16:                      case SF_FORMAT_PCM_16:
1166                        case SF_FORMAT_PCM_U8:
1167                          bitdepth = 16;                          bitdepth = 16;
1168                          break;                          break;
1169                      case SF_FORMAT_PCM_24:                      case SF_FORMAT_PCM_24:
                         bitdepth = 32; // we simply convert to 32 bit for now  
                         break;  
1170                      case SF_FORMAT_PCM_32:                      case SF_FORMAT_PCM_32:
                         bitdepth = 32;  
                         break;  
                     case SF_FORMAT_PCM_U8:  
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1171                      case SF_FORMAT_FLOAT:                      case SF_FORMAT_FLOAT:
                         bitdepth = 32;  
                         break;  
1172                      case SF_FORMAT_DOUBLE:                      case SF_FORMAT_DOUBLE:
1173                          bitdepth = 32; // I guess we will always truncate this to 32 bit                          bitdepth = 24;
1174                          break;                          break;
1175                      default:                      default:
1176                          sf_close(hFile); // close sound file                          sf_close(hFile); // close sound file
# Line 1084  void MainWindow::on_action_add_sample() Line 1179  void MainWindow::on_action_add_sample()
1179                  // add a new sample to the .gig file                  // add a new sample to the .gig file
1180                  gig::Sample* sample = file->AddSample();                  gig::Sample* sample = file->AddSample();
1181                  // file name without path                  // file name without path
1182                  sample->pInfo->Name = (*iter).substr((*iter).rfind('/') + 1).raw();                  Glib::ustring filename = Glib::filename_display_basename(*iter);
1183                    // remove file extension if there is one
1184                    for (int i = 0; supportedFileTypes[i]; i++) {
1185                        if (Glib::str_has_suffix(filename, supportedFileTypes[i] + 1)) {
1186                            filename.erase(filename.length() - strlen(supportedFileTypes[i] + 1));
1187                            break;
1188                        }
1189                    }
1190                    sample->pInfo->Name = filename;
1191                  sample->Channels = info.channels;                  sample->Channels = info.channels;
1192                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
1193                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
1194                  sample->SamplesPerSecond = info.samplerate;                  sample->SamplesPerSecond = info.samplerate;
1195                    sample->AverageBytesPerSecond = sample->FrameSize * sample->SamplesPerSecond;
1196                    sample->BlockAlign = sample->FrameSize;
1197                    sample->SamplesTotal = info.frames;
1198    
1199                    SF_INSTRUMENT instrument;
1200                    if (sf_command(hFile, SFC_GET_INSTRUMENT,
1201                                   &instrument, sizeof(instrument)) != SF_FALSE)
1202                    {
1203                        sample->MIDIUnityNote = instrument.basenote;
1204    
1205    #if HAVE_SF_INSTRUMENT_LOOPS
1206                        if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
1207                            sample->Loops = 1;
1208    
1209                            switch (instrument.loops[0].mode) {
1210                            case SF_LOOP_FORWARD:
1211                                sample->LoopType = gig::loop_type_normal;
1212                                break;
1213                            case SF_LOOP_BACKWARD:
1214                                sample->LoopType = gig::loop_type_backward;
1215                                break;
1216                            case SF_LOOP_ALTERNATING:
1217                                sample->LoopType = gig::loop_type_bidirectional;
1218                                break;
1219                            }
1220                            sample->LoopStart = instrument.loops[0].start;
1221                            sample->LoopEnd = instrument.loops[0].end;
1222                            sample->LoopPlayCount = instrument.loops[0].count;
1223                            sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;
1224                        }
1225    #endif
1226                    }
1227    
1228                  // schedule resizing the sample (which will be done                  // schedule resizing the sample (which will be done
1229                  // physically when File::Save() is called)                  // physically when File::Save() is called)
1230                  sample->Resize(info.frames);                  sample->Resize(info.frames);
# Line 1104  void MainWindow::on_action_add_sample() Line 1240  void MainWindow::on_action_add_sample()
1240                  Gtk::TreeModel::iterator iterSample =                  Gtk::TreeModel::iterator iterSample =
1241                      m_refSamplesTreeModel->append(row.children());                      m_refSamplesTreeModel->append(row.children());
1242                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
1243                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name]   = filename;
1244                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
1245                  rowSample[m_SamplesModel.m_col_group]  = NULL;                  rowSample[m_SamplesModel.m_col_group]  = NULL;
1246                  // close sound file                  // close sound file
# Line 1143  void MainWindow::on_action_remove_sample Line 1279  void MainWindow::on_action_remove_sample
1279                       pSample; pSample = group->GetNextSample()) {                       pSample; pSample = group->GetNextSample()) {
1280                      members.push_back(pSample);                      members.push_back(pSample);
1281                  }                  }
1282                    // notify everybody that we're going to remove these samples
1283                    samples_to_be_removed_signal.emit(members);
1284                  // delete the group in the .gig file including the                  // delete the group in the .gig file including the
1285                  // samples that belong to the group                  // samples that belong to the group
1286                  file->DeleteGroup(group);                  file->DeleteGroup(group);
1287                    // notify that we're done with removal
1288                    samples_removed_signal.emit();
1289                  // if sample(s) were just previously added, remove                  // if sample(s) were just previously added, remove
1290                  // them from the import queue                  // them from the import queue
1291                  for (std::list<gig::Sample*>::iterator member = members.begin();                  for (std::list<gig::Sample*>::iterator member = members.begin();
# Line 1162  void MainWindow::on_action_remove_sample Line 1302  void MainWindow::on_action_remove_sample
1302                  }                  }
1303                  file_changed();                  file_changed();
1304              } else if (sample) {              } else if (sample) {
1305                    // notify everybody that we're going to remove this sample
1306                    std::list<gig::Sample*> lsamples;
1307                    lsamples.push_back(sample);
1308                    samples_to_be_removed_signal.emit(lsamples);
1309                  // remove sample from the .gig file                  // remove sample from the .gig file
1310                  file->DeleteSample(sample);                  file->DeleteSample(sample);
1311                    // notify that we're done with removal
1312                    samples_removed_signal.emit();
1313                  // if sample was just previously added, remove it from                  // if sample was just previously added, remove it from
1314                  // the import queue                  // the import queue
1315                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
# Line 1175  void MainWindow::on_action_remove_sample Line 1321  void MainWindow::on_action_remove_sample
1321                          break;                          break;
1322                      }                      }
1323                  }                  }
1324                    dimreg_changed();
1325                  file_changed();                  file_changed();
1326              }              }
1327              // remove respective row(s) from samples tree view              // remove respective row(s) from samples tree view
1328              m_refSamplesTreeModel->erase(it);              m_refSamplesTreeModel->erase(it);
1329          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1330                // pretend we're done with removal (i.e. to avoid dead locks)
1331                samples_removed_signal.emit();
1332                // show error message
1333              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1334              msg.run();              msg.run();
1335          }          }
1336      }      }
1337  }  }
1338    
1339    // For some reason drag_data_get gets called two times for each
1340    // drag'n'drop (at least when target is an Entry). This work-around
1341    // makes sure the code in drag_data_get and drop_drag_data_received is
1342    // only executed once, as drag_begin only gets called once.
1343    void MainWindow::on_sample_treeview_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context)
1344    {
1345        first_call_to_drag_data_get = true;
1346    }
1347    
1348  void MainWindow::on_sample_treeview_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&,  void MainWindow::on_sample_treeview_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&,
1349                                                    Gtk::SelectionData& selection_data, guint, guint)                                                    Gtk::SelectionData& selection_data, guint, guint)
1350  {  {
1351        if (!first_call_to_drag_data_get) return;
1352        first_call_to_drag_data_get = false;
1353    
1354      // get selected sample      // get selected sample
1355      gig::Sample* sample = NULL;      gig::Sample* sample = NULL;
1356      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
# Line 1206  void MainWindow::on_sample_label_drop_dr Line 1368  void MainWindow::on_sample_label_drop_dr
1368      const Glib::RefPtr<Gdk::DragContext>& context, int, int,      const Glib::RefPtr<Gdk::DragContext>& context, int, int,
1369      const Gtk::SelectionData& selection_data, guint, guint time)      const Gtk::SelectionData& selection_data, guint, guint time)
1370  {  {
     gig::DimensionRegion* dimregion = m_DimRegionChooser.get_dimregion();  
1371      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1372    
1373      if (sample && dimregion && selection_data.get_length() == sizeof(gig::Sample*)) {      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {
1374          if (sample != dimregion->pSample) {          std::cout << "Drop received sample \"" <<
1375              dimregion->pSample = sample;              sample->pInfo->Name << "\"" << std::endl;
1376              dimreg_edit.wSample->set_text(dimregion->pSample->pInfo->Name.c_str());          // drop success
1377              std::cout << "Drop received sample \"" <<          context->drop_reply(true, time);
1378                  dimregion->pSample->pInfo->Name.c_str() << "\"" << std::endl;  
1379              // drop success          //TODO: we should better move most of the following code to DimRegionEdit::set_sample()
1380              context->drop_reply(true, time);  
1381              file_changed();          // notify everybody that we're going to alter the region
1382              return;          gig::Region* region = m_RegionChooser.get_region();
1383            region_to_be_changed_signal.emit(region);
1384    
1385            // find the samplechannel dimension
1386            gig::dimension_def_t* stereo_dimension = 0;
1387            for (int i = 0 ; i < region->Dimensions ; i++) {
1388                if (region->pDimensionDefinitions[i].dimension ==
1389                    gig::dimension_samplechannel) {
1390                    stereo_dimension = &region->pDimensionDefinitions[i];
1391                    break;
1392                }
1393          }          }
1394            bool channels_changed = false;
1395            if (sample->Channels == 1 && stereo_dimension) {
1396                // remove the samplechannel dimension
1397                region->DeleteDimension(stereo_dimension);
1398                channels_changed = true;
1399                region_changed();
1400            }
1401            dimreg_edit.set_sample(sample);
1402    
1403            if (sample->Channels == 2 && !stereo_dimension) {
1404                // add samplechannel dimension
1405                gig::dimension_def_t dim;
1406                dim.dimension = gig::dimension_samplechannel;
1407                dim.bits = 1;
1408                dim.zones = 2;
1409                region->AddDimension(&dim);
1410                channels_changed = true;
1411                region_changed();
1412            }
1413            if (channels_changed) {
1414                // unmap all samples with wrong number of channels
1415                // TODO: maybe there should be a warning dialog for this
1416                for (int i = 0 ; i < region->DimensionRegions ; i++) {
1417                    gig::DimensionRegion* d = region->pDimensionRegions[i];
1418                    if (d->pSample && d->pSample->Channels != sample->Channels) {
1419                        gig::Sample* oldref = d->pSample;
1420                        d->pSample = NULL;
1421                        sample_ref_changed_signal.emit(oldref, NULL);
1422                    }
1423                }
1424            }
1425    
1426            // notify we're done with altering
1427            region_changed_signal.emit(region);
1428    
1429            return;
1430      }      }
1431      // drop failed      // drop failed
1432      context->drop_reply(false, time);      context->drop_reply(false, time);
# Line 1258  void MainWindow::instrument_name_changed Line 1465  void MainWindow::instrument_name_changed
1465          file_changed();          file_changed();
1466      }      }
1467  }  }
1468    
1469    sigc::signal<void, gig::File*> MainWindow::signal_file_structure_to_be_changed() {
1470        return file_structure_to_be_changed_signal;
1471    }
1472    
1473    sigc::signal<void, gig::File*> MainWindow::signal_file_structure_changed() {
1474        return file_structure_changed_signal;
1475    }
1476    
1477    sigc::signal<void, std::list<gig::Sample*> > MainWindow::signal_samples_to_be_removed() {
1478        return samples_to_be_removed_signal;
1479    }
1480    
1481    sigc::signal<void> MainWindow::signal_samples_removed() {
1482        return samples_removed_signal;
1483    }
1484    
1485    sigc::signal<void, gig::Region*> MainWindow::signal_region_to_be_changed() {
1486        return region_to_be_changed_signal;
1487    }
1488    
1489    sigc::signal<void, gig::Region*> MainWindow::signal_region_changed() {
1490        return region_changed_signal;
1491    }
1492    
1493    sigc::signal<void, gig::Sample*/*old*/, gig::Sample*/*new*/> MainWindow::signal_sample_ref_changed() {
1494        return sample_ref_changed_signal;
1495    }
1496    
1497    sigc::signal<void, gig::DimensionRegion*> MainWindow::signal_dimreg_to_be_changed() {
1498        return dimreg_to_be_changed_signal;
1499    }
1500    
1501    sigc::signal<void, gig::DimensionRegion*> MainWindow::signal_dimreg_changed() {
1502        return dimreg_changed_signal;
1503    }

Legend:
Removed from v.1261  
changed lines
  Added in v.1322

  ViewVC Help
Powered by ViewVC