summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-09-19 14:38:46 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-09-19 14:38:46 +0000
commit6f8cd634501efd70711b148b4ac0e0ce2aa5cc95 (patch)
tree07df4b771792ec9a0b8ba7c8c01db0234f1efe22
parent60f588f21d6ad62335d72e8dc682abf8859107ea (diff)
chris goddard's region list patch; port 2.X marker drag/move changes to 3.0; compilation fixes-post-evoral
git-svn-id: svn://localhost/ardour2/branches/3.0@3760 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour_ui.cc27
-rw-r--r--gtk2_ardour/audio_clock.cc1
-rw-r--r--gtk2_ardour/audio_clock.h3
-rw-r--r--gtk2_ardour/draginfo.h6
-rw-r--r--gtk2_ardour/editor.cc26
-rw-r--r--gtk2_ardour/editor.h19
-rw-r--r--gtk2_ardour/editor_canvas.cc1
-rw-r--r--gtk2_ardour/editor_mouse.cc275
-rw-r--r--gtk2_ardour/editor_ops.cc124
-rw-r--r--gtk2_ardour/editor_region_list.cc297
-rw-r--r--gtk2_ardour/editor_selection.cc38
-rw-r--r--gtk2_ardour/marker_selection.h1
-rw-r--r--gtk2_ardour/selection.cc34
-rw-r--r--gtk2_ardour/selection.h2
-rw-r--r--gtk2_ardour/time_axis_view.cc6
-rw-r--r--libs/ardour/ardour/automation_control.h4
-rw-r--r--libs/ardour/ardour/location.h19
-rw-r--r--libs/ardour/ardour/region.h1
-rw-r--r--libs/ardour/audioanalyser.cc2
-rw-r--r--libs/ardour/location.cc13
-rw-r--r--libs/ardour/region.cc16
-rw-r--r--libs/ardour/utils.cc1
-rw-r--r--libs/evoral/SConscript2
-rw-r--r--libs/evoral/evoral/ControlList.hpp6
-rw-r--r--libs/evoral/evoral/EventSink.hpp1
-rw-r--r--libs/evoral/evoral/Parameter.hpp4
-rw-r--r--libs/evoral/src/Sequence.cpp3
-rw-r--r--libs/surfaces/generic_midi/SConscript1
-rw-r--r--libs/surfaces/mackie/SConscript1
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc2
-rw-r--r--libs/surfaces/mackie/route_signal.cc2
-rw-r--r--libs/surfaces/powermate/SConscript1
-rw-r--r--libs/surfaces/tranzport/SConscript1
33 files changed, 755 insertions, 185 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 6c59837abc..a9dbc01db1 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -224,7 +224,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
// We do not have jack linked in yet so;
last_shuttle_request = last_peak_grab = 0; // get_microseconds();
-
+
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
@@ -933,15 +933,11 @@ ARDOUR_UI::update_disk_space()
nframes_t frames = session->available_capture_duration();
char buf[64];
-
+ nframes_t fr = session->frame_rate();
+
if (frames == max_frames) {
strcpy (buf, _("Disk: 24hrs+"));
} else {
- int hrs;
- int mins;
- int secs;
- nframes_t fr = session->frame_rate();
-
rec_enabled_streams = 0;
session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
@@ -949,16 +945,29 @@ ARDOUR_UI::update_disk_space()
frames /= rec_enabled_streams;
}
+ int hrs;
+ int mins;
+ int secs;
+
hrs = frames / (fr * 3600);
frames -= hrs * fr * 3600;
mins = frames / (fr * 60);
frames -= mins * fr * 60;
secs = frames / fr;
-
+
snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
}
-
+
disk_space_label.set_text (buf);
+
+ // An attempt to make the disk space label flash red when space has run out.
+
+ if (frames < fr * 60 * 5) {
+ /* disk_space_box.style ("disk_space_label_empty"); */
+ } else {
+ /* disk_space_box.style ("disk_space_label"); */
+ }
+
}
gint
diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc
index 23b9787408..58db7f636b 100644
--- a/gtk2_ardour/audio_clock.cc
+++ b/gtk2_ardour/audio_clock.cc
@@ -1994,6 +1994,7 @@ AudioClock::set_mode (Mode m)
if (!is_transient) {
ModeChanged (); /* EMIT SIGNAL */
+ mode_changed (); /* EMIT SIGNAL */
}
}
diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h
index fe3eef30dc..7c1b6d386b 100644
--- a/gtk2_ardour/audio_clock.h
+++ b/gtk2_ardour/audio_clock.h
@@ -61,11 +61,12 @@ class AudioClock : public Gtk::HBox
void set_session (ARDOUR::Session *s);
sigc::signal<void> ValueChanged;
+ sigc::signal<void> mode_changed;
sigc::signal<void> ChangeAborted;
static sigc::signal<void> ModeChanged;
static std::vector<AudioClock*> clocks;
-
+
static bool has_focus() { return _has_focus; }
private:
diff --git a/gtk2_ardour/draginfo.h b/gtk2_ardour/draginfo.h
index 4b91fa6c1b..6d3a6b8de3 100644
--- a/gtk2_ardour/draginfo.h
+++ b/gtk2_ardour/draginfo.h
@@ -20,6 +20,8 @@
#ifndef __gtk2_ardour_drag_info_h_
#define __gtk2_ardour_drag_info_h_
+#include <list>
+
#include <gdk/gdk.h>
#include <stdint.h>
@@ -64,7 +66,9 @@ struct DragInfo {
bool move_threshold_passed;
bool want_move_threshold;
bool brushing;
- ARDOUR::Location* copied_location;
+ std::list<ARDOUR::Location*> copied_locations;
+
+ void clear_copied_locations ();
};
struct LineDragInfo {
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 170e9b57e2..510b0f8537 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -195,6 +195,15 @@ show_me_the_size (Requisition* r, const char* what)
cerr << "size of " << what << " = " << r->width << " x " << r->height << endl;
}
+void
+DragInfo::clear_copied_locations ()
+{
+ for (list<Location*>::iterator i = copied_locations.begin(); i != copied_locations.end(); ++i) {
+ delete *i;
+ }
+ copied_locations.clear ();
+}
+
Editor::Editor ()
:
/* time display buttons */
@@ -263,7 +272,6 @@ Editor::Editor ()
clicked_control_point = 0;
last_update_frame = 0;
drag_info.item = 0;
- drag_info.copied_location = 0;
current_mixer_strip = 0;
current_bbt_points = 0;
@@ -641,7 +649,12 @@ Editor::Editor ()
region_list_display.set_model (region_list_model);
region_list_display.append_column (_("Regions"), region_list_columns.name);
- region_list_display.set_headers_visible (false);
+ region_list_display.append_column (_("Start"), region_list_columns.start);
+ region_list_display.append_column (_("End"), region_list_columns.end);
+ region_list_display.append_column (_("Length"), region_list_columns.length);
+ region_list_display.append_column (_("Used"), region_list_columns.used);
+ region_list_display.append_column (_("Path to parent file"), region_list_columns.path);
+ region_list_display.set_headers_visible (true);
CellRendererText* region_name_cell = dynamic_cast<CellRendererText*>(region_list_display.get_column_cell_renderer (0));
region_name_cell->property_editable() = true;
@@ -656,7 +669,7 @@ Editor::Editor ()
region_list_display.get_selection()->set_mode (SELECTION_MULTIPLE);
region_list_display.add_object_drag (region_list_columns.region.index(), "regions");
-
+
/* setup DnD handling */
list<TargetEntry> region_list_target_table;
@@ -669,8 +682,8 @@ Editor::Editor ()
region_list_display.signal_drag_data_received().connect (mem_fun(*this, &Editor::region_list_display_drag_data_received));
region_list_scroller.add (region_list_display);
- region_list_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
-
+ region_list_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
+
region_list_display.signal_key_press_event().connect (mem_fun(*this, &Editor::region_list_display_key_press));
region_list_display.signal_key_release_event().connect (mem_fun(*this, &Editor::region_list_display_key_release));
region_list_display.signal_button_press_event().connect (mem_fun(*this, &Editor::region_list_display_button_press), false);
@@ -678,6 +691,9 @@ Editor::Editor ()
region_list_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::region_list_selection_changed));
// region_list_display.signal_popup_menu().connect (bind (mem_fun (*this, &Editor::show_region_list_display_context_menu), 1, 0));
+ ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::redisplay_regions));
+ ARDOUR::Region::RegionPropertyChanged.connect (mem_fun(*this, &Editor::update_region_row));
+
named_selection_scroller.add (named_selection_display);
named_selection_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 32de17a8a1..d2b0043d66 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -128,7 +128,7 @@ class Editor : public PublicEditor
public:
Editor ();
~Editor ();
-
+
void connect_to_session (ARDOUR::Session *);
ARDOUR::Session* current_session() const { return session; }
void first_idle ();
@@ -545,6 +545,8 @@ class Editor : public PublicEditor
void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false);
void select_all_tracks ();
+ int get_regionview_count_from_region_list (boost::shared_ptr<ARDOUR::Region> region);
+
bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false);
void set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false);
void set_selected_track_as_side_effect (bool force = false);
@@ -926,13 +928,23 @@ class Editor : public PublicEditor
struct RegionListDisplayModelColumns : public Gtk::TreeModel::ColumnRecord {
RegionListDisplayModelColumns() {
- add (name);
+ add (name);
add (region);
add (color_);
+ add (start);
+ add (end);
+ add (length);
+ add (used);
+ add (path);
}
- Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<Glib::ustring> name;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Region> > region;
Gtk::TreeModelColumn<Gdk::Color> color_;
+ Gtk::TreeModelColumn<Glib::ustring> start;
+ Gtk::TreeModelColumn<Glib::ustring> end;
+ Gtk::TreeModelColumn<Glib::ustring> length;
+ Gtk::TreeModelColumn<Glib::ustring> used;
+ Gtk::TreeModelColumn<Glib::ustring> path;
};
RegionListDisplayModelColumns region_list_columns;
@@ -1080,6 +1092,7 @@ class Editor : public PublicEditor
void add_regions_to_region_display (std::vector<boost::weak_ptr<ARDOUR::Region> > & );
void region_hidden (boost::shared_ptr<ARDOUR::Region>);
void redisplay_regions ();
+ void update_region_row (boost::shared_ptr<ARDOUR::Region>);
bool no_region_list_redisplay;
void insert_into_tmp_regionlist(boost::shared_ptr<ARDOUR::Region>);
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index b74ece99be..27a6eb479e 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -207,6 +207,7 @@ Editor::initialize_canvas ()
range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, 100, timebar_height);
range_bar_drag_rect->property_outline_pixels() = 0;
+ range_bar_drag_rect->hide ();
transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, 100, timebar_height);
transport_bar_drag_rect->property_outline_pixels() = 0;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index d0931e4579..ed7f46df08 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -1879,11 +1879,7 @@ Editor::finalize_drag ()
drag_info.last_pointer_frame = 0;
drag_info.current_pointer_frame = 0;
drag_info.brushing = false;
-
- if (drag_info.copied_location) {
- delete drag_info.copied_location;
- drag_info.copied_location = 0;
- }
+ drag_info.clear_copied_locations ();
}
void
@@ -1928,7 +1924,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
drag_info.want_move_threshold = false;
drag_info.pointer_frame_offset = 0;
drag_info.brushing = false;
- drag_info.copied_location = 0;
+ drag_info.clear_copied_locations ();
drag_info.original_x = 0;
drag_info.original_y = 0;
@@ -2320,6 +2316,7 @@ Editor::update_marker_drag_item (Location *location)
}
}
+
void
Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
{
@@ -2343,7 +2340,6 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
_dragging_edit_point = true;
- drag_info.copied_location = new Location (*location);
drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end());
update_marker_drag_item (location);
@@ -2369,28 +2365,67 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
selection->toggle (marker);
break;
case Selection::Set:
- selection->set (marker);
+ if (!selection->selected (marker)) {
+ selection->set (marker);
+ }
break;
case Selection::Extend:
- selection->add (marker);
+ {
+ Locations::LocationList ll;
+ list<Marker*> to_add;
+ nframes64_t s, e;
+ selection->markers.range (s, e);
+ s = min (marker->position(), s);
+ e = max (marker->position(), e);
+ s = min (s, e);
+ e = max (s, e);
+ if (e < max_frames) {
+ ++e;
+ }
+ session->locations()->find_all_between (s, e, ll, Location::Flags (0));
+ for (Locations::LocationList::iterator i = ll.begin(); i != ll.end(); ++i) {
+ LocationMarkers* lm = find_location_markers (*i);
+ if (lm) {
+ if (lm->start) {
+ to_add.push_back (lm->start);
+ }
+ if (lm->end) {
+ to_add.push_back (lm->end);
+ }
+ }
+ }
+ if (!to_add.empty()) {
+ selection->add (to_add);
+ }
break;
+ }
case Selection::Add:
selection->add (marker);
break;
}
+
+ /* set up copies for us to manipulate during the drag */
+
+ drag_info.clear_copied_locations ();
+
+ for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
+ Location *l = find_location_from_marker (*i, is_start);
+ drag_info.copied_locations.push_back (new Location (*l));
+ }
}
void
Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
nframes64_t f_delta;
- Marker* marker = (Marker *) drag_info.data;
- Location *real_location;
- Location *copy_location;
+ nframes64_t newframe;
bool is_start;
bool move_both = false;
+ Marker* dragged_marker = (Marker*) drag_info.data;
+ Marker* marker;
+ Location *real_location;
+ Location *copy_location;
- nframes64_t newframe;
if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) {
newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
} else {
@@ -2407,102 +2442,196 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
return;
}
- /* call this to find out if its the start or end */
-
- if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
- return;
+ if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+ move_both = true;
}
- if (real_location->locked()) {
+ MarkerSelection::iterator i;
+ list<Location*>::iterator x;
+
+ /* find the marker we're dragging, and compute the delta */
+
+ for (i = selection->markers.begin(), x = drag_info.copied_locations.begin();
+ x != drag_info.copied_locations.end() && i != selection->markers.end();
+ ++i, ++x) {
+
+ copy_location = *x;
+ marker = *i;
+
+ if (marker == dragged_marker) {
+
+ if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
+ /* que pasa ?? */
+ return;
+ }
+
+ if (real_location->is_mark()) {
+ f_delta = newframe - copy_location->start();
+ } else {
+
+
+ switch (marker->type()) {
+ case Marker::Start:
+ case Marker::LoopStart:
+ case Marker::PunchIn:
+ f_delta = newframe - copy_location->start();
+ break;
+
+ case Marker::End:
+ case Marker::LoopEnd:
+ case Marker::PunchOut:
+ f_delta = newframe - copy_location->end();
+ break;
+ default:
+ /* what kind of marker is this ? */
+ return;
+ }
+ }
+ break;
+ }
+ }
+
+ if (i == selection->markers.end()) {
+ /* hmm, impossible - we didn't find the dragged marker */
return;
}
- /* use the copy that we're "dragging" around */
-
- copy_location = drag_info.copied_location;
+ /* now move them all */
- f_delta = copy_location->end() - copy_location->start();
-
- if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
- move_both = true;
- }
+ for (i = selection->markers.begin(), x = drag_info.copied_locations.begin();
+ x != drag_info.copied_locations.end() && i != selection->markers.end();
+ ++i, ++x) {
- if (copy_location->is_mark()) {
- /* just move it */
+ copy_location = *x;
+ marker = *i;
- copy_location->set_start (newframe);
+ /* call this to find out if its the start or end */
+
+ if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
+ continue;
+ }
+
+ if (real_location->locked()) {
+ continue;
+ }
- } else {
+ if (copy_location->is_mark()) {
- if (is_start) { // start-of-range marker
+ /* just move it */
- if (move_both) {
- copy_location->set_start (newframe);
- copy_location->set_end (newframe + f_delta);
- } else if (newframe < copy_location->end()) {
- copy_location->set_start (newframe);
- } else {
- snap_to (next, 1, true);
- copy_location->set_end (next);
- copy_location->set_start (newframe);
- }
+ copy_location->set_start (copy_location->start() + f_delta);
+
+ } else {
- } else { // end marker
+ nframes64_t new_start = copy_location->start() + f_delta;
+ nframes64_t new_end = copy_location->end() + f_delta;
- if (move_both) {
- copy_location->set_end (newframe);
- copy_location->set_start (newframe - f_delta);
- } else if (newframe > copy_location->start()) {
- copy_location->set_end (newframe);
+ if (is_start) { // start-of-range marker
+
+ if (move_both) {
+ copy_location->set_start (new_start);
+ copy_location->set_end (new_end);
+ } else if (new_start < copy_location->end()) {
+ copy_location->set_start (new_start);
+ } else {
+ snap_to (next, 1, true);
+ copy_location->set_end (next);
+ copy_location->set_start (newframe);
+ }
+
+ } else { // end marker
- } else if (newframe > 0) {
- snap_to (next, -1, true);
- copy_location->set_start (next);
- copy_location->set_end (newframe);
+ if (move_both) {
+ copy_location->set_end (new_end);
+ copy_location->set_start (new_start);
+ } else if (new_end > copy_location->start()) {
+ copy_location->set_end (new_end);
+ } else if (newframe > 0) {
+ snap_to (next, -1, true);
+ copy_location->set_start (next);
+ copy_location->set_end (newframe);
+ }
}
}
+ update_marker_drag_item (copy_location);
+
+ LocationMarkers* lm = find_location_markers (real_location);
+
+ if (lm) {
+ lm->set_position (copy_location->start(), copy_location->end());
+ }
}
drag_info.last_pointer_frame = drag_info.current_pointer_frame;
drag_info.first_move = false;
- update_marker_drag_item (copy_location);
-
- LocationMarkers* lm = find_location_markers (real_location);
- lm->set_position (copy_location->start(), copy_location->end());
- edit_point_clock.set (copy_location->start());
+ if (drag_info.copied_locations.empty()) {
+ abort();
+ }
+ edit_point_clock.set (drag_info.copied_locations.front()->start());
show_verbose_time_cursor (newframe, 10);
+
+#ifdef GTKOSX
+ track_canvas->update_now ();
+#endif
}
void
Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
if (drag_info.first_move) {
- /* just a click, do nothing but whatever selection occured */
+
+ /* just a click, do nothing but finish
+ off the selection process
+ */
+
+ Selection::Operation op = Keyboard::selection_type (event->button.state);
+ Marker* marker = (Marker *) drag_info.data;
+
+ switch (op) {
+ case Selection::Set:
+ if (selection->selected (marker) && selection->markers.size() > 1) {
+ selection->set (marker);
+ }
+ break;
+
+ case Selection::Toggle:
+ case Selection::Extend:
+ case Selection::Add:
+ break;
+ }
+
return;
}
_dragging_edit_point = false;
- Marker* marker = (Marker *) drag_info.data;
- bool is_start;
begin_reversible_command ( _("move marker") );
XMLNode &before = session->locations()->get_state();
-
- Location * location = find_location_from_marker (marker, is_start);
- if (location) {
-
- if (location->locked()) {
- return;
- }
+ MarkerSelection::iterator i;
+ list<Location*>::iterator x;
+ bool is_start;
- if (location->is_mark()) {
- location->set_start (drag_info.copied_location->start());
- } else {
- location->set (drag_info.copied_location->start(), drag_info.copied_location->end());
+ for (i = selection->markers.begin(), x = drag_info.copied_locations.begin();
+ x != drag_info.copied_locations.end() && i != selection->markers.end();
+ ++i, ++x) {
+
+ Location * location = find_location_from_marker ((*i), is_start);
+
+ if (location) {
+
+ if (location->locked()) {
+ return;
+ }
+
+ if (location->is_mark()) {
+ location->set_start ((*x)->start());
+ } else {
+ location->set ((*x)->start(), (*x)->end());
+ }
}
}
@@ -3696,6 +3825,12 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
/* for evaluation of the track position of iy1, we have to adjust
to allow for the vertical scrolling adjustment and the height of the timebars.
*/
+
+ cerr << "adjust y from " << iy1 << " using "
+ << vertical_adjustment.get_value() << " - "
+ << canvas_timebars_vsize
+ << endl;
+
iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize;
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index d52f4da231..df2752bd93 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -426,40 +426,45 @@ Editor::nudge_forward (bool next, bool force_playhead)
} else if (!force_playhead && !selection->markers.empty()) {
bool is_start;
- Location* loc = find_location_from_marker (selection->markers.front(), is_start);
- if (loc) {
-
- begin_reversible_command (_("nudge location forward"));
-
- XMLNode& before (loc->get_state());
-
- if (is_start) {
- distance = get_nudge_distance (loc->start(), next_distance);
- if (next) {
- distance = next_distance;
- }
- if (max_frames - distance > loc->start() + loc->length()) {
- loc->set_start (loc->start() + distance);
- } else {
- loc->set_start (max_frames - loc->length());
- }
- } else {
- distance = get_nudge_distance (loc->end(), next_distance);
- if (next) {
- distance = next_distance;
- }
- if (max_frames - distance > loc->end()) {
- loc->set_end (loc->end() + distance);
+ begin_reversible_command (_("nudge location forward"));
+
+ for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
+
+ Location* loc = find_location_from_marker ((*i), is_start);
+
+ if (loc) {
+
+ XMLNode& before (loc->get_state());
+
+ if (is_start) {
+ distance = get_nudge_distance (loc->start(), next_distance);
+ if (next) {
+ distance = next_distance;
+ }
+ if (max_frames - distance > loc->start() + loc->length()) {
+ loc->set_start (loc->start() + distance);
+ } else {
+ loc->set_start (max_frames - loc->length());
+ }
} else {
- loc->set_end (max_frames);
+ distance = get_nudge_distance (loc->end(), next_distance);
+ if (next) {
+ distance = next_distance;
+ }
+ if (max_frames - distance > loc->end()) {
+ loc->set_end (loc->end() + distance);
+ } else {
+ loc->set_end (max_frames);
+ }
}
+ XMLNode& after (loc->get_state());
+ session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
- XMLNode& after (loc->get_state());
- session->add_command (new MementoCommand<Location>(*loc, &before, &after));
- commit_reversible_command ();
}
+ commit_reversible_command ();
+
} else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
session->request_locate (playhead_cursor->current_frame + distance);
@@ -506,41 +511,48 @@ Editor::nudge_backward (bool next, bool force_playhead)
} else if (!force_playhead && !selection->markers.empty()) {
bool is_start;
- Location* loc = find_location_from_marker (selection->markers.front(), is_start);
-
- if (loc) {
- begin_reversible_command (_("nudge location forward"));
- XMLNode& before (loc->get_state());
+ begin_reversible_command (_("nudge location forward"));
- if (is_start) {
- distance = get_nudge_distance (loc->start(), next_distance);
- if (next) {
- distance = next_distance;
- }
- if (distance < loc->start()) {
- loc->set_start (loc->start() - distance);
- } else {
- loc->set_start (0);
- }
- } else {
- distance = get_nudge_distance (loc->end(), next_distance);
-
- if (next) {
- distance = next_distance;
- }
+ for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
- if (distance < loc->end() - loc->length()) {
- loc->set_end (loc->end() - distance);
+ Location* loc = find_location_from_marker ((*i), is_start);
+
+ if (loc) {
+
+ XMLNode& before (loc->get_state());
+
+ if (is_start) {
+ distance = get_nudge_distance (loc->start(), next_distance);
+ if (next) {
+ distance = next_distance;
+ }
+ if (distance < loc->start()) {
+ loc->set_start (loc->start() - distance);
+ } else {
+ loc->set_start (0);
+ }
} else {
- loc->set_end (loc->length());
+ distance = get_nudge_distance (loc->end(), next_distance);
+
+ if (next) {
+ distance = next_distance;
+ }
+
+ if (distance < loc->end() - loc->length()) {
+ loc->set_end (loc->end() - distance);
+ } else {
+ loc->set_end (loc->length());
+ }
}
+
+ XMLNode& after (loc->get_state());
+ session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
-
- XMLNode& after (loc->get_state());
- session->add_command (new MementoCommand<Location>(*loc, &before, &after));
}
-
+
+ commit_reversible_command ();
+
} else {
distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 121550f86f..c37540e2b1 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -30,6 +30,7 @@
#include <ardour/silentfilesource.h>
#include <ardour/session_region.h>
+
#include <gtkmm2ext/stop_signal.h>
#include "editor.h"
@@ -41,6 +42,7 @@
#include "region_view.h"
#include "utils.h"
+
#include "i18n.h"
using namespace sigc;
@@ -89,10 +91,18 @@ void
Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
{
string str;
+ char start_str[16];
+ char end_str[16];
+ char length_str[16];
+ char used_str[8];
+ int used;
TreeModel::Row row;
Gdk::Color c;
bool missing_source;
+ BBT_Time bbt; // FIXME Why do these have to be declared here ?
+ SMPTE::Time smpte; // FIXME I would like them declared in the case statment where they are used.
+
missing_source = boost::dynamic_pointer_cast<SilentFileSource>(region->source());
if (!show_automatic_regions_in_region_list && region->automatic()) {
@@ -100,12 +110,10 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
}
if (region->hidden()) {
-
TreeModel::iterator iter = region_list_model->get_iter ("0");
TreeModel::Row parent;
TreeModel::Row child;
-
if (!iter) {
parent = *(region_list_model->append());
@@ -113,21 +121,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
parent[region_list_columns.name] = _("Hidden");
boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
proxy.reset ();
-
} else {
-
if ((*iter)[region_list_columns.name] != _("Hidden")) {
-
parent = *(region_list_model->insert(iter));
parent[region_list_columns.name] = _("Hidden");
boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
proxy.reset ();
-
} else {
parent = *iter;
}
-
}
row = *(region_list_model->append (parent.children()));
@@ -149,17 +152,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
row = *(region_list_model->append());
if (missing_source) {
c.set_rgb(65535,0,0); // FIXME: error color from style
+ } else if (region->automatic()){
+ c.set_rgb(0,65535,0); // FIXME: error color from style
} else {
set_color(c, rgba_from_style ("RegionListWholeFile", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
}
row[region_list_columns.color_] = c;
if (region->source()->name()[0] == '/') { // external file
-
if (region->whole_file()) {
-
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(region->source());
-
str = ".../";
if (afs) {
@@ -173,9 +175,7 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
}
} else {
-
str = region->name();
-
}
if (region->n_channels() > 1) {
@@ -186,14 +186,16 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
str += ']';
}
- if (missing_source) {
- str += _(" (MISSING)");
- }
+ //if (missing_source) {
+ // str += _(" (MISSING)");
+ //}
row[region_list_columns.name] = str;
row[region_list_columns.region] = region;
- return;
+ if (region->automatic()) {
+ return;
+ }
} else {
@@ -204,7 +206,6 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
bool found_parent = false;
for (i = rows.begin(); i != rows.end(); ++i) {
-
boost::shared_ptr<Region> rr = (*i)[region_list_columns.region];
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion>(rr);
@@ -228,21 +229,101 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
}
}
}
-
if (!found_parent) {
row = *(region_list_model->append());
- }
-
+ }
+ }
+
+ used = get_regionview_count_from_region_list(region);
+ sprintf (used_str, "%4d" , used);
+
+ switch (ARDOUR_UI::instance()->secondary_clock.mode ()) {
+ case AudioClock::SMPTE:
+ case AudioClock::Off: /* If the secondary clock is off, default to SMPTE */
+ session->smpte_time (region->position(), smpte);
+ sprintf (start_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+
+ session->smpte_time (region->position() + region->length() - 1, smpte);
+ sprintf (end_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+
+ session->smpte_time (region->length(), smpte);
+ sprintf (length_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+ break;
+
+ case AudioClock::BBT:
+ session->tempo_map().bbt_time (region->position(), bbt);
+ sprintf (start_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+ session->tempo_map().bbt_time (region->position() + region->length() - 1, bbt);
+ sprintf (end_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+ session->tempo_map().bbt_time (region->length(), bbt);
+ sprintf (length_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+ break;
+
+ case AudioClock::MinSec:
+ nframes_t left;
+ int hrs;
+ int mins;
+ float secs;
+
+ left = region->position();
+ hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+ left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+ mins = (int) floor (left / (session->frame_rate() * 60.0f));
+ left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
+ secs = left / (float) session->frame_rate();
+ sprintf (start_str, "%02d:%02d:%06.3f", hrs, mins, secs);
+
+ left = region->position() + region->length() - 1;
+ hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+ left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+ mins = (int) floor (left / (session->frame_rate() * 60.0f));
+ left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
+ secs = left / (float) session->frame_rate();
+ sprintf (end_str, "%02d:%02d:%06.3f", hrs, mins, secs);
+
+ left = region->length();
+ hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+ left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+ mins = (int) floor (left / (session->frame_rate() * 60.0f));
+ left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
+ secs = left / (float) session->frame_rate();
+ sprintf (length_str, "%02d:%02d:%06.3f", hrs, mins, secs);
+ break;
+ case AudioClock::Frames:
+ snprintf (start_str, sizeof (start_str), "%u", region->position());
+ snprintf (end_str, sizeof (end_str), "%u", (region->position() + region->length() - 1));
+ snprintf (length_str, sizeof (length_str), "%u", region->length());
+ break;
+
+ default:
+ break;
}
row[region_list_columns.region] = region;
+ if (used > 1) {
+ row[region_list_columns.start] = "Multiple";
+ row[region_list_columns.end] = "Multiple";
+ } else {
+ row[region_list_columns.start] = start_str;
+ row[region_list_columns.end] = end_str;
+ }
+
+ row[region_list_columns.length] = length_str;
+ row[region_list_columns.used] = used_str;
+
+ if (missing_source) {
+ row[region_list_columns.path] = _("(MISSING) ") + region->source()->name();
+ } else {
+ row[region_list_columns.path] = region->source()->name();
+ }
+
if (region->n_channels() > 1) {
row[region_list_columns.name] = string_compose("%1 [%2]", region->name(), region->n_channels());
} else {
row[region_list_columns.name] = region->name();
- }
+ }
}
@@ -356,6 +437,180 @@ Editor::redisplay_regions ()
}
}
+
+void
+Editor::update_region_row (boost::shared_ptr<Region> region)
+{
+ if (!region || !session) {
+ return;
+ }
+
+ char start_str[16];
+ char end_str[16];
+ char length_str[16];
+ char used_str[8];
+ int used;
+ bool missing_source;
+ bool matched_region = false;
+ BBT_Time bbt;
+ SMPTE::Time smpte;
+
+ missing_source = boost::dynamic_pointer_cast<SilentFileSource>(region->source());
+
+ TreeModel::iterator found_region;
+
+ if (show_automatic_regions_in_region_list) {
+
+ TreeModel::iterator i;
+ TreeModel::iterator ii;
+ TreeModel::Children rows = region_list_model->children();
+
+ for (i = rows.begin(); i != rows.end(); ++i) {
+
+ cerr << "Parent " << (*i)[region_list_columns.name] << "\n";
+
+ TreeModel::Children subrows = (*i).children();
+
+ for (ii = subrows.begin(); ii != subrows.end(); ++ii) {
+
+ cerr << "Compare " << region->name() << " with child " << (*ii)[region_list_columns.name] << "\n";
+
+ boost::shared_ptr<Region> compared_region = (*ii)[region_list_columns.region];
+
+ if (region == compared_region) {
+ cerr << "Matched\n";
+ matched_region = true;
+ found_region = ii;
+ break;
+ }
+ }
+
+ if (matched_region) {
+ break;
+ }
+ }
+
+ } else {
+
+ TreeModel::iterator i;
+ TreeModel::Children rows = region_list_model->children();
+
+ for (i = rows.begin(); i != rows.end(); ++i) {
+
+ cerr << "Compare " << region->name() << " with " << (*i)[region_list_columns.name] << "\n";
+
+ boost::shared_ptr<Region> compared_region = (*i)[region_list_columns.region];
+
+ if (region == compared_region) {
+ cerr << "Matched\n";
+ matched_region = true;
+ found_region = i;
+ break;
+ }
+
+ }
+ }
+
+ if (!matched_region) {
+ cerr << "Returning - No match\n\n";
+ return;
+ }
+
+ used = get_regionview_count_from_region_list(region);
+ sprintf (used_str, "%4d" , used);
+
+ switch (ARDOUR_UI::instance()->secondary_clock.mode ()) {
+ case AudioClock::SMPTE:
+ case AudioClock::Off: // If the secondary clock is off, default to SMPTE
+ session->smpte_time (region->position(), smpte);
+ sprintf (start_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+
+ session->smpte_time (region->position() + region->length() - 1, smpte);
+ sprintf (end_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+
+ session->smpte_time (region->length(), smpte);
+ sprintf (length_str, "%02d:%02d:%02d:%02d", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+ break;
+
+ case AudioClock::BBT:
+ session->tempo_map().bbt_time (region->position(), bbt);
+ sprintf (start_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+ session->tempo_map().bbt_time (region->position() + region->length() - 1, bbt);
+ sprintf (end_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+ session->tempo_map().bbt_time (region->length(), bbt);
+ sprintf (length_str, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+ break;
+
+ case AudioClock::MinSec:
+ nframes_t left;
+ int hrs;
+ int mins;
+ float secs;
+
+ left = region->position();
+ hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+ left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+ mins = (int) floor (left / (session->frame_rate() * 60.0f));
+ left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
+ secs = left / (float) session->frame_rate();
+ sprintf (start_str, "%02d:%02d:%06.3f", hrs, mins, secs);
+
+ left = region->position() + region->length() - 1;
+ hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+ left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+ mins = (int) floor (left / (session->frame_rate() * 60.0f));
+ left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
+ secs = left / (float) session->frame_rate();
+ sprintf (end_str, "%02d:%02d:%06.3f", hrs, mins, secs);
+
+ left = region->length();
+ hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+ left -= (nframes_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+ mins = (int) floor (left / (session->frame_rate() * 60.0f));
+ left -= (nframes_t) floor (mins * session->frame_rate() * 60.0f);
+ secs = left / (float) session->frame_rate();
+ sprintf (length_str, "%02d:%02d:%06.3f", hrs, mins, secs);
+ break;
+
+ case AudioClock::Frames:
+ snprintf (start_str, sizeof (start_str), "%u", region->position());
+ snprintf (end_str, sizeof (end_str), "%u", (region->position() + region->length() - 1));
+ snprintf (length_str, sizeof (length_str), "%u", region->length());
+ break;
+
+ default:
+ break;
+ }
+
+ cerr << "Updating " << (*found_region)[region_list_columns.name] << "\n";
+
+ if (used > 1) {
+ (*found_region)[region_list_columns.start] = "Multiple";
+ (*found_region)[region_list_columns.end] = "Multiple";
+ } else {
+ (*found_region)[region_list_columns.start] = start_str;
+ (*found_region)[region_list_columns.end] = end_str;
+ }
+
+ (*found_region)[region_list_columns.length] = length_str;
+ (*found_region)[region_list_columns.used] = used_str;
+
+ if (missing_source) {
+ (*found_region)[region_list_columns.path] = _("(MISSING) ") + region->source()->name();
+ } else {
+ (*found_region)[region_list_columns.path] = region->source()->name();
+ }
+
+ if (region->n_channels() > 1) {
+ (*found_region)[region_list_columns.name] = string_compose("%1 [%2]", region->name(), region->n_channels());
+ } else {
+ (*found_region)[region_list_columns.name] = region->name();
+ }
+
+ cerr << "Returning after updating\n\n";
+ //return;
+}
+
void
Editor::build_region_list_menu ()
{
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index f35391cff5..e1c6f4e7ea 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -362,6 +362,44 @@ Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivale
equivalent_regions.push_back (basis);
}
+int
+Editor::get_regionview_count_from_region_list (boost::shared_ptr<Region> region)
+{
+ int region_count = 0;
+
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+
+ RouteTimeAxisView* tatv;
+
+ if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
+
+ boost::shared_ptr<Playlist> pl;
+ vector<boost::shared_ptr<Region> > results;
+ RegionView* marv;
+ boost::shared_ptr<Diskstream> ds;
+
+ if ((ds = tatv->get_diskstream()) == 0) {
+ /* bus */
+ continue;
+ }
+
+ if ((pl = (ds->playlist())) != 0) {
+ pl->get_region_list_equivalent_regions (region, results);
+ }
+
+ for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
+ if ((marv = tatv->view()->find_view (*ir)) != 0) {
+ region_count++;
+ }
+ }
+
+ }
+ }
+
+ return region_count;
+}
+
+
bool
Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
{
diff --git a/gtk2_ardour/marker_selection.h b/gtk2_ardour/marker_selection.h
index aa1413ed3e..ae6417f6c6 100644
--- a/gtk2_ardour/marker_selection.h
+++ b/gtk2_ardour/marker_selection.h
@@ -26,6 +26,7 @@
struct MarkerSelection : public std::list<Marker*>
{
+ void range (nframes64_t& start, nframes64_t& end);
};
#endif /* __ardour_gtk_marker_selection_h__ */
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index 2f9601fcec..3f6c282d3a 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -609,6 +609,12 @@ Selection::set (boost::shared_ptr<Evoral::ControlList> ac)
}
bool
+Selection::selected (Marker* m)
+{
+ return find (markers.begin(), markers.end(), m) != markers.end();
+}
+
+bool
Selection::selected (TimeAxisView* tv)
{
return find (tracks.begin(), tracks.end(), tv) != tracks.end();
@@ -801,3 +807,31 @@ Selection::add (Marker* m)
MarkersChanged();
}
}
+
+void
+Selection::add (const list<Marker*>& m)
+{
+ markers.insert (markers.end(), m.begin(), m.end());
+ MarkersChanged ();
+}
+
+void
+MarkerSelection::range (nframes64_t& s, nframes64_t& e)
+{
+ s = max_frames;
+ e = 0;
+
+ for (MarkerSelection::iterator i = begin(); i != end(); ++i) {
+
+ if ((*i)->position() < s) {
+ s = (*i)->position();
+ }
+
+ if ((*i)->position() > e) {
+ e = (*i)->position();
+ }
+ }
+
+ s = std::min (s, e);
+ e = std::max (s, e);
+}
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index c6923e663c..1e2257fc15 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -99,6 +99,7 @@ class Selection : public sigc::trackable
bool selected (TimeAxisView*);
bool selected (RegionView*);
+ bool selected (Marker*);
void set (std::list<Selectable*>&);
void add (std::list<Selectable*>&);
@@ -136,6 +137,7 @@ class Selection : public sigc::trackable
void add (boost::shared_ptr<ARDOUR::Playlist>);
void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (Marker*);
+ void add (const std::list<Marker*>&);
void add (const RegionSelection&);
void remove (TimeAxisView*);
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index f31ee1a10c..1f6d1f9da6 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -1181,10 +1181,14 @@ TimeAxisView::color_handler ()
TimeAxisView*
TimeAxisView::covers_y_position (double y)
{
+ if (y_position < 0) {
+ abort ();
+ }
+
if (hidden()) {
return 0;
}
-
+
cerr << name() << " check for " << y << " within " << y_position << " and + " << height << endl;
if (y_position <= y && y < (y_position + height)) {
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h
index 24d1db3eec..78f4553d87 100644
--- a/libs/ardour/ardour/automation_control.h
+++ b/libs/ardour/ardour/automation_control.h
@@ -43,7 +43,7 @@ public:
boost::shared_ptr<ARDOUR::AutomationList>,
std::string name="unnamed controllable");
- boost::shared_ptr<AutomationList> alist() { return boost::dynamic_pointer_cast<AutomationList>(_list); }
+ boost::shared_ptr<AutomationList> alist() const { return boost::dynamic_pointer_cast<AutomationList>(_list); }
void set_list(boost::shared_ptr<Evoral::ControlList>);
@@ -55,7 +55,7 @@ public:
return ((ARDOUR::AutomationList*)_list.get())->automation_write();
}
- inline AutoState automation_state() {
+ inline AutoState automation_state() const {
return ((ARDOUR::AutomationList*)_list.get())->automation_state();
}
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index 53d9489823..d5b672a89d 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -100,14 +100,15 @@ class Location : public PBD::StatefulDestructible
void set_is_end (bool yn, void* src);
void set_is_start (bool yn, void* src);
- bool is_auto_punch () { return _flags & IsAutoPunch; }
- bool is_auto_loop () { return _flags & IsAutoLoop; }
- bool is_mark () { return _flags & IsMark; }
- bool is_hidden () { return _flags & IsHidden; }
- bool is_cd_marker () { return _flags & IsCDMarker; }
- bool is_end() { return _flags & IsEnd; }
- bool is_start() { return _flags & IsStart; }
- bool is_range_marker() { return _flags & IsRangeMarker; }
+ bool is_auto_punch () const { return _flags & IsAutoPunch; }
+ bool is_auto_loop () const { return _flags & IsAutoLoop; }
+ bool is_mark () const { return _flags & IsMark; }
+ bool is_hidden () const { return _flags & IsHidden; }
+ bool is_cd_marker () const { return _flags & IsCDMarker; }
+ bool is_end() const { return _flags & IsEnd; }
+ bool is_start() const { return _flags & IsStart; }
+ bool is_range_marker() const { return _flags & IsRangeMarker; }
+ bool matches (Flags f) const { return _flags & f; }
sigc::signal<void,Location*> name_changed;
sigc::signal<void,Location*> end_changed;
@@ -175,6 +176,8 @@ class Locations : public PBD::StatefulDestructible
nframes_t first_mark_before (nframes_t, bool include_special_ranges = false);
nframes_t first_mark_after (nframes_t, bool include_special_ranges = false);
+ void find_all_between (nframes64_t start, nframes64_t, LocationList&, Location::Flags);
+
sigc::signal<void,Location*> current_changed;
sigc::signal<void> changed;
sigc::signal<void,Location*> added;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 32f47d42d7..dc81de6374 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -90,6 +90,7 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region>
static Change HiddenChanged;
sigc::signal<void,Change> StateChanged;
+ static sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > RegionPropertyChanged;
virtual ~Region();
diff --git a/libs/ardour/audioanalyser.cc b/libs/ardour/audioanalyser.cc
index 98c4206301..ab3691d8d1 100644
--- a/libs/ardour/audioanalyser.cc
+++ b/libs/ardour/audioanalyser.cc
@@ -10,6 +10,8 @@
#include <ardour/readable.h>
#include <ardour/readable.h>
+#include <cstring>
+
#include "i18n.h"
using namespace std;
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index 3654e03a9d..8dd4bbc636 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -924,3 +924,16 @@ Locations::get_location_by_id(PBD::ID id)
return 0;
}
+
+void
+Locations::find_all_between (nframes64_t start, nframes64_t end, LocationList& ll, Location::Flags flags)
+{
+ Glib::Mutex::Lock lm (lock);
+
+ for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
+ if ((flags == 0 || (*i)->matches (flags)) &&
+ ((*i)->start() >= start && (*i)->end() < end)) {
+ ll.push_back (*i);
+ }
+ }
+}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 42564a8b5e..25435024b3 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -53,6 +53,7 @@ Change Region::LockChanged = ARDOUR::new_change ();
Change Region::LayerChanged = ARDOUR::new_change ();
Change Region::HiddenChanged = ARDOUR::new_change ();
+sigc::signal<void,boost::shared_ptr<ARDOUR::Region> > Region::RegionPropertyChanged;
/* derived-from-derived constructor (no sources in constructor) */
Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
@@ -1350,6 +1351,21 @@ Region::send_change (Change what_changed)
}
StateChanged (what_changed);
+
+ if (!(_flags & DoNotSaveState)) {
+
+ /* Try and send a shared_pointer unless this is part of the constructor.
+ If so, do nothing.
+ */
+
+ try {
+ boost::shared_ptr<Region> rptr = shared_from_this();
+ RegionPropertyChanged (rptr);
+ } catch (...) {
+ /* no shared_ptr available, relax; */
+ }
+ }
+
}
void
diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc
index 1906d92b88..c598a3d279 100644
--- a/libs/ardour/utils.cc
+++ b/libs/ardour/utils.cc
@@ -24,7 +24,6 @@
#include <cstring>
#include <cmath>
#include <cctype>
-#include <string>
#include <cstring>
#include <cerrno>
#include <iostream>
diff --git a/libs/evoral/SConscript b/libs/evoral/SConscript
index fcc29c9b56..6141f10e4f 100644
--- a/libs/evoral/SConscript
+++ b/libs/evoral/SConscript
@@ -8,6 +8,8 @@ Import('env libraries install_prefix')
evoral = env.Clone()
evoral.Merge([
+ libraries['glib2'],
+ libraries['sigc2'],
libraries['glibmm2'],
libraries['xml'],
libraries['pbd'],
diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp
index 45519955c5..bc994d90c8 100644
--- a/libs/evoral/evoral/ControlList.hpp
+++ b/libs/evoral/evoral/ControlList.hpp
@@ -47,9 +47,9 @@ struct ControlEvent {
}
}
- ~ControlEvent() { if (coeff) delete[] coeff; }
+ ~ControlEvent() { if (coeff) delete[] coeff; }
- void create_coeffs() {
+ void create_coeffs() {
if (!coeff)
coeff = new double[4];
@@ -85,7 +85,7 @@ public:
ControlList (const Parameter& id);
//ControlList (const XMLNode&, Parameter id);
- ~ControlList();
+ virtual ~ControlList();
virtual boost::shared_ptr<ControlList> create(Parameter id);
diff --git a/libs/evoral/evoral/EventSink.hpp b/libs/evoral/evoral/EventSink.hpp
index fde6399f2e..67b33d6965 100644
--- a/libs/evoral/evoral/EventSink.hpp
+++ b/libs/evoral/evoral/EventSink.hpp
@@ -28,6 +28,7 @@ namespace Evoral {
*/
class EventSink {
public:
+ virtual ~EventSink() {}
virtual size_t write(timestamp_t time,
uint32_t size,
const uint8_t* buf) = 0;
diff --git a/libs/evoral/evoral/Parameter.hpp b/libs/evoral/evoral/Parameter.hpp
index 301a432bd0..a88483aec4 100644
--- a/libs/evoral/evoral/Parameter.hpp
+++ b/libs/evoral/evoral/Parameter.hpp
@@ -43,7 +43,7 @@ public:
Parameter(uint32_t type, uint8_t channel, uint32_t id=0)
: _type(type), _id(id), _channel(channel)
{}
-
+
Parameter(const std::string& str) {
int channel;
if (sscanf(str.c_str(), "%d_c%d_n%d", &_type, &channel, &_id) == 3) {
@@ -56,6 +56,8 @@ public:
std::cerr << "WARNING: Unable to create parameter from string: " << str << std::endl;
}
+ virtual ~Parameter() {}
+
inline uint32_t type() const { return _type; }
inline uint32_t id() const { return _id; }
inline uint8_t channel() const { return _channel; }
diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp
index 4880b5a04d..fecc37be29 100644
--- a/libs/evoral/src/Sequence.cpp
+++ b/libs/evoral/src/Sequence.cpp
@@ -19,6 +19,7 @@
#define __STDC_LIMIT_MACROS 1
#include <iostream>
+#include <cmath>
#include <algorithm>
#include <stdexcept>
#include <stdint.h>
@@ -313,7 +314,7 @@ size_t Sequence::read(EventSink& dst, timestamp_t start, timestamp_t nframes, ti
//cerr << "Using cached iterator at " << _next_read << endl;
}
- _next_read = start + nframes;
+ _next_read = (nframes_t) floor (start + nframes);
while (_read_iter != end() && _read_iter->time() < start + nframes) {
assert(_read_iter->size() > 0);
diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript
index e3e62e7402..d4c9e92214 100644
--- a/libs/surfaces/generic_midi/SConscript
+++ b/libs/surfaces/generic_midi/SConscript
@@ -33,6 +33,7 @@ genericmidi.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
genericmidi.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
genericmidi.Merge ([
+ libraries['evoral'],
libraries['ardour'],
libraries['ardour_cp'],
libraries['sndfile'],
diff --git a/libs/surfaces/mackie/SConscript b/libs/surfaces/mackie/SConscript
index 143ebc9856..c19d145c73 100644
--- a/libs/surfaces/mackie/SConscript
+++ b/libs/surfaces/mackie/SConscript
@@ -47,6 +47,7 @@ mackie.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
mackie.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
mackie.Merge ([
+ libraries['evoral'],
libraries['ardour'],
libraries['ardour_cp'],
libraries['sigc2'],
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 5ef28d4549..4558dc641c 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -1019,7 +1019,7 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal )
// TODO handle plugin automation polling
void MackieControlProtocol::update_automation( RouteSignal & rs )
{
- ARDOUR::AutoState gain_state = rs.route().gain_control()->list()->automation_state();
+ ARDOUR::AutoState gain_state = rs.route().gain_control()->alist()->automation_state();
if ( gain_state == Touch || gain_state == Play )
{
notify_gain_changed( &rs );
diff --git a/libs/surfaces/mackie/route_signal.cc b/libs/surfaces/mackie/route_signal.cc
index b01b5e0cf5..adaeadd805 100644
--- a/libs/surfaces/mackie/route_signal.cc
+++ b/libs/surfaces/mackie/route_signal.cc
@@ -37,7 +37,7 @@ void RouteSignal::connect()
_mute_changed_connection = _route.mute_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_mute_changed ), this ) );
if ( _strip.has_gain() )
- _gain_changed_connection = _route.control(ARDOUR::GainAutomation)->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this ) );
+ _gain_changed_connection = _route.gain_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this ) );
_name_changed_connection = _route.NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );
diff --git a/libs/surfaces/powermate/SConscript b/libs/surfaces/powermate/SConscript
index c1a79fe955..3e01e2042b 100644
--- a/libs/surfaces/powermate/SConscript
+++ b/libs/surfaces/powermate/SConscript
@@ -31,6 +31,7 @@ powermate.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"")
powermate.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
powermate.Merge ([
+ libraries['evoral'],
libraries['ardour'],
libraries['ardour_cp'],
libraries['sigc2'],
diff --git a/libs/surfaces/tranzport/SConscript b/libs/surfaces/tranzport/SConscript
index ff48eb64e3..31630fb2e0 100644
--- a/libs/surfaces/tranzport/SConscript
+++ b/libs/surfaces/tranzport/SConscript
@@ -55,6 +55,7 @@ tranzport.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
tranzport.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
tranzport.Merge ([
+ libraries['evoral'],
libraries['ardour'],
libraries['ardour_cp'],
libraries['sigc2'],