summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-01-17 01:42:44 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-01-17 01:42:44 +0000
commit762d2ae936bd78053d9f344ce9392b7867304ae2 (patch)
tree4d5b8655b28f02ba56183b133b87e18b0f9e5d50
parentd3071f84e5be7d611b83ce68908da697566a9713 (diff)
fix ordering of cut/copied regions when pasting; ctrl-click now does the right thing the first time its used on a region; fix missing click and other dubious behaviour in new sessions caused by not connecting to Configuration::ParameterChanged in the new session constructor
git-svn-id: svn://localhost/ardour2/trunk@1331 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/actions.cc2
-rw-r--r--gtk2_ardour/ardour_ui_options.cc1
-rw-r--r--gtk2_ardour/editor.cc20
-rw-r--r--gtk2_ardour/editor.h2
-rw-r--r--gtk2_ardour/editor_keyboard.cc2
-rw-r--r--gtk2_ardour/editor_mixer.cc3
-rw-r--r--gtk2_ardour/editor_ops.cc147
-rw-r--r--gtk2_ardour/region_selection.cc62
-rw-r--r--gtk2_ardour/region_selection.h16
-rw-r--r--gtk2_ardour/time_axis_view_item.h5
-rw-r--r--libs/ardour/ardour/configuration_variable.h6
-rw-r--r--libs/ardour/configuration.cc13
-rw-r--r--libs/ardour/session.cc3
13 files changed, 200 insertions, 82 deletions
diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc
index 2fe305cf84..d382878582 100644
--- a/gtk2_ardour/actions.cc
+++ b/gtk2_ardour/actions.cc
@@ -266,7 +266,7 @@ ActionManager::toggle_config_state (const char* group, const char* action, bool
if (tact) {
bool x = (Config->*get)();
-
+
if (x != tact->get_active()) {
(Config->*set) (!x);
}
diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc
index d0f523481f..7b8557f18b 100644
--- a/gtk2_ardour/ardour_ui_options.cc
+++ b/gtk2_ardour/ardour_ui_options.cc
@@ -19,6 +19,7 @@
*/
#include <pbd/convert.h>
+#include <pbd/stacktrace.h>
#include <gtkmm2ext/utils.h>
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index cd1e9f3f61..e447603100 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -28,6 +28,7 @@
#include <pbd/convert.h>
#include <pbd/error.h>
+#include <pbd/stacktrace.h>
#include <pbd/memento_command.h>
#include <gtkmm/image.h>
@@ -3030,7 +3031,6 @@ Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32
return;
}
-
if ((pl = ds->playlist()) != 0) {
pl->get_equivalent_regions (basis->region(), results);
}
@@ -3052,6 +3052,10 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
return false;
}
+ if (press) {
+ button_release_can_deselect = false;
+ }
+
if (op == Selection::Toggle || op == Selection::Set) {
mapover_audio_tracks (bind (mem_fun (*this, &Editor::mapped_set_selected_regionview_from_click),
@@ -4292,3 +4296,17 @@ Editor::idle_visual_changer ()
return 0;
}
+
+struct EditorOrderTimeAxisSorter {
+ bool operator() (const TimeAxisView* a, const TimeAxisView* b) const {
+ return a->order < b->order;
+ }
+};
+
+void
+Editor::sort_track_selection ()
+{
+ EditorOrderTimeAxisSorter cmp;
+ selection->tracks.sort (cmp);
+}
+
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 241ce808ff..b09f76c9d9 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -419,6 +419,8 @@ class Editor : public PublicEditor
CrossfadeView* clicked_crossfadeview;
ControlPoint* clicked_control_point;
+ void sort_track_selection ();
+
void get_relevant_audio_tracks (std::set<AudioTimeAxisView*>& relevant_tracks);
void mapover_audio_tracks (sigc::slot<void,AudioTimeAxisView&,uint32_t> sl);
diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc
index cdea9d2272..bfe61eae5c 100644
--- a/gtk2_ardour/editor_keyboard.cc
+++ b/gtk2_ardour/editor_keyboard.cc
@@ -82,7 +82,7 @@ Editor::kbd_do_split (GdkEvent* ev)
nframes_t where = event_frame (ev);
if (entered_regionview) {
- if (selection->regions.find (entered_regionview) != selection->regions.end()) {
+ if (selection->regions.contains (entered_regionview)) {
split_regions_at (where, selection->regions);
} else {
RegionSelection s;
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index 2d8d04e94a..13eafe1602 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -77,6 +77,9 @@ Editor::show_editor_mixer (bool yn)
}
} else {
+
+ sort_track_selection ();
+
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
AudioTimeAxisView* atv;
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 2e271d7671..5ab343392a 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -1351,27 +1351,20 @@ Editor::select_all_within (nframes_t start, nframes_t end, double top, double bo
(*iter)->get_selectables (start, end, top, bot, touched);
}
- cerr << "select all within found " << touched.size() << endl;
-
begin_reversible_command (_("select all within"));
switch (op) {
case Selection::Add:
case Selection::Toggle:
- cerr << "toggle\n";
selection->add (touched);
break;
case Selection::Set:
- cerr << "set\n";
selection->set (touched);
break;
case Selection::Extend:
- cerr << "extend\n";
/* not defined yet */
break;
}
- cerr << "selection now has " << selection->points.size() << endl;
-
commit_reversible_command ();
return !touched.empty();
}
@@ -2166,6 +2159,8 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
nframes_t start = selection->time[clicked_selection].start;
nframes_t end = selection->time[clicked_selection].end;
+ sort_track_selection ();
+
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
boost::shared_ptr<AudioRegion> current;
@@ -2227,6 +2222,8 @@ Editor::separate_region_from_selection ()
boost::shared_ptr<Playlist> playlist;
+ sort_track_selection ();
+
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
AudioTimeAxisView* atv;
@@ -2333,6 +2330,8 @@ Editor::crop_region_to_selection ()
} else {
+ sort_track_selection ();
+
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
AudioTimeAxisView* atv;
@@ -2949,17 +2948,33 @@ struct lt_playlist {
}
};
+struct PlaylistMapping {
+ TimeAxisView* tv;
+ boost::shared_ptr<AudioPlaylist> pl;
+
+ PlaylistMapping (TimeAxisView* tvp) : tv (tvp) {}
+};
+
void
Editor::cut_copy_regions (CutCopyOp op)
{
- typedef std::map<boost::shared_ptr<AudioPlaylist>,boost::shared_ptr<AudioPlaylist> > PlaylistMapping;
- PlaylistMapping pmap;
- nframes_t first_position = max_frames;
+ /* we can't use a std::map here because the ordering is important, and we can't trivially sort
+ a map when we want ordered access to both elements. i think.
+ */
+
+ vector<PlaylistMapping> pmap;
+ nframes_t first_position = max_frames;
+
set<PlaylistState, lt_playlist> freezelist;
pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
+
+ /* get ordering correct before we cut/copy */
+
+ selection->regions.sort_by_position_and_track ();
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+
first_position = min ((*x)->region()->position(), first_position);
if (op == Cut || op == Clear) {
@@ -2972,66 +2987,94 @@ Editor::cut_copy_regions (CutCopyOp op)
before.before = &pl->get_state();
insert_result = freezelist.insert (before);
-
+
if (insert_result.second) {
pl->freeze ();
}
}
}
+
+ TimeAxisView* tv = &(*x)->get_trackview();
+ vector<PlaylistMapping>::iterator z;
+
+ for (z = pmap.begin(); z != pmap.end(); ++z) {
+ if ((*z).tv == tv) {
+ break;
+ }
+ }
+
+ if (z == pmap.end()) {
+ pmap.push_back (PlaylistMapping (tv));
+ }
}
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
+
+ if (!pl) {
+ /* impossible, but this handles it for the future */
+ continue;
+ }
+
+ TimeAxisView& tv = (*x)->get_trackview();
boost::shared_ptr<AudioPlaylist> npl;
RegionSelection::iterator tmp;
tmp = x;
++tmp;
- if (pl) {
-
- PlaylistMapping::iterator pi = pmap.find (pl);
-
- if (pi == pmap.end()) {
- npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (*session, "cutlist", true));
- npl->freeze();
- pmap[pl] = npl;
- } else {
- npl = pi->second;
- }
-
- // FIXME
- boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>((*x)->region());
- switch (op) {
- case Cut:
- if (!ar) break;
-
- npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position);
- pl->remove_region (((*x)->region()));
- break;
-
- case Copy:
- if (!ar) break;
-
- npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position);
- break;
-
- case Clear:
- pl->remove_region (((*x)->region()));
+ vector<PlaylistMapping>::iterator z;
+
+ for (z = pmap.begin(); z != pmap.end(); ++z) {
+ if ((*z).tv == &tv) {
break;
}
}
+
+ assert (z != pmap.end());
+
+ if (!(*z).pl) {
+ npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (*session, "cutlist", true));
+ npl->freeze();
+ (*z).pl = npl;
+ } else {
+ npl = (*z).pl;
+ }
+
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>((*x)->region());
+
+ switch (op) {
+ case Cut:
+ if (!ar) break;
+
+ npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position);
+ pl->remove_region (((*x)->region()));
+ break;
+
+ case Copy:
+ if (!ar) break;
+
+ npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position);
+ break;
+
+ case Clear:
+ pl->remove_region (((*x)->region()));
+ break;
+ }
x = tmp;
}
-
+
list<boost::shared_ptr<Playlist> > foo;
-
- for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) {
- foo.push_back (i->second);
+
+ /* the pmap is in the same order as the tracks in which selected regions occured */
+
+ for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) {
+ (*i).pl->thaw();
+ foo.push_back ((*i).pl);
}
-
+
if (!foo.empty()) {
cut_buffer->set (foo);
}
@@ -3095,15 +3138,19 @@ Editor::paste_internal (nframes_t position, float times)
TrackSelection::iterator i;
size_t nth;
+ /* get everything in the correct order */
+
+ sort_track_selection ();
+
for (nth = 0, i = selection->tracks.begin(); i != selection->tracks.end(); ++i, ++nth) {
-
+
/* undo/redo is handled by individual tracks */
if ((*i)->paste (position, times, *cut_buffer, nth)) {
commit = true;
}
}
-
+
if (commit) {
commit_reversible_command ();
}
@@ -3129,6 +3176,8 @@ Editor::paste_named_selection (float times)
chunk = ns->playlists.begin();
begin_reversible_command (_("paste chunk"));
+
+ sort_track_selection ();
for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
@@ -3241,8 +3290,6 @@ Editor::reset_point_selection ()
{
/* reset all selected points to the relevant default value */
- cerr << "point selection has " << selection->points.size() << " entries\n";
-
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track);
diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc
index a418b1de23..430e1d3728 100644
--- a/gtk2_ardour/region_selection.cc
+++ b/gtk2_ardour/region_selection.cc
@@ -22,22 +22,13 @@
#include "region_view.h"
#include "region_selection.h"
+#include "time_axis_view.h"
using namespace ARDOUR;
using namespace PBD;
using namespace sigc;
-bool
-RegionComparator::operator() (const RegionView* a, const RegionView* b) const
-{
- if (a == b) {
- return false;
- } else {
- return a < b;
- }
-}
-
RegionSelection::RegionSelection ()
{
_current_start = 0;
@@ -46,9 +37,8 @@ RegionSelection::RegionSelection ()
RegionSelection::RegionSelection (const RegionSelection& other)
{
-
for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
- add (*i, false);
+ add (*i);
}
_current_start = other._current_start;
_current_end = other._current_end;
@@ -64,7 +54,7 @@ RegionSelection::operator= (const RegionSelection& other)
clear_all();
for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
- add (*i, false);
+ add (*i);
}
_current_start = other._current_start;
@@ -85,11 +75,11 @@ RegionSelection::clear_all()
bool RegionSelection::contains (RegionView* rv)
{
- return this->find (rv) != end();
+ return find (begin(), end(), rv) != end();
}
void
-RegionSelection::add (RegionView* rv, bool dosort)
+RegionSelection::add (RegionView* rv)
{
if (contains (rv)) {
/* we already have it */
@@ -106,11 +96,11 @@ RegionSelection::add (RegionView* rv, bool dosort)
_current_end = rv->region()->last_frame();
}
- insert (rv);
+ push_back (rv);
// add to layer sorted list
+
add_to_layer (rv);
-
}
void
@@ -124,7 +114,7 @@ RegionSelection::remove (RegionView* rv)
{
RegionSelection::iterator i;
- if ((i = this->find (rv)) != end()) {
+ if ((i = find (begin(), end(), rv)) != end()) {
erase (i);
@@ -198,7 +188,7 @@ RegionSelection::add_to_layer (RegionView * rv)
}
struct RegionSortByTime {
- bool operator() (const RegionView* a, const RegionView* b) {
+ bool operator() (const RegionView* a, const RegionView* b) const {
return a->region()->position() < b->region()->position();
}
};
@@ -217,3 +207,37 @@ RegionSelection::by_position (list<RegionView*>& foo) const
foo.sort (sorter);
return;
}
+
+struct RegionSortByTrack {
+ bool operator() (const RegionView* a, const RegionView* b) const {
+
+ /* really, track and position */
+
+ if (a->get_trackview().order == b->get_trackview().order) {
+ return a->region()->position() < b->region()->position();
+ } else {
+ return a->get_trackview().order < b->get_trackview().order;
+ }
+ }
+};
+
+void
+RegionSelection::by_track (list<RegionView*>& foo) const
+{
+ list<RegionView*>::const_iterator i;
+ RegionSortByTrack sorter;
+
+ for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
+ foo.push_back (*i);
+ }
+
+ foo.sort (sorter);
+ return;
+}
+
+void
+RegionSelection::sort_by_position_and_track ()
+{
+ RegionSortByTrack sorter;
+ sort (sorter);
+}
diff --git a/gtk2_ardour/region_selection.h b/gtk2_ardour/region_selection.h
index 7e1d3b0835..5c05a813f9 100644
--- a/gtk2_ardour/region_selection.h
+++ b/gtk2_ardour/region_selection.h
@@ -29,11 +29,7 @@ using std::set;
class RegionView;
-struct RegionComparator {
- bool operator() (const RegionView* a, const RegionView* b) const;
-};
-
-class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::trackable
+class RegionSelection : public std::list<RegionView*>, public sigc::trackable
{
public:
RegionSelection();
@@ -41,9 +37,10 @@ class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::
RegionSelection& operator= (const RegionSelection&);
- void add (RegionView*, bool dosort = true);
+ void add (RegionView*);
bool remove (RegionView*);
bool contains (RegionView*);
+ void sort_by_position_and_track ();
void clear_all();
@@ -51,14 +48,15 @@ class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::
return _current_start;
}
- /* collides with list<>::end */
+ /* "end" collides with list<>::end */
nframes_t end_frame () const {
return _current_end;
}
- const list<RegionView *> & by_layer() const { return _bylayer; }
- void by_position (list<RegionView*>&) const;
+ const std::list<RegionView *>& by_layer() const { return _bylayer; }
+ void by_position (std::list<RegionView*>&) const;
+ void by_track (std::list<RegionView*>&) const;
private:
void remove_it (RegionView*);
diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h
index e27b944e2a..80d9177041 100644
--- a/gtk2_ardour/time_axis_view_item.h
+++ b/gtk2_ardour/time_axis_view_item.h
@@ -233,6 +233,11 @@ class TimeAxisViewItem : public Selectable
/**
+ * Returns the time axis that this item is upon
+ */
+ TimeAxisView& get_trackview() const { return trackview; }
+
+ /**
* Sets the samples per unit of this item.
* this item is used to determine the relative visual size and position of this item
* based upon its duration and start value.
diff --git a/libs/ardour/ardour/configuration_variable.h b/libs/ardour/ardour/configuration_variable.h
index 6f0a8a3571..4327fa69b1 100644
--- a/libs/ardour/ardour/configuration_variable.h
+++ b/libs/ardour/ardour/configuration_variable.h
@@ -27,9 +27,13 @@ class ConfigVariableBase {
virtual void add_to_node (XMLNode& node) = 0;
virtual bool set_from_node (const XMLNode& node, Owner owner) = 0;
+
protected:
std::string _name;
Owner _owner;
+
+ void notify ();
+ void miss ();
};
template<class T>
@@ -41,10 +45,12 @@ class ConfigVariable : public ConfigVariableBase
virtual bool set (T val, Owner owner) {
if (val == value) {
+ miss ();
return false;
}
value = val;
_owner = (ConfigVariableBase::Owner)(_owner |owner);
+ notify ();
return true;
}
diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc
index eb3d879447..a0f2b5e036 100644
--- a/libs/ardour/configuration.cc
+++ b/libs/ardour/configuration.cc
@@ -317,3 +317,16 @@ Configuration::map_parameters (sigc::slot<void,const char*> theSlot)
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
}
+
+void
+ConfigVariableBase::notify ()
+{
+ // placeholder for any debugging desired when a config variable is modified
+}
+
+void
+ConfigVariableBase::miss ()
+{
+ // placeholder for any debugging desired when a config variable
+ // is set but to the same value as it already has
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index d49fb2c116..eba090665a 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -368,7 +368,6 @@ Session::Session (AudioEngine &eng,
if (master_out_channels) {
shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
r->set_remote_control_id (control_id);
- cerr << "master bus has remote control ID " << r->remote_control_id() << endl;
rl.push_back (r);
} else {
@@ -396,6 +395,8 @@ Session::Session (AudioEngine &eng,
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
+ Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
+
if (was_dirty) {
DirtyChanged (); /* EMIT SIGNAL */
}