--- gigedit/trunk/src/gigedit/mainwindow.cpp 2014/06/11 20:26:26 2624 +++ gigedit/trunk/src/gigedit/mainwindow.cpp 2015/01/04 19:46:54 2691 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2014 Andreas Persson + * Copyright (C) 2006-2015 Andreas Persson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -53,6 +53,7 @@ MainWindow::MainWindow() : + m_DimRegionChooser(*this), dimreg_label(_("Changes apply to:")), dimreg_all_regions(_("all regions")), dimreg_all_dimregs(_("all dimension splits")), @@ -146,8 +147,19 @@ actionGroup->add(Gtk::Action::create("Quit", Gtk::Stock::QUIT), sigc::mem_fun( *this, &MainWindow::on_action_quit)); - actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument"))); - + actionGroup->add( + Gtk::Action::create("MenuSample", _("_Sample")), + sigc::mem_fun(*this, &MainWindow::show_samples_tab) + ); + actionGroup->add( + Gtk::Action::create("MenuInstrument", _("_Instrument")), + sigc::mem_fun(*this, &MainWindow::show_intruments_tab) + ); + actionGroup->add( + Gtk::Action::create("MenuScript", _("S_cript")), + sigc::mem_fun(*this, &MainWindow::show_scripts_tab) + ); + actionGroup->add(Gtk::Action::create("AllInstruments", _("_Select"))); actionGroup->add(Gtk::Action::create("MenuEdit", _("_Edit"))); @@ -205,6 +217,14 @@ sigc::mem_fun(*this, &MainWindow::on_action_warn_user_on_extensions) ); + toggle_action = + Gtk::ToggleAction::create("SyncSamplerInstrumentSelection", _("Synchronize sampler's instrument selection")); + toggle_action->set_active(Settings::singleton()->syncSamplerInstrumentSelection); + actionGroup->add( + toggle_action, + sigc::mem_fun(*this, &MainWindow::on_action_sync_sampler_instrument_selection) + ); + actionGroup->add(Gtk::Action::create("MenuTools", _("_Tools"))); @@ -287,7 +307,33 @@ " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " " " " " @@ -298,6 +344,7 @@ " " " " " " + " " " " " " " " @@ -359,6 +406,11 @@ } { Gtk::MenuItem* item = dynamic_cast( + uiManager->get_widget("/MenuBar/MenuSettings/SyncSamplerInstrumentSelection")); + item->set_tooltip_text(_("If checked, the sampler's current instrument will automatically be switched whenever another instrument was selected in gigedit (only available in live-mode).")); + } + { + Gtk::MenuItem* item = dynamic_cast( uiManager->get_widget("/MenuBar/MenuTools/CombineInstruments")); item->set_tooltip_text(_("Create combi sounds out of individual sounds of this .gig file.")); } @@ -370,7 +422,7 @@ instrument_menu = static_cast( - uiManager->get_widget("/MenuBar/MenuInstrument"))->get_submenu(); + uiManager->get_widget("/MenuBar/MenuInstrument/AllInstruments"))->get_submenu(); Gtk::Widget* menuBar = uiManager->get_widget("/MenuBar"); m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK); @@ -415,7 +467,7 @@ { Gtk::TreeViewColumn* column = m_TreeViewSamples.get_column(0); Gtk::CellRendererText* cellrenderer = - dynamic_cast(column->get_first_cell_renderer()); + dynamic_cast(column->get_first_cell()); column->add_attribute( cellrenderer->property_foreground(), m_SamplesModel.m_color ); @@ -423,7 +475,7 @@ { Gtk::TreeViewColumn* column = m_TreeViewSamples.get_column(1); Gtk::CellRendererText* cellrenderer = - dynamic_cast(column->get_first_cell_renderer()); + dynamic_cast(column->get_first_cell()); column->add_attribute( cellrenderer->property_foreground(), m_SamplesModel.m_color ); @@ -440,6 +492,8 @@ m_refScriptsTreeModel = ScriptsTreeStore::create(m_ScriptsModel); m_TreeViewScripts.set_model(m_refScriptsTreeModel); m_TreeViewScripts.set_tooltip_text(_( + "Use CTRL + double click for editing a script." + "\n\n" "Note: instrument scripts are a LinuxSampler extension of the gig " "format. This feature will not work with the GigaStudio software!" )); @@ -449,6 +503,10 @@ m_TreeViewScripts.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &MainWindow::on_script_treeview_button_release) ); + //FIXME: why the heck does this double click signal_row_activated() only fired while CTRL key is pressed ? + m_TreeViewScripts.signal_row_activated().connect( + sigc::mem_fun(*this, &MainWindow::script_double_clicked) + ); m_refScriptsTreeModel->signal_row_changed().connect( sigc::mem_fun(*this, &MainWindow::script_name_changed) ); @@ -504,6 +562,10 @@ sigc::mem_fun(*this, &MainWindow::on_samples_to_be_removed) ); + dimreg_edit.signal_select_sample().connect( + sigc::mem_fun(*this, &MainWindow::select_sample) + ); + m_RegionChooser.signal_instrument_struct_to_be_changed().connect( sigc::hide( sigc::bind( @@ -628,7 +690,7 @@ void MainWindow::dimreg_changed() { update_dimregs(); - dimreg_edit.set_dim_region(m_DimRegionChooser.get_dimregion()); + dimreg_edit.set_dim_region(m_DimRegionChooser.get_main_dimregion()); } void MainWindow::on_sel_change() @@ -644,6 +706,10 @@ } m_RegionChooser.set_instrument(get_instrument()); + + if (Settings::singleton()->syncSamplerInstrumentSelection) { + switch_sampler_instrument_signal.emit(get_instrument()); + } } void loader_progress_callback(gig::progress_t* progress) @@ -664,20 +730,28 @@ void Loader::thread_function() { printf("thread_function self=%x\n", Glib::Threads::Thread::self()); - printf("Start %s\n", filename); - RIFF::File* riff = new RIFF::File(filename); - gig = new gig::File(riff); - gig::progress_t progress; - progress.callback = loader_progress_callback; - progress.custom = this; - - gig->GetInstrument(0, &progress); - printf("End\n"); - finished_dispatcher(); + printf("Start %s\n", filename.c_str()); + try { + RIFF::File* riff = new RIFF::File(filename); + gig = new gig::File(riff); + gig::progress_t progress; + progress.callback = loader_progress_callback; + progress.custom = this; + + gig->GetInstrument(0, &progress); + printf("End\n"); + finished_dispatcher(); + } catch (RIFF::Exception e) { + error_message = e.Message; + error_dispatcher.emit(); + } catch (...) { + error_message = _("Unknown exception occurred"); + error_dispatcher.emit(); + } } Loader::Loader(const char* filename) - : filename(filename), thread(0) + : filename(filename), thread(0), progress(0.f) { } @@ -711,11 +785,99 @@ return finished_dispatcher; } -LoadDialog::LoadDialog(const Glib::ustring& title, Gtk::Window& parent) +Glib::Dispatcher& Loader::signal_error() +{ + return error_dispatcher; +} + +void saver_progress_callback(gig::progress_t* progress) +{ + Saver* saver = static_cast(progress->custom); + saver->progress_callback(progress->factor); +} + +void Saver::progress_callback(float fraction) +{ + { + Glib::Threads::Mutex::Lock lock(progressMutex); + progress = fraction; + } + progress_dispatcher.emit(); +} + +void Saver::thread_function() +{ + printf("thread_function self=%x\n", Glib::Threads::Thread::self()); + printf("Start %s\n", filename.c_str()); + try { + gig::progress_t progress; + progress.callback = saver_progress_callback; + progress.custom = this; + + // if no filename was provided, that means "save", if filename was provided means "save as" + if (filename.empty()) { + gig->Save(&progress); + } else { + gig->Save(filename, &progress); + } + + printf("End\n"); + finished_dispatcher.emit(); + } catch (RIFF::Exception e) { + error_message = e.Message; + error_dispatcher.emit(); + } catch (...) { + error_message = _("Unknown exception occurred"); + error_dispatcher.emit(); + } +} + +Saver::Saver(gig::File* file, Glib::ustring filename) + : gig(file), filename(filename), thread(0), progress(0.f) +{ +} + +void Saver::launch() +{ +#ifdef OLD_THREADS + thread = Glib::Thread::create(sigc::mem_fun(*this, &Saver::thread_function), true); +#else + thread = Glib::Threads::Thread::create(sigc::mem_fun(*this, &Saver::thread_function)); +#endif + printf("launch thread=%x\n", thread); +} + +float Saver::get_progress() +{ + float res; + { + Glib::Threads::Mutex::Lock lock(progressMutex); + res = progress; + } + return res; +} + +Glib::Dispatcher& Saver::signal_progress() +{ + return progress_dispatcher; +} + +Glib::Dispatcher& Saver::signal_finished() +{ + return finished_dispatcher; +} + +Glib::Dispatcher& Saver::signal_error() +{ + return error_dispatcher; +} + +ProgressDialog::ProgressDialog(const Glib::ustring& title, Gtk::Window& parent) : Gtk::Dialog(title, parent, true) { get_vbox()->pack_start(progressBar); show_all_children(); + resize(600,50); } // Clear all GUI elements / controls. This method is typically called @@ -784,8 +946,17 @@ dialog.set_default_response(Gtk::RESPONSE_YES); int response = dialog.run(); dialog.hide(); - if (response == Gtk::RESPONSE_YES) return file_save(); - return response != Gtk::RESPONSE_CANCEL; + + // TODO: the following return valid is disabled and hard coded instead for + // now, due to the fact that saving with progress bar is now implemented + // asynchronously, as a result the app does not close automatically anymore + // after saving the file has completed + // + // if (response == Gtk::RESPONSE_YES) return file_save(); + // return response != Gtk::RESPONSE_CANCEL; + // + if (response == Gtk::RESPONSE_YES) file_save(); + return false; // always prevent closing the app for now (see comment above) } bool MainWindow::leaving_shared_mode_dialog() { @@ -836,13 +1007,20 @@ void MainWindow::load_file(const char* name) { __clear(); - load_dialog = new LoadDialog(_("Loading..."), *this); - load_dialog->show_all(); - loader = new Loader(strdup(name)); + + progress_dialog = new ProgressDialog( //FIXME: memory leak! + _("Loading") + Glib::ustring(" '") + + Glib::filename_display_basename(name) + "' ...", + *this + ); + progress_dialog->show_all(); + loader = new Loader(name); //FIXME: memory leak! loader->signal_progress().connect( sigc::mem_fun(*this, &MainWindow::on_loader_progress)); loader->signal_finished().connect( sigc::mem_fun(*this, &MainWindow::on_loader_finished)); + loader->signal_error().connect( + sigc::mem_fun(*this, &MainWindow::on_loader_error)); loader->launch(); } @@ -858,20 +1036,49 @@ // load the instrument gig::File* pFile = (gig::File*) instr->GetParent(); load_gig(pFile, 0 /*file name*/, true /*shared instrument*/); - //TODO: automatically select the given instrument + // automatically select the given instrument + int i = 0; + for (gig::Instrument* instrument = pFile->GetFirstInstrument(); instrument; + instrument = pFile->GetNextInstrument(), ++i) + { + if (instrument == instr) { + // select item in "instruments" tree view + m_TreeView.get_selection()->select(Gtk::TreePath(ToString(i))); + // make sure the selected item in the "instruments" tree view is + // visible (scroll to it) + m_TreeView.scroll_to_row(Gtk::TreePath(ToString(i))); + // select item in instrument menu + { + const std::vector children = + instrument_menu->get_children(); + static_cast(children[i])->set_active(); + } + // update region chooser and dimension region chooser + m_RegionChooser.set_instrument(instr); + break; + } + } } void MainWindow::on_loader_progress() { - load_dialog->set_fraction(loader->get_progress()); + progress_dialog->set_fraction(loader->get_progress()); } void MainWindow::on_loader_finished() { printf("Loader finished!\n"); printf("on_loader_finished self=%x\n", Glib::Threads::Thread::self()); - load_gig(loader->gig, loader->filename); - load_dialog->hide(); + load_gig(loader->gig, loader->filename.c_str()); + progress_dialog->hide(); +} + +void MainWindow::on_loader_error() +{ + Glib::ustring txt = _("Could not load file: ") + loader->error_message; + Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR); + msg.run(); + progress_dialog->hide(); } void MainWindow::on_action_file_save() @@ -910,23 +1117,54 @@ std::cout << "Saving file\n" << std::flush; file_structure_to_be_changed_signal.emit(this->file); - try { - file->Save(); - if (file_is_changed) { - set_title(get_title().substr(1)); - file_is_changed = false; - } - } catch (RIFF::Exception e) { - file_structure_changed_signal.emit(this->file); - Glib::ustring txt = _("Could not save file: ") + e.Message; - Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR); - msg.run(); - return false; - } - std::cout << "Saving file done\n" << std::flush; + + progress_dialog = new ProgressDialog( //FIXME: memory leak! + _("Saving") + Glib::ustring(" '") + + Glib::filename_display_basename(this->filename) + "' ...", + *this + ); + progress_dialog->show_all(); + saver = new Saver(this->file); //FIXME: memory leak! + saver->signal_progress().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_progress)); + saver->signal_finished().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_finished)); + saver->signal_error().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_error)); + saver->launch(); + + return true; +} + +void MainWindow::on_saver_progress() +{ + progress_dialog->set_fraction(saver->get_progress()); +} + +void MainWindow::on_saver_error() +{ + file_structure_changed_signal.emit(this->file); + Glib::ustring txt = _("Could not save file: ") + saver->error_message; + Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR); + msg.run(); +} + +void MainWindow::on_saver_finished() +{ + this->file = saver->gig; + this->filename = saver->filename; + current_gig_dir = Glib::path_get_dirname(filename); + set_title(Glib::filename_display_basename(filename)); + file_has_name = true; + file_is_changed = false; + std::cout << "Saving file done. Importing queued samples now ...\n" << std::flush; __import_queued_samples(); + std::cout << "Importing queued samples done.\n" << std::flush; + file_structure_changed_signal.emit(this->file); - return true; + + load_gig(this->file, this->filename.c_str()); + progress_dialog->hide(); } void MainWindow::on_action_file_save_as() @@ -991,28 +1229,28 @@ descriptionArea.show_all(); if (dialog.run() == Gtk::RESPONSE_OK) { - file_structure_to_be_changed_signal.emit(this->file); - try { - std::string filename = dialog.get_filename(); - if (!Glib::str_has_suffix(filename, ".gig")) { - filename += ".gig"; - } - printf("filename=%s\n", filename.c_str()); - file->Save(filename); - this->filename = filename; - current_gig_dir = Glib::path_get_dirname(filename); - set_title(Glib::filename_display_basename(filename)); - file_has_name = true; - file_is_changed = false; - } catch (RIFF::Exception e) { - file_structure_changed_signal.emit(this->file); - Glib::ustring txt = _("Could not save file: ") + e.Message; - Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR); - msg.run(); - return false; + std::string filename = dialog.get_filename(); + if (!Glib::str_has_suffix(filename, ".gig")) { + filename += ".gig"; } - __import_queued_samples(); - file_structure_changed_signal.emit(this->file); + printf("filename=%s\n", filename.c_str()); + + progress_dialog = new ProgressDialog( //FIXME: memory leak! + _("Saving") + Glib::ustring(" '") + + Glib::filename_display_basename(filename) + "' ...", + *this + ); + progress_dialog->show_all(); + + saver = new Saver(file, filename); //FIXME: memory leak! + saver->signal_progress().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_progress)); + saver->signal_finished().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_finished)); + saver->signal_error().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_error)); + saver->launch(); + return true; } return false; @@ -1123,6 +1361,11 @@ !Settings::singleton()->warnUserOnExtensions; } +void MainWindow::on_action_sync_sampler_instrument_selection() { + Settings::singleton()->syncSamplerInstrumentSelection = + !Settings::singleton()->syncSamplerInstrumentSelection; +} + void MainWindow::on_action_help_about() { Gtk::AboutDialog dialog; @@ -1132,15 +1375,15 @@ dialog.set_name("Gigedit"); #endif dialog.set_version(VERSION); - dialog.set_copyright("Copyright (C) 2006-2014 Andreas Persson"); + dialog.set_copyright("Copyright (C) 2006-2015 Andreas Persson"); const std::string sComment = _("Built " __DATE__ "\nUsing ") + ::gig::libraryName() + " " + ::gig::libraryVersion() + "\n\n" + _( "Gigedit is released under the GNU General Public License.\n" "\n" - "Please notice that this is still a very young instrument editor. " - "So better backup your Gigasampler files before editing them with " + "This program is distributed WITHOUT ANY WARRANTY; So better " + "backup your Gigasampler/GigaStudio files before editing them with " "this application.\n" "\n" "Please report bugs to: http://bugs.linuxsampler.org" @@ -1436,7 +1679,7 @@ add_instrument_to_menu(name); } instrument_name_connection.unblock(); - uiManager->get_widget("/MenuBar/MenuInstrument")->show(); + uiManager->get_widget("/MenuBar/MenuInstrument/AllInstruments")->show(); updateSampleRefCountMap(gig); @@ -1458,7 +1701,7 @@ rowSample[m_SamplesModel.m_col_group] = NULL; int refcount = sample_ref_count.count(sample) ? sample_ref_count[sample] : 0; rowSample[m_SamplesModel.m_col_refcount] = ToString(refcount) + " " + _("Refs."); - rowSample[m_SamplesModel.m_color] = refcount ? "black" : "gray"; + rowSample[m_SamplesModel.m_color] = refcount ? "black" : "red"; } } } @@ -1616,9 +1859,15 @@ show_instr_props(); } else if (button->type == GDK_BUTTON_PRESS && button->button == 3) { // gig v2 files have no midi rules + const bool bEnabled = !(file->pVersion && file->pVersion->major == 2); + static_cast( + uiManager->get_widget("/MenuBar/MenuInstrument/MidiRules"))->set_sensitive( + bEnabled + ); static_cast( uiManager->get_widget("/PopupMenu/MidiRules"))->set_sensitive( - !(file->pVersion && file->pVersion->major == 2)); + bEnabled + ); popup_menu->popup(button->button, button->time); } } @@ -1638,6 +1887,25 @@ } } +void MainWindow::select_sample(gig::Sample* sample) { + Glib::RefPtr model = m_TreeViewSamples.get_model(); + for (int g = 0; g < model->children().size(); ++g) { + Gtk::TreeModel::Row rowGroup = model->children()[g]; + for (int s = 0; s < rowGroup.children().size(); ++s) { + Gtk::TreeModel::Row rowSample = rowGroup.children()[s]; + if (rowSample[m_SamplesModel.m_col_sample] == sample) { + show_samples_tab(); + m_TreeViewSamples.get_selection()->select(rowGroup.children()[s]); + Gtk::TreePath path( + m_TreeViewSamples.get_selection()->get_selected() + ); + m_TreeViewSamples.scroll_to_row(path); + return; + } + } + } +} + void MainWindow::on_sample_treeview_button_release(GdkEventButton* button) { if (button->type == GDK_BUTTON_PRESS && button->button == 3) { Gtk::Menu* sample_popup = @@ -1652,6 +1920,8 @@ group_selected = row[m_SamplesModel.m_col_group]; sample_selected = row[m_SamplesModel.m_col_sample]; } + + dynamic_cast(uiManager->get_widget("/SamplePopupMenu/SampleProperties"))-> set_sensitive(group_selected || sample_selected); dynamic_cast(uiManager->get_widget("/SamplePopupMenu/AddSample"))-> @@ -1664,6 +1934,17 @@ set_sensitive(group_selected || sample_selected); // show sample popup sample_popup->popup(button->button, button->time); + + dynamic_cast(uiManager->get_widget("/MenuBar/MenuSample/SampleProperties"))-> + set_sensitive(group_selected || sample_selected); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuSample/AddSample"))-> + set_sensitive(group_selected || sample_selected); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuSample/AddGroup"))-> + set_sensitive(file); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuSample/ShowSampleRefs"))-> + set_sensitive(sample_selected); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuSample/RemoveSample"))-> + set_sensitive(group_selected || sample_selected); } } @@ -1691,6 +1972,15 @@ set_sensitive(group_selected || script_selected); // show sample popup script_popup->popup(button->button, button->time); + + dynamic_cast(uiManager->get_widget("/MenuBar/MenuScript/AddScript"))-> + set_sensitive(group_selected || script_selected); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuScript/AddScriptGroup"))-> + set_sensitive(file); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuScript/EditScript"))-> + set_sensitive(script_selected); + dynamic_cast(uiManager->get_widget("/MenuBar/MenuScript/RemoveScript"))-> + set_sensitive(group_selected || script_selected); } } @@ -2498,6 +2788,21 @@ } } +void MainWindow::script_double_clicked(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column) +{ + Gtk::TreeModel::iterator iter = m_refScriptsTreeModel->get_iter(path); + if (!iter) return; + Gtk::TreeModel::Row row = *iter; + gig::Script* script = row[m_ScriptsModel.m_col_script]; + if (!script) return; + + ScriptEditor* editor = new ScriptEditor; + editor->setScript(script); + //editor->reparent(*this); + editor->show(); +} + void MainWindow::instrument_name_changed(const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter) { if (!iter) return; @@ -2627,8 +2932,27 @@ ); } - // Note: requires that this file already has a filename ! - this->file->Save(); + // Finally save gig file persistently to disk ... + //NOTE: requires that this gig file already has a filename ! + { + std::cout << "Saving file\n" << std::flush; + file_structure_to_be_changed_signal.emit(this->file); + + progress_dialog = new ProgressDialog( //FIXME: memory leak! + _("Saving") + Glib::ustring(" '") + + Glib::filename_display_basename(this->filename) + "' ...", + *this + ); + progress_dialog->show_all(); + saver = new Saver(this->file); //FIXME: memory leak! + saver->signal_progress().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_progress)); + saver->signal_finished().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_finished)); + saver->signal_error().connect( + sigc::mem_fun(*this, &MainWindow::on_saver_error)); + saver->launch(); + } } void MainWindow::on_action_merge_files() { @@ -2718,6 +3042,12 @@ Gdk::Pixbuf::create_from_xpm_data(status_detached_xpm) ); } + + { + Gtk::MenuItem* item = dynamic_cast( + uiManager->get_widget("/MenuBar/MenuSettings/SyncSamplerInstrumentSelection")); + if (item) item->set_sensitive(b); + } } void MainWindow::on_sample_ref_count_incremented(gig::Sample* sample, int offset) { @@ -2732,7 +3062,7 @@ Gtk::TreeModel::Row rowSample = rowGroup.children()[s]; if (rowSample[m_SamplesModel.m_col_sample] != sample) continue; rowSample[m_SamplesModel.m_col_refcount] = ToString(refcount) + " " + _("Refs."); - rowSample[m_SamplesModel.m_color] = refcount ? "black" : "gray"; + rowSample[m_SamplesModel.m_color] = refcount ? "black" : "red"; } } } @@ -2746,12 +3076,24 @@ // just in case a new sample is added later with exactly the same memory // address, which would lead to incorrect refcount if not deleted here for (std::list::const_iterator it = samples.begin(); - it != samples.end(); it != samples.end()) + it != samples.end(); ++it) { sample_ref_count.erase(*it); } } +void MainWindow::show_samples_tab() { + m_TreeViewNotebook.set_current_page(0); +} + +void MainWindow::show_intruments_tab() { + m_TreeViewNotebook.set_current_page(1); +} + +void MainWindow::show_scripts_tab() { + m_TreeViewNotebook.set_current_page(2); +} + sigc::signal& MainWindow::signal_file_structure_to_be_changed() { return file_structure_to_be_changed_signal; } @@ -2807,3 +3149,7 @@ sigc::signal& MainWindow::signal_keyboard_key_released() { return m_RegionChooser.signal_keyboard_key_released(); } + +sigc::signal& MainWindow::signal_switch_sampler_instrument() { + return switch_sampler_instrument_signal; +}