/[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 1262 by persson, Sun Jul 22 15:07:08 2007 UTC revision 1328 by schoenebeck, Fri Sep 7 21:18:31 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 460  void MainWindow::load_instrument(gig::In Line 510  void MainWindow::load_instrument(gig::In
510          msg.run();          msg.run();
511          Gtk::Main::quit();          Gtk::Main::quit();
512      }      }
513        // clear all GUI elements
514        __clear();
515        // load the instrument
516      gig::File* pFile = (gig::File*) instr->GetParent();      gig::File* pFile = (gig::File*) instr->GetParent();
517      load_gig(pFile, 0 /*file name*/);      load_gig(pFile, 0 /*file name*/);
518      //TODO: automatically select the given instrument      //TODO: automatically select the given instrument
# Line 483  void MainWindow::on_action_file_save() Line 536  void MainWindow::on_action_file_save()
536      file_save();      file_save();
537  }  }
538    
539  bool MainWindow::file_save()  bool MainWindow::check_if_savable()
540  {  {
541      if (!file) return false;      if (!file) return false;
542    
543        if (!file->GetFirstSample()) {
544            Gtk::MessageDialog(*this, _("The file could not be saved "
545                                        "because it contains no samples"),
546                               false, Gtk::MESSAGE_ERROR).run();
547            return false;
548        }
549    
550        for (gig::Instrument* instrument = file->GetFirstInstrument() ; instrument ;
551             instrument = file->GetNextInstrument()) {
552            if (!instrument->GetFirstRegion()) {
553                Gtk::MessageDialog(*this, _("The file could not be saved "
554                                            "because there are instruments "
555                                            "that have no regions"),
556                                   false, Gtk::MESSAGE_ERROR).run();
557                return false;
558            }
559        }
560        return true;
561    }
562    
563    bool MainWindow::file_save()
564    {
565        if (!check_if_savable()) return false;
566      if (!file_has_name) return file_save_as();      if (!file_has_name) return file_save_as();
567    
568      std::cout << "Saving file\n" << std::flush;      std::cout << "Saving file\n" << std::flush;
569        file_structure_to_be_changed_signal.emit(this->file);
570      try {      try {
571          file->Save();          file->Save();
572          if (file_is_changed) {          if (file_is_changed) {
# Line 496  bool MainWindow::file_save() Line 574  bool MainWindow::file_save()
574              file_is_changed = false;              file_is_changed = false;
575          }          }
576      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
577            file_structure_changed_signal.emit(this->file);
578          Glib::ustring txt = "Could not save file: " + e.Message;          Glib::ustring txt = "Could not save file: " + e.Message;
579          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
580          msg.run();          msg.run();
# Line 503  bool MainWindow::file_save() Line 582  bool MainWindow::file_save()
582      }      }
583      std::cout << "Saving file done\n" << std::flush;      std::cout << "Saving file done\n" << std::flush;
584      __import_queued_samples();      __import_queued_samples();
585        file_structure_changed_signal.emit(this->file);
586      return true;      return true;
587  }  }
588    
589  void MainWindow::on_action_file_save_as()  void MainWindow::on_action_file_save_as()
590  {  {
591        if (!check_if_savable()) return;
592      file_save_as();      file_save_as();
593  }  }
594    
595  bool MainWindow::file_save_as()  bool MainWindow::file_save_as()
596  {  {
     if (!file) return false;  
597      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);
598      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
599      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 615  bool MainWindow::file_save_as()
615      dialog.set_current_name(Glib::filename_display_basename(filename));      dialog.set_current_name(Glib::filename_display_basename(filename));
616    
617      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
618            file_structure_to_be_changed_signal.emit(this->file);
619          try {          try {
620              std::string filename = dialog.get_filename();              std::string filename = dialog.get_filename();
621              if (!Glib::str_has_suffix(filename, ".gig")) {              if (!Glib::str_has_suffix(filename, ".gig")) {
# Line 548  bool MainWindow::file_save_as() Line 629  bool MainWindow::file_save_as()
629              file_has_name = true;              file_has_name = true;
630              file_is_changed = false;              file_is_changed = false;
631          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
632                file_structure_changed_signal.emit(this->file);
633              Glib::ustring txt = "Could not save file: " + e.Message;              Glib::ustring txt = "Could not save file: " + e.Message;
634              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
635              msg.run();              msg.run();
636              return false;              return false;
637          }          }
638          __import_queued_samples();          __import_queued_samples();
639            file_structure_changed_signal.emit(this->file);
640          return true;          return true;
641      }      }
642      return false;      return false;
# Line 576  void MainWindow::__import_queued_samples Line 659  void MainWindow::__import_queued_samples
659              int bitdepth;              int bitdepth;
660              switch (info.format & 0xff) {              switch (info.format & 0xff) {
661                  case SF_FORMAT_PCM_S8:                  case SF_FORMAT_PCM_S8:
                     bitdepth = 16; // we simply convert to 16 bit for now  
                     break;  
662                  case SF_FORMAT_PCM_16:                  case SF_FORMAT_PCM_16:
663                    case SF_FORMAT_PCM_U8:
664                      bitdepth = 16;                      bitdepth = 16;
665                      break;                      break;
666                  case SF_FORMAT_PCM_24:                  case SF_FORMAT_PCM_24:
                     bitdepth = 32; // we simply convert to 32 bit for now  
                     break;  
667                  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;  
668                  case SF_FORMAT_FLOAT:                  case SF_FORMAT_FLOAT:
                     bitdepth = 32;  
                     break;  
669                  case SF_FORMAT_DOUBLE:                  case SF_FORMAT_DOUBLE:
670                      bitdepth = 32; // I guess we will always truncate this to 32 bit                      bitdepth = 24;
671                      break;                      break;
672                  default:                  default:
673                      sf_close(hFile); // close sound file                      sf_close(hFile); // close sound file
674                      throw std::string("format not supported"); // unsupported subformat (yet?)                      throw std::string("format not supported"); // unsupported subformat (yet?)
675              }              }
676              // allocate appropriate copy buffer (TODO: for now we copy  
677              // 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;  
678              switch (bitdepth) {              switch (bitdepth) {
679                  case 16:                  case 16: {
680                      buffer = new int8_t[2 * info.channels * info.frames];                      short* buffer = new short[bufsize * info.channels];
681                      // libsndfile does the conversion for us (if needed)                      sf_count_t cnt = info.frames;
682                      sf_readf_short(hFile, (short*) buffer, info.frames);                      while (cnt) {
683                            // libsndfile does the conversion for us (if needed)
684                            int n = sf_readf_short(hFile, buffer, bufsize);
685                            // write from buffer directly (physically) into .gig file
686                            iter->gig_sample->Write(buffer, n);
687                            cnt -= n;
688                        }
689                        delete[] buffer;
690                      break;                      break;
691                  case 32:                  }
692                      buffer = new int8_t[4 * info.channels * info.frames];                  case 24: {
693                      // libsndfile does the conversion for us (if needed)                      int* srcbuf = new int[bufsize * info.channels];
694                      sf_readf_int(hFile, (int*) buffer, info.frames);                      uint8_t* dstbuf = new uint8_t[bufsize * 3 * info.channels];
695                        sf_count_t cnt = info.frames;
696                        while (cnt) {
697                            // libsndfile returns 32 bits, convert to 24
698                            int n = sf_readf_int(hFile, srcbuf, bufsize);
699                            int j = 0;
700                            for (int i = 0 ; i < n * info.channels ; i++) {
701                                dstbuf[j++] = srcbuf[i] >> 8;
702                                dstbuf[j++] = srcbuf[i] >> 16;
703                                dstbuf[j++] = srcbuf[i] >> 24;
704                            }
705                            // write from buffer directly (physically) into .gig file
706                            iter->gig_sample->Write(dstbuf, n);
707                            cnt -= n;
708                        }
709                        delete[] srcbuf;
710                        delete[] dstbuf;
711                      break;                      break;
712                    }
713              }              }
             // write from buffer directly (physically) into .gig file  
             (*iter).gig_sample->Write(buffer, info.frames);  
714              // cleanup              // cleanup
715              sf_close(hFile);              sf_close(hFile);
             delete[] buffer;  
716              // on success we remove the sample from the import queue,              // on success we remove the sample from the import queue,
717              // otherwise keep it, maybe it works the next time ?              // otherwise keep it, maybe it works the next time ?
718              std::list<SampleImportItem>::iterator cur = iter;              std::list<SampleImportItem>::iterator cur = iter;
# Line 1073  void MainWindow::on_action_add_sample() Line 1165  void MainWindow::on_action_add_sample()
1165                  int bitdepth;                  int bitdepth;
1166                  switch (info.format & 0xff) {                  switch (info.format & 0xff) {
1167                      case SF_FORMAT_PCM_S8:                      case SF_FORMAT_PCM_S8:
                         bitdepth = 16; // we simply convert to 16 bit for now  
                         break;  
1168                      case SF_FORMAT_PCM_16:                      case SF_FORMAT_PCM_16:
1169                        case SF_FORMAT_PCM_U8:
1170                          bitdepth = 16;                          bitdepth = 16;
1171                          break;                          break;
1172                      case SF_FORMAT_PCM_24:                      case SF_FORMAT_PCM_24:
                         bitdepth = 32; // we simply convert to 32 bit for now  
                         break;  
1173                      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;  
1174                      case SF_FORMAT_FLOAT:                      case SF_FORMAT_FLOAT:
                         bitdepth = 32;  
                         break;  
1175                      case SF_FORMAT_DOUBLE:                      case SF_FORMAT_DOUBLE:
1176                          bitdepth = 32; // I guess we will always truncate this to 32 bit                          bitdepth = 24;
1177                          break;                          break;
1178                      default:                      default:
1179                          sf_close(hFile); // close sound file                          sf_close(hFile); // close sound file
# Line 1113  void MainWindow::on_action_add_sample() Line 1195  void MainWindow::on_action_add_sample()
1195                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
1196                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
1197                  sample->SamplesPerSecond = info.samplerate;                  sample->SamplesPerSecond = info.samplerate;
1198                    sample->AverageBytesPerSecond = sample->FrameSize * sample->SamplesPerSecond;
1199                    sample->BlockAlign = sample->FrameSize;
1200                    sample->SamplesTotal = info.frames;
1201    
1202                    SF_INSTRUMENT instrument;
1203                    if (sf_command(hFile, SFC_GET_INSTRUMENT,
1204                                   &instrument, sizeof(instrument)) != SF_FALSE)
1205                    {
1206                        sample->MIDIUnityNote = instrument.basenote;
1207    
1208    #if HAVE_SF_INSTRUMENT_LOOPS
1209                        if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
1210                            sample->Loops = 1;
1211    
1212                            switch (instrument.loops[0].mode) {
1213                            case SF_LOOP_FORWARD:
1214                                sample->LoopType = gig::loop_type_normal;
1215                                break;
1216                            case SF_LOOP_BACKWARD:
1217                                sample->LoopType = gig::loop_type_backward;
1218                                break;
1219                            case SF_LOOP_ALTERNATING:
1220                                sample->LoopType = gig::loop_type_bidirectional;
1221                                break;
1222                            }
1223                            sample->LoopStart = instrument.loops[0].start;
1224                            sample->LoopEnd = instrument.loops[0].end;
1225                            sample->LoopPlayCount = instrument.loops[0].count;
1226                            sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;
1227                        }
1228    #endif
1229                    }
1230    
1231                  // schedule resizing the sample (which will be done                  // schedule resizing the sample (which will be done
1232                  // physically when File::Save() is called)                  // physically when File::Save() is called)
1233                  sample->Resize(info.frames);                  sample->Resize(info.frames);
# Line 1167  void MainWindow::on_action_remove_sample Line 1282  void MainWindow::on_action_remove_sample
1282                       pSample; pSample = group->GetNextSample()) {                       pSample; pSample = group->GetNextSample()) {
1283                      members.push_back(pSample);                      members.push_back(pSample);
1284                  }                  }
1285                    // notify everybody that we're going to remove these samples
1286                    samples_to_be_removed_signal.emit(members);
1287                  // delete the group in the .gig file including the                  // delete the group in the .gig file including the
1288                  // samples that belong to the group                  // samples that belong to the group
1289                  file->DeleteGroup(group);                  file->DeleteGroup(group);
1290                    // notify that we're done with removal
1291                    samples_removed_signal.emit();
1292                  // if sample(s) were just previously added, remove                  // if sample(s) were just previously added, remove
1293                  // them from the import queue                  // them from the import queue
1294                  for (std::list<gig::Sample*>::iterator member = members.begin();                  for (std::list<gig::Sample*>::iterator member = members.begin();
# Line 1186  void MainWindow::on_action_remove_sample Line 1305  void MainWindow::on_action_remove_sample
1305                  }                  }
1306                  file_changed();                  file_changed();
1307              } else if (sample) {              } else if (sample) {
1308                    // notify everybody that we're going to remove this sample
1309                    std::list<gig::Sample*> lsamples;
1310                    lsamples.push_back(sample);
1311                    samples_to_be_removed_signal.emit(lsamples);
1312                  // remove sample from the .gig file                  // remove sample from the .gig file
1313                  file->DeleteSample(sample);                  file->DeleteSample(sample);
1314                    // notify that we're done with removal
1315                    samples_removed_signal.emit();
1316                  // if sample was just previously added, remove it from                  // if sample was just previously added, remove it from
1317                  // the import queue                  // the import queue
1318                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
# Line 1199  void MainWindow::on_action_remove_sample Line 1324  void MainWindow::on_action_remove_sample
1324                          break;                          break;
1325                      }                      }
1326                  }                  }
1327                    dimreg_changed();
1328                  file_changed();                  file_changed();
1329              }              }
1330              // remove respective row(s) from samples tree view              // remove respective row(s) from samples tree view
1331              m_refSamplesTreeModel->erase(it);              m_refSamplesTreeModel->erase(it);
1332          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1333                // pretend we're done with removal (i.e. to avoid dead locks)
1334                samples_removed_signal.emit();
1335                // show error message
1336              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1337              msg.run();              msg.run();
1338          }          }
1339      }      }
1340  }  }
1341    
1342    // For some reason drag_data_get gets called two times for each
1343    // drag'n'drop (at least when target is an Entry). This work-around
1344    // makes sure the code in drag_data_get and drop_drag_data_received is
1345    // only executed once, as drag_begin only gets called once.
1346    void MainWindow::on_sample_treeview_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context)
1347    {
1348        first_call_to_drag_data_get = true;
1349    }
1350    
1351  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>&,
1352                                                    Gtk::SelectionData& selection_data, guint, guint)                                                    Gtk::SelectionData& selection_data, guint, guint)
1353  {  {
1354        if (!first_call_to_drag_data_get) return;
1355        first_call_to_drag_data_get = false;
1356    
1357      // get selected sample      // get selected sample
1358      gig::Sample* sample = NULL;      gig::Sample* sample = NULL;
1359      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
# Line 1230  void MainWindow::on_sample_label_drop_dr Line 1371  void MainWindow::on_sample_label_drop_dr
1371      const Glib::RefPtr<Gdk::DragContext>& context, int, int,      const Glib::RefPtr<Gdk::DragContext>& context, int, int,
1372      const Gtk::SelectionData& selection_data, guint, guint time)      const Gtk::SelectionData& selection_data, guint, guint time)
1373  {  {
     gig::DimensionRegion* dimregion = m_DimRegionChooser.get_dimregion();  
1374      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1375    
1376      if (sample && dimregion && selection_data.get_length() == sizeof(gig::Sample*)) {      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {
1377          if (sample != dimregion->pSample) {          std::cout << "Drop received sample \"" <<
1378              dimregion->pSample = sample;              sample->pInfo->Name << "\"" << std::endl;
1379              dimreg_edit.wSample->set_text(dimregion->pSample->pInfo->Name.c_str());          // drop success
1380              std::cout << "Drop received sample \"" <<          context->drop_reply(true, time);
1381                  dimregion->pSample->pInfo->Name.c_str() << "\"" << std::endl;  
1382              // drop success          //TODO: we should better move most of the following code to DimRegionEdit::set_sample()
1383              context->drop_reply(true, time);  
1384              file_changed();          // notify everybody that we're going to alter the region
1385              return;          gig::Region* region = m_RegionChooser.get_region();
1386            region_to_be_changed_signal.emit(region);
1387    
1388            // find the samplechannel dimension
1389            gig::dimension_def_t* stereo_dimension = 0;
1390            for (int i = 0 ; i < region->Dimensions ; i++) {
1391                if (region->pDimensionDefinitions[i].dimension ==
1392                    gig::dimension_samplechannel) {
1393                    stereo_dimension = &region->pDimensionDefinitions[i];
1394                    break;
1395                }
1396            }
1397            bool channels_changed = false;
1398            if (sample->Channels == 1 && stereo_dimension) {
1399                // remove the samplechannel dimension
1400                region->DeleteDimension(stereo_dimension);
1401                channels_changed = true;
1402                region_changed();
1403            }
1404            dimreg_edit.set_sample(sample);
1405    
1406            if (sample->Channels == 2 && !stereo_dimension) {
1407                // add samplechannel dimension
1408                gig::dimension_def_t dim;
1409                dim.dimension = gig::dimension_samplechannel;
1410                dim.bits = 1;
1411                dim.zones = 2;
1412                region->AddDimension(&dim);
1413                channels_changed = true;
1414                region_changed();
1415          }          }
1416            if (channels_changed) {
1417                // unmap all samples with wrong number of channels
1418                // TODO: maybe there should be a warning dialog for this
1419                for (int i = 0 ; i < region->DimensionRegions ; i++) {
1420                    gig::DimensionRegion* d = region->pDimensionRegions[i];
1421                    if (d->pSample && d->pSample->Channels != sample->Channels) {
1422                        gig::Sample* oldref = d->pSample;
1423                        d->pSample = NULL;
1424                        sample_ref_changed_signal.emit(oldref, NULL);
1425                    }
1426                }
1427            }
1428    
1429            // notify we're done with altering
1430            region_changed_signal.emit(region);
1431    
1432            return;
1433      }      }
1434      // drop failed      // drop failed
1435      context->drop_reply(false, time);      context->drop_reply(false, time);
# Line 1282  void MainWindow::instrument_name_changed Line 1468  void MainWindow::instrument_name_changed
1468          file_changed();          file_changed();
1469      }      }
1470  }  }
1471    
1472    sigc::signal<void, gig::File*> MainWindow::signal_file_structure_to_be_changed() {
1473        return file_structure_to_be_changed_signal;
1474    }
1475    
1476    sigc::signal<void, gig::File*> MainWindow::signal_file_structure_changed() {
1477        return file_structure_changed_signal;
1478    }
1479    
1480    sigc::signal<void, std::list<gig::Sample*> > MainWindow::signal_samples_to_be_removed() {
1481        return samples_to_be_removed_signal;
1482    }
1483    
1484    sigc::signal<void> MainWindow::signal_samples_removed() {
1485        return samples_removed_signal;
1486    }
1487    
1488    sigc::signal<void, gig::Region*> MainWindow::signal_region_to_be_changed() {
1489        return region_to_be_changed_signal;
1490    }
1491    
1492    sigc::signal<void, gig::Region*> MainWindow::signal_region_changed() {
1493        return region_changed_signal;
1494    }
1495    
1496    sigc::signal<void, gig::Sample*/*old*/, gig::Sample*/*new*/> MainWindow::signal_sample_ref_changed() {
1497        return sample_ref_changed_signal;
1498    }
1499    
1500    sigc::signal<void, gig::DimensionRegion*> MainWindow::signal_dimreg_to_be_changed() {
1501        return dimreg_to_be_changed_signal;
1502    }
1503    
1504    sigc::signal<void, gig::DimensionRegion*> MainWindow::signal_dimreg_changed() {
1505        return dimreg_changed_signal;
1506    }

Legend:
Removed from v.1262  
changed lines
  Added in v.1328

  ViewVC Help
Powered by ViewVC