/[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 1225 by schoenebeck, Sun Jun 10 10:56:11 2007 UTC revision 1265 by persson, Sun Jul 29 13:44:59 2007 UTC
# Line 26  Line 26 
26  #include <gtkmm/targetentry.h>  #include <gtkmm/targetentry.h>
27  #include <gtkmm/main.h>  #include <gtkmm/main.h>
28    
29  #if GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2
30  #define ABOUT_DIALOG  #define ABOUT_DIALOG
31  #include <gtkmm/aboutdialog.h>  #include <gtkmm/aboutdialog.h>
32  #endif  #endif
# Line 99  MainWindow::MainWindow() Line 99  MainWindow::MainWindow()
99      action = Gtk::Action::create("SaveAs", Gtk::Stock::SAVE_AS);      action = Gtk::Action::create("SaveAs", Gtk::Stock::SAVE_AS);
100      action->property_label() = action->property_label() + "...";      action->property_label() = action->property_label() + "...";
101      actionGroup->add(action,      actionGroup->add(action,
102                       *(new Gtk::AccelKey("<shift><control>s")),                       Gtk::AccelKey("<shift><control>s"),
103                       sigc::mem_fun(                       sigc::mem_fun(
104                           *this, &MainWindow::on_action_file_save_as)                           *this, &MainWindow::on_action_file_save_as));
         );  
105      actionGroup->add(Gtk::Action::create("Properties",      actionGroup->add(Gtk::Action::create("Properties",
106                                           Gtk::Stock::PROPERTIES),                                           Gtk::Stock::PROPERTIES),
107                       sigc::mem_fun(                       sigc::mem_fun(
# Line 113  MainWindow::MainWindow() Line 112  MainWindow::MainWindow()
112                           *this, &MainWindow::show_instr_props));                           *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::on_action_quit));
116      actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));      actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));
117    
118      action = Gtk::Action::create("MenuHelp", Gtk::Stock::HELP);      action = Gtk::Action::create("MenuHelp", Gtk::Stock::HELP);
# Line 153  MainWindow::MainWindow() Line 152  MainWindow::MainWindow()
152    
153      uiManager = Gtk::UIManager::create();      uiManager = Gtk::UIManager::create();
154      uiManager->insert_action_group(actionGroup);      uiManager->insert_action_group(actionGroup);
155      // add_accel_group(uiManager->get_accel_group());      add_accel_group(uiManager->get_accel_group());
156    
157      Glib::ustring ui_info =      Glib::ustring ui_info =
158          "<ui>"          "<ui>"
# Line 201  MainWindow::MainWindow() Line 200  MainWindow::MainWindow()
200      m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK);      m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK);
201      m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK);      m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK);
202    
203      m_RegionChooser.signal_sel_changed().connect(      m_RegionChooser.signal_region_selected().connect(
204          sigc::mem_fun(*this, &MainWindow::region_changed) );          sigc::mem_fun(*this, &MainWindow::region_changed) );
205      m_DimRegionChooser.signal_sel_changed().connect(      m_DimRegionChooser.signal_dimregion_selected().connect(
206          sigc::mem_fun(*this, &MainWindow::dimreg_changed) );          sigc::mem_fun(*this, &MainWindow::dimreg_changed) );
207    
208    
# Line 242  MainWindow::MainWindow() Line 241  MainWindow::MainWindow()
241      dimreg_edit.wSample->signal_drag_data_received().connect(      dimreg_edit.wSample->signal_drag_data_received().connect(
242          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)
243      );      );
244        dimreg_edit.signal_dimreg_changed().connect(
245            sigc::mem_fun(*this, &MainWindow::file_changed));
246        m_RegionChooser.signal_instrument_changed().connect(
247            sigc::mem_fun(*this, &MainWindow::file_changed));
248        m_DimRegionChooser.signal_region_changed().connect(
249            sigc::mem_fun(*this, &MainWindow::file_changed));
250        instrumentProps.signal_instrument_changed().connect(
251            sigc::mem_fun(*this, &MainWindow::file_changed));
252      file = 0;      file = 0;
253        file_is_changed = false;
254    
255      show_all_children();      show_all_children();
256  }  }
# Line 252  MainWindow::~MainWindow() Line 259  MainWindow::~MainWindow()
259  {  {
260  }  }
261    
262    bool MainWindow::on_delete_event(GdkEventAny* event)
263    {
264        return file_is_changed && !close_confirmation_dialog();
265    }
266    
267    void MainWindow::on_action_quit()
268    {
269        if (file_is_changed && !close_confirmation_dialog()) return;
270        hide();
271    }
272    
273  void MainWindow::region_changed()  void MainWindow::region_changed()
274  {  {
275      m_DimRegionChooser.set_region(m_RegionChooser.get_region());      m_DimRegionChooser.set_region(m_RegionChooser.get_region());
# Line 370  void MainWindow::__clear() { Line 388  void MainWindow::__clear() {
388    
389  void MainWindow::on_action_file_new()  void MainWindow::on_action_file_new()
390  {  {
391        if (file_is_changed && !close_confirmation_dialog()) return;
392    
393      // clear all GUI elements      // clear all GUI elements
394      __clear();      __clear();
395      // create a new .gig file (virtually yet)      // create a new .gig file (virtually yet)
# Line 378  void MainWindow::on_action_file_new() Line 398  void MainWindow::on_action_file_new()
398      gig::Instrument* pInstrument = pFile->AddInstrument();      gig::Instrument* pInstrument = pFile->AddInstrument();
399      pInstrument->pInfo->Name = "Unnamed Instrument";      pInstrument->pInfo->Name = "Unnamed Instrument";
400      // update GUI with that new gig::File      // update GUI with that new gig::File
401      load_gig(pFile, NULL /*no file name yet*/);      load_gig(pFile, 0 /*no file name yet*/);
402    }
403    
404    bool MainWindow::close_confirmation_dialog()
405    {
406        gchar* msg = g_strdup_printf(_("Save changes to \"%s\" before closing?"),
407                                     Glib::filename_display_basename(filename).c_str());
408        Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
409        g_free(msg);
410        dialog.set_secondary_text(_("If you close without saving, your changes will be lost."));
411        dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);
412        dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
413        dialog.add_button(file_has_name ? Gtk::Stock::SAVE : Gtk::Stock::SAVE_AS, Gtk::RESPONSE_YES);
414        dialog.set_default_response(Gtk::RESPONSE_YES);
415        int response = dialog.run();
416        if (response == Gtk::RESPONSE_YES) return file_save();
417        return response != Gtk::RESPONSE_CANCEL;
418  }  }
419    
420  void MainWindow::on_action_file_open()  void MainWindow::on_action_file_open()
421  {  {
422        if (file_is_changed && !close_confirmation_dialog()) return;
423    
424      Gtk::FileChooserDialog dialog(*this, _("Open file"));      Gtk::FileChooserDialog dialog(*this, _("Open file"));
425      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
426      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
427        dialog.set_default_response(Gtk::RESPONSE_OK);
428      Gtk::FileFilter filter;      Gtk::FileFilter filter;
429      filter.add_pattern("*.gig");      filter.add_pattern("*.gig");
430      dialog.set_filter(filter);      dialog.set_filter(filter);
431        if (current_dir != "") {
432            dialog.set_current_folder(current_dir);
433        }
434      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
435          printf("filename=%s\n", dialog.get_filename().c_str());          std::string filename = dialog.get_filename();
436            printf("filename=%s\n", filename.c_str());
437          __clear();          __clear();
438          printf("on_action_file_open self=%x\n", Glib::Thread::self());          printf("on_action_file_open self=%x\n", Glib::Thread::self());
439          load_file(dialog.get_filename().c_str());          load_file(filename.c_str());
440            current_dir = Glib::path_get_dirname(filename);
441      }      }
442  }  }
443    
# Line 417  void MainWindow::load_instrument(gig::In Line 461  void MainWindow::load_instrument(gig::In
461          Gtk::Main::quit();          Gtk::Main::quit();
462      }      }
463      gig::File* pFile = (gig::File*) instr->GetParent();      gig::File* pFile = (gig::File*) instr->GetParent();
464      load_gig(pFile, NULL /*file name*/);      load_gig(pFile, 0 /*file name*/);
465      //TODO: automatically select the given instrument      //TODO: automatically select the given instrument
466  }  }
467    
# Line 436  void MainWindow::on_loader_finished() Line 480  void MainWindow::on_loader_finished()
480    
481  void MainWindow::on_action_file_save()  void MainWindow::on_action_file_save()
482  {  {
483      if (!file) return;      file_save();
484    }
485    
486    bool MainWindow::file_save()
487    {
488        if (!file) return false;
489        if (!file_has_name) return file_save_as();
490    
491      std::cout << "Saving file\n" << std::flush;      std::cout << "Saving file\n" << std::flush;
492      try {      try {
493          file->Save();          file->Save();
494            if (file_is_changed) {
495                set_title(get_title().substr(1));
496                file_is_changed = false;
497            }
498      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
499          Glib::ustring txt = "Could not save file: " + e.Message;          Glib::ustring txt = "Could not save file: " + e.Message;
500          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
501          msg.run();          msg.run();
502          return;          return false;
503      }      }
504      std::cout << "Saving file done\n" << std::flush;      std::cout << "Saving file done\n" << std::flush;
505      __import_queued_samples();      __import_queued_samples();
506        return true;
507  }  }
508    
509  void MainWindow::on_action_file_save_as()  void MainWindow::on_action_file_save_as()
510  {  {
511      if (!file) return;      file_save_as();
512      Gtk::FileChooserDialog dialog(*this, "Open", Gtk::FILE_CHOOSER_ACTION_SAVE);  }
513    
514    bool MainWindow::file_save_as()
515    {
516        if (!file) return false;
517        Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);
518      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
519      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
520        dialog.set_default_response(Gtk::RESPONSE_OK);
521    
522    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 8) || GTKMM_MAJOR_VERSION > 2
523        dialog.set_do_overwrite_confirmation();
524        // TODO: an overwrite dialog for gtkmm < 2.8
525    #endif
526      Gtk::FileFilter filter;      Gtk::FileFilter filter;
527      filter.add_pattern("*.gig");      filter.add_pattern("*.gig");
528      dialog.set_filter(filter);      dialog.set_filter(filter);
529    
530        if (Glib::path_is_absolute(filename)) {
531            dialog.set_filename(filename);
532        } else if (current_dir != "") {
533            dialog.set_current_folder(current_dir);
534        }
535        dialog.set_current_name(Glib::filename_display_basename(filename));
536    
537      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
         printf("filename=%s\n", dialog.get_filename().c_str());  
