/[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 1300 by schoenebeck, Fri Aug 24 19:11:41 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    
257        // start with a new gig file by default
258        on_action_file_new();
259  }  }
260    
261  MainWindow::~MainWindow()  MainWindow::~MainWindow()
262  {  {
263  }  }
264    
265    bool MainWindow::on_delete_event(GdkEventAny* event)
266    {
267        return file_is_changed && !close_confirmation_dialog();
268    }
269    
270    void MainWindow::on_action_quit()
271    {
272        if (file_is_changed && !close_confirmation_dialog()) return;
273        hide();
274    }
275    
276  void MainWindow::region_changed()  void MainWindow::region_changed()
277  {  {
278      m_DimRegionChooser.set_region(m_RegionChooser.get_region());      m_DimRegionChooser.set_region(m_RegionChooser.get_region());
# Line 370  void MainWindow::__clear() { Line 391  void MainWindow::__clear() {
391    
392  void MainWindow::on_action_file_new()  void MainWindow::on_action_file_new()
393  {  {
394        if (file_is_changed && !close_confirmation_dialog()) return;
395    
396      // clear all GUI elements      // clear all GUI elements
397      __clear();      __clear();
398      // create a new .gig file (virtually yet)      // create a new .gig file (virtually yet)
# Line 378  void MainWindow::on_action_file_new() Line 401  void MainWindow::on_action_file_new()
401      gig::Instrument* pInstrument = pFile->AddInstrument();      gig::Instrument* pInstrument = pFile->AddInstrument();
402      pInstrument->pInfo->Name = "Unnamed Instrument";      pInstrument->pInfo->Name = "Unnamed Instrument";
403      // update GUI with that new gig::File      // update GUI with that new gig::File
404      load_gig(pFile, NULL /*no file name yet*/);      load_gig(pFile, 0 /*no file name yet*/);
405    }
406    
407    bool MainWindow::close_confirmation_dialog()
408    {
409        gchar* msg = g_strdup_printf(_("Save changes to \"%s\" before closing?"),
410                                     Glib::filename_display_basename(filename).c_str());
411        Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
412        g_free(msg);
413        dialog.set_secondary_text(_("If you close without saving, your changes will be lost."));
414        dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);
415        dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
416        dialog.add_button(file_has_name ? Gtk::Stock::SAVE : Gtk::Stock::SAVE_AS, Gtk::RESPONSE_YES);
417        dialog.set_default_response(Gtk::RESPONSE_YES);
418        int response = dialog.run();
419        if (response == Gtk::RESPONSE_YES) return file_save();
420        return response != Gtk::RESPONSE_CANCEL;
421  }  }
422    
423  void MainWindow::on_action_file_open()  void MainWindow::on_action_file_open()
424  {  {
425        if (file_is_changed && !close_confirmation_dialog()) return;
426    
427      Gtk::FileChooserDialog dialog(*this, _("Open file"));      Gtk::FileChooserDialog dialog(*this, _("Open file"));
428      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
429      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
430        dialog.set_default_response(Gtk::RESPONSE_OK);
431      Gtk::FileFilter filter;      Gtk::FileFilter filter;
432      filter.add_pattern("*.gig");      filter.add_pattern("*.gig");
433      dialog.set_filter(filter);      dialog.set_filter(filter);
434        if (current_dir != "") {
435            dialog.set_current_folder(current_dir);
436        }
437      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
438          printf("filename=%s\n", dialog.get_filename().c_str());          std::string filename = dialog.get_filename();
439            printf("filename=%s\n", filename.c_str());
440          __clear();          __clear();
441          printf("on_action_file_open self=%x\n", Glib::Thread::self());          printf("on_action_file_open self=%x\n", Glib::Thread::self());
442          load_file(dialog.get_filename().c_str());          load_file(filename.c_str());
443            current_dir = Glib::path_get_dirname(filename);
444      }      }
445  }  }
446    
# Line 417  void MainWindow::load_instrument(gig::In Line 464  void MainWindow::load_instrument(gig::In
464          Gtk::Main::quit();          Gtk::Main::quit();
465      }      }
466      gig::File* pFile = (gig::File*) instr->GetParent();      gig::File* pFile = (gig::File*) instr->GetParent();
467      load_gig(pFile, NULL /*file name*/);      load_gig(pFile, 0 /*file name*/);
468      //TODO: automatically select the given instrument      //TODO: automatically select the given instrument
469  }  }
470    
# Line 436  void MainWindow::on_loader_finished() Line 483  void MainWindow::on_loader_finished()
483    
484  void MainWindow::on_action_file_save()  void MainWindow::on_action_file_save()
485  {  {
486      if (!file) return;      file_save();
487    }
488    
489    bool MainWindow::file_save()
490    {
491        if (!file) return false;
492        if (!file_has_name) return file_save_as();
493    
494      std::cout << "Saving file\n" << std::flush;      std::cout << "Saving file\n" << std::flush;
495      try {      try {
496          file->Save();          file->Save();
497            if (file_is_changed) {
498                set_title(get_title().substr(1));
499                file_is_changed = false;
500            }
501      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
502          Glib::ustring txt = "Could not save file: " + e.Message;          Glib::ustring txt = "Could not save file: " + e.Message;
503          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
504          msg.run();          msg.run();
505          return;          return false;
506      }      }
507      std::cout << "Saving file done\n" << std::flush;      std::cout << "Saving file done\n" << std::flush;
508      __import_queued_samples();      __import_queued_samples();
509        return true;
510  }  }
511    
512  void MainWindow::on_action_file_save_as()  void MainWindow::on_action_file_save_as()
513  {  {
514      if (!file) return;      file_save_as();
515      Gtk::FileChooserDialog dialog(*this, "Open", Gtk::FILE_CHOOSER_ACTION_SAVE);  }
516    
517    bool MainWindow::file_save_as()
518    {
519        if (!file) return false;
520        Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);
521      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
522      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
523        dialog.set_default_response(Gtk::RESPONSE_OK);
524    
525    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 8) || GTKMM_MAJOR_VERSION > 2
526        dialog.set_do_overwrite_confirmation();
527        // TODO: an overwrite dialog for gtkmm < 2.8
528    #endif
529      Gtk::FileFilter filter;      Gtk::FileFilter filter;
530      filter.add_pattern("*.gig");      filter.add_pattern("*.gig");
531      dialog.set_filter(filter);      dialog.set_filter(filter);
532    
533        if (Glib::path_is_absolute(filename)) {
534            dialog.set_filename(filename);
535        } else if (current_dir != "") {
536            dialog.set_current_folder(current_dir);
537        }
538        dialog.set_current_name(Glib::filename_display_basename(filename));
539    
540      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
         printf("filename=%s\n", dialog.get_filename().c_str());  
