diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-09-02 15:17:13 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-09-02 15:17:13 +0000 |
commit | f2a2e9c00281c9bfe5ff7df31cdc8860129b282c (patch) | |
tree | e45988a790da04e1e72e917d2b0f7935526fe8a2 | |
parent | 6c2728f9815bcdbf1cbd702f271344e295ddb074 (diff) |
limited history depth (no GUI yet); more work on import dialog and semantics
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2361 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/audio_streamview.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/editing_syms.h | 7 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 17 | ||||
-rw-r--r-- | gtk2_ardour/editor_audio_import.cc | 132 | ||||
-rw-r--r-- | gtk2_ardour/editor_canvas.cc | 5 | ||||
-rw-r--r-- | gtk2_ardour/editor_region_list.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/mixer_ui.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/playlist_selector.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.cc | 12 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.h | 9 | ||||
-rw-r--r-- | gtk2_ardour/sfdb_ui.cc | 256 | ||||
-rw-r--r-- | gtk2_ardour/sfdb_ui.h | 17 | ||||
-rw-r--r-- | gtk2_ardour/streamview.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration_vars.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 1 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 14 | ||||
-rw-r--r-- | libs/pbd/pbd/undo.h | 10 | ||||
-rw-r--r-- | libs/pbd/undo.cc | 16 |
21 files changed, 349 insertions, 174 deletions
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index d80207fad9..abfecce046 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -513,16 +513,14 @@ AudioStreamView::setup_rec_box () /* start a new rec box */ - AudioTrack* at; - - at = _trackview.audio_track(); /* we know what it is already */ + boost::shared_ptr<AudioTrack> at = _trackview.audio_track (); boost::shared_ptr<AudioDiskstream> ds = at->audio_diskstream(); nframes_t frame_pos = ds->current_capture_start (); gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); gdouble xend; uint32_t fill_color; - switch (_trackview.audio_track()->mode()) { + switch (at->mode()) { case Normal: xend = xstart; fill_color = ARDOUR_UI::config()->canvasvar_RecordingRect.get(); diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h index 8971f79995..116588a1ce 100644 --- a/gtk2_ardour/editing_syms.h +++ b/gtk2_ardour/editing_syms.h @@ -86,7 +86,8 @@ IMPORTPOSITION(ImportAtPlayhead=2) IMPORTPOSITION(ImportAtStart=3) // if this is changed, remember to update the string table in sfdb_ui.cc -IMPORTCHANNEL(ImportThingPerFile=0) -IMPORTCHANNEL(ImportThingPerChannel=1) -IMPORTCHANNEL(ImportThingForAll=2) +IMPORTCHANNEL(ImportDistinctFiles=0) +IMPORTCHANNEL(ImportMergeFiles=1) +IMPORTCHANNEL(ImportSerializeFiles=2) +IMPORTCHANNEL(ImportDistinctChannels=3) diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 715ca04b41..c79bb317b0 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -965,17 +965,18 @@ class Editor : public PublicEditor void external_audio_dialog (); bool check_multichannel_status (const std::vector<Glib::ustring>& paths); - void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t& pos); - void do_import (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&); + void bring_in_external_audio (Editing::ImportMode mode, nframes64_t& pos); + void do_import (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&); - void _do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&); - void do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&); - bool idle_do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&); + void _do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&); + void do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&); + bool idle_do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&); - int import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes64_t& pos); + int import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, nframes64_t& pos); int embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode, - ARDOUR::AudioTrack* track, nframes64_t& pos); - int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, ARDOUR::AudioTrack* track, nframes64_t& pos, Editing::ImportMode mode); + nframes64_t& pos); + int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, nframes64_t& pos, Editing::ImportMode mode, + boost::shared_ptr<ARDOUR::AudioTrack>& existing_track, int nth); /* generic interthread progress window */ diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 0f05b27449..d2bbfa1113 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -97,14 +97,6 @@ Editor::external_audio_dialog () /* lets do it */ - AudioTrack* track = 0; - - if (!selection->tracks.empty()) { - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front()); - if (atv) { - track = atv->audio_track(); - } - } paths = browser.get_paths (); ImportPosition pos = browser.get_position (); @@ -128,24 +120,24 @@ Editor::external_audio_dialog () } if (browser.import.get_active()) { - do_import (paths, chns, mode, track, where); + do_import (paths, chns, mode, where); } else { - do_embed (paths, chns, mode, track, where); + do_embed (paths, chns, mode, where); } } void -Editor::do_import (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos) +Editor::do_import (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos) { switch (chns) { - case Editing::ImportThingPerFile: - case Editing::ImportThingForAll: - import_status.multichan = true; + case Editing::ImportDistinctChannels: + import_status.multichan = false; break; - case Editing::ImportThingPerChannel: - import_status.multichan = false; + default: + import_status.multichan = true; break; + } if (interthread_progress_window == 0) { @@ -159,31 +151,31 @@ Editor::do_import (vector<ustring> paths, ImportChannel chns, ImportMode mode, A to_import.clear (); to_import.push_back (*a); - import_sndfile (to_import, mode, track, pos); + import_sndfile (to_import, mode, pos); } interthread_progress_window->hide_all (); } bool -Editor::idle_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos) +Editor::idle_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos) { - _do_embed (paths, chns, mode, track, pos); + _do_embed (paths, chns, mode, pos); return false; } void -Editor::do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos) +Editor::do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos) { #ifdef GTKOSX - Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, chns, mode, track, pos)); + Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, chns, mode, pos)); #else - _do_embed (paths, chns, mode, track, pos); + _do_embed (paths, chns, mode, pos); #endif } void -Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos) +Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos) { bool multiple_files = paths.size() > 1; bool check_sample_rate = true; @@ -192,21 +184,22 @@ Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, A switch (chns) { - case Editing::ImportThingPerFile: - case Editing::ImportThingPerChannel: + case Editing::ImportDistinctFiles: + case Editing::ImportDistinctChannels: for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) { to_embed.clear (); to_embed.push_back (*a); - if (embed_sndfile (to_embed, chns, multiple_files, check_sample_rate, mode, track, pos) < -1) { + if (embed_sndfile (to_embed, chns, multiple_files, check_sample_rate, mode, pos) < -1) { goto out; } } break; - case Editing::ImportThingForAll: - if (embed_sndfile (paths, chns, multiple_files, check_sample_rate, mode, track, pos) < -1) { + case Editing::ImportSerializeFiles: + case Editing::ImportMergeFiles: + if (embed_sndfile (paths, chns, multiple_files, check_sample_rate, mode, pos) < -1) { goto out; } break; @@ -221,7 +214,7 @@ Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, A } int -Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* track, nframes64_t& pos) +Editor::import_sndfile (vector<ustring> paths, ImportMode mode, nframes64_t& pos) { WindowTitle title = string_compose (_("importing %1"), paths.front()); @@ -261,10 +254,12 @@ Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* trac interthread_progress_connection.disconnect (); /* import thread finished - see if we should build a new track */ + + boost::shared_ptr<AudioTrack> track; if (!import_status.new_regions.empty()) { boost::shared_ptr<AudioRegion> region (import_status.new_regions.front()); - finish_bringing_in_audio (region, region->n_channels(), region->n_channels(), track, pos, mode); + finish_bringing_in_audio (region, region->n_channels(), region->n_channels(), pos, mode, track, 0); } track_canvas.get_window()->set_cursor (*current_canvas_cursor); @@ -272,9 +267,9 @@ Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* trac } int -Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, bool multiple_files, bool& check_sample_rate, ImportMode mode, - AudioTrack* track, nframes64_t& pos) +Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, bool multiple_files, bool& check_sample_rate, ImportMode mode, nframes64_t& pos) { + boost::shared_ptr<AudioTrack> track; boost::shared_ptr<AudioFileSource> source; SourceList sources; boost::shared_ptr<AudioRegion> region; @@ -437,7 +432,7 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, } } - if (chns == Editing::ImportThingPerFile || chns == Editing::ImportThingForAll) { + if (chns == Editing::ImportMergeFiles) { /* take all the sources we have and package them up as a region */ @@ -452,9 +447,9 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, output_chan = input_chan; } - finish_bringing_in_audio (region, input_chan, output_chan, track, pos, mode); + finish_bringing_in_audio (region, input_chan, output_chan, pos, mode, track, 0); - } else { + } else { // SerializeFiles, DistinctFiles, DistinctChannels /* take each source and create a region for each one */ @@ -462,8 +457,9 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, SourceList::iterator x; vector<Glib::ustring>::iterator p = paths.begin(); vector<Glib::ustring>::iterator next_path; - - for (x = sources.begin(); x != sources.end(); ++x) { + int nth; + + for (nth = 0, x = sources.begin(); x != sources.end(); ++x, ++nth) { just_one.clear (); just_one.push_back (*x); @@ -479,7 +475,16 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, output_chan = input_chan; } - finish_bringing_in_audio (region, 1, output_chan, track, pos, mode); + finish_bringing_in_audio (region, 1, output_chan, pos, mode, track, nth); + + if (chns == ImportSerializeFiles) { + pos += region->length(); + } + + if (chns == ImportDistinctChannels || chns == ImportDistinctFiles) { + /* make a new track for the next region */ + track.reset (); + } /* don't run out of paths */ @@ -499,39 +504,56 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, } int -Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, nframes64_t& pos, ImportMode mode) +Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_t in_chans, uint32_t out_chans, nframes64_t& pos, + ImportMode mode, boost::shared_ptr<AudioTrack>& existing_track, int nth) { + boost::shared_ptr<AudioTrack> track; + switch (mode) { case ImportAsRegion: /* relax, its been done */ break; case ImportToTrack: - if (track) { - boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist(); - - boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region))); - begin_reversible_command (_("insert sndfile")); - XMLNode &before = playlist->get_state(); - playlist->add_region (copy, pos); - session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state())); - commit_reversible_command (); + { + if (selection->tracks.empty()) { + return -1; + } - pos += region->length(); + AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front()); + + if (!atv) { + return -1; } - break; + + track = atv->audio_track(); + boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist(); + boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region))); + begin_reversible_command (_("insert sndfile")); + XMLNode &before = playlist->get_state(); + playlist->add_region (copy, pos); + session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state())); + commit_reversible_command (); + break; + } + case ImportAsTrack: { - list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1)); - if (!at.empty()) { - boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region))); - at.front()->set_name (basename_nosuffix (copy->name()), this); - at.front()->diskstream()->playlist()->add_region (copy, pos); + if (!existing_track) { + list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1)); + if (at.empty()) { + return -1; + } + existing_track = at.front(); + existing_track->set_name (basename_nosuffix (region->name()), this); } + boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region))); + existing_track->diskstream()->playlist()->add_region (copy, pos); break; } + case ImportAsTapeTrack: { list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive)); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 0e381921e1..3a6a6d8e0a 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -465,14 +465,15 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, frame = 0; - do_embed (paths, Editing::ImportThingPerFile, ImportAsTrack, 0, frame); + do_embed (paths, Editing::ImportDistinctFiles, ImportAsTrack, frame); } else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) { /* check that its an audio track, not a bus */ if (tv->get_diskstream()) { - do_embed (paths, Editing::ImportThingPerFile, ImportToTrack, tv->audio_track(), frame); + // XXX NEED A WAY TO DROP INTO THIS SPECIFIC TRACK: tv->audio_track() + do_embed (paths, Editing::ImportDistinctFiles, ImportToTrack, frame); } } diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index 87c006c339..55e668eb00 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -621,7 +621,7 @@ Editor::region_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) { nframes64_t pos = 0; - do_embed (paths, Editing::ImportThingPerFile, ImportAsRegion, 0, pos); + do_embed (paths, Editing::ImportDistinctFiles, ImportAsRegion, pos); context->drag_finish (true, false, time); } } diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index b6d24c0871..cd382c41e6 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -185,7 +185,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt rec_enable_button->set_name ("MixerRecordEnableButton"); - AudioTrack* at = audio_track(); + boost::shared_ptr<AudioTrack> at = audio_track(); at->FreezeChange.connect (mem_fun(*this, &MixerStrip::map_frozen)); @@ -1130,7 +1130,7 @@ MixerStrip::map_frozen () { ENSURE_GUI_THREAD (mem_fun(*this, &MixerStrip::map_frozen)); - AudioTrack* at = audio_track(); + boost::shared_ptr<AudioTrack> at = audio_track(); if (at) { switch (at->freeze_state()) { diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index de888ff9ab..b40ace3766 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -509,7 +509,7 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn) continue; } - AudioTrack* at = strip->audio_track(); + boost::shared_ptr<AudioTrack> at = strip->audio_track(); switch (tracks) { case 0: diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc index 40f837eb5e..39abfe3dc1 100644 --- a/gtk2_ardour/playlist_selector.cc +++ b/gtk2_ardour/playlist_selector.cc @@ -245,7 +245,7 @@ PlaylistSelector::selection_changed () if ((playlist = ((*iter)[columns.playlist])) != 0) { - AudioTrack* at; + boost::shared_ptr<AudioTrack> at; boost::shared_ptr<AudioPlaylist> apl; if ((at = rui->audio_track()) == 0) { diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 237a39bba3..e198397307 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -503,7 +503,7 @@ RouteTimeAxisView::set_track_mode (TrackMode mode) } void -RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem* reset_item) +RouteTimeAxisView::_set_track_mode (boost::shared_ptr<Track> track, TrackMode mode, RadioMenuItem* reset_item) { bool needs_bounce; diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index ae425cf9b3..a2ccc5d7c8 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -234,7 +234,7 @@ protected: ArdourCanvas::SimpleRect* timestretch_rect; void set_track_mode (ARDOUR::TrackMode); - void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item); + void _set_track_mode (boost::shared_ptr<ARDOUR::Track> track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item); void track_mode_changed (); list<RedirectAutomationInfo*> redirect_automation; diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 240072eeb1..6eb5499f23 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -968,25 +968,25 @@ RouteUI::disconnect_output () bool RouteUI::is_track () const { - return dynamic_cast<Track*>(_route.get()) != 0; + return boost::dynamic_pointer_cast<Track>(_route) != 0; } -Track* +boost::shared_ptr<Track> RouteUI::track() const { - return dynamic_cast<Track*>(_route.get()); + return boost::dynamic_pointer_cast<Track>(_route); } bool RouteUI::is_audio_track () const { - return dynamic_cast<AudioTrack*>(_route.get()) != 0; + return boost::dynamic_pointer_cast<AudioTrack>(_route) != 0; } -AudioTrack* +boost::shared_ptr<AudioTrack> RouteUI::audio_track() const { - return dynamic_cast<AudioTrack*>(_route.get()); + return boost::dynamic_pointer_cast<AudioTrack>(_route); } boost::shared_ptr<Diskstream> diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index 1c442afcae..1a6a6ecc73 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -50,12 +50,9 @@ class RouteUI : public virtual AxisView bool is_track() const; bool is_audio_track() const; - boost::shared_ptr<ARDOUR::Route> route() const { return _route; } - - // FIXME: make these return shared_ptr - ARDOUR::Track* track() const; - ARDOUR::AudioTrack* audio_track() const; - + boost::shared_ptr<ARDOUR::Route> route() const { return _route; } + boost::shared_ptr<ARDOUR::Track> track() const; + boost::shared_ptr<ARDOUR::AudioTrack> audio_track() const; boost::shared_ptr<ARDOUR::Diskstream> get_diskstream() const; string name() const; diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 819d13aa5b..0abb810bc2 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -295,7 +295,6 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S found_list_view (found_list), import (rgroup2, _("Copy to Ardour-native files")), embed (rgroup2, _("Use file without copying")), - mode (ImportAsTrack), found_search_btn (_("Search")), selected_track_cnt (selected_tracks) { @@ -303,8 +302,9 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S VBox* vbox; HBox* hbox; HBox* hpacker; - + set_session (s); + resetting_ourselves = false; vpacker = manage (new VBox); vpacker->pack_start (preview, true, true); @@ -320,6 +320,25 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S options.set_spacing (12); + vector<string> action_strings; + vector<string> where_strings; + + action_strings.push_back (_("as new tracks")); + if (selected_track_cnt > 0) { + action_strings.push_back (_("to selected tracks")); + } + action_strings.push_back (_("to the region list")); + action_strings.push_back (_("as new tape tracks")); + set_popdown_strings (action_combo, action_strings); + action_combo.set_active_text (action_strings.front()); + + where_strings.push_back (_("use file timestamp")); + where_strings.push_back (_("at edit cursor")); + where_strings.push_back (_("at playhead")); + where_strings.push_back (_("at session start")); + set_popdown_strings (where_combo, where_strings); + where_combo.set_active_text (where_strings.front()); + Label* l = manage (new Label); l->set_text (_("Add files:")); @@ -358,6 +377,8 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S options.pack_start (*vbox, false, false); reset_options (); + + action_combo.signal_changed().connect (mem_fun (*this, &SoundFileBrowser::reset_options_noret)); block_four.pack_start (import, false, false); block_four.pack_start (embed, false, false); @@ -394,6 +415,7 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S chooser.add_filter (matchall_filter); chooser.set_select_multiple (true); chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview)); + chooser.signal_selection_changed().connect (mem_fun (*this, &SoundFileBrowser::file_selection_changed)); chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated)); if (!persistent_folder.empty()) { @@ -405,10 +427,19 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked)); found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked)); - add_button (Stock::OK, RESPONSE_OK); add_button (Stock::CANCEL, RESPONSE_CANCEL); + add_button (Stock::OK, RESPONSE_OK); + + /* setup disposition map */ - set_response_sensitive (RESPONSE_OK, false); + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one track per file"), ImportDistinctFiles)); + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one track per channel"), ImportDistinctChannels)); + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("merge files"), ImportMergeFiles)); + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("sequence files"), ImportSerializeFiles)); + + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one region per file"), ImportDistinctFiles)); + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one region per channel"), ImportDistinctChannels)); + disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("all files in one region"), ImportMergeFiles)); } SoundFileBrowser::~SoundFileBrowser () @@ -417,6 +448,24 @@ SoundFileBrowser::~SoundFileBrowser () } void +SoundFileBrowser::file_selection_changed () +{ + if (resetting_ourselves) { + return; + } + + if (!reset_options ()) { + set_response_sensitive (RESPONSE_OK, false); + } else { + if (chooser.get_filenames().size() > 0) { + set_response_sensitive (RESPONSE_OK, true); + } else { + set_response_sensitive (RESPONSE_OK, false); + } + } +} + +void SoundFileBrowser::chooser_file_activated () { preview.audition (); @@ -438,32 +487,36 @@ SoundFileBrowser::set_session (Session* s) bool SoundFileBrowser::on_custom (const FileFilter::Info& filter_info) { - return AudioFileSource::safe_file_extension(filter_info.filename); + return AudioFileSource::safe_file_extension (filter_info.filename); } void SoundFileBrowser::update_preview () { preview.setup_labels (chooser.get_filename()); - set_response_sensitive (RESPONSE_OK, true); - reset_options (); } void SoundFileBrowser::found_list_view_selected () { - Glib::ustring file; - - TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows (); - - if (!rows.empty()) { - TreeIter iter = found_list->get_iter(*rows.begin()); - file = (*iter)[found_list_columns.pathname]; - chooser.set_filename (file); + if (!reset_options ()) { + set_response_sensitive (RESPONSE_OK, false); + } else { + Glib::ustring file; + + TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows (); + + if (!rows.empty()) { + TreeIter iter = found_list->get_iter(*rows.begin()); + file = (*iter)[found_list_columns.pathname]; + chooser.set_filename (file); + set_response_sensitive (RESPONSE_OK, true); + } else { + set_response_sensitive (RESPONSE_OK, false); + } + + preview.setup_labels (file); } - preview.setup_labels (file); - set_response_sensitive (RESPONSE_OK, true); - reset_options (); } void @@ -524,95 +577,155 @@ SoundFileBrowser::get_paths () } void +SoundFileBrowser::reset_options_noret () +{ + (void) reset_options (); +} + +bool SoundFileBrowser::reset_options () { vector<Glib::ustring> paths = get_paths (); - bool selection_includes_multichannel = check_multichannel_status (paths); - bool selection_can_be_embedded_with_links = check_link_status (*session, paths); - vector<string> action_strings; - vector<string> where_strings; - vector<string> channel_strings; + if (paths.empty()) { - action_strings.push_back (_("as new tracks")); - if (selected_track_cnt > 0) { - action_strings.push_back (_("to selected tracks")); - } - action_strings.push_back (_("to the region list")); - action_strings.push_back (_("as new tape tracks")); + channel_combo.set_sensitive (false); + action_combo.set_sensitive (false); + where_combo.set_sensitive (false); + import.set_sensitive (false); + embed.set_sensitive (false); + return false; - set_popdown_strings (action_combo, action_strings); - action_combo.set_active_text (action_strings.front()); + } else { - where_strings.push_back (_("use file timestamp")); - where_strings.push_back (_("at edit cursor")); - where_strings.push_back (_("at playhead")); - where_strings.push_back (_("at session start")); - - set_popdown_strings (where_combo, where_strings); - where_combo.set_active_text (where_strings.front()); + channel_combo.set_sensitive (true); + action_combo.set_sensitive (true); + where_combo.set_sensitive (true); + import.set_sensitive (true); + embed.set_sensitive (true); + + } - if (mode == ImportAsTrack) { - channel_strings.push_back (_("one file per track")); + bool same_size; + bool err; + bool selection_includes_multichannel = check_multichannel_status (paths, same_size, err); + bool selection_can_be_embedded_with_links = check_link_status (*session, paths); + ImportMode mode; + + if (err) { + Glib::signal_idle().connect (mem_fun (*this, &SoundFileBrowser::bad_file_message)); + return false; + } + + if ((mode = get_mode()) == ImportAsRegion) { + where_combo.set_sensitive (false); + } else { + where_combo.set_sensitive (true); + } + + vector<string> channel_strings; + + if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) { + channel_strings.push_back (_("one track per file")); if (selection_includes_multichannel) { - channel_strings.push_back (_("one channel per track")); + channel_strings.push_back (_("one track per channel")); } + if (paths.size() > 1) { - channel_strings.push_back (_("all files in one track")); + /* tape tracks are a single region per track, so we cannot + sequence multiple files. + */ + if (mode != ImportAsTapeTrack) { + channel_strings.push_back (_("sequence files")); + } + if (same_size) { + channel_strings.push_back (_("all files in one track")); + } + } - channel_combo.show(); + } else { - channel_combo.hide(); + channel_strings.push_back (_("one region per file")); + + if (selection_includes_multichannel) { + channel_strings.push_back (_("one region per channel")); + } + + if (paths.size() > 1) { + if (same_size) { + channel_strings.push_back (_("all files in one region")); + } + } } set_popdown_strings (channel_combo, channel_strings); channel_combo.set_active_text (channel_strings.front()); - + if (Profile->get_sae()) { if (selection_can_be_embedded_with_links) { - block_four.show (); + embed.set_sensitive (true); } else { - block_four.hide (); + embed.set_sensitive (false); } } else { - block_four.show (); - } - - if ((mode == ImportAsTrack || mode == ImportAsTapeTrack) && paths.size() == 2) { - merge_stereo.set_sensitive (true); - } else { - merge_stereo.set_sensitive (false); + embed.set_sensitive (true); } - if (selection_includes_multichannel) { - split_files.set_sensitive (true); - } else { - split_files.set_sensitive (false); - } + return true; } bool -SoundFileBrowser::check_multichannel_status (const vector<Glib::ustring>& paths) +SoundFileBrowser::bad_file_message() +{ + MessageDialog msg (*this, + _("One or more of the selected files\ncannot be used by Ardour"), + true, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK); + msg.run (); + resetting_ourselves = true; + chooser.unselect_uri (chooser.get_preview_uri()); + resetting_ourselves = false; +} + +bool +SoundFileBrowser::check_multichannel_status (const vector<Glib::ustring>& paths, bool& same_size, bool& err) { SNDFILE* sf; SF_INFO info; - + nframes64_t sz = 0; + bool some_mult = false; + + same_size = true; + err = false; + for (vector<Glib::ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) { info.format = 0; // libsndfile says to clear this before sf_open(). if ((sf = sf_open ((char*) (*i).c_str(), SFM_READ, &info)) != 0) { sf_close (sf); + if (info.channels > 1) { - return true; + some_mult = true; } + + if (sz == 0) { + sz = info.frames; + } else { + if (sz != info.frames) { + same_size = false; + } + } + } else { + err = true; } } - return false; + return some_mult; } bool @@ -720,13 +833,18 @@ SoundFileBrowser::get_position() const ImportChannel SoundFileBrowser::get_channel_disposition () const { + /* we use a map here because the channel combo can contain different strings + depending on the state of the other combos. the map contains all possible strings + and the ImportDisposition enum that corresponds to it. + */ + Glib::ustring str = channel_combo.get_active_text(); + DispositionMap::const_iterator x = disposition_map.find (str); - if (str == _("one file per track")) { - return ImportThingPerFile; - } else if (str == _("one channel per track")) { - return ImportThingPerChannel; - } else { - return ImportThingForAll; + if (x == disposition_map.end()) { + fatal << string_compose (_("programming error: %1"), "unknown string for import disposition") << endmsg; + /*NOTREACHED*/ } + + return x->second; } diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h index de1e9d617b..89e756ce73 100644 --- a/gtk2_ardour/sfdb_ui.h +++ b/gtk2_ardour/sfdb_ui.h @@ -22,6 +22,7 @@ #include <string> #include <vector> +#include <map> #include <glibmm/ustring.h> #include <sigc++/signal.h> @@ -117,9 +118,6 @@ class SoundFileBrowser : public ArdourDialog Gtk::FileChooserWidget chooser; Gtk::TreeView found_list_view; - Gtk::CheckButton split_files; - Gtk::CheckButton merge_stereo; - Gtk::ComboBoxText action_combo; Gtk::ComboBoxText where_combo; Gtk::ComboBoxText channel_combo; @@ -132,7 +130,6 @@ class SoundFileBrowser : public ArdourDialog Editing::ImportChannel get_channel_disposition() const; protected: - Editing::ImportMode mode; Gtk::FileFilter custom_filter; Gtk::FileFilter matchall_filter; SoundFileBox preview; @@ -151,18 +148,26 @@ class SoundFileBrowser : public ArdourDialog void chooser_file_activated (); bool on_custom (const Gtk::FileFilter::Info& filter_info); + void file_selection_changed (); int selected_track_cnt; + typedef std::map<Glib::ustring,Editing::ImportChannel> DispositionMap; + DispositionMap disposition_map; + + bool resetting_ourselves; + Gtk::HBox options; Gtk::VBox block_two; Gtk::VBox block_three; Gtk::VBox block_four; - static bool check_multichannel_status (const std::vector<Glib::ustring>& paths); + static bool check_multichannel_status (const std::vector<Glib::ustring>& paths, bool& same_size, bool& err); static bool check_link_status (const ARDOUR::Session&, const std::vector<Glib::ustring>& paths); - void reset_options (); + bool reset_options (); + void reset_options_noret (); + bool bad_file_message (); }; class SoundFileChooser : public SoundFileBrowser diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index 55311135fb..24dc8750f9 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -247,9 +247,9 @@ StreamView::playlist_changed (boost::weak_ptr<Diskstream> wptr) void StreamView::diskstream_changed () { - Track *t; + boost::shared_ptr<Track> t = _trackview.track(); - if ((t = _trackview.track()) != 0) { + if (t) { Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), boost::weak_ptr<Diskstream> (t->diskstream()))); } else { Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::undisplay_diskstream)); diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 8c3cb38ebe..d3e2ac5159 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -138,7 +138,8 @@ CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false) CONFIG_VARIABLE (bool, use_vst, "use-vst", true) CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100) -CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 100) +CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 20) +CONFIG_VARIABLE (uint32_t, history_depth, "history-depth", 20) CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false) CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true) CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 19db991d04..6e8650fc61 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1717,6 +1717,7 @@ class Session : public PBD::StatefulDestructible XMLNode& get_control_protocol_state (); + void set_history_depth (uint32_t depth); }; } // namespace ARDOUR diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index e39ebf72f2..c21bae5cc9 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -117,6 +117,9 @@ Session::first_stage_init (string fullpath, string snapshot_name) _path += '/'; } + set_history_depth (Config->get_history_depth()); + + /* these two are just provisional settings. set_state() will likely override them. */ @@ -2979,7 +2982,6 @@ Session::add_instant_xml (XMLNode& node, const std::string& dir) Config->add_instant_xml (node, get_user_ardour_path()); } - int Session::save_history (string snapshot_name) { @@ -3284,8 +3286,10 @@ Session::config_changed (const char* parameter_name) set_slave_source (Config->get_slave_source()); } else if (PARAM_IS ("remote-model")) { set_remote_control_ids (); - } else if (PARAM_IS ("denormal-model")) { + } else if (PARAM_IS ("denormal-model")) { setup_fpu (); + } else if (PARAM_IS ("history-depth")) { + set_history_depth (Config->get_history_depth()); } set_dirty (); @@ -3293,3 +3297,9 @@ Session::config_changed (const char* parameter_name) #undef PARAM_IS } + +void +Session::set_history_depth (uint32_t d) +{ + _history.set_depth (d); +} diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h index 9539d8b41d..3f4a1c5e9d 100644 --- a/libs/pbd/pbd/undo.h +++ b/libs/pbd/pbd/undo.h @@ -86,8 +86,8 @@ class UndoHistory : public sigc::trackable unsigned long undo_depth() const { return UndoList.size(); } unsigned long redo_depth() const { return RedoList.size(); } - std::string next_undo() const { return (UndoList.empty() ? std::string("") : UndoList.back()->name()); } - std::string next_redo() const { return (RedoList.empty() ? std::string("") : RedoList.back()->name()); } + std::string next_undo() const { return (UndoList.empty() ? std::string() : UndoList.back()->name()); } + std::string next_redo() const { return (RedoList.empty() ? std::string() : RedoList.back()->name()); } void clear (); void clear_undo (); @@ -96,10 +96,14 @@ class UndoHistory : public sigc::trackable XMLNode &get_state(uint32_t depth = 0); void save_state(); - sigc::signal<void> Changed; + void set_depth (uint32_t); + uint32_t get_depth() const { return _depth; } + sigc::signal<void> Changed; + private: bool _clearing; + uint32_t _depth; std::list<UndoTransaction*> UndoList; std::list<UndoTransaction*> RedoList; diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc index 4719d0968e..d54c6b0fff 100644 --- a/libs/pbd/undo.cc +++ b/libs/pbd/undo.cc @@ -148,12 +148,28 @@ XMLNode &UndoTransaction::get_state() UndoHistory::UndoHistory () { _clearing = false; + _depth = 0; +} + +void +UndoHistory::set_depth (uint32_t d) +{ + _depth = d; + + while (_depth > 0 && UndoList.size() > _depth) { + UndoList.pop_front (); + } } void UndoHistory::add (UndoTransaction* const ut) { ut->GoingAway.connect (bind (mem_fun (*this, &UndoHistory::remove), ut)); + + while (_depth > 0 && UndoList.size() > _depth) { + UndoList.pop_front (); + } + UndoList.push_back (ut); /* we are now owners of the transaction */ |