538          try {          try {
539              file->Save(dialog.get_filename());              std::string filename = dialog.get_filename();
540                if (!Glib::str_has_suffix(filename, ".gig")) {
541                    filename += ".gig";
542                }
543                printf("filename=%s\n", filename.c_str());
544                file->Save(filename);
545                this->filename = filename;
546                current_dir = Glib::path_get_dirname(filename);
547                set_title(Glib::filename_display_basename(filename));
548                file_has_name = true;
549                file_is_changed = false;
550          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
551              Glib::ustring txt = "Could not save file: " + e.Message;              Glib::ustring txt = "Could not save file: " + e.Message;
552              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
553              msg.run();              msg.run();
554              return;              return false;
555          }          }
556          __import_queued_samples();          __import_queued_samples();
557            return true;
558      }      }
559        return false;
560  }  }
561    
562  // actually write the sample(s)' data to the gig file  // actually write the sample(s)' data to the gig file
# Line 490  void MainWindow::__import_queued_samples Line 576  void MainWindow::__import_queued_samples
576              int bitdepth;              int bitdepth;
577              switch (info.format & 0xff) {              switch (info.format & 0xff) {
578                  case SF_FORMAT_PCM_S8:                  case SF_FORMAT_PCM_S8:
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
579                  case SF_FORMAT_PCM_16:                  case SF_FORMAT_PCM_16:
580                    case SF_FORMAT_PCM_U8:
581                      bitdepth = 16;                      bitdepth = 16;
582                      break;                      break;
583                  case SF_FORMAT_PCM_24:                  case SF_FORMAT_PCM_24:
                     bitdepth = 32; // we simply convert to 32 bit for now  
                     break;  
584                  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;  
585                  case SF_FORMAT_FLOAT:                  case SF_FORMAT_FLOAT:
                     bitdepth = 32;  
                     break;  
586                  case SF_FORMAT_DOUBLE:                  case SF_FORMAT_DOUBLE:
587                      bitdepth = 32; // I guess we will always truncate this to 32 bit                      bitdepth = 24;
588                      break;                      break;
589                  default:                  default:
590                      sf_close(hFile); // close sound file                      sf_close(hFile); // close sound file
591                      throw std::string("format not supported"); // unsupported subformat (yet?)                      throw std::string("format not supported"); // unsupported subformat (yet?)
592              }              }
593              // allocate appropriate copy buffer (TODO: for now we copy  
594              // 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;  
595              switch (bitdepth) {              switch (bitdepth) {
596                  case 16:                  case 16: {
597                      buffer = new int8_t[2 * info.channels * info.frames];                      short* buffer = new short[bufsize * info.channels];
598                      // libsndfile does the conversion for us (if needed)                      sf_count_t cnt = info.frames;
599                      sf_readf_short(hFile, (short*) buffer, info.frames);                      while (cnt) {
600                            // libsndfile does the conversion for us (if needed)
601                            int n = sf_readf_short(hFile, buffer, bufsize);
602                            // write from buffer directly (physically) into .gig file
603                            iter->gig_sample->Write(buffer, n);
604                            cnt -= n;
605                        }
606                        delete[] buffer;
607                      break;                      break;
608                  case 32:                  }
609                      buffer = new int8_t[4 * info.channels * info.frames];                  case 24: {
610                      // libsndfile does the conversion for us (if needed)                      int* srcbuf = new int[bufsize * info.channels];
611                      sf_readf_int(hFile, (int*) buffer, info.frames);                      uint8_t* dstbuf = new uint8_t[bufsize * 3 * info.channels];
612                        sf_count_t cnt = info.frames;
613                        while (cnt) {
614                            // libsndfile returns 32 bits, convert to 24
615                            int n = sf_readf_int(hFile, srcbuf, bufsize);
616                            int j = 0;
617                            for (int i = 0 ; i < n * info.channels ; i++) {
618                                dstbuf[j++] = srcbuf[i] >> 8;
619                                dstbuf[j++] = srcbuf[i] >> 16;
620                                dstbuf[j++] = srcbuf[i] >> 24;
621                            }
622                            // write from buffer directly (physically) into .gig file
623                            iter->gig_sample->Write(dstbuf, n);
624                            cnt -= n;
625                        }
626                        delete[] srcbuf;
627                        delete[] dstbuf;
628                      break;                      break;
629                    }
630              }              }
             // write from buffer directly (physically) into .gig file  
             (*iter).gig_sample->Write(buffer, info.frames);  