541          try {          try {
542              file->Save(dialog.get_filename());              std::string filename = dialog.get_filename();
543                if (!Glib::str_has_suffix(filename, ".gig")) {
544                    filename += ".gig";
545                }
546                printf("filename=%s\n", filename.c_str());
547                file->Save(filename);
548                this->filename = filename;
549                current_dir = Glib::path_get_dirname(filename);
550                set_title(Glib::filename_display_basename(filename));
551                file_has_name = true;
552                file_is_changed = false;
553          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
554              Glib::ustring txt = "Could not save file: " + e.Message;              Glib::ustring txt = "Could not save file: " + e.Message;
555              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
556              msg.run();              msg.run();
557              return;              return false;
558          }          }
559          __import_queued_samples();          __import_queued_samples();
560            return true;
561      }      }
562        return false;
563  }  }
564    
565  // 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 579  void MainWindow::__import_queued_samples
579              int bitdepth;              int bitdepth;
580              switch (info.format & 0xff) {              switch (info.format & 0xff) {
581                  case SF_FORMAT_PCM_S8:                  case SF_FORMAT_PCM_S8:
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
582                  case SF_FORMAT_PCM_16:                  case SF_FORMAT_PCM_16:
583                    case SF_FORMAT_PCM_U8:
584                      bitdepth = 16;                      bitdepth = 16;
585                      break;                      break;
586                  case SF_FORMAT_PCM_24:                  case SF_FORMAT_PCM_24:
                     bitdepth = 32; // we simply convert to 32 bit for now  
                     break;  
587                  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;  
588                  case SF_FORMAT_FLOAT:                  case SF_FORMAT_FLOAT:
                     bitdepth = 32;  
                     break;  
589                  case SF_FORMAT_DOUBLE:                  case SF_FORMAT_DOUBLE:
590                      bitdepth = 32; // I guess we will always truncate this to 32 bit                      bitdepth = 24;
591                      break;                      break;
592                  default:                  default:
593                      sf_close(hFile); // close sound file                      sf_close(hFile); // close sound file
594                      throw std::string("format not supported"); // unsupported subformat (yet?)                      throw std::string("format not supported"); // unsupported subformat (yet?)
595              }              }
596              // allocate appropriate copy buffer (TODO: for now we copy  
597              // 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;  
598              switch (bitdepth) {              switch (bitdepth) {
599                  case 16:                  case 16: {
600                      buffer = new int8_t[2 * info.channels * info.frames];                      short* buffer = new short[bufsize * info.channels];
601                      // libsndfile does the conversion for us (if needed)                      sf_count_t cnt = info.frames;
602                      sf_readf_short(hFile, (short*) buffer, info.frames);                      while (cnt) {
603                            // libsndfile does the conversion for us (if needed)
604                            int n = sf_readf_short(hFile, buffer, bufsize);
605                            // write from buffer directly (physically) into .gig file
606                            iter->gig_sample->Write(buffer, n);
607                            cnt -= n;
608                        }
609                        delete[] buffer;
610                      break;                      break;
611                  case 32:                  }
612                      buffer = new int8_t[4 * info.channels * info.frames];                  case 24: {
613                      // libsndfile does the conversion for us (if needed)                      int* srcbuf = new int[bufsize * info.channels];
614                      sf_readf_int(hFile, (int*) buffer, info.frames);                      uint8_t* dstbuf = new uint8_t[bufsize * 3 * info.channels];
615                        sf_count_t cnt = info.frames;
616                        while (cnt) {
617                            // libsndfile returns 32 bits, convert to 24
618                            int n = sf_readf_int(hFile, srcbuf, bufsize);
619                            int j = 0;
620                            for (int i = 0 ; i < n * info.channels ; i++) {
621                                dstbuf[j++] = srcbuf[i] >> 8;
622                                dstbuf[j++] = srcbuf[i] >> 16;
623                                dstbuf[j++] = srcbuf[i] >> 24;
624                            }
625                            // write from buffer directly (physically) into .gig file
626                            iter->gig_sample->Write(dstbuf, n);
627                            cnt -= n;
628                        }
629                        delete[] srcbuf;
630                        delete[] dstbuf;
631                      break;                      break;
632                    }
633              }              }
             // write from buffer directly (physically) into .gig file  
             (*iter).gig_sample->Write(buffer, info.frames);  
