/[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 1265 by persson, Sun Jul 29 13:44:59 2007 UTC revision 1661 by schoenebeck, Sun Feb 3 14:10:47 2008 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006, 2007 Andreas Persson   * Copyright (C) 2006 - 2008 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 17  Line 17 
17   * 02110-1301 USA.   * 02110-1301 USA.
18   */   */
19    
 #include <libintl.h>  
20  #include <iostream>  #include <iostream>
21    
22  #include <gtkmm/filechooserdialog.h>  #include <gtkmm/filechooserdialog.h>
# Line 25  Line 24 
24  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
25  #include <gtkmm/targetentry.h>  #include <gtkmm/targetentry.h>
26  #include <gtkmm/main.h>  #include <gtkmm/main.h>
27    #include <gtkmm/toggleaction.h>
28    
29    #include "global.h"
30    
31  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2
32  #define ABOUT_DIALOG  #define ABOUT_DIALOG
33  #include <gtkmm/aboutdialog.h>  #include <gtkmm/aboutdialog.h>
34  #endif  #endif
35    
36    #if (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION < 6) || GLIBMM_MAJOR_VERSION < 2
37    namespace Glib {
38    Glib::ustring filename_display_basename(const std::string& filename)
39    {
40        gchar* gstr = g_path_get_basename(filename.c_str());
41        Glib::ustring str(gstr);
42        g_free(gstr);
43        return Glib::filename_to_utf8(str);
44    }
45    }
46    #endif
47    
48  #include <stdio.h>  #include <stdio.h>
49  #include <sndfile.h>  #include <sndfile.h>
50    
51  #include "mainwindow.h"  #include "mainwindow.h"
52    
53  #define _(String) gettext(String)  #include "../../gfx/status_attached.xpm"
54    #include "../../gfx/status_detached.xpm"
55    
56  template<class T> inline std::string ToString(T o) {  template<class T> inline std::string ToString(T o) {
57      std::stringstream ss;      std::stringstream ss;
# Line 44  template<class T> inline std::string ToS Line 59  template<class T> inline std::string ToS
59      return ss.str();      return ss.str();
60  }  }
61    
62  MainWindow::MainWindow()  Table::Table(int x, int y) : Gtk::Table(x, y), rowno(0) {  }
63    
64    void Table::add(BoolEntry& boolentry)
65    {
66        attach(boolentry.widget, 0, 2, rowno, rowno + 1,
67               Gtk::FILL, Gtk::SHRINK);
68        rowno++;
69    }
70    
71    void Table::add(BoolEntryPlus6& boolentry)
72    {
73        attach(boolentry.widget, 0, 2, rowno, rowno + 1,
74               Gtk::FILL, Gtk::SHRINK);
75        rowno++;
76    }
77    
78    void Table::add(LabelWidget& prop)
79    {
80        attach(prop.label, 1, 2, rowno, rowno + 1,
81               Gtk::FILL, Gtk::SHRINK);
82        attach(prop.widget, 2, 3, rowno, rowno + 1,
83               Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
84        rowno++;
85    }
86    
87    MainWindow::MainWindow() :
88        dimreg_label(_("Changes apply to:")),
89        dimreg_all_regions(_("all regions")),
90        dimreg_all_dimregs(_("all dimension splits")),
91        dimreg_stereo(_("both channels"))
92  {  {
93  //    set_border_width(5);  //    set_border_width(5);
94  //    set_default_size(400, 200);  //    set_default_size(400, 200);
# Line 74  MainWindow::MainWindow() Line 118  MainWindow::MainWindow()
118      m_TreeViewNotebook.set_size_request(300);      m_TreeViewNotebook.set_size_request(300);
119    
120      m_HPaned.add1(m_TreeViewNotebook);      m_HPaned.add1(m_TreeViewNotebook);
121      m_HPaned.add2(dimreg_edit);      dimreg_hbox.add(dimreg_label);
122        dimreg_hbox.add(dimreg_all_regions);
123        dimreg_hbox.add(dimreg_all_dimregs);
124        dimreg_stereo.set_active();
125        dimreg_hbox.add(dimreg_stereo);
126        dimreg_vbox.add(dimreg_edit);
127        dimreg_vbox.pack_start(dimreg_hbox, Gtk::PACK_SHRINK);
128        m_HPaned.add2(dimreg_vbox);
129    
130    
131      m_TreeViewNotebook.append_page(m_ScrolledWindowSamples, "Samples");      m_TreeViewNotebook.append_page(m_ScrolledWindowSamples, "Samples");
# Line 115  MainWindow::MainWindow() Line 166  MainWindow::MainWindow()
166                           *this, &MainWindow::on_action_quit));                           *this, &MainWindow::on_action_quit));
167      actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));      actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));
168    
169        actionGroup->add(Gtk::Action::create("MenuView", _("_View")));
170        Glib::RefPtr<Gtk::ToggleAction> toggle_action =
171            Gtk::ToggleAction::create("Statusbar", _("_Statusbar"));
172        toggle_action->set_active(true);
173        actionGroup->add(toggle_action,
174                         sigc::mem_fun(
175                             *this, &MainWindow::on_action_view_status_bar));
176    
177      action = Gtk::Action::create("MenuHelp", Gtk::Stock::HELP);      action = Gtk::Action::create("MenuHelp", Gtk::Stock::HELP);
178      actionGroup->add(Gtk::Action::create("MenuHelp",      actionGroup->add(Gtk::Action::create("MenuHelp",
179                                           action->property_label()));                                           action->property_label()));
# Line 170  MainWindow::MainWindow() Line 229  MainWindow::MainWindow()
229          "    </menu>"          "    </menu>"
230          "    <menu action='MenuInstrument'>"          "    <menu action='MenuInstrument'>"
231          "    </menu>"          "    </menu>"
232            "    <menu action='MenuView'>"
233            "      <menuitem action='Statusbar'/>"
234            "    </menu>"
235  #ifdef ABOUT_DIALOG  #ifdef ABOUT_DIALOG
236          "    <menu action='MenuHelp'>"          "    <menu action='MenuHelp'>"
237          "      <menuitem action='About'/>"          "      <menuitem action='About'/>"
# Line 198  MainWindow::MainWindow() Line 260  MainWindow::MainWindow()
260      m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK);      m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK);
261      m_VBox.pack_start(m_HPaned);      m_VBox.pack_start(m_HPaned);
262      m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK);      m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK);
263        m_VBox.pack_start(m_RegionChooser.m_VirtKeybPropsBox, Gtk::PACK_SHRINK);
264      m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK);      m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK);
265        m_VBox.pack_start(m_StatusBar, Gtk::PACK_SHRINK);
266    
267        // Status Bar:
268        m_StatusBar.pack_start(m_AttachedStateLabel, Gtk::PACK_SHRINK);
269        m_StatusBar.pack_start(m_AttachedStateImage, Gtk::PACK_SHRINK);
270        m_StatusBar.show();
271    
272      m_RegionChooser.signal_region_selected().connect(      m_RegionChooser.signal_region_selected().connect(
273          sigc::mem_fun(*this, &MainWindow::region_changed) );          sigc::mem_fun(*this, &MainWindow::region_changed) );
# Line 234  MainWindow::MainWindow() Line 303  MainWindow::MainWindow()
303      std::list<Gtk::TargetEntry> drag_target_gig_sample;      std::list<Gtk::TargetEntry> drag_target_gig_sample;
304      drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );      drag_target_gig_sample.push_back( Gtk::TargetEntry("gig::Sample") );
305      m_TreeViewSamples.drag_source_set(drag_target_gig_sample);      m_TreeViewSamples.drag_source_set(drag_target_gig_sample);
306        m_TreeViewSamples.signal_drag_begin().connect(
307            sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_begin)
308        );
309      m_TreeViewSamples.signal_drag_data_get().connect(      m_TreeViewSamples.signal_drag_data_get().connect(
310          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)          sigc::mem_fun(*this, &MainWindow::on_sample_treeview_drag_data_get)
311      );      );
# Line 242  MainWindow::MainWindow() Line 314  MainWindow::MainWindow()
314          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)          sigc::mem_fun(*this, &MainWindow::on_sample_label_drop_drag_data_received)
315      );      );
316      dimreg_edit.signal_dimreg_changed().connect(      dimreg_edit.signal_dimreg_changed().connect(
317          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::hide(sigc::mem_fun(*this, &MainWindow::file_changed)));
318      m_RegionChooser.signal_instrument_changed().connect(      m_RegionChooser.signal_instrument_changed().connect(
319          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
320      m_DimRegionChooser.signal_region_changed().connect(      m_DimRegionChooser.signal_region_changed().connect(
321          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
322      instrumentProps.signal_instrument_changed().connect(      instrumentProps.signal_instrument_changed().connect(
323          sigc::mem_fun(*this, &MainWindow::file_changed));          sigc::mem_fun(*this, &MainWindow::file_changed));
324        propDialog.signal_info_changed().connect(
325            sigc::mem_fun(*this, &MainWindow::file_changed));
326    
327        dimreg_edit.signal_dimreg_to_be_changed().connect(
328            dimreg_to_be_changed_signal.make_slot());
329        dimreg_edit.signal_dimreg_changed().connect(
330            dimreg_changed_signal.make_slot());
331        dimreg_edit.signal_sample_ref_changed().connect(
332            sample_ref_changed_signal.make_slot());
333    
334        m_RegionChooser.signal_instrument_struct_to_be_changed().connect(
335            sigc::hide(
336                sigc::bind(
337                    file_structure_to_be_changed_signal.make_slot(),
338                    sigc::ref(this->file)
339                )
340            )
341        );
342        m_RegionChooser.signal_instrument_struct_changed().connect(
343            sigc::hide(
344                sigc::bind(
345                    file_structure_changed_signal.make_slot(),
346                    sigc::ref(this->file)
347                )
348            )
349        );
350        m_RegionChooser.signal_region_to_be_changed().connect(
351            region_to_be_changed_signal.make_slot());
352        m_RegionChooser.signal_region_changed_signal().connect(
353            region_changed_signal.make_slot());
354    
355        note_on_signal.connect(
356            sigc::mem_fun(m_RegionChooser, &RegionChooser::on_note_on_event));
357        note_off_signal.connect(
358            sigc::mem_fun(m_RegionChooser, &RegionChooser::on_note_off_event));
359    
360        dimreg_all_regions.signal_toggled().connect(
361            sigc::mem_fun(*this, &MainWindow::update_dimregs));
362        dimreg_all_dimregs.signal_toggled().connect(
363            sigc::mem_fun(*this, &MainWindow::dimreg_all_dimregs_toggled));
364        dimreg_stereo.signal_toggled().connect(
365            sigc::mem_fun(*this, &MainWindow::update_dimregs));
366    
367      file = 0;      file = 0;
368      file_is_changed = false;      file_is_changed = false;
369        set_file_is_shared(false);
370    
371      show_all_children();      show_all_children();
372    
373        // start with a new gig file by default
374        on_action_file_new();
375  }  }
376    
377  MainWindow::~MainWindow()  MainWindow::~MainWindow()
# Line 261  MainWindow::~MainWindow() Line 380  MainWindow::~MainWindow()
380    
381  bool MainWindow::on_delete_event(GdkEventAny* event)  bool MainWindow::on_delete_event(GdkEventAny* event)
382  {  {
383      return file_is_changed && !close_confirmation_dialog();      return !file_is_shared && file_is_changed && !close_confirmation_dialog();
384  }  }
385    
386  void MainWindow::on_action_quit()  void MainWindow::on_action_quit()
387  {  {
388      if (file_is_changed && !close_confirmation_dialog()) return;      if (!file_is_shared && file_is_changed && !close_confirmation_dialog()) return;
389      hide();      hide();
390  }  }
391    
# Line 275  void MainWindow::region_changed() Line 394  void MainWindow::region_changed()
394      m_DimRegionChooser.set_region(m_RegionChooser.get_region());      m_DimRegionChooser.set_region(m_RegionChooser.get_region());
395  }  }
396    
397  void MainWindow::dimreg_changed()  gig::Instrument* MainWindow::get_instrument()
 {  
     dimreg_edit.set_dim_region(m_DimRegionChooser.get_dimregion());  
 }  
   
 void MainWindow::on_sel_change()  
398  {  {
399        gig::Instrument* instrument = 0;
400      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
401    
402      Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();      Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
403      if (it) {      if (it) {
404          Gtk::TreeModel::Row row = *it;          Gtk::TreeModel::Row row = *it;
405          std::cout << row[m_Columns.m_col_name] << std::endl;          instrument = row[m_Columns.m_col_instr];
406        }
407        return instrument;
408    }
409    
410    void MainWindow::add_region_to_dimregs(gig::Region* region, bool stereo, bool all_dimregs)
411    {
412        if (all_dimregs) {
413            for (int i = 0 ; i < region->DimensionRegions ; i++) {
414                if (region->pDimensionRegions[i]) {
415                    dimreg_edit.dimregs.insert(region->pDimensionRegions[i]);
416                }
417            }
418        } else {
419            m_DimRegionChooser.get_dimregions(region, stereo, dimreg_edit.dimregs);
420        }
421    }
422    
423    void MainWindow::update_dimregs()
424    {
425        dimreg_edit.dimregs.clear();
426        bool all_regions = dimreg_all_regions.get_active();
427        bool stereo = dimreg_stereo.get_active();
428        bool all_dimregs = dimreg_all_dimregs.get_active();
429    
430          m_RegionChooser.set_instrument(row[m_Columns.m_col_instr]);      if (all_regions) {
431            gig::Instrument* instrument = get_instrument();
432            if (instrument) {
433                for (gig::Region* region = instrument->GetFirstRegion() ;
434                     region ;
435                     region = instrument->GetNextRegion()) {
436                    add_region_to_dimregs(region, stereo, all_dimregs);
437                }
438            }
439      } else {      } else {
440          m_RegionChooser.set_instrument(0);          gig::Region* region = m_RegionChooser.get_region();
441            if (region) {
442                add_region_to_dimregs(region, stereo, all_dimregs);
443            }
444      }      }
445  }  }
446    
447    void MainWindow::dimreg_all_dimregs_toggled()
448    {
449        dimreg_stereo.set_sensitive(!dimreg_all_dimregs.get_active());
450        update_dimregs();
451    }
452    
453    void MainWindow::dimreg_changed()
454    {
455        update_dimregs();
456        dimreg_edit.set_dim_region(m_DimRegionChooser.get_dimregion());
457    }
458    
459    void MainWindow::on_sel_change()
460    {
461        m_RegionChooser.set_instrument(get_instrument());
462    }
463    
464  void loader_progress_callback(gig::progress_t* progress)  void loader_progress_callback(gig::progress_t* progress)
465  {  {
466      Loader* loader = static_cast<Loader*>(progress->custom);      Loader* loader = static_cast<Loader*>(progress->custom);
# Line 380  void MainWindow::__clear() { Line 546  void MainWindow::__clear() {
546      m_refTreeModel->clear();      m_refTreeModel->clear();
547      m_refSamplesTreeModel->clear();      m_refSamplesTreeModel->clear();
548      // free libgig's gig::File instance      // free libgig's gig::File instance
549      if (file) {      if (file && !file_is_shared) delete file;
550          delete file;      file = NULL;
551          file = NULL;      set_file_is_shared(false);
     }  
552  }  }
553    
554  void MainWindow::on_action_file_new()  void MainWindow::on_action_file_new()
555  {  {
556      if (file_is_changed && !close_confirmation_dialog()) return;      if (!file_is_shared && file_is_changed && !close_confirmation_dialog()) return;
557    
558        if (file_is_shared && !leaving_shared_mode_dialog()) return;
559    
560      // clear all GUI elements      // clear all GUI elements
561      __clear();      __clear();
# Line 407  bool MainWindow::close_confirmation_dial Line 574  bool MainWindow::close_confirmation_dial
574                                   Glib::filename_display_basename(filename).c_str());                                   Glib::filename_display_basename(filename).c_str());
575      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);      Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
576      g_free(msg);      g_free(msg);
577    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2
578      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."));
579    #endif
580      dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);      dialog.add_button(_("Close _Without Saving"), Gtk::RESPONSE_NO);
581      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
582      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);
583      dialog.set_default_response(Gtk::RESPONSE_YES);      dialog.set_default_response(Gtk::RESPONSE_YES);
584      int response = dialog.run();      int response = dialog.run();
585        dialog.hide();
586      if (response == Gtk::RESPONSE_YES) return file_save();      if (response == Gtk::RESPONSE_YES) return file_save();
587      return response != Gtk::RESPONSE_CANCEL;      return response != Gtk::RESPONSE_CANCEL;
588  }  }
589    
590    bool MainWindow::leaving_shared_mode_dialog() {
591        Glib::ustring msg = _("Detach from sampler and proceed working stand-alone?");
592        Gtk::MessageDialog dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
593    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6) || GTKMM_MAJOR_VERSION > 2
594        dialog.set_secondary_text(
595            _("If you proceed to work on another instrument file, it won't be "
596              "used by the sampler until you tell the sampler explicitly to "
597              "load it.")
598       );
599    #endif
600        dialog.add_button(_("_Yes, Detach"), Gtk::RESPONSE_YES);
601        dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
602        dialog.set_default_response(Gtk::RESPONSE_CANCEL);
603        int response = dialog.run();
604        dialog.hide();
605        return response == Gtk::RESPONSE_YES;
606    }
607    
608  void MainWindow::on_action_file_open()  void MainWindow::on_action_file_open()
609  {  {
610      if (file_is_changed && !close_confirmation_dialog()) return;      if (!file_is_shared && file_is_changed && !close_confirmation_dialog()) return;
611    
612        if (file_is_shared && !leaving_shared_mode_dialog()) return;
613    
614      Gtk::FileChooserDialog dialog(*this, _("Open file"));      Gtk::FileChooserDialog dialog(*this, _("Open file"));
615      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
# Line 434  void MainWindow::on_action_file_open() Line 624  void MainWindow::on_action_file_open()
624      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
625          std::string filename = dialog.get_filename();          std::string filename = dialog.get_filename();
626          printf("filename=%s\n", filename.c_str());          printf("filename=%s\n", filename.c_str());
         __clear();  
627          printf("on_action_file_open self=%x\n", Glib::Thread::self());          printf("on_action_file_open self=%x\n", Glib::Thread::self());
628          load_file(filename.c_str());          load_file(filename.c_str());
629          current_dir = Glib::path_get_dirname(filename);          current_dir = Glib::path_get_dirname(filename);
# Line 443  void MainWindow::on_action_file_open() Line 632  void MainWindow::on_action_file_open()
632    
633  void MainWindow::load_file(const char* name)  void MainWindow::load_file(const char* name)
634  {  {
635        __clear();
636      load_dialog = new LoadDialog("Loading...", *this);      load_dialog = new LoadDialog("Loading...", *this);
637      load_dialog->show_all();      load_dialog->show_all();
638      loader = new Loader(strdup(name));      loader = new Loader(strdup(name));
# Line 460  void MainWindow::load_instrument(gig::In Line 650  void MainWindow::load_instrument(gig::In
650          msg.run();          msg.run();
651          Gtk::Main::quit();          Gtk::Main::quit();
652      }      }
653        // clear all GUI elements
654        __clear();
655        // load the instrument
656      gig::File* pFile = (gig::File*) instr->GetParent();      gig::File* pFile = (gig::File*) instr->GetParent();
657      load_gig(pFile, 0 /*file name*/);      load_gig(pFile, 0 /*file name*/, true /*shared instrument*/);
658      //TODO: automatically select the given instrument      //TODO: automatically select the given instrument
659  }  }
660    
# Line 483  void MainWindow::on_action_file_save() Line 676  void MainWindow::on_action_file_save()
676      file_save();      file_save();
677  }  }
678    
679  bool MainWindow::file_save()  bool MainWindow::check_if_savable()
680  {  {
681      if (!file) return false;      if (!file) return false;
682      if (!file_has_name) return file_save_as();  
683        if (!file->GetFirstSample()) {
684            Gtk::MessageDialog(*this, _("The file could not be saved "
685                                        "because it contains no samples"),
686                               false, Gtk::MESSAGE_ERROR).run();
687            return false;
688        }
689    
690        for (gig::Instrument* instrument = file->GetFirstInstrument() ; instrument ;
691             instrument = file->GetNextInstrument()) {
692            if (!instrument->GetFirstRegion()) {
693                Gtk::MessageDialog(*this, _("The file could not be saved "
694                                            "because there are instruments "
695                                            "that have no regions"),
696                                   false, Gtk::MESSAGE_ERROR).run();
697                return false;
698            }
699        }
700        return true;
701    }
702    
703    bool MainWindow::file_save()
704    {
705        if (!check_if_savable()) return false;
706        if (!file_is_shared && !file_has_name) return file_save_as();
707    
708      std::cout << "Saving file\n" << std::flush;      std::cout << "Saving file\n" << std::flush;
709        file_structure_to_be_changed_signal.emit(this->file);
710      try {      try {
711          file->Save();          file->Save();
712          if (file_is_changed) {          if (file_is_changed) {
# Line 496  bool MainWindow::file_save() Line 714  bool MainWindow::file_save()
714              file_is_changed = false;              file_is_changed = false;
715          }          }
716      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
717          Glib::ustring txt = "Could not save file: " + e.Message;          file_structure_changed_signal.emit(this->file);
718            Glib::ustring txt = _("Could not save file: ") + e.Message;
719          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
720          msg.run();          msg.run();
721          return false;          return false;
722      }      }
723      std::cout << "Saving file done\n" << std::flush;      std::cout << "Saving file done\n" << std::flush;
724      __import_queued_samples();      __import_queued_samples();
725        file_structure_changed_signal.emit(this->file);
726      return true;      return true;
727  }  }
728    
729  void MainWindow::on_action_file_save_as()  void MainWindow::on_action_file_save_as()
730  {  {
731        if (!check_if_savable()) return;
732      file_save_as();      file_save_as();
733  }  }
734    
735  bool MainWindow::file_save_as()  bool MainWindow::file_save_as()
736  {  {
     if (!file) return false;  
737      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);      Gtk::FileChooserDialog dialog(*this, _("Save as"), Gtk::FILE_CHOOSER_ACTION_SAVE);
738      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
739      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 755  bool MainWindow::file_save_as()
755      dialog.set_current_name(Glib::filename_display_basename(filename));      dialog.set_current_name(Glib::filename_display_basename(filename));
756    
757      if (dialog.run() == Gtk::RESPONSE_OK) {      if (dialog.run() == Gtk::RESPONSE_OK) {
758            file_structure_to_be_changed_signal.emit(this->file);
759          try {          try {
760              std::string filename = dialog.get_filename();              std::string filename = dialog.get_filename();
761              if (!Glib::str_has_suffix(filename, ".gig")) {              if (!Glib::str_has_suffix(filename, ".gig")) {
# Line 548  bool MainWindow::file_save_as() Line 769  bool MainWindow::file_save_as()
769              file_has_name = true;              file_has_name = true;
770              file_is_changed = false;              file_is_changed = false;
771          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
772              Glib::ustring txt = "Could not save file: " + e.Message;              file_structure_changed_signal.emit(this->file);
773                Glib::ustring txt = _("Could not save file: ") + e.Message;
774              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
775              msg.run();              msg.run();
776              return false;              return false;
777          }          }
778          __import_queued_samples();          __import_queued_samples();
779            file_structure_changed_signal.emit(this->file);
780          return true;          return true;
781      }      }
782      return false;      return false;
# Line 644  void MainWindow::__import_queued_samples Line 867  void MainWindow::__import_queued_samples
867      }      }
868      // show error message box when some sample(s) could not be imported      // show error message box when some sample(s) could not be imported
869      if (error_files.size()) {      if (error_files.size()) {
870          Glib::ustring txt = "Could not import the following sample(s):\n" + error_files;          Glib::ustring txt = _("Could not import the following sample(s):\n") + error_files;
871          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
872          msg.run();          msg.run();
873      }      }
# Line 661  void MainWindow::on_action_help_about() Line 884  void MainWindow::on_action_help_about()
884  #ifdef ABOUT_DIALOG  #ifdef ABOUT_DIALOG
885      Gtk::AboutDialog dialog;      Gtk::AboutDialog dialog;
886      dialog.set_version(VERSION);      dialog.set_version(VERSION);
887        dialog.set_copyright("Copyright (C) 2006,2007 Andreas Persson");
888        dialog.set_comments(
889            "Released under the GNU General Public License.\n"
890            "\n"
891            "Please notice that this is still a very young instrument editor. "
892            "So better backup your Gigasampler files before editing them with "
893            "this application.\n"
894            "\n"
895            "Please report bugs to: http://bugs.linuxsampler.org"
896        );
897        dialog.set_website("http://www.linuxsampler.org");
898        dialog.set_website_label("http://www.linuxsampler.org");
899      dialog.run();      dialog.run();
900  #endif  #endif
901  }  }
902    
903  PropDialog::PropDialog()  PropDialog::PropDialog()
904      : table(2,1)      : table(2,1),
905          eName("Name"),
906          eCreationDate("Creation date"),
907          eComments("Comments"),
908          eProduct("Product"),
909          eCopyright("Copyright"),
910          eArtists("Artists"),
911          eGenre("Genre"),
912          eKeywords("Keywords"),
913          eEngineer("Engineer"),
914          eTechnician("Technician"),
915          eSoftware("Software"),
916          eMedium("Medium"),
917          eSource("Source"),
918          eSourceForm("Source form"),
919          eCommissioned("Commissioned"),
920          eSubject("Subject"),
921          quitButton(Gtk::Stock::CLOSE),
922          update_model(0)
923  {  {
924        set_title("File Properties");
925        eName.set_width_chars(50);
926    
927        connect(eName, &DLS::Info::Name);
928        connect(eCreationDate, &DLS::Info::CreationDate);
929        connect(eComments, &DLS::Info::Comments);
930        connect(eProduct, &DLS::Info::Product);
931        connect(eCopyright, &DLS::Info::Copyright);
932        connect(eArtists, &DLS::Info::Artists);
933        connect(eGenre, &DLS::Info::Genre);
934        connect(eKeywords, &DLS::Info::Keywords);
935        connect(eEngineer, &DLS::Info::Engineer);
936        connect(eTechnician, &DLS::Info::Technician);
937        connect(eSoftware, &DLS::Info::Software);
938        connect(eMedium, &DLS::Info::Medium);
939        connect(eSource, &DLS::Info::Source);
940        connect(eSourceForm, &DLS::Info::SourceForm);
941        connect(eCommissioned, &DLS::Info::Commissioned);
942        connect(eSubject, &DLS::Info::Subject);
943    
944        table.add(eName);
945        table.add(eCreationDate);
946        table.add(eComments);
947        table.add(eProduct);
948        table.add(eCopyright);
949        table.add(eArtists);
950        table.add(eGenre);
951        table.add(eKeywords);
952        table.add(eEngineer);
953        table.add(eTechnician);
954        table.add(eSoftware);
955        table.add(eMedium);
956        table.add(eSource);
957        table.add(eSourceForm);
958        table.add(eCommissioned);
959        table.add(eSubject);
960    
961      table.set_col_spacings(5);      table.set_col_spacings(5);
962      const char* propLabels[] = {      add(vbox);
963          "Name:",      table.set_border_width(5);
964          "CreationDate:",      vbox.add(table);
965          "Comments:", // TODO: multiline      vbox.pack_start(buttonBox, Gtk::PACK_SHRINK);
966          "Product:",      buttonBox.set_layout(Gtk::BUTTONBOX_END);
967          "Copyright:",      buttonBox.set_border_width(5);
968          "Artists:",      buttonBox.show();
969          "Genre:",      buttonBox.pack_start(quitButton);
970          "Keywords:",      quitButton.set_flags(Gtk::CAN_DEFAULT);
971          "Engineer:",      quitButton.grab_focus();
972          "Technician:",      quitButton.signal_clicked().connect(
973          "Software:", // TODO: readonly          sigc::mem_fun(*this, &PropDialog::hide));
         "Medium:",  
         "Source:",  
         "SourceForm:",  
         "Commissioned:",  
         "Subject:"  
     };  
     for (int i = 0 ; i < sizeof(propLabels) / sizeof(char*) ; i++) {  
         label[i].set_text(propLabels[i]);  
         label[i].set_alignment(Gtk::ALIGN_LEFT);  
         table.attach(label[i], 0, 1, i, i + 1, Gtk::FILL, Gtk::SHRINK);  
         table.attach(entry[i], 1, 2, i, i + 1, Gtk::FILL | Gtk::EXPAND,  
                      Gtk::SHRINK);  
     }  
974    
975      add(table);      quitButton.show();
976      // add_button(Gtk::Stock::CANCEL, 0);      vbox.show();
     // add_button(Gtk::Stock::OK, 1);  
977      show_all_children();      show_all_children();
978  }  }
979    
980  void PropDialog::set_info(DLS::Info* info)  void PropDialog::set_info(DLS::Info* info)
981  {  {
982      entry[0].set_text(info->Name);      this->info = info;
983      entry[1].set_text(info->CreationDate);      update_model++;
984      entry[2].set_text(Glib::convert(info->Comments, "UTF-8", "ISO-8859-1"));      eName.set_value(info->Name);
985      entry[3].set_text(info->Product);      eCreationDate.set_value(info->CreationDate);
986      entry[4].set_text(info->Copyright);      eComments.set_value(info->Comments);
987      entry[5].set_text(info->Artists);      eProduct.set_value(info->Product);
988      entry[6].set_text(info->Genre);      eCopyright.set_value(info->Copyright);
989      entry[7].set_text(info->Keywords);      eArtists.set_value(info->Artists);
990      entry[8].set_text(info->Engineer);      eGenre.set_value(info->Genre);
991      entry[9].set_text(info->Technician);      eKeywords.set_value(info->Keywords);
992      entry[10].set_text(info->Software);      eEngineer.set_value(info->Engineer);
993      entry[11].set_text(info->Medium);      eTechnician.set_value(info->Technician);
994      entry[12].set_text(info->Source);      eSoftware.set_value(info->Software);
995      entry[13].set_text(info->SourceForm);      eMedium.set_value(info->Medium);
996      entry[14].set_text(info->Commissioned);      eSource.set_value(info->Source);
997      entry[15].set_text(info->Subject);      eSourceForm.set_value(info->SourceForm);
998        eCommissioned.set_value(info->Commissioned);
999        eSubject.set_value(info->Subject);
1000        update_model--;
1001  }  }
1002    
1003  void InstrumentProps::add_prop(BoolEntry& boolentry)  sigc::signal<void>& PropDialog::signal_info_changed()
1004  {  {
1005      table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,      return info_changed;
                  Gtk::FILL, Gtk::SHRINK);  
     rowno++;  
     boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());  
1006  }  }
1007    
1008  void InstrumentProps::add_prop(BoolEntryPlus6& boolentry)  void InstrumentProps::set_IsDrum(bool value)
1009  {  {
1010      table.attach(boolentry.widget, 0, 2, rowno, rowno + 1,      instrument->IsDrum = value;
                  Gtk::FILL, Gtk::SHRINK);  
     rowno++;  
     boolentry.signal_changed_by_user().connect(instrument_changed.make_slot());  
1011  }  }
1012    
1013  void InstrumentProps::add_prop(LabelWidget& prop)  void InstrumentProps::set_MIDIBank(uint16_t value)
1014  {  {
1015      table.attach(prop.label, 0, 1, rowno, rowno + 1,      instrument->MIDIBank = value;
1016                   Gtk::FILL, Gtk::SHRINK);  }
1017      table.attach(prop.widget, 1, 2, rowno, rowno + 1,  
1018                   Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);  void InstrumentProps::set_MIDIProgram(uint32_t value)
1019      rowno++;  {
1020      prop.signal_changed_by_user().connect(instrument_changed.make_slot());      instrument->MIDIProgram = value;
1021    }
1022    
1023    void InstrumentProps::set_DimensionKeyRange_low(uint8_t value)
1024    {
1025        instrument->DimensionKeyRange.low = value;
1026        if (value > instrument->DimensionKeyRange.high) {
1027            eDimensionKeyRangeHigh.set_value(value);
1028        }
1029    }
1030    
1031    void InstrumentProps::set_DimensionKeyRange_high(uint8_t value)
1032    {
1033        instrument->DimensionKeyRange.high = value;
1034        if (value < instrument->DimensionKeyRange.low) {
1035            eDimensionKeyRangeLow.set_value(value);
1036        }
1037  }  }
1038    
1039  InstrumentProps::InstrumentProps()  InstrumentProps::InstrumentProps()
# Line 760  InstrumentProps::InstrumentProps() Line 1049  InstrumentProps::InstrumentProps()
1049        eFineTune("Fine tune", -8400, 8400),        eFineTune("Fine tune", -8400, 8400),
1050        ePitchbendRange("Pitchbend range", 0, 12),        ePitchbendRange("Pitchbend range", 0, 12),
1051        ePianoReleaseMode("Piano release mode"),        ePianoReleaseMode("Piano release mode"),
1052        eDimensionKeyRangeLow("Dimension key range low"),        eDimensionKeyRangeLow("Keyswitching range low"),
1053        eDimensionKeyRangeHigh("Dimension key range high")        eDimensionKeyRangeHigh("Keyswitching range high"),
1054  {        update_model(0)
1055      set_title("Instrument properties");  {
1056        set_title("Instrument Properties");
1057    
1058        eDimensionKeyRangeLow.set_tip(
1059            _("start of the keyboard area which should switch the "
1060              "\"keyswitching\" dimension")
1061        );
1062        eDimensionKeyRangeHigh.set_tip(
1063            _("end of the keyboard area which should switch the "
1064              "\"keyswitching\" dimension")
1065        );
1066    
1067        connect(eIsDrum, &InstrumentProps::set_IsDrum);
1068        connect(eMIDIBank, &InstrumentProps::set_MIDIBank);
1069        connect(eMIDIProgram, &InstrumentProps::set_MIDIProgram);
1070        connect(eAttenuation, &gig::Instrument::Attenuation);
1071        connect(eGainPlus6, &gig::Instrument::Attenuation);
1072        connect(eEffectSend, &gig::Instrument::EffectSend);
1073        connect(eFineTune, &gig::Instrument::FineTune);
1074        connect(ePitchbendRange, &gig::Instrument::PitchbendRange);
1075        connect(ePianoReleaseMode, &gig::Instrument::PianoReleaseMode);
1076        connect(eDimensionKeyRangeLow,
1077                &InstrumentProps::set_DimensionKeyRange_low);
1078        connect(eDimensionKeyRangeHigh,
1079                &InstrumentProps::set_DimensionKeyRange_high);
1080    
     rowno = 0;  
1081      table.set_col_spacings(5);      table.set_col_spacings(5);
1082    
1083      add_prop(eName);      table.add(eName);
1084      add_prop(eIsDrum);      table.add(eIsDrum);
1085      add_prop(eMIDIBank);      table.add(eMIDIBank);
1086      add_prop(eMIDIProgram);      table.add(eMIDIProgram);
1087      add_prop(eAttenuation);      table.add(eAttenuation);
1088      add_prop(eGainPlus6);      table.add(eGainPlus6);
1089      add_prop(eEffectSend);      table.add(eEffectSend);
1090      add_prop(eFineTune);      table.add(eFineTune);
1091      add_prop(ePitchbendRange);      table.add(ePitchbendRange);
1092      add_prop(ePianoReleaseMode);      table.add(ePianoReleaseMode);
1093      add_prop(eDimensionKeyRangeLow);      table.add(eDimensionKeyRangeLow);
1094      add_prop(eDimensionKeyRangeHigh);      table.add(eDimensionKeyRangeHigh);
   
     eDimensionKeyRangeLow.signal_changed_by_user().connect(  
         sigc::mem_fun(*this, &InstrumentProps::key_range_low_changed));  
     eDimensionKeyRangeHigh.signal_changed_by_user().connect(  
         sigc::mem_fun(*this, &InstrumentProps::key_range_high_changed));  
1095    
1096      add(vbox);      add(vbox);
1097      table.set_border_width(5);      table.set_border_width(5);
# Line 808  InstrumentProps::InstrumentProps() Line 1115  InstrumentProps::InstrumentProps()
1115    
1116  void InstrumentProps::set_instrument(gig::Instrument* instrument)  void InstrumentProps::set_instrument(gig::Instrument* instrument)
1117  {  {
1118      eName.set_ptr(&instrument->pInfo->Name);      this->instrument = instrument;
     eIsDrum.set_ptr(&instrument->IsDrum);  
     eMIDIBank.set_ptr(&instrument->MIDIBank);  
     eMIDIProgram.set_ptr(&instrument->MIDIProgram);  
     eAttenuation.set_ptr(&instrument->Attenuation);  
     eGainPlus6.set_ptr(&instrument->Attenuation);  
     eEffectSend.set_ptr(&instrument->EffectSend);  
     eFineTune.set_ptr(&instrument->FineTune);  
     ePitchbendRange.set_ptr(&instrument->PitchbendRange);  
     ePianoReleaseMode.set_ptr(&instrument->PianoReleaseMode);  
     eDimensionKeyRangeLow.set_ptr(0);  
     eDimensionKeyRangeHigh.set_ptr(0);  
     eDimensionKeyRangeLow.set_ptr(&instrument->DimensionKeyRange.low);  
     eDimensionKeyRangeHigh.set_ptr(&instrument->DimensionKeyRange.high);  
 }  
1119    
1120  void InstrumentProps::key_range_low_changed()      update_model++;
1121  {      eName.set_value(instrument->pInfo->Name);
1122      double l = eDimensionKeyRangeLow.get_value();      eIsDrum.set_value(instrument->IsDrum);
1123      double h = eDimensionKeyRangeHigh.get_value();      eMIDIBank.set_value(instrument->MIDIBank);
1124      if (h < l) eDimensionKeyRangeHigh.set_value(l);      eMIDIProgram.set_value(instrument->MIDIProgram);
1125        eAttenuation.set_value(instrument->Attenuation);
1126        eGainPlus6.set_value(instrument->Attenuation);
1127        eEffectSend.set_value(instrument->EffectSend);
1128        eFineTune.set_value(instrument->FineTune);
1129        ePitchbendRange.set_value(instrument->PitchbendRange);
1130        ePianoReleaseMode.set_value(instrument->PianoReleaseMode);
1131        eDimensionKeyRangeLow.set_value(instrument->DimensionKeyRange.low);
1132        eDimensionKeyRangeHigh.set_value(instrument->DimensionKeyRange.high);
1133        update_model--;
1134  }  }
1135    
1136  void InstrumentProps::key_range_high_changed()  sigc::signal<void>& InstrumentProps::signal_instrument_changed()
 {  
     double l = eDimensionKeyRangeLow.get_value();  
     double h = eDimensionKeyRangeHigh.get_value();  
     if (h < l) eDimensionKeyRangeLow.set_value(h);  
 }  
   
 sigc::signal<void> InstrumentProps::signal_instrument_changed()  
1137  {  {
1138      return instrument_changed;      return instrument_changed;
1139  }  }
# Line 851  void MainWindow::file_changed() Line 1146  void MainWindow::file_changed()
1146      }      }
1147  }  }
1148    
1149  void MainWindow::load_gig(gig::File* gig, const char* filename)  void MainWindow::load_gig(gig::File* gig, const char* filename, bool isSharedInstrument)
1150  {  {
1151      file = 0;      file = 0;
1152        set_file_is_shared(isSharedInstrument);
1153    
1154      this->filename = filename ? filename : _("Unsaved Gig File");      this->filename = filename ? filename : _("Unsaved Gig File");
1155      set_title(Glib::filename_display_basename(this->filename));      set_title(Glib::filename_display_basename(this->filename));
# Line 916  void MainWindow::load_gig(gig::File* gig Line 1212  void MainWindow::load_gig(gig::File* gig
1212    
1213  void MainWindow::show_instr_props()  void MainWindow::show_instr_props()
1214  {  {
1215      Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();      gig::Instrument* instrument = get_instrument();
1216      Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();      if (instrument)
     if (it)  
1217      {      {
1218          Gtk::TreeModel::Row row = *it;          instrumentProps.set_instrument(instrument);
1219          if (row[m_Columns.m_col_instr])          instrumentProps.show();
1220          {          instrumentProps.deiconify();
             instrumentProps.set_instrument(row[m_Columns.m_col_instr]);  
             instrumentProps.show();  
             instrumentProps.deiconify();  
         }  
1221      }      }
1222  }  }
1223    
1224    void MainWindow::on_action_view_status_bar() {
1225        Gtk::CheckMenuItem* item =
1226            dynamic_cast<Gtk::CheckMenuItem*>(uiManager->get_widget("/MenuBar/MenuView/Statusbar"));
1227        if (!item) {
1228            std::cerr << "/MenuBar/MenuView/Statusbar == NULL\n";
1229            return;
1230        }
1231        if (item->get_active()) m_StatusBar.show();
1232        else                    m_StatusBar.hide();
1233    }
1234    
1235  void MainWindow::on_button_release(GdkEventButton* button)  void MainWindow::on_button_release(GdkEventButton* button)
1236  {  {
1237      if (button->type == GDK_2BUTTON_PRESS) {      if (button->type == GDK_2BUTTON_PRESS) {
# Line 987  void MainWindow::on_action_add_instrumen Line 1289  void MainWindow::on_action_add_instrumen
1289    
1290  void MainWindow::on_action_remove_instrument() {  void MainWindow::on_action_remove_instrument() {
1291      if (!file) return;      if (!file) return;
1292        if (file_is_shared) {
1293            Gtk::MessageDialog msg(
1294                *this,
1295                 _("You cannot delete an instrument from this file, since it's "
1296                   "currently used by the sampler."),
1297                 false, Gtk::MESSAGE_INFO
1298            );
1299            msg.run();
1300            return;
1301        }
1302    
1303      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeView.get_selection();      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeView.get_selection();
1304      Gtk::TreeModel::iterator it = sel->get_selected();      Gtk::TreeModel::iterator it = sel->get_selected();
1305      if (it) {      if (it) {
# Line 1122  void MainWindow::on_action_add_sample() Line 1435  void MainWindow::on_action_add_sample()
1435                  {                  {
1436                      sample->MIDIUnityNote = instrument.basenote;                      sample->MIDIUnityNote = instrument.basenote;
1437    
1438    #if HAVE_SF_INSTRUMENT_LOOPS
1439                      if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {                      if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
1440                          sample->Loops = 1;                          sample->Loops = 1;
1441    
# Line 1141  void MainWindow::on_action_add_sample() Line 1455  void MainWindow::on_action_add_sample()
1455                          sample->LoopPlayCount = instrument.loops[0].count;                          sample->LoopPlayCount = instrument.loops[0].count;
1456                          sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;                          sample->LoopSize = sample->LoopEnd - sample->LoopStart + 1;
1457                      }                      }
1458    #endif
1459                  }                  }
1460    
1461                  // schedule resizing the sample (which will be done                  // schedule resizing the sample (which will be done
# Line 1171  void MainWindow::on_action_add_sample() Line 1486  void MainWindow::on_action_add_sample()
1486          }          }
1487          // show error message box when some file(s) could not be opened / added          // show error message box when some file(s) could not be opened / added
1488          if (error_files.size()) {          if (error_files.size()) {
1489              Glib::ustring txt = "Could not add the following sample(s):\n" + error_files;              Glib::ustring txt = _("Could not add the following sample(s):\n") + error_files;
1490              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
1491              msg.run();              msg.run();
1492          }          }
# Line 1197  void MainWindow::on_action_remove_sample Line 1512  void MainWindow::on_action_remove_sample
1512                       pSample; pSample = group->GetNextSample()) {                       pSample; pSample = group->GetNextSample()) {
1513                      members.push_back(pSample);                      members.push_back(pSample);
1514                  }                  }
1515                    // notify everybody that we're going to remove these samples
1516                    samples_to_be_removed_signal.emit(members);
1517                  // delete the group in the .gig file including the                  // delete the group in the .gig file including the
1518                  // samples that belong to the group                  // samples that belong to the group
1519                  file->DeleteGroup(group);                  file->DeleteGroup(group);
1520                    // notify that we're done with removal
1521                    samples_removed_signal.emit();
1522                  // if sample(s) were just previously added, remove                  // if sample(s) were just previously added, remove
1523                  // them from the import queue                  // them from the import queue
1524                  for (std::list<gig::Sample*>::iterator member = members.begin();                  for (std::list<gig::Sample*>::iterator member = members.begin();
# Line 1216  void MainWindow::on_action_remove_sample Line 1535  void MainWindow::on_action_remove_sample
1535                  }                  }
1536                  file_changed();                  file_changed();
1537              } else if (sample) {              } else if (sample) {
1538                    // notify everybody that we're going to remove this sample
1539                    std::list<gig::Sample*> lsamples;
1540                    lsamples.push_back(sample);
1541                    samples_to_be_removed_signal.emit(lsamples);
1542                  // remove sample from the .gig file                  // remove sample from the .gig file
1543                  file->DeleteSample(sample);                  file->DeleteSample(sample);
1544                    // notify that we're done with removal
1545                    samples_removed_signal.emit();
1546                  // if sample was just previously added, remove it from                  // if sample was just previously added, remove it from
1547                  // the import queue                  // the import queue
1548                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();                  for (std::list<SampleImportItem>::iterator iter = m_SampleImportQueue.begin();
# Line 1229  void MainWindow::on_action_remove_sample Line 1554  void MainWindow::on_action_remove_sample
1554                          break;                          break;
1555                      }                      }
1556                  }                  }
1557                    dimreg_changed();
1558                  file_changed();                  file_changed();
1559              }              }
1560              // remove respective row(s) from samples tree view              // remove respective row(s) from samples tree view
1561              m_refSamplesTreeModel->erase(it);              m_refSamplesTreeModel->erase(it);
1562          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1563                // pretend we're done with removal (i.e. to avoid dead locks)
1564                samples_removed_signal.emit();
1565                // show error message
1566              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1567              msg.run();              msg.run();
1568          }          }
1569      }      }
1570  }  }
1571    
1572    // For some reason drag_data_get gets called two times for each
1573    // drag'n'drop (at least when target is an Entry). This work-around
1574    // makes sure the code in drag_data_get and drop_drag_data_received is
1575    // only executed once, as drag_begin only gets called once.
1576    void MainWindow::on_sample_treeview_drag_begin(const Glib::RefPtr<Gdk::DragContext>& context)
1577    {
1578        first_call_to_drag_data_get = true;
1579    }
1580    
1581  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>&,
1582                                                    Gtk::SelectionData& selection_data, guint, guint)                                                    Gtk::SelectionData& selection_data, guint, guint)
1583  {  {
1584        if (!first_call_to_drag_data_get) return;
1585        first_call_to_drag_data_get = false;
1586    
1587      // get selected sample      // get selected sample
1588      gig::Sample* sample = NULL;      gig::Sample* sample = NULL;
1589      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();      Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
# Line 1263  void MainWindow::on_sample_label_drop_dr Line 1604  void MainWindow::on_sample_label_drop_dr
1604      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());      gig::Sample* sample = *((gig::Sample**) selection_data.get_data());
1605    
1606      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {      if (sample && selection_data.get_length() == sizeof(gig::Sample*)) {
1607          if (dimreg_edit.set_sample(sample)) {          std::cout << "Drop received sample \"" <<
1608              std::cout << "Drop received sample \"" <<              sample->pInfo->Name << "\"" << std::endl;
1609                  sample->pInfo->Name << "\"" << std::endl;          // drop success
1610              // drop success          context->drop_reply(true, time);
1611              context->drop_reply(true, time);  
1612              return;          //TODO: we should better move most of the following code to DimRegionEdit::set_sample()
1613    
1614            // notify everybody that we're going to alter the region
1615            gig::Region* region = m_RegionChooser.get_region();
1616            region_to_be_changed_signal.emit(region);
1617    
1618            // find the samplechannel dimension
1619            gig::dimension_def_t* stereo_dimension = 0;
1620            for (int i = 0 ; i < region->Dimensions ; i++) {
1621                if (region->pDimensionDefinitions[i].dimension ==
1622                    gig::dimension_samplechannel) {
1623                    stereo_dimension = &region->pDimensionDefinitions[i];
1624                    break;
1625                }
1626            }
1627            bool channels_changed = false;
1628            if (sample->Channels == 1 && stereo_dimension) {
1629                // remove the samplechannel dimension
1630                region->DeleteDimension(stereo_dimension);
1631                channels_changed = true;
1632                region_changed();
1633            }
1634            dimreg_edit.set_sample(sample);
1635    
1636            if (sample->Channels == 2 && !stereo_dimension) {
1637                // add samplechannel dimension
1638                gig::dimension_def_t dim;
1639                dim.dimension = gig::dimension_samplechannel;
1640                dim.bits = 1;
1641                dim.zones = 2;
1642                region->AddDimension(&dim);
1643                channels_changed = true;
1644                region_changed();
1645            }
1646            if (channels_changed) {
1647                // unmap all samples with wrong number of channels
1648                // TODO: maybe there should be a warning dialog for this
1649                for (int i = 0 ; i < region->DimensionRegions ; i++) {
1650                    gig::DimensionRegion* d = region->pDimensionRegions[i];
1651                    if (d->pSample && d->pSample->Channels != sample->Channels) {
1652                        gig::Sample* oldref = d->pSample;
1653                        d->pSample = NULL;
1654                        sample_ref_changed_signal.emit(oldref, NULL);
1655                    }
1656                }
1657          }          }
1658    
1659            // notify we're done with altering
1660            region_changed_signal.emit(region);
1661    
1662            file_changed();
1663    
1664            return;
1665      }      }
1666      // drop failed      // drop failed
1667      context->drop_reply(false, time);      context->drop_reply(false, time);
# Line 1308  void MainWindow::instrument_name_changed Line 1700  void MainWindow::instrument_name_changed
1700          file_changed();          file_changed();
1701      }      }
1702  }  }
1703    
1704    void MainWindow::set_file_is_shared(bool b) {
1705        this->file_is_shared = b;
1706    
1707        if (file_is_shared) {
1708            m_AttachedStateLabel.set_label(_("live-mode"));
1709            m_AttachedStateImage.set(
1710                Gdk::Pixbuf::create_from_xpm_data(status_attached_xpm)
1711            );
1712        } else {
1713            m_AttachedStateLabel.set_label(_("stand-alone"));
1714            m_AttachedStateImage.set(
1715                Gdk::Pixbuf::create_from_xpm_data(status_detached_xpm)
1716            );
1717        }
1718    }
1719    
1720    sigc::signal<void, gig::File*>& MainWindow::signal_file_structure_to_be_changed() {
1721        return file_structure_to_be_changed_signal;
1722    }
1723    
1724    sigc::signal<void, gig::File*>& MainWindow::signal_file_structure_changed() {
1725        return file_structure_changed_signal;
1726    }
1727    
1728    sigc::signal<void, std::list<gig::Sample*> >& MainWindow::signal_samples_to_be_removed() {
1729        return samples_to_be_removed_signal;
1730    }
1731    
1732    sigc::signal<void>& MainWindow::signal_samples_removed() {
1733        return samples_removed_signal;
1734    }
1735    
1736    sigc::signal<void, gig::Region*>& MainWindow::signal_region_to_be_changed() {
1737        return region_to_be_changed_signal;
1738    }
1739    
1740    sigc::signal<void, gig::Region*>& MainWindow::signal_region_changed() {
1741        return region_changed_signal;
1742    }
1743    
1744    sigc::signal<void, gig::Sample*/*old*/, gig::Sample*/*new*/>& MainWindow::signal_sample_ref_changed() {
1745        return sample_ref_changed_signal;
1746    }
1747    
1748    sigc::signal<void, gig::DimensionRegion*>& MainWindow::signal_dimreg_to_be_changed() {
1749        return dimreg_to_be_changed_signal;
1750    }
1751    
1752    sigc::signal<void, gig::DimensionRegion*>& MainWindow::signal_dimreg_changed() {
1753        return dimreg_changed_signal;
1754    }
1755    
1756    sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_note_on() {
1757        return note_on_signal;
1758    }
1759    
1760    sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_note_off() {
1761        return note_off_signal;
1762    }
1763    
1764    sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_keyboard_key_hit() {
1765        return m_RegionChooser.signal_keyboard_key_hit();
1766    }
1767    
1768    sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_keyboard_key_released() {
1769        return m_RegionChooser.signal_keyboard_key_released();
1770    }

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

  ViewVC Help
Powered by ViewVC