631              // cleanup              // cleanup
632              sf_close(hFile);              sf_close(hFile);
             delete[] buffer;  
633              // on success we remove the sample from the import queue,              // on success we remove the sample from the import queue,
634              // otherwise keep it, maybe it works the next time ?              // otherwise keep it, maybe it works the next time ?
635              std::list<SampleImportItem>::iterator cur = iter;              std::list<SampleImportItem>::iterator cur = iter;
# Line 626  void PropDialog::set_info(DLS::Info* inf Line 721  void PropDialog::set_info(DLS::Info* inf
721      entry[15].set_text(info->Subject);      entry[15].set_text(info->Subject);
722  }  }
723    
724    void InstrumentProps::add_prop(BoolEntry& boolentry)
725    {
726        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
727                     Gtk::FILL, Gtk::SHRINK);
728        rowno++;
729        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
730    }
731    
732    void InstrumentProps::add_prop(BoolEntryPlus6& boolentry)
733    {
734        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
735                     Gtk::FILL, Gtk::SHRINK);
736        rowno++;
737        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
738    }
739    
740  void InstrumentProps::add_prop(LabelWidget& prop)  void InstrumentProps::add_prop(LabelWidget& prop)
741  {  {
742      table.attach(prop.label, 0, 1, rowno, rowno + 1,      table.attach(prop.label, 0, 1, rowno, rowno + 1,
# Line 633  void InstrumentProps::add_prop(LabelWidg Line 744  void InstrumentProps::add_prop(LabelWidg
744      table.attach(prop.widget, 1, 2, rowno, rowno + 1,      table.attach(prop.widget, 1, 2, rowno, rowno + 1,
745                   Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);                   Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
746      rowno++;      rowno++;
747        prop.signal_changed_by_user().connect(instrument_changed.make_slot());
748  }  }
749    
750  InstrumentProps::InstrumentProps()  InstrumentProps::InstrumentProps()
751      : table(2,1),      : table(2,1),
752        quitButton(Gtk::Stock::CLOSE),        quitButton(Gtk::Stock::CLOSE),
753        eName("Name"),        eName("Name"),
754        eIsDrum("IsDrum"),        eIsDrum("Is drum"),
755        eMIDIBank("MIDIBank", 0, 16383),        eMIDIBank("MIDI bank", 0, 16383),
756        eMIDIProgram("MIDIProgram"),        eMIDIProgram("MIDI program"),
757        eAttenuation("Attenuation", 0, 96, 0, 1),        eAttenuation("Attenuation", 0, 96, 0, 1),
758        eGainPlus6("Gain +6dB", eAttenuation, -6),        eGainPlus6("Gain +6dB", eAttenuation, -6),
759        eEffectSend("EffectSend", 0, 65535),        eEffectSend("Effect send", 0, 65535),
760        eFineTune("FineTune", -8400, 8400),        eFineTune("Fine tune", -8400, 8400),
761        ePitchbendRange("PitchbendRange", 0, 12),        ePitchbendRange("Pitchbend range", 0, 12),
762        ePianoReleaseMode("PianoReleaseMode"),        ePianoReleaseMode("Piano release mode"),
763        eDimensionKeyRangeLow("DimensionKeyRangeLow"),        eDimensionKeyRangeLow("Dimension key range low"),
764        eDimensionKeyRangeHigh("DimensionKeyRangeHigh")        eDimensionKeyRangeHigh("Dimension key range high")
765  {  {
766      set_title("Instrument properties");      set_title("Instrument properties");
767    
# Line 669  InstrumentProps::InstrumentProps() Line 781  InstrumentProps::InstrumentProps()
781      add_prop(eDimensionKeyRangeLow);      add_prop(eDimensionKeyRangeLow);
782      add_prop(eDimensionKeyRangeHigh);      add_prop(eDimensionKeyRangeHigh);
783    
784      eDimensionKeyRangeLow.signal_value_changed().connect(      eDimensionKeyRangeLow.signal_changed_by_user().connect(
785          sigc::mem_fun(*this, &InstrumentProps::key_range_low_changed));          sigc::mem_fun(*this, &InstrumentProps::key_range_low_changed));
786      eDimensionKeyRangeHigh.signal_value_changed().connect(      eDimensionKeyRangeHigh.signal_changed_by_user().connect(
787          sigc::mem_fun(*this, &InstrumentProps::key_range_high_changed));          sigc::mem_fun(*this, &InstrumentProps::key_range_high_changed));
788    
789      add(vbox);      add(vbox);
# Line 696  InstrumentProps::InstrumentProps() Line 808  InstrumentProps::InstrumentProps()
808    
809  void InstrumentProps::set_instrument(gig::Instrument* instrument)  void InstrumentProps::set_instrument(gig::Instrument* instrument)
810  {  {
     update_gui = false;  
811      eName.set_ptr(&instrument->pInfo->Name);      eName.set_ptr(&instrument->pInfo->Name);
812      eIsDrum.set_ptr(&instrument->IsDrum);      eIsDrum.set_ptr(&instrument->IsDrum);
813      eMIDIBank.set_ptr(&instrument->MIDIBank);      eMIDIBank.set_ptr(&instrument->MIDIBank);
# Line 707  void InstrumentProps::set_instrument(gig Line 818  void InstrumentProps::set_instrument(gig
818      eFineTune.set_ptr(&instrument->FineTune);      eFineTune.set_ptr(&instrument->FineTune);
819      ePitchbendRange.set_ptr(&instrument->PitchbendRange);      ePitchbendRange.set_ptr(&instrument->PitchbendRange);
820      ePianoReleaseMode.set_ptr(&instrument->PianoReleaseMode);      ePianoReleaseMode.set_ptr(&instrument->PianoReleaseMode);
821        eDimensionKeyRangeLow.set_ptr(0);
822        eDimensionKeyRangeHigh.set_ptr(0);
823      eDimensionKeyRangeLow.set_ptr(&instrument->DimensionKeyRange.low);      eDimensionKeyRangeLow.set_ptr(&instrument->DimensionKeyRange.low);
824      eDimensionKeyRangeHigh.set_ptr(&instrument->DimensionKeyRange.high);      eDimensionKeyRangeHigh.set_ptr(&instrument->DimensionKeyRange.high);
     update_gui = true;  
825  }  }
826    
827  void InstrumentProps::key_range_low_changed()  void InstrumentProps::key_range_low_changed()
# Line 726  void InstrumentProps::key_range_high_cha Line 838  void InstrumentProps::key_range_high_cha
838      if (h < l) eDimensionKeyRangeLow.set_value(h);      if (h < l) eDimensionKeyRangeLow.set_value(h);
839  }  }
840    
841  void MainWindow::load_gig(gig::File* gig, const char* filename)  sigc::signal<void> InstrumentProps::signal_instrument_changed()
842  {  {
843      file = gig;      return instrument_changed;
844    }
845    
846      if (filename) {  void MainWindow::file_changed()
847          const char *basename = strrchr(filename, '/');  {
848          basename = basename ? basename + 1 : filename;      if (file && !file_is_changed) {
849          set_title(basename);          set_title("*" + get_title());
850      } else {          file_is_changed = true;
         set_title("unnamed");  
851      }      }
852    }
853    
854    void MainWindow::load_gig(gig::File* gig, const char* filename)
855    {
856        file = 0;
857    
858        this->filename = filename ? filename : _("Unsaved Gig File");
859        set_title(Glib::filename_display_basename(this->filename));
860        file_has_name = filename;
861        file_is_changed = false;
862    
863      propDialog.set_info(gig->pInfo);      propDialog.set_info(gig->pInfo);
864    
# Line 785  void MainWindow::load_gig(gig::File* gig Line 907  void MainWindow::load_gig(gig::File* gig
907          }          }
908      }      }
909    
910        file = gig;
911    
912      // select the first instrument      // select the first instrument
913      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
914      tree_sel_ref->select(Gtk::TreePath("0"));      tree_sel_ref->select(Gtk::TreePath("0"));
# Line 858  void MainWindow::on_action_add_instrumen Line 982  void MainWindow::on_action_add_instrumen
982      Gtk::TreeModel::Row rowInstr = *iterInstr;      Gtk::TreeModel::Row rowInstr = *iterInstr;
983      rowInstr[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();      rowInstr[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();
984      rowInstr[m_Columns.m_col_instr] = instrument;      rowInstr[m_Columns.m_col_instr] = instrument;
985        file_changed();
986  }  }
987    
988  void MainWindow::on_action_remove_instrument() {  void MainWindow::on_action_remove_instrument() {
# Line 872  void MainWindow::on_action_remove_instru Line 997  void MainWindow::on_action_remove_instru
997              if (instr) file->DeleteInstrument(instr);              if (instr) file->DeleteInstrument(instr);
998              // remove respective row from instruments tree view              // remove respective row from instruments tree view
999              m_refTreeModel->erase(it);              m_refTreeModel->erase(it);
1000                file_changed();
1001          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1002              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1003              msg.run();              msg.run();
# Line 900  void MainWindow::on_action_add_group() { Line 1026  void MainWindow::on_action_add_group() {
1026      rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();      rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();
1027      rowGroup[m_SamplesModel.m_col_sample] = NULL;      rowGroup[m_SamplesModel.m_col_sample] = NULL;
1028      rowGroup[m_SamplesModel.m_col_group] = group;      rowGroup[m_SamplesModel.m_col_group] = group;
1029        file_changed();
1030  }  }
1031    
1032  void MainWindow::on_action_add_sample() {  void MainWindow::on_action_add_sample() {
# Line 925  void MainWindow::on_action_add_sample() Line 1052  void MainWindow::on_action_add_sample()
1052      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1053      dialog.set_select_multiple(true);      dialog.set_select_multiple(true);
1054      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile
1055      const char* supportedFileTypes[] = {      const char* const supportedFileTypes[] = {
1056          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",
1057          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",
1058          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",
# Line 955  void MainWindow::on_action_add_sample() Line 1082  void MainWindow::on_action_add_sample()
1082                  int bitdepth;                  int bitdepth;
1083                  switch (info.format & 0xff) {                  switch (info.format & 0xff) {
1084                      case SF_FORMAT_PCM_S8:                      case SF_FORMAT_PCM_S8:
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1085                      case SF_FORMAT_PCM_16:                      case SF_FORMAT_PCM_16:
1086                        case SF_FORMAT_PCM_U8:
1087                          bitdepth = 16;                          bitdepth = 16;
1088                          break;                          break;
1089                      case SF_FORMAT_PCM_24:                      case SF_FORMAT_PCM_24:
                         bitdepth = 32; // we simply convert to 32 bit for now  
                         break;  
1090                      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;  
1091                      case SF_FORMAT_FLOAT:                      case SF_FORMAT_FLOAT:
                         bitdepth = 32;  
                         break;  
1092                      case SF_FORMAT_DOUBLE:                      case SF_FORMAT_DOUBLE:
1093                          bitdepth = 32; // I guess we will always truncate this to 32 bit                          bitdepth = 24;
1094                          break;                          break;
1095                      default:                      default:
1096                          sf_close(hFile); // close sound file                          sf_close(hFile); // close sound file
# Line 982  void MainWindow::on_action_add_sample() Line 1099  void MainWindow::on_action_add_sample()
1099                  // add a new sample to the .gig file                  // add a new sample to the .gig file
1100                  gig::Sample* sample = file->AddSample();                  gig::Sample* sample = file->AddSample();
1101                  // file name without path                  // file name without path
1102                  sample->pInfo->Name = (*iter).substr((*iter).rfind('/') + 1).raw();                  Glib::ustring filename = Glib::filename_display_basename(*iter);
1103                    // remove file extension if there is one
1104                    for (int i = 0; supportedFileTypes[i]; i++) {
1105                        if (Glib::str_has_suffix(filename, supportedFileTypes[i] + 1)) {
1106                            filename.erase(filename.length() - strlen(supportedFileTypes[i] + 1));
1107                            break;
1108                        }
1109                    }
1110                    sample->pInfo->Name = filename;
1111                  sample->Channels = info.channels;                  sample->Channels = info.channels;
1112                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
1113                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
1114                  sample->SamplesPerSecond = info.samplerate;                  sample->SamplesPerSecond = info.samplerate;
1115                    sample->AverageBytesPerSecond = sample->FrameSize * sample->SamplesPerSecond;
1116                    sample->BlockAlign = sample->FrameSize;
1117                    sample->SamplesTotal = info.frames;
1118    
1119                    SF_INSTRUMENT instrument;
1120                    if (sf_command(hFile, SFC_GET_INSTRUMENT,
1121                                   &instrument, sizeof(instrument)) != SF_FALSE)
1122                    {
1123                        sample->MIDIUnityNote = instrument.basenote;
1124    
1125                        if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
1126                            sample->Loops = 1;
1127    
1128                            switch (instrument.loops[0].mode) {
1129                            case SF_LOOP_FORWARD:
1130                                sample->LoopType = gig::loop_type_normal;
1131                                break;
1132                            case SF_LOOP_BACKWARD:
1133                                sample->LoopType = gig::loop_type_backward;
1134                                break;
1135                            case SF_LOOP_ALTERNATING:
1136                                sample->LoopType = gig::loop_type_bidirectional;
1137                                break;
1138                            }
1139                            sample->LoopStart = instrument.loops[0].start;
1140                            sample->LoopEnd = instrument.loops[0].end;
1141                            sample->LoopPlayCount = instrument.loops[0].count;
1142                            sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;
1143                        }
1144                    }
1145    
1146                  // schedule resizing the sample (which will be done                  // schedule resizing the sample (which will be done
1147                  // physically when File::Save() is called)                  // physically when File::Save() is called)
1148                  sample->Resize(info.frames);                  sample->Resize(info.frames);
# Line 1002  void MainWindow::on_action_add_sample() Line 1158  void MainWindow::on_action_add_sample()
1158                  Gtk::TreeModel::iterator iterSample =                  Gtk::TreeModel::iterator iterSample =
1159                      m_refSamplesTreeModel->append(row.children());                      m_refSamplesTreeModel->append(row.children());
1160                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
1161                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name]   = filename;
1162                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
1163                  rowSample[m_SamplesModel.m_col_group]  = NULL;                  rowSample[m_SamplesModel.m_col_group]  = NULL;
1164                  // close sound file                  // close sound file
1165                  sf_close(hFile);                  sf_close(hFile);
1166                    file_changed();
1167              } catch (std::string what) { // remember the files that made trouble (and their cause)              } catch (std::string what) { // remember the files that made trouble (and their cause)
1168                  if (error_files.size()) error_files += "\n";                  if (error_files.size()) error_files += "\n";
1169                  error_files += *iter += " (" + what + ")";                  error_files += *iter += " (" + what + ")";
# Line 1057  void MainWindow::on_action_remove_sample Line 1214  void MainWindow::on_action_remove_sample
1214                          }                          }
1215                      }                      }
1216                  }                  }
1217                    file_changed();
1218              } else if (sample) {              } else if (sample) {
1219                  // remove sample from the .gig file                  // remove sample from the .gig file
1220                  file->DeleteSample(sample);                  file->DeleteSample(sample);
# Line 1071  void MainWindow::on_action_remove_sample Line 1229  void MainWindow::on_action_remove_sample
1229                          break;                          break;
1230                      }                      }
1231                  }                  }
1232                    file_changed();
1233              }              }
1234              // remove respective row(s) from samples tree view              // remove respective row(s) from samples tree view
1235              m_refSamplesTreeModel->erase(it);              m_refSamplesTreeModel->erase(it);
# Line 1101  void MainWindow::on_sample_label_drop_dr Line 1260  void MainWindow::on_sample_label_drop_dr
1260      const Glib::RefPtr<Gdk::DragContext>& context, int, int,      const Glib::RefPtr<Gdk::DragContext>& context, int, int,
1261      const Gtk::SelectionData& selection_data, guint, guint time)      const Gtk::SelectionData& selection_data, guint, guint time)
1262  {  {
     gig::DimensionRegion* dimregion = m_DimRegionChooser.get_dimregion();  
1263      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1264    
1265      if (sample && dimregion && selection_data.get_length() == sizeof(gig::Sample*)) {      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {
1266          if (sample != dimregion->pSample) {          if (dimreg_edit.set_sample(sample)) {
             dimregion->pSample = sample;  
             dimreg_edit.wSample->set_text(dimregion->pSample->pInfo->Name.c_str());  
1267              std::cout << "Drop received sample \"" <<              std::cout << "Drop received sample \"" <<
1268                  dimregion->pSample->pInfo->Name.c_str() << "\"" << std::endl;                  sample->pInfo->Name << "\"" << std::endl;
1269              // drop success              // drop success
1270              context->drop_reply(true, time);              context->drop_reply(true, time);
1271              return;              return;
# Line 1127  void MainWindow::sample_name_changed(con Line 1283  void MainWindow::sample_name_changed(con
1283      gig::Group* group   = row[m_SamplesModel.m_col_group];      gig::Group* group   = row[m_SamplesModel.m_col_group];
1284      gig::Sample* sample = row[m_SamplesModel.m_col_sample];      gig::Sample* sample = row[m_SamplesModel.m_col_sample];
1285      if (group) {      if (group) {
1286          group->Name = name;          if (group->Name != name) {
1287                group->Name = name;
1288                printf("group name changed\n");
1289                file_changed();
1290            }
1291      } else if (sample) {      } else if (sample) {
1292          sample->pInfo->Name = name.raw();          if (sample->pInfo->Name != name.raw()) {
1293                sample->pInfo->Name = name.raw();
1294                printf("sample name changed\n");
1295                file_changed();
1296            }
1297      }      }
1298  }  }
1299    
# Line 1139  void MainWindow::instrument_name_changed Line 1303  void MainWindow::instrument_name_changed
1303      Gtk::TreeModel::Row row = *iter;      Gtk::TreeModel::Row row = *iter;
1304      Glib::ustring name = row[m_Columns.m_col_name];      Glib::ustring name = row[m_Columns.m_col_name];
1305      gig::Instrument* instrument = row[m_Columns.m_col_instr];      gig::Instrument* instrument = row[m_Columns.m_col_instr];
1306      if (instrument) instrument->pInfo->Name = name.raw();      if (instrument && instrument->pInfo->Name != name.raw()) {
1307            instrument->pInfo->Name = name.raw();
1308            file_changed();
1309        }
1310  }  }

Legend:
Removed from v.1225  
changed lines
  Added in v.1265

  ViewVC Help
Powered by ViewVC