634              // cleanup              // cleanup
635              sf_close(hFile);              sf_close(hFile);
             delete[] buffer;  
636              // on success we remove the sample from the import queue,              // on success we remove the sample from the import queue,
637              // otherwise keep it, maybe it works the next time ?              // otherwise keep it, maybe it works the next time ?
638              std::list<SampleImportItem>::iterator cur = iter;              std::list<SampleImportItem>::iterator cur = iter;
# Line 626  void PropDialog::set_info(DLS::Info* inf Line 724  void PropDialog::set_info(DLS::Info* inf
724      entry[15].set_text(info->Subject);      entry[15].set_text(info->Subject);
725  }  }
726    
727    void InstrumentProps::add_prop(BoolEntry& boolentry)
728    {
729        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
730                     Gtk::FILL, Gtk::SHRINK);
731        rowno++;
732        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
733    }
734    
735    void InstrumentProps::add_prop(BoolEntryPlus6& boolentry)
736    {
737        table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,
738                     Gtk::FILL, Gtk::SHRINK);
739        rowno++;
740        boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());
741    }
742    
743  void InstrumentProps::add_prop(LabelWidget& prop)  void InstrumentProps::add_prop(LabelWidget& prop)
744  {  {
745      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 747  void InstrumentProps::add_prop(LabelWidg
747      table.attach(prop.widget, 1, 2, rowno, rowno + 1,      table.attach(prop.widget, 1, 2, rowno, rowno + 1,
748                   Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);                   Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
749      rowno++;      rowno++;
750        prop.signal_changed_by_user().connect(instrument_changed.make_slot());
751  }  }
752    
753  InstrumentProps::InstrumentProps()  InstrumentProps::InstrumentProps()
754      : table(2,1),      : table(2,1),
755        quitButton(Gtk::Stock::CLOSE),        quitButton(Gtk::Stock::CLOSE),
756        eName("Name"),        eName("Name"),
757        eIsDrum("IsDrum"),        eIsDrum("Is drum"),
758        eMIDIBank("MIDIBank", 0, 16383),        eMIDIBank("MIDI bank", 0, 16383),
759        eMIDIProgram("MIDIProgram"),        eMIDIProgram("MIDI program"),
760        eAttenuation("Attenuation", 0, 96, 0, 1),        eAttenuation("Attenuation", 0, 96, 0, 1),
761        eGainPlus6("Gain +6dB", eAttenuation, -6),        eGainPlus6("Gain +6dB", eAttenuation, -6),
762        eEffectSend("EffectSend", 0, 65535),        eEffectSend("Effect send", 0, 65535),
763        eFineTune("FineTune", -8400, 8400),        eFineTune("Fine tune", -8400, 8400),
764        ePitchbendRange("PitchbendRange", 0, 12),        ePitchbendRange("Pitchbend range", 0, 12),
765        ePianoReleaseMode("PianoReleaseMode"),        ePianoReleaseMode("Piano release mode"),
766        eDimensionKeyRangeLow("DimensionKeyRangeLow"),        eDimensionKeyRangeLow("Dimension key range low"),
767        eDimensionKeyRangeHigh("DimensionKeyRangeHigh")        eDimensionKeyRangeHigh("Dimension key range high")
768  {  {
769      set_title("Instrument properties");      set_title("Instrument properties");
770    
# Line 669  InstrumentProps::InstrumentProps() Line 784  InstrumentProps::InstrumentProps()
784      add_prop(eDimensionKeyRangeLow);      add_prop(eDimensionKeyRangeLow);
785      add_prop(eDimensionKeyRangeHigh);      add_prop(eDimensionKeyRangeHigh);
786    
787      eDimensionKeyRangeLow.signal_value_changed().connect(      eDimensionKeyRangeLow.signal_changed_by_user().connect(
788          sigc::mem_fun(*this, &InstrumentProps::key_range_low_changed));          sigc::mem_fun(*this, &InstrumentProps::key_range_low_changed));
789      eDimensionKeyRangeHigh.signal_value_changed().connect(      eDimensionKeyRangeHigh.signal_changed_by_user().connect(
790          sigc::mem_fun(*this, &InstrumentProps::key_range_high_changed));          sigc::mem_fun(*this, &InstrumentProps::key_range_high_changed));
791    
792      add(vbox);      add(vbox);
# Line 696  InstrumentProps::InstrumentProps() Line 811  InstrumentProps::InstrumentProps()
811    
812  void InstrumentProps::set_instrument(gig::Instrument* instrument)  void InstrumentProps::set_instrument(gig::Instrument* instrument)
813  {  {
     update_gui = false;  
814      eName.set_ptr(&instrument->pInfo->Name);      eName.set_ptr(&instrument->pInfo->Name);
815      eIsDrum.set_ptr(&instrument->IsDrum);      eIsDrum.set_ptr(&instrument->IsDrum);
816      eMIDIBank.set_ptr(&instrument->MIDIBank);      eMIDIBank.set_ptr(&instrument->MIDIBank);
# Line 707  void InstrumentProps::set_instrument(gig Line 821  void InstrumentProps::set_instrument(gig
821      eFineTune.set_ptr(&instrument->FineTune);      eFineTune.set_ptr(&instrument->FineTune);
822      ePitchbendRange.set_ptr(&instrument->PitchbendRange);      ePitchbendRange.set_ptr(&instrument->PitchbendRange);
823      ePianoReleaseMode.set_ptr(&instrument->PianoReleaseMode);      ePianoReleaseMode.set_ptr(&instrument->PianoReleaseMode);
824        eDimensionKeyRangeLow.set_ptr(0);
825        eDimensionKeyRangeHigh.set_ptr(0);
826      eDimensionKeyRangeLow.set_ptr(&instrument->DimensionKeyRange.low);      eDimensionKeyRangeLow.set_ptr(&instrument->DimensionKeyRange.low);
827      eDimensionKeyRangeHigh.set_ptr(&instrument->DimensionKeyRange.high);      eDimensionKeyRangeHigh.set_ptr(&instrument->DimensionKeyRange.high);
     update_gui = true;  
828  }  }
829    
830  void InstrumentProps::key_range_low_changed()  void InstrumentProps::key_range_low_changed()
# Line 726  void InstrumentProps::key_range_high_cha Line 841  void InstrumentProps::key_range_high_cha
841      if (h < l) eDimensionKeyRangeLow.set_value(h);      if (h < l) eDimensionKeyRangeLow.set_value(h);
842  }  }
843    
844  void MainWindow::load_gig(gig::File* gig, const char* filename)  sigc::signal<void> InstrumentProps::signal_instrument_changed()
845  {  {
846      file = gig;      return instrument_changed;
847    }
848    
849      if (filename) {  void MainWindow::file_changed()
850          const char *basename = strrchr(filename, '/');  {
851          basename = basename ? basename + 1 : filename;      if (file && !file_is_changed) {
852          set_title(basename);          set_title("*" + get_title());
853      } else {          file_is_changed = true;
         set_title("unnamed");  
854      }      }
855    }
856    
857    void MainWindow::load_gig(gig::File* gig, const char* filename)
858    {
859        file = 0;
860    
861        this->filename = filename ? filename : _("Unsaved Gig File");
862        set_title(Glib::filename_display_basename(this->filename));
863        file_has_name = filename;
864        file_is_changed = false;
865    
866      propDialog.set_info(gig->pInfo);      propDialog.set_info(gig->pInfo);
867    
# Line 785  void MainWindow::load_gig(gig::File* gig Line 910  void MainWindow::load_gig(gig::File* gig
910          }          }
911      }      }
912    
913        file = gig;
914    
915      // select the first instrument      // select the first instrument
916      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
917      tree_sel_ref->select(Gtk::TreePath("0"));      tree_sel_ref->select(Gtk::TreePath("0"));
# Line 858  void MainWindow::on_action_add_instrumen Line 985  void MainWindow::on_action_add_instrumen
985      Gtk::TreeModel::Row rowInstr = *iterInstr;      Gtk::TreeModel::Row rowInstr = *iterInstr;
986      rowInstr[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();      rowInstr[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();
987      rowInstr[m_Columns.m_col_instr] = instrument;      rowInstr[m_Columns.m_col_instr] = instrument;
988        file_changed();
989  }  }
990    
991  void MainWindow::on_action_remove_instrument() {  void MainWindow::on_action_remove_instrument() {
# Line 872  void MainWindow::on_action_remove_instru Line 1000  void MainWindow::on_action_remove_instru
1000              if (instr) file->DeleteInstrument(instr);              if (instr) file->DeleteInstrument(instr);
1001              // remove respective row from instruments tree view              // remove respective row from instruments tree view
1002              m_refTreeModel->erase(it);              m_refTreeModel->erase(it);
1003                file_changed();
1004          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1005              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1006              msg.run();              msg.run();
# Line 900  void MainWindow::on_action_add_group() { Line 1029  void MainWindow::on_action_add_group() {
1029      rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();      rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();
1030      rowGroup[m_SamplesModel.m_col_sample] = NULL;      rowGroup[m_SamplesModel.m_col_sample] = NULL;
1031      rowGroup[m_SamplesModel.m_col_group] = group;      rowGroup[m_SamplesModel.m_col_group] = group;
1032        file_changed();
1033  }  }
1034    
1035  void MainWindow::on_action_add_sample() {  void MainWindow::on_action_add_sample() {
# Line 925  void MainWindow::on_action_add_sample() Line 1055  void MainWindow::on_action_add_sample()
1055      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);      dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1056      dialog.set_select_multiple(true);      dialog.set_select_multiple(true);
1057      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile      Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile
1058      const char* supportedFileTypes[] = {      const char* const supportedFileTypes[] = {
1059          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",          "*.wav", "*.WAV", "*.aiff", "*.AIFF", "*.aifc", "*.AIFC", "*.snd",
1060          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",          "*.SND", "*.au", "*.AU", "*.paf", "*.PAF", "*.iff", "*.IFF",
1061          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",          "*.svx", "*.SVX", "*.sf", "*.SF", "*.voc", "*.VOC", "*.w64",
# Line 955  void MainWindow::on_action_add_sample() Line 1085  void MainWindow::on_action_add_sample()
1085                  int bitdepth;                  int bitdepth;
1086                  switch (info.format & 0xff) {                  switch (info.format & 0xff) {
1087                      case SF_FORMAT_PCM_S8:                      case SF_FORMAT_PCM_S8:
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1088                      case SF_FORMAT_PCM_16:                      case SF_FORMAT_PCM_16:
1089                        case SF_FORMAT_PCM_U8:
1090                          bitdepth = 16;                          bitdepth = 16;
1091                          break;                          break;
1092                      case SF_FORMAT_PCM_24:                      case SF_FORMAT_PCM_24:
                         bitdepth = 32; // we simply convert to 32 bit for now  
                         break;  
1093                      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;  
1094                      case SF_FORMAT_FLOAT:                      case SF_FORMAT_FLOAT:
                         bitdepth = 32;  
                         break;  
1095                      case SF_FORMAT_DOUBLE:                      case SF_FORMAT_DOUBLE:
1096                          bitdepth = 32; // I guess we will always truncate this to 32 bit                          bitdepth = 24;
1097                          break;                          break;
1098                      default:                      default:
1099                          sf_close(hFile); // close sound file                          sf_close(hFile); // close sound file
# Line 982  void MainWindow::on_action_add_sample() Line 1102  void MainWindow::on_action_add_sample()
1102                  // add a new sample to the .gig file                  // add a new sample to the .gig file
1103                  gig::Sample* sample = file->AddSample();                  gig::Sample* sample = file->AddSample();
1104                  // file name without path                  // file name without path
1105                  sample->pInfo->Name = (*iter).substr((*iter).rfind('/') + 1).raw();                  Glib::ustring filename = Glib::filename_display_basename(*iter);
1106                    // remove file extension if there is one
1107                    for (int i = 0; supportedFileTypes[i]; i++) {
1108                        if (Glib::str_has_suffix(filename, supportedFileTypes[i] + 1)) {
1109                            filename.erase(filename.length() - strlen(supportedFileTypes[i] + 1));
1110                            break;
1111                        }
1112                    }
1113                    sample->pInfo->Name = filename;
1114                  sample->Channels = info.channels;                  sample->Channels = info.channels;
1115                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
1116                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
1117                  sample->SamplesPerSecond = info.samplerate;                  sample->SamplesPerSecond = info.samplerate;
1118                    sample->AverageBytesPerSecond = sample->FrameSize * sample->SamplesPerSecond;
1119                    sample->BlockAlign = sample->FrameSize;
1120                    sample->SamplesTotal = info.frames;
1121    
1122                    SF_INSTRUMENT instrument;
1123                    if (sf_command(hFile, SFC_GET_INSTRUMENT,
1124                                   &instrument, sizeof(instrument)) != SF_FALSE)
1125                    {
1126                        sample->MIDIUnityNote = instrument.basenote;
1127    
1128                        if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
1129                            sample->Loops = 1;
1130    
1131                            switch (instrument.loops[0].mode) {
1132                            case SF_LOOP_FORWARD:
1133                                sample->LoopType = gig::loop_type_normal;
1134                                break;
1135                            case SF_LOOP_BACKWARD:
1136                                sample->LoopType = gig::loop_type_backward;
1137                                break;
1138                            case SF_LOOP_ALTERNATING:
1139                                sample->LoopType = gig::loop_type_bidirectional;
1140                                break;
1141                            }
1142                            sample->LoopStart = instrument.loops[0].start;
1143                            sample->LoopEnd = instrument.loops[0].end;
1144                            sample->LoopPlayCount = instrument.loops[0].count;
1145                            sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;
1146                        }
1147                    }
1148    
1149                  // schedule resizing the sample (which will be done                  // schedule resizing the sample (which will be done
1150                  // physically when File::Save() is called)                  // physically when File::Save() is called)
1151                  sample->Resize(info.frames);                  sample->Resize(info.frames);
# Line 1002  void MainWindow::on_action_add_sample() Line 1161  void MainWindow::on_action_add_sample()
1161                  Gtk::TreeModel::iterator iterSample =                  Gtk::TreeModel::iterator iterSample =
1162                      m_refSamplesTreeModel->append(row.children());                      m_refSamplesTreeModel->append(row.children());
1163                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
1164                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name]   = filename;
1165                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
1166                  rowSample[m_SamplesModel.m_col_group]  = NULL;                  rowSample[m_SamplesModel.m_col_group]  = NULL;
1167                  // close sound file                  // close sound file
1168                  sf_close(hFile);                  sf_close(hFile);
1169                    file_changed();
1170              } 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)
1171                  if (error_files.size()) error_files += "\n";                  if (error_files.size()) error_files += "\n";
1172                  error_files += *iter += " (" + what + ")";                  error_files += *iter += " (" + what + ")";
# Line 1057  void MainWindow::on_action_remove_sample Line 1217  void MainWindow::on_action_remove_sample
1217                          }                          }
1218                      }                      }
1219                  }                  }
1220                    file_changed();
1221              } else if (sample) {              } else if (sample) {
1222                  // remove sample from the .gig file                  // remove sample from the .gig file
1223                  file->DeleteSample(sample);                  file->DeleteSample(sample);
# Line 1071  void MainWindow::on_action_remove_sample Line 1232  void MainWindow::on_action_remove_sample
1232                          break;                          break;
1233                      }                      }
1234                  }                  }
1235                    file_changed();
1236              }              }
1237              // remove respective row(s) from samples tree view              // remove respective row(s) from samples tree view
1238              m_refSamplesTreeModel->erase(it);              m_refSamplesTreeModel->erase(it);
# Line 1101  void MainWindow::on_sample_label_drop_dr Line 1263  void MainWindow::on_sample_label_drop_dr
1263      const Glib::RefPtr<Gdk::DragContext>& context, int, int,      const Glib::RefPtr<Gdk::DragContext>& context, int, int,
1264      const Gtk::SelectionData& selection_data, guint, guint time)      const Gtk::SelectionData& selection_data, guint, guint time)
1265  {  {
     gig::DimensionRegion* dimregion = m_DimRegionChooser.get_dimregion();  
1266      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1267    
1268      if (sample && dimregion && selection_data.get_length() == sizeof(gig::Sample*)) {      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {
1269          if (sample != dimregion->pSample) {          if (dimreg_edit.set_sample(sample)) {
             dimregion->pSample = sample;  
             dimreg_edit.wSample->set_text(dimregion->pSample->pInfo->Name.c_str());  
1270              std::cout << "Drop received sample \"" <<              std::cout << "Drop received sample \"" <<
1271                  dimregion->pSample->pInfo->Name.c_str() << "\"" << std::endl;                  sample->pInfo->Name << "\"" << std::endl;
1272              // drop success              // drop success
1273              context->drop_reply(true, time);              context->drop_reply(true, time);
1274              return;              return;
# Line 1127  void MainWindow::sample_name_changed(con Line 1286  void MainWindow::sample_name_changed(con
1286      gig::Group* group   = row[m_SamplesModel.m_col_group];      gig::Group* group   = row[m_SamplesModel.m_col_group];
1287      gig::Sample* sample = row[m_SamplesModel.m_col_sample];      gig::Sample* sample = row[m_SamplesModel.m_col_sample];
1288      if (group) {      if (group) {
1289          group->Name = name;          if (group->Name != name) {
1290                group->Name = name;
1291                printf("group name changed\n");
1292                file_changed();
1293            }
1294      } else if (sample) {      } else if (sample) {
1295          sample->pInfo->Name = name.raw();          if (sample->pInfo->Name != name.raw()) {
1296                sample->pInfo->Name = name.raw();
1297                printf("sample name changed\n");
1298                file_changed();
1299            }
1300      }      }
1301  }  }
1302    
# Line 1139  void MainWindow::instrument_name_changed Line 1306  void MainWindow::instrument_name_changed
1306      Gtk::TreeModel::Row row = *iter;      Gtk::TreeModel::Row row = *iter;
1307      Glib::ustring name = row[m_Columns.m_col_name];      Glib::ustring name = row[m_Columns.m_col_name];
1308      gig::Instrument* instrument = row[m_Columns.m_col_instr];      gig::Instrument* instrument = row[m_Columns.m_col_instr];
1309      if (instrument) instrument->pInfo->Name = name.raw();      if (instrument && instrument->pInfo->Name != name.raw()) {
1310            instrument->pInfo->Name = name.raw();
1311            file_changed();
1312        }
1313  }  }

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

  ViewVC Help
Powered by ViewVC