summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/audio_region_view.cc4
-rw-r--r--gtk2_ardour/automation_line.cc14
-rw-r--r--gtk2_ardour/automation_region_view.cc6
-rw-r--r--gtk2_ardour/automation_time_axis.cc9
-rw-r--r--gtk2_ardour/crossfade_edit.cc4
-rw-r--r--gtk2_ardour/editor.cc62
-rw-r--r--gtk2_ardour/editor.h9
-rw-r--r--gtk2_ardour/editor_drag.cc36
-rw-r--r--gtk2_ardour/editor_locations.cc2
-rw-r--r--gtk2_ardour/editor_markers.cc10
-rw-r--r--gtk2_ardour/editor_mouse.cc5
-rw-r--r--gtk2_ardour/editor_ops.cc149
-rw-r--r--gtk2_ardour/location_ui.cc13
-rw-r--r--gtk2_ardour/midi_region_view.cc4
-rw-r--r--gtk2_ardour/public_editor.h8
-rw-r--r--gtk2_ardour/region_editor.cc21
-rw-r--r--gtk2_ardour/region_gain_line.cc4
-rw-r--r--gtk2_ardour/region_selection.cc1
-rw-r--r--gtk2_ardour/region_selection.h1
-rw-r--r--gtk2_ardour/rhythm_ferret.cc4
-rw-r--r--gtk2_ardour/selection.cc52
-rw-r--r--gtk2_ardour/selection_memento.cc95
-rw-r--r--gtk2_ardour/selection_memento.h34
-rw-r--r--gtk2_ardour/wscript1
24 files changed, 414 insertions, 134 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 2adb9e9500..d5882514c7 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -1237,7 +1237,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
can represent automation data with it.
*/
- trackview.session()->begin_reversible_command (_("add gain control point"));
+ trackview.editor().begin_reversible_command (_("add gain control point"));
XMLNode &before = audio_region()->envelope()->get_state();
if (!audio_region()->envelope_active()) {
@@ -1251,7 +1251,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
XMLNode &after = audio_region()->envelope()->get_state();
trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
- trackview.session()->commit_reversible_command ();
+ trackview.editor().commit_reversible_command ();
}
void
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc
index 62c9118ef4..c0ed14f7f9 100644
--- a/gtk2_ardour/automation_line.cc
+++ b/gtk2_ardour/automation_line.cc
@@ -283,7 +283,7 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
double const x = trackview.editor().sample_to_pixel_unrounded (_time_converter->to((*cp.model())->when) - _offset);
- trackview.editor().session()->begin_reversible_command (_("automation event move"));
+ trackview.editor().begin_reversible_command (_("automation event move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder(), &get_state(), 0));
@@ -304,7 +304,7 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder(), 0, &alist->get_state()));
- trackview.editor().session()->commit_reversible_command ();
+ trackview.editor().commit_reversible_command ();
trackview.editor().session()->set_dirty ();
}
@@ -456,7 +456,7 @@ AutomationLine::string_to_fraction (string const & s) const
void
AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction)
{
- trackview.editor().session()->begin_reversible_command (_("automation event move"));
+ trackview.editor().begin_reversible_command (_("automation event move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder(), &get_state(), 0));
@@ -482,7 +482,7 @@ AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction)
void
AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
{
- trackview.editor().session()->begin_reversible_command (_("automation range move"));
+ trackview.editor().begin_reversible_command (_("automation range move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder (), &get_state(), 0));
@@ -502,7 +502,7 @@ AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
void
AutomationLine::start_drag_multiple (list<ControlPoint*> cp, float fraction, XMLNode* state)
{
- trackview.editor().session()->begin_reversible_command (_("automation range move"));
+ trackview.editor().begin_reversible_command (_("automation range move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder(), state, 0));
@@ -857,7 +857,7 @@ AutomationLine::is_first_point (ControlPoint& cp)
void
AutomationLine::remove_point (ControlPoint& cp)
{
- trackview.editor().session()->begin_reversible_command (_("remove control point"));
+ trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
alist->erase (cp.model());
@@ -865,7 +865,7 @@ AutomationLine::remove_point (ControlPoint& cp)
trackview.editor().session()->add_command(
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
- trackview.editor().session()->commit_reversible_command ();
+ trackview.editor().commit_reversible_command ();
trackview.editor().session()->set_dirty ();
}
diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc
index ac9083e6ed..c5afcadfe0 100644
--- a/gtk2_ardour/automation_region_view.cc
+++ b/gtk2_ardour/automation_region_view.cc
@@ -182,15 +182,15 @@ AutomationRegionView::add_automation_event (GdkEvent *, framepos_t when, double
double when_d = when;
_line->view_to_model_coord (when_d, y);
- view->session()->begin_reversible_command (_("add automation event"));
+ view->editor().begin_reversible_command (_("add automation event"));
XMLNode& before = _line->the_list()->get_state();
_line->the_list()->add (when_d, y, with_guard_points, false);
XMLNode& after = _line->the_list()->get_state();
- view->session()->commit_reversible_command (
- new MementoCommand<ARDOUR::AutomationList> (_line->memento_command_binder(), &before, &after));
+ view->session()->add_command (new MementoCommand<ARDOUR::AutomationList> (_line->memento_command_binder(), &before, &after));
+ view->editor().commit_reversible_command ();
view->session()->set_dirty ();
}
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc
index 3452da3847..ff50c7bece 100644
--- a/gtk2_ardour/automation_time_axis.cc
+++ b/gtk2_ardour/automation_time_axis.cc
@@ -434,7 +434,7 @@ AutomationTimeAxisView::clear_clicked ()
{
assert (_line || _view);
- _session->begin_reversible_command (_("clear automation"));
+ _editor.begin_reversible_command (_("clear automation"));
if (_line) {
_line->clear ();
@@ -442,7 +442,7 @@ AutomationTimeAxisView::clear_clicked ()
_view->clear ();
}
- _session->commit_reversible_command ();
+ _editor.commit_reversible_command ();
_session->set_dirty ();
}
@@ -627,13 +627,14 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when,
_editor.snap_to_with_modifier (when, event);
- _session->begin_reversible_command (_("add automation event"));
+ _editor.begin_reversible_command (_("add automation event"));
XMLNode& before = list->get_state();
list->add (when, y, with_guard_points);
XMLNode& after = list->get_state();
- _session->commit_reversible_command (new MementoCommand<ARDOUR::AutomationList> (*list, &before, &after));
+ _session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list, &before, &after));
+ _editor.commit_reversible_command ();
_session->set_dirty ();
}
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index 9654a9afd9..976ca8ff9e 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -780,7 +780,7 @@ CrossfadeEditor::apply_preset (Preset *preset)
void
CrossfadeEditor::apply ()
{
- _session->begin_reversible_command (_("Edit crossfade"));
+ the_editor().begin_reversible_command (_("Edit crossfade"));
XMLNode& before = xfade->get_state ();
@@ -793,7 +793,7 @@ CrossfadeEditor::apply ()
)
);
- _session->commit_reversible_command ();
+ the_editor().commit_reversible_command ();
}
void
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index f7e641fbb2..e3c03db510 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -305,6 +305,8 @@ Editor::Editor ()
selection = new Selection (this);
cut_buffer = new Selection (this);
+ _selection_memento = new SelectionMemento ();
+ before.clear();
clicked_regionview = 0;
clicked_axisview = 0;
@@ -1392,6 +1394,7 @@ Editor::set_session (Session *t)
/* register for undo history */
_session->register_with_memento_command_factory(id(), this);
+ _session->register_with_memento_command_factory(_selection_memento->id(), _selection_memento);
ActionManager::ui_manager->signal_pre_activate().connect (sigc::mem_fun (*this, &Editor::action_pre_activated));
@@ -3317,6 +3320,7 @@ void
Editor::begin_reversible_command (string name)
{
if (_session) {
+ before.push_back (&_selection_memento->get_state ());
_session->begin_reversible_command (name);
}
}
@@ -3325,6 +3329,7 @@ void
Editor::begin_reversible_command (GQuark q)
{
if (_session) {
+ before.push_back (&_selection_memento->get_state ());
_session->begin_reversible_command (q);
}
}
@@ -3333,6 +3338,14 @@ void
Editor::commit_reversible_command ()
{
if (_session) {
+ if (before.size() == 1) {
+ _session->add_command (new MementoCommand<SelectionMemento>(*(_selection_memento), before.front(), &_selection_memento->get_state ()));
+ }
+
+ if (!before.empty()) {
+ before.pop_back();
+ }
+
_session->commit_reversible_command ();
}
}
@@ -4182,7 +4195,7 @@ Editor::copy_playlists (TimeAxisView* v)
void
Editor::clear_playlists (TimeAxisView* v)
{
- begin_reversible_command (_("clear playlists"));
+ begin_reversible_command (_("clear playlists"));
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
_session->playlists->get (playlists);
mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::select.property_id);
@@ -4220,6 +4233,12 @@ Editor::on_key_release_event (GdkEventKey* ev)
// return key_press_focus_accelerator_handler (*this, ev);
}
+double
+Editor::get_y_origin () const
+{
+ return vertical_adjustment.get_value ();
+}
+
/** Queue up a change to the viewport x origin.
* @param frame New x origin.
*/
@@ -4629,8 +4648,7 @@ Editor::set_punch_range (framepos_t start, framepos_t end, string cmd)
_session->set_auto_punch_location (loc);
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- }
- else {
+ } else {
XMLNode &before = tpl->get_state();
tpl->set_hidden (false, this);
tpl->set (start, end);
@@ -4808,6 +4826,35 @@ Editor::get_regions_from_selection_and_entered ()
}
void
+Editor::get_regionviews_by_id (PBD::ID const & id, RegionSelection & regions) const
+{
+ for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ RouteTimeAxisView* tatv;
+
+ if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
+ boost::shared_ptr<Playlist> pl;
+ std::vector<boost::shared_ptr<Region> > results;
+ boost::shared_ptr<Track> tr;
+
+ if ((tr = tatv->track()) == 0) {
+ /* bus */
+ continue;
+ }
+
+ if ((pl = (tr->playlist())) != 0) {
+ boost::shared_ptr<Region> r = pl->region_by_id (id);
+ if (r) {
+ RegionView* marv = tatv->view()->find_view (r);
+ if (marv) {
+ regions.push_back (marv);
+ }
+ }
+ }
+ }
+ }
+}
+
+void
Editor::get_regions_corresponding_to (boost::shared_ptr<Region> region, vector<RegionView*>& regions, bool src_comparison)
{
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
@@ -4966,8 +5013,15 @@ Editor::located ()
}
void
-Editor::region_view_added (RegionView *)
+Editor::region_view_added (RegionView * rv)
{
+ for (list<PBD::ID>::iterator pr = selection->regions.pending.begin (); pr != selection->regions.pending.end (); ++pr) {
+ if (rv->region ()->id () == (*pr)) {
+ selection->add (rv);
+ selection->regions.pending.erase (pr);
+ break;
+ }
+ }
_summary->set_background_dirty ();
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index ab781d3cd4..fa86833dc6 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -58,6 +58,7 @@
#include "enums.h"
#include "editor_items.h"
#include "region_selection.h"
+#include "selection_memento.h"
namespace Gtkmm2ext {
class TearOff;
@@ -149,7 +150,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
double visible_canvas_height () const {
return _visible_canvas_height;
}
- double trackviews_height() const;
+ double trackviews_height () const;
void cycle_snap_mode ();
void next_snap_choice ();
@@ -372,6 +373,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void update_tearoff_visibility();
void reattach_all_tearoffs ();
+ double get_y_origin () const;
void reset_x_origin (framepos_t);
void reset_x_origin_to_follow_playhead ();
void reset_y_origin (double);
@@ -405,6 +407,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void get_regions_corresponding_to (boost::shared_ptr<ARDOUR::Region> region, std::vector<RegionView*>& regions, bool src_comparison);
+ void get_regionviews_by_id (PBD::ID const & id, RegionSelection & regions) const;
+
void center_screen (framepos_t);
TrackViewList axis_views_from_routes (boost::shared_ptr<ARDOUR::RouteList>) const;
@@ -1716,6 +1720,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Selection* selection;
Selection* cut_buffer;
+ SelectionMemento* _selection_memento;
void time_selection_changed ();
void update_time_selection_display ();
@@ -1875,7 +1880,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void write_selection ();
- XMLNode *before; /* used in *_reversible_command */
+ std::list<XMLNode *> before; /* used in *_reversible_command */
void update_title ();
void update_title_s (const std::string & snapshot_name);
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index 370a6936b1..73a6e4dad6 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -840,6 +840,12 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
{
if (_copy && first_move) {
+ if (_x_constrained) {
+ _editor->begin_reversible_command (Operations::fixed_time_region_copy);
+ } else {
+ _editor->begin_reversible_command (Operations::region_copy);
+ }
+
/* duplicate the regionview(s) and region(s) */
list<DraggingView> new_regionviews;
@@ -890,6 +896,14 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
swap_grab (new_regionviews.front().view->get_canvas_group (), 0, event ? event->motion.time : 0);
}
+
+ } else if (!_copy && first_move) {
+
+ if (_x_constrained) {
+ _editor->begin_reversible_command (_("fixed time region drag"));
+ } else {
+ _editor->begin_reversible_command (Operations::region_drag);
+ }
}
RegionMotionDrag::motion (event, first_move);
@@ -1020,12 +1034,6 @@ RegionMoveDrag::finished_copy (bool const changed_position, bool const /*changed
return;
}
- if (_x_constrained) {
- _editor->begin_reversible_command (Operations::fixed_time_region_copy);
- } else {
- _editor->begin_reversible_command (Operations::region_copy);
- }
-
/* insert the regions into their new playlists */
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end();) {
@@ -1102,12 +1110,6 @@ RegionMoveDrag::finished_no_copy (
return;
}
- if (_x_constrained) {
- _editor->begin_reversible_command (_("fixed time region drag"));
- } else {
- _editor->begin_reversible_command (Operations::region_drag);
- }
-
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ) {
RegionView* rv = i->view;
@@ -3632,7 +3634,7 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred)
}
_point->line().end_drag (_pushing, _final_index);
- _editor->session()->commit_reversible_command ();
+ _editor->commit_reversible_command ();
}
void
@@ -3746,7 +3748,7 @@ LineDrag::finished (GdkEvent* event, bool movement_occured)
}
}
- _editor->session()->commit_reversible_command ();
+ _editor->commit_reversible_command ();
}
void
@@ -5043,7 +5045,7 @@ AutomationRangeDrag::finished (GdkEvent* event, bool)
i->line->end_drag (false, 0);
}
- _editor->session()->commit_reversible_command ();
+ _editor->commit_reversible_command ();
}
void
@@ -5189,9 +5191,11 @@ EditorRubberbandSelectDrag::select_things (int button_state, framepos_t x1, fram
}
Selection::Operation op = ArdourKeyboard::selection_type (button_state);
-
+
_editor->begin_reversible_command (_("rubberband selection"));
+
_editor->select_all_within (x1, x2 - 1, y1, y2, _editor->track_views, op, false);
+
_editor->commit_reversible_command ();
}
diff --git a/gtk2_ardour/editor_locations.cc b/gtk2_ardour/editor_locations.cc
index bbaf0daf75..03509ac023 100644
--- a/gtk2_ardour/editor_locations.cc
+++ b/gtk2_ardour/editor_locations.cc
@@ -28,7 +28,7 @@ using namespace Gtk;
EditorLocations::EditorLocations (Editor* e)
: EditorComponent (e)
{
- _locations = new LocationUI;
+ _locations = new LocationUI ();
_scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER);
_scroller.add (*_locations);
}
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index 6d07ecc357..d982de3a32 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -654,12 +654,12 @@ Editor::mouse_add_new_marker (framepos_t where, bool is_cd, bool is_xrun)
return;
}
Location *location = new Location (*_session, where, where, markername, (Location::Flags) flags);
- _session->begin_reversible_command (_("add marker"));
+ begin_reversible_command (_("add marker"));
+
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
/* find the marker we just added */
@@ -668,6 +668,8 @@ Editor::mouse_add_new_marker (framepos_t where, bool is_cd, bool is_xrun)
/* make it the selected marker */
selection->set (lam->start);
}
+
+ commit_reversible_command ();
}
}
@@ -721,12 +723,12 @@ Editor::remove_marker (ArdourCanvas::Item& item, GdkEvent*)
gint
Editor::really_remove_marker (Location* loc)
{
- _session->begin_reversible_command (_("remove marker"));
+ begin_reversible_command (_("remove marker"));
XMLNode &before = _session->locations()->get_state();
_session->locations()->remove (loc);
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+ commit_reversible_command ();
return FALSE;
}
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 84b632202f..19351d49e4 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2344,8 +2344,6 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
clicked_routeview->playlist()->add_region (region, selection->time[clicked_selection].start);
_session->add_command(new StatefulDiffCommand (playlist));
- commit_reversible_command ();
-
c.disconnect ();
if (latest_regionviews.empty()) {
@@ -2356,8 +2354,11 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
/* we need to deselect all other regionviews, and select this one
i'm ignoring undo stuff, because the region creation will take care of it
*/
+
selection->set (latest_regionviews);
+ commit_reversible_command ();
+
_drags->set (new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false, false), event);
}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index aa0f316467..9f2f4acccf 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -219,14 +219,14 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions)
a = tmp;
}
+ latest_regionviews.clear ();
+
vector<sigc::connection> region_added_connections;
for (list<RouteTimeAxisView*>::iterator i = used_trackviews.begin(); i != used_trackviews.end(); ++i) {
region_added_connections.push_back ((*i)->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view)));
}
- latest_regionviews.clear ();
-
while (used_playlists.size() > 0) {
list <boost::shared_ptr<Playlist > >::iterator i = used_playlists.begin();
(*i)->thaw();
@@ -236,8 +236,6 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions)
for (vector<sigc::connection>::iterator c = region_added_connections.begin(); c != region_added_connections.end(); ++c) {
(*c).disconnect ();
}
-
- commit_reversible_command ();
if (frozen){
EditorThaw(); /* Emit Signal */
@@ -251,7 +249,15 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions)
selection->add (latest_regionviews); //these are the new regions created after the split
}
_ignore_follow_edits = false;
+ } else {
+ _ignore_follow_edits = true;
+ if( working_on_selection ) {
+ selection->add (latest_regionviews); //these are the new regions created after the split
+ }
+ _ignore_follow_edits = false;
}
+
+ commit_reversible_command ();
}
/** Move one extreme of the current range selection. If more than one range is selected,
@@ -1928,12 +1934,14 @@ Editor::add_location_from_selection ()
_session->locations()->next_available_name(rangename,"selection");
Location *location = new Location (*_session, start, end, rangename, Location::IsRangeMarker);
- _session->begin_reversible_command (_("add marker"));
+ begin_reversible_command (_("add marker"));
+
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -1948,12 +1956,14 @@ Editor::add_location_mark (framepos_t where)
return;
}
Location *location = new Location (*_session, where, where, markername, Location::IsMark);
- _session->begin_reversible_command (_("add marker"));
+ begin_reversible_command (_("add marker"));
+
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -1968,7 +1978,8 @@ Editor::remove_location_at_playhead_cursor ()
if (_session) {
//set up for undo
- _session->begin_reversible_command (_("remove marker"));
+ begin_reversible_command (_("remove marker"));
+
XMLNode &before = _session->locations()->get_state();
bool removed = false;
@@ -1986,7 +1997,8 @@ Editor::remove_location_at_playhead_cursor ()
if (removed) {
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
}
}
@@ -2001,7 +2013,8 @@ Editor::add_locations_from_region ()
return;
}
- _session->begin_reversible_command (selection->regions.size () > 1 ? _("add markers") : _("add marker"));
+ begin_reversible_command (selection->regions.size () > 1 ? _("add markers") : _("add marker"));
+
XMLNode &before = _session->locations()->get_state();
for (RegionSelection::iterator i = rs.begin (); i != rs.end (); ++i) {
@@ -2015,7 +2028,8 @@ Editor::add_locations_from_region ()
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
/** Add a single range marker around all selected regions */
@@ -2028,7 +2042,8 @@ Editor::add_location_from_region ()
return;
}
- _session->begin_reversible_command (_("add marker"));
+ begin_reversible_command (_("add marker"));
+
XMLNode &before = _session->locations()->get_state();
string markername;
@@ -2051,7 +2066,8 @@ Editor::add_location_from_region ()
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
/* MARKS */
@@ -2107,12 +2123,14 @@ void
Editor::clear_markers ()
{
if (_session) {
- _session->begin_reversible_command (_("clear markers"));
+ begin_reversible_command (_("clear markers"));
+
XMLNode &before = _session->locations()->get_state();
_session->locations()->clear_markers ();
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
}
@@ -2120,27 +2138,30 @@ void
Editor::clear_ranges ()
{
if (_session) {
- _session->begin_reversible_command (_("clear ranges"));
+ begin_reversible_command (_("clear ranges"));
+
XMLNode &before = _session->locations()->get_state();
_session->locations()->clear_ranges ();
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
}
void
Editor::clear_locations ()
{
- _session->begin_reversible_command (_("clear locations"));
+ begin_reversible_command (_("clear locations"));
+
XMLNode &before = _session->locations()->get_state();
_session->locations()->clear ();
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
- _session->locations()->clear ();
+
+ commit_reversible_command ();
}
void
@@ -4537,11 +4558,11 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end());
}
- commit_reversible_command ();
-
if (!foo.empty()) {
selection->set (foo);
}
+
+ commit_reversible_command ();
}
void
@@ -5168,8 +5189,8 @@ Editor::reset_region_gain_envelopes ()
return;
}
- _session->begin_reversible_command (_("reset region gain"));
-
+ begin_reversible_command (_("reset region gain"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
@@ -5180,8 +5201,8 @@ Editor::reset_region_gain_envelopes ()
_session->add_command (new MementoCommand<AutomationList>(*arv->audio_region()->envelope().get(), &before, &alist->get_state()));
}
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -5221,8 +5242,8 @@ Editor::toggle_gain_envelope_active ()
return;
}
- _session->begin_reversible_command (_("region gain envelope active"));
-
+ begin_reversible_command (_("region gain envelope active"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
@@ -5231,8 +5252,8 @@ Editor::toggle_gain_envelope_active ()
_session->add_command (new StatefulDiffCommand (arv->region()));
}
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -5248,15 +5269,15 @@ Editor::toggle_region_lock ()
return;
}
- _session->begin_reversible_command (_("toggle region lock"));
-
+ begin_reversible_command (_("toggle region lock"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->clear_changes ();
(*i)->region()->set_locked (!(*i)->region()->locked());
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -5272,15 +5293,15 @@ Editor::toggle_region_video_lock ()
return;
}
- _session->begin_reversible_command (_("Toggle Video Lock"));
-
+ begin_reversible_command (_("Toggle Video Lock"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->clear_changes ();
(*i)->region()->set_video_locked (!(*i)->region()->video_locked());
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -5296,16 +5317,16 @@ Editor::toggle_region_lock_style ()
return;
}
- _session->begin_reversible_command (_("region lock style"));
-
+ begin_reversible_command (_("region lock style"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->clear_changes ();
PositionLockStyle const ns = (*i)->region()->position_lock_style() == AudioTime ? MusicTime : AudioTime;
(*i)->region()->set_position_lock_style (ns);
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -5321,15 +5342,15 @@ Editor::toggle_opaque_region ()
return;
}
- _session->begin_reversible_command (_("change region opacity"));
-
+ begin_reversible_command (_("change region opacity"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->clear_changes ();
(*i)->region()->set_opaque (!(*i)->region()->opaque());
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -6137,8 +6158,8 @@ Editor::split_region_at_transients ()
return;
}
- _session->begin_reversible_command (_("split regions"));
-
+ begin_reversible_command (_("split regions"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ) {
RegionSelection::iterator tmp;
@@ -6155,8 +6176,8 @@ Editor::split_region_at_transients ()
i = tmp;
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
@@ -6344,14 +6365,14 @@ Editor::place_transient()
framepos_t where = get_preferred_edit_position();
- _session->begin_reversible_command (_("place transient"));
-
+ begin_reversible_command (_("place transient"));
+
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
framepos_t position = (*r)->region()->position();
(*r)->region()->add_transient(where - position);
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -6379,8 +6400,8 @@ Editor::snap_regions_to_grid ()
return;
}
- _session->begin_reversible_command (_("snap regions to grid"));
-
+ begin_reversible_command (_("snap regions to grid"));
+
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
boost::shared_ptr<Playlist> pl = (*r)->region()->playlist();
@@ -6403,8 +6424,8 @@ Editor::snap_regions_to_grid ()
(*i)->thaw();
used_playlists.pop_front();
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -6462,8 +6483,8 @@ Editor::close_region_gaps ()
/* Iterate over the region list and make adjacent regions overlap by crossfade_len_ms */
- _session->begin_reversible_command (_("close region gaps"));
-
+ begin_reversible_command (_("close region gaps"));
+
int idx = 0;
boost::shared_ptr<Region> last_region;
@@ -6502,8 +6523,8 @@ Editor::close_region_gaps ()
(*i)->thaw();
used_playlists.pop_front();
}
-
- _session->commit_reversible_command ();
+
+ commit_reversible_command ();
}
void
@@ -7111,7 +7132,7 @@ Editor::toggle_region_mute ()
(*i)->region()->playlist()->clear_changes ();
(*i)->region()->set_muted (!(*i)->region()->muted ());
- _session->add_command (new StatefulDiffCommand ((*i)->region()->playlist()));
+ _session->add_command (new StatefulDiffCommand ((*i)->region()));
}
diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc
index 689706ba01..3c4a28097e 100644
--- a/gtk2_ardour/location_ui.cc
+++ b/gtk2_ardour/location_ui.cc
@@ -33,6 +33,7 @@
#include "location_ui.h"
#include "prompter.h"
#include "utils.h"
+#include "public_editor.h"
#include "i18n.h"
@@ -853,12 +854,12 @@ LocationUI::do_location_remove (ARDOUR::Location *loc)
return FALSE;
}
- _session->begin_reversible_command (_("remove marker"));
+ PublicEditor::instance().begin_reversible_command (_("remove marker"));
XMLNode &before = _session->locations()->get_state();
_session->locations()->remove (loc);
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
return FALSE;
}
@@ -1017,12 +1018,12 @@ LocationUI::add_new_location()
if (Config->get_name_new_markers()) {
newest_location = location;
}
- _session->begin_reversible_command (_("add marker"));
+ PublicEditor::instance().begin_reversible_command (_("add marker"));
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
}
}
@@ -1036,12 +1037,12 @@ LocationUI::add_new_range()
framepos_t where = _session->audible_frame();
_session->locations()->next_available_name(rangename,"unnamed");
Location *location = new Location (*_session, where, where, rangename, Location::IsRangeMarker);
- _session->begin_reversible_command (_("add range marker"));
+ PublicEditor::instance().begin_reversible_command (_("add range marker"));
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
}
}
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 6b6d40f93c..85ea05fe3f 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -3350,7 +3350,7 @@ MidiRegionView::selection_as_cut_buffer () const
bool
MidiRegionView::paste (framepos_t pos, const ::Selection& selection, PasteContext& ctx)
{
- trackview.session()->begin_reversible_command (Operations::paste);
+ trackview.editor().begin_reversible_command (Operations::paste);
// Paste notes, if available
MidiNoteSelection::const_iterator m = selection.midi_notes.get_nth(ctx.counts.n_notes());
@@ -3366,7 +3366,7 @@ MidiRegionView::paste (framepos_t pos, const ::Selection& selection, PasteContex
a->second->paste(pos, selection, ctx);
}
- trackview.session()->commit_reversible_command ();
+ trackview.editor().commit_reversible_command ();
return true;
}
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 9969d9d49e..c2972116a1 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -245,6 +245,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual void set_zoom_focus (Editing::ZoomFocus) = 0;
virtual Editing::ZoomFocus get_zoom_focus () const = 0;
virtual framecnt_t get_current_zoom () const = 0;
+ virtual void reset_zoom (framecnt_t) = 0;
virtual PlaylistSelector& playlist_selector() const = 0;
virtual void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>) = 0;
virtual void new_playlists (TimeAxisView*) = 0;
@@ -288,6 +289,8 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual void prepare_for_cleanup () = 0;
virtual void finish_cleanup () = 0;
virtual void reset_x_origin (framepos_t frame) = 0;
+ virtual double get_y_origin () const = 0;
+ virtual void reset_y_origin (double pos) = 0;
virtual void remove_last_capture () = 0;
virtual void maximise_editing_space () = 0;
virtual void restore_editing_space () = 0;
@@ -403,6 +406,10 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual void stop_canvas_autoscroll () = 0;
virtual bool autoscroll_active() const = 0;
+ virtual void begin_reversible_command (std::string cmd_name) = 0;
+ virtual void begin_reversible_command (GQuark) = 0;
+ virtual void commit_reversible_command () = 0;
+
virtual MouseCursors const * cursors () const = 0;
virtual VerboseCursor * verbose_cursor () const = 0;
@@ -420,6 +427,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual void get_regions_at (RegionSelection &, framepos_t where, TrackViewList const &) const = 0;
virtual RegionSelection get_regions_from_selection_and_mouse (framepos_t) = 0;
+ virtual void get_regionviews_by_id (PBD::ID const & id, RegionSelection & regions) const = 0;
/// Singleton instance, set up by Editor::Editor()
diff --git a/gtk2_ardour/region_editor.cc b/gtk2_ardour/region_editor.cc
index 511314dfc5..16888fb688 100644
--- a/gtk2_ardour/region_editor.cc
+++ b/gtk2_ardour/region_editor.cc
@@ -33,6 +33,7 @@
#include "main_clock.h"
#include "gui_thread.h"
#include "region_editor.h"
+#include "public_editor.h"
#include "i18n.h"
@@ -269,7 +270,7 @@ RegionEditor::connect_editor_events ()
void
RegionEditor::position_clock_changed ()
{
- _session->begin_reversible_command (_("change region start position"));
+ PublicEditor::instance().begin_reversible_command (_("change region start position"));
boost::shared_ptr<Playlist> pl = _region->playlist();
@@ -279,13 +280,13 @@ RegionEditor::position_clock_changed ()
_session->add_command(new StatefulDiffCommand (_region));
}
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
}
void
RegionEditor::end_clock_changed ()
{
- _session->begin_reversible_command (_("change region end position"));
+ PublicEditor::instance().begin_reversible_command (_("change region end position"));
boost::shared_ptr<Playlist> pl = _region->playlist();
@@ -295,7 +296,7 @@ RegionEditor::end_clock_changed ()
_session->add_command(new StatefulDiffCommand (_region));
}
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
end_clock.set (_region->position() + _region->length() - 1, true);
}
@@ -305,7 +306,7 @@ RegionEditor::length_clock_changed ()
{
framecnt_t frames = length_clock.current_time();
- _session->begin_reversible_command (_("change region length"));
+ PublicEditor::instance().begin_reversible_command (_("change region length"));
boost::shared_ptr<Playlist> pl = _region->playlist();
@@ -315,7 +316,7 @@ RegionEditor::length_clock_changed ()
_session->add_command(new StatefulDiffCommand (_region));
}
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
length_clock.set (_region->length());
}
@@ -399,25 +400,25 @@ RegionEditor::audition_state_changed (bool yn)
void
RegionEditor::sync_offset_absolute_clock_changed ()
{
- _session->begin_reversible_command (_("change region sync point"));
+ PublicEditor::instance().begin_reversible_command (_("change region sync point"));
_region->clear_changes ();
_region->set_sync_position (sync_offset_absolute_clock.current_time());
_session->add_command (new StatefulDiffCommand (_region));
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
}
void
RegionEditor::sync_offset_relative_clock_changed ()
{
- _session->begin_reversible_command (_("change region sync point"));
+ PublicEditor::instance().begin_reversible_command (_("change region sync point"));
_region->clear_changes ();
_region->set_sync_position (sync_offset_relative_clock.current_time() + _region->position ());
_session->add_command (new StatefulDiffCommand (_region));
- _session->commit_reversible_command ();
+ PublicEditor::instance().commit_reversible_command ();
}
bool
diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc
index b010efc04c..cbeb1224af 100644
--- a/gtk2_ardour/region_gain_line.cc
+++ b/gtk2_ardour/region_gain_line.cc
@@ -69,7 +69,7 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
void
AudioRegionGainLine::remove_point (ControlPoint& cp)
{
- trackview.editor().session()->begin_reversible_command (_("remove control point"));
+ trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
if (!rv.audio_region()->envelope_active()) {
@@ -81,7 +81,7 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
alist->erase (cp.model());
trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
- trackview.editor().session()->commit_reversible_command ();
+ trackview.editor().commit_reversible_command ();
trackview.editor().session()->set_dirty ();
}
diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc
index 57ab59fd68..54e5aa3acc 100644
--- a/gtk2_ardour/region_selection.cc
+++ b/gtk2_ardour/region_selection.cc
@@ -73,6 +73,7 @@ void
RegionSelection::clear_all()
{
clear();
+ pending.clear ();
_bylayer.clear();
}
diff --git a/gtk2_ardour/region_selection.h b/gtk2_ardour/region_selection.h
index 36e40061c1..0cd603e5f4 100644
--- a/gtk2_ardour/region_selection.h
+++ b/gtk2_ardour/region_selection.h
@@ -62,6 +62,7 @@ class RegionSelection : public std::list<RegionView*>
void by_track (std::list<RegionView*>&) const;
std::set<boost::shared_ptr<ARDOUR::Playlist> > playlists () const;
+ std::list<PBD::ID> pending;
private:
void remove_it (RegionView*);
diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc
index f159331018..e257f56b52 100644
--- a/gtk2_ardour/rhythm_ferret.cc
+++ b/gtk2_ardour/rhythm_ferret.cc
@@ -352,7 +352,7 @@ RhythmFerret::do_split_action ()
editor.EditorFreeze(); /* Emit signal */
- _session->begin_reversible_command (_("split regions (rhythm ferret)"));
+ editor.begin_reversible_command (_("split regions (rhythm ferret)"));
/* Merge the transient positions for regions in consideration */
AnalysisFeatureList merged_features;
@@ -381,7 +381,7 @@ RhythmFerret::do_split_action ()
i = tmp;
}
- _session->commit_reversible_command ();
+ editor.commit_reversible_command ();
editor.EditorThaw(); /* Emit signal */
}
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index 7e2ee1338b..b29f5c3241 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -1206,6 +1206,7 @@ Selection::get_state () const
so that re-opening plugin windows for editor mixer strips works
*/
+ char buf[32];
XMLNode* node = new XMLNode (X_("Selection"));
for (TrackSelection::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
@@ -1221,9 +1222,23 @@ Selection::get_state () const
}
}
+ for (RegionSelection::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+ XMLNode* r = node->add_child (X_("Region"));
+ r->add_property (X_("id"), atoi ((*i)->region ()->id ().to_s ().c_str()));
+
+ }
+
+ for (TimeSelection::const_iterator i = time.begin(); i != time.end(); ++i) {
+ XMLNode* t = node->add_child (X_("AudioRange"));
+ snprintf(buf, sizeof(buf), "%ld", (*i).start);
+ t->add_property (X_("start"), string(buf));
+ snprintf(buf, sizeof(buf), "%ld", (*i).end);
+ t->add_property (X_("end"), string(buf));
+ }
+
for (MarkerSelection::const_iterator i = markers.begin(); i != markers.end(); ++i) {
XMLNode* t = node->add_child (X_("Marker"));
-
+
bool is_start;
Location* loc = editor->find_location_from_marker (*i, is_start);
@@ -1241,6 +1256,11 @@ Selection::set_state (XMLNode const & node, int)
return -1;
}
+ clear_regions ();
+ clear_time ();
+ clear_tracks ();
+ clear_markers ();
+
XMLNodeList children = node.children ();
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == X_("RouteView")) {
@@ -1253,6 +1273,36 @@ Selection::set_state (XMLNode const & node, int)
add (rtv);
}
+ } else if ((*i)->name() == X_("Region")) {
+ XMLProperty* prop_id = (*i)->property (X_("id"));
+ assert (prop_id);
+ PBD::ID id (prop_id->value ());
+
+ RegionSelection rs;
+ editor->get_regionviews_by_id (id, rs);
+
+ if (!rs.empty ()) {
+ add (rs);
+ } else {
+ /*
+ regionviews are being constructed - stash the region IDs
+ so we can identify them in Editor::region_view_added ()
+ */
+ regions.pending.push_back (id);
+ }
+
+ } else if ((*i)->name() == X_("AudioRange")) {
+ XMLProperty* prop_start = (*i)->property (X_("start"));
+ XMLProperty* prop_end = (*i)->property (X_("end"));
+
+ assert (prop_start);
+ assert (prop_end);
+
+ framepos_t s (atol (prop_start->value ().c_str()));
+ framepos_t e (atol (prop_end->value ().c_str()));
+
+ set_preserving_all_ranges (s, e);
+
} else if ((*i)->name() == X_("AutomationView")) {
XMLProperty* prop_id = (*i)->property (X_("id"));
diff --git a/gtk2_ardour/selection_memento.cc b/gtk2_ardour/selection_memento.cc
new file mode 100644
index 0000000000..67e527b07f
--- /dev/null
+++ b/gtk2_ardour/selection_memento.cc
@@ -0,0 +1,95 @@
+/*
+ Copyright (C) 2014 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "selection_memento.h"
+#include "editing.h"
+#include "public_editor.h"
+
+#include "i18n.h"
+
+SelectionMemento::SelectionMemento ()
+{
+}
+
+SelectionMemento::~SelectionMemento ()
+{
+}
+
+XMLNode&
+SelectionMemento::get_state () {
+
+ XMLNode* node = new XMLNode ("SelectionMemento");
+ char buf[32];
+ PublicEditor& editor = PublicEditor::instance();
+
+ node->add_property ("mouse-mode", enum2str(editor.current_mouse_mode()));
+ snprintf (buf, sizeof(buf), "%" PRId64, editor.get_current_zoom());
+ node->add_property ("zoom", buf);
+ snprintf (buf, sizeof (buf), "%" PRIi64, editor.leftmost_sample());
+ node->add_property ("left-frame", buf);
+ snprintf (buf, sizeof (buf), "%f", editor.get_y_origin());
+ node->add_property ("y-origin", buf);
+
+ node->add_child_nocopy (editor.get_selection().get_state());
+ return *node;
+}
+
+int
+SelectionMemento::set_state (const XMLNode& node, int /*version*/) {
+
+ const XMLProperty* prop;
+ PublicEditor& editor = PublicEditor::instance();
+ if (node.name() != X_("SelectionMemento")) {
+ return -1;
+ }
+
+ if ((prop = node.property ("mouse-mode"))) {
+ Editing::MouseMode m = Editing::str2mousemode(prop->value());
+ editor.set_mouse_mode (m, true);
+ } else {
+ editor.set_mouse_mode (Editing::MouseObject, true);
+ }
+
+ if ((prop = node.property ("zoom"))) {
+ /* older versions of ardour used floating point samples_per_pixel */
+ double f = PBD::atof (prop->value());
+ editor.reset_zoom (llrintf (f));
+ }
+
+ if ((prop = node.property ("left-frame")) != 0) {
+ framepos_t pos;
+ if (sscanf (prop->value().c_str(), "%" PRId64, &pos) == 1) {
+ if (pos < 0) {
+ pos = 0;
+ }
+ editor.reset_x_origin (pos);
+ }
+ }
+
+ if ((prop = node.property ("y-origin")) != 0) {
+ editor.reset_y_origin (atof (prop->value ().c_str()));
+ }
+
+ XMLNodeList children = node.children ();
+ for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+ editor.get_selection().set_state (**i, Stateful::current_state_version);
+ }
+
+ return 0;
+}
diff --git a/gtk2_ardour/selection_memento.h b/gtk2_ardour/selection_memento.h
new file mode 100644
index 0000000000..571f9c75b4
--- /dev/null
+++ b/gtk2_ardour/selection_memento.h
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 2014 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_gtk_selection_memento_h__
+#define __ardour_gtk_selection_memento_h__
+
+#include "pbd/statefuldestructible.h"
+
+class SelectionMemento : public PBD::StatefulDestructible
+{
+public:
+ SelectionMemento ();
+ ~SelectionMemento ();
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&, int version);
+};
+#endif /* __ardour_gtk_selection_memento_h__ */
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index c38c8509ab..165cd2f82b 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -201,6 +201,7 @@ gtk2_ardour_sources = [
'ruler_dialog.cc',
'search_path_option.cc',
'selection.cc',
+ 'selection_memento.cc',
'send_ui.cc',
'session_dialog.cc',
'session_import_dialog.cc',