mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-21 06:06:25 +01:00
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
This commit is contained in:
parent
6c2728f981
commit
f2a2e9c002
21 changed files with 355 additions and 180 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
case Editing::ImportDistinctChannels:
|
||||
import_status.multichan = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
import_status.multichan = true;
|
||||
break;
|
||||
|
||||
case Editing::ImportThingPerChannel:
|
||||
import_status.multichan = false;
|
||||
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());
|
||||
|
||||
|
|
@ -262,9 +255,11 @@ Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* trac
|
|||
|
||||
/* 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;
|
||||
int nth;
|
||||
|
||||
for (x = sources.begin(); x != sources.end(); ++x) {
|
||||
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();
|
||||
{
|
||||
if (selection->tracks.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front());
|
||||
|
||||
if (!atv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 ();
|
||||
|
||||
pos += region->length();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ImportAsTrack:
|
||||
{
|
||||
if (!existing_track) {
|
||||
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 (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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -51,11 +51,8 @@ class RouteUI : public virtual AxisView
|
|||
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::Track> track() const;
|
||||
boost::shared_ptr<ARDOUR::AudioTrack> audio_track() const;
|
||||
boost::shared_ptr<ARDOUR::Diskstream> get_diskstream() const;
|
||||
|
||||
string name() const;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -305,6 +304,7 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
|
|||
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:"));
|
||||
|
||||
|
|
@ -359,6 +378,8 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
|
|||
|
||||
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);
|
||||
|
||||
set_response_sensitive (RESPONSE_OK, false);
|
||||
/* setup disposition map */
|
||||
|
||||
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 ()
|
||||
|
|
@ -416,6 +447,24 @@ SoundFileBrowser::~SoundFileBrowser ()
|
|||
persistent_folder = chooser.get_current_folder();
|
||||
}
|
||||
|
||||
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 ()
|
||||
{
|
||||
|
|
@ -445,13 +494,14 @@ void
|
|||
SoundFileBrowser::update_preview ()
|
||||
{
|
||||
preview.setup_labels (chooser.get_filename());
|
||||
set_response_sensitive (RESPONSE_OK, true);
|
||||
reset_options ();
|
||||
}
|
||||
|
||||
void
|
||||
SoundFileBrowser::found_list_view_selected ()
|
||||
{
|
||||
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 ();
|
||||
|
|
@ -460,10 +510,13 @@ SoundFileBrowser::found_list_view_selected ()
|
|||
TreeIter iter = found_list->get_iter(*rows.begin());
|
||||
file = (*iter)[found_list_columns.pathname];
|
||||
chooser.set_filename (file);
|
||||
}
|
||||
preview.setup_labels (file);
|
||||
set_response_sensitive (RESPONSE_OK, true);
|
||||
reset_options ();
|
||||
} else {
|
||||
set_response_sensitive (RESPONSE_OK, false);
|
||||
}
|
||||
|
||||
preview.setup_labels (file);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -524,47 +577,87 @@ 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;
|
||||
if (paths.empty()) {
|
||||
|
||||
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;
|
||||
|
||||
} else {
|
||||
|
||||
channel_combo.set_sensitive (true);
|
||||
action_combo.set_sensitive (true);
|
||||
where_combo.set_sensitive (true);
|
||||
import.set_sensitive (true);
|
||||
embed.set_sensitive (true);
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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());
|
||||
|
||||
if (mode == ImportAsTrack) {
|
||||
channel_strings.push_back (_("one file per track"));
|
||||
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) {
|
||||
/* 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);
|
||||
|
|
@ -572,33 +665,42 @@ SoundFileBrowser::reset_options ()
|
|||
|
||||
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 ();
|
||||
embed.set_sensitive (true);
|
||||
}
|
||||
|
||||
if ((mode == ImportAsTrack || mode == ImportAsTapeTrack) && paths.size() == 2) {
|
||||
merge_stereo.set_sensitive (true);
|
||||
} else {
|
||||
merge_stereo.set_sensitive (false);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
|
@ -606,13 +708,24 @@ SoundFileBrowser::check_multichannel_status (const vector<Glib::ustring>& paths)
|
|||
|
||||
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
|
||||
{
|
||||
Glib::ustring str = channel_combo.get_active_text();
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
if (str == _("one file per track")) {
|
||||
return ImportThingPerFile;
|
||||
} else if (str == _("one channel per track")) {
|
||||
return ImportThingPerChannel;
|
||||
} else {
|
||||
return ImportThingForAll;
|
||||
Glib::ustring str = channel_combo.get_active_text();
|
||||
DispositionMap::const_iterator x = disposition_map.find (str);
|
||||
|
||||
if (x == disposition_map.end()) {
|
||||
fatal << string_compose (_("programming error: %1"), "unknown string for import disposition") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
return x->second;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1717,6 +1717,7 @@ class Session : public PBD::StatefulDestructible
|
|||
|
||||
XMLNode& get_control_protocol_state ();
|
||||
|
||||
void set_history_depth (uint32_t depth);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -3286,6 +3288,8 @@ Session::config_changed (const char* parameter_name)
|
|||
set_remote_control_ids ();
|
||||
} 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue