chris goddard's region list patch; port 2.X marker drag/move changes to 3.0; compilat...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 19 Sep 2008 14:38:46 +0000 (14:38 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 19 Sep 2008 14:38:46 +0000 (14:38 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@3760 d708f5d6-7413-0410-9779-e7cbd77b26cf

33 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/audio_clock.h
gtk2_ardour/draginfo.h
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_selection.cc
gtk2_ardour/marker_selection.h
gtk2_ardour/selection.cc
gtk2_ardour/selection.h
gtk2_ardour/time_axis_view.cc
libs/ardour/ardour/automation_control.h
libs/ardour/ardour/location.h
libs/ardour/ardour/region.h
libs/ardour/audioanalyser.cc
libs/ardour/location.cc
libs/ardour/region.cc
libs/ardour/utils.cc
libs/evoral/SConscript
libs/evoral/evoral/ControlList.hpp
libs/evoral/evoral/EventSink.hpp
libs/evoral/evoral/Parameter.hpp
libs/evoral/src/Sequence.cpp
libs/surfaces/generic_midi/SConscript
libs/surfaces/mackie/SConscript
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/route_signal.cc
libs/surfaces/powermate/SConscript
libs/surfaces/tranzport/SConscript

index 6c59837abc4e49e85b61c9874c8c24b190d3d5b0..a9dbc01db131cf9cec30b31aa9d98b4cbf8cd6a0 100644 (file)
@@ -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
index 23b9787408c9ea658db0556fe7d92b513461fae9..58db7f636b4d292804c07acd8b8aa7485e995ef0 100644 (file)
@@ -1994,6 +1994,7 @@ AudioClock::set_mode (Mode m)
 
        if (!is_transient) {
                ModeChanged (); /* EMIT SIGNAL */
+               mode_changed (); /* EMIT SIGNAL */
        }
 }
 
index fe3eef30dc524cc8663ffc0dfefadd4e3af759a3..7c1b6d386bcab422cd34740dc0ca8ede19c93c35 100644 (file)
@@ -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:
index 4b91fa6c1b9b35c77467fa86bbea188abda5e41d..6d3a6b8de3714d78ba7a9a6a1bac62dc974cdfe0 100644 (file)
@@ -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 {
index 170e9b57e2073bb1d5a717e6d8a796bf20b6e7ab..510b0f8537dc7f26a6880d0fd23eba955e9c9dfa 100644 (file)
@@ -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);
 
index 32de17a8a11bba32b5261b1546b9e20ce2da113c..d2b0043d6684b415e01ad796b5b8bd9de4fb1178 100644 (file)
@@ -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>);
 
index b74ece99be09819f83bd2b9b9672a2b7d30a0623..27a6eb479e7834048f077bcfcdc8352b589db2cf 100644 (file)
@@ -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;
index d0931e4579bdbf416eb5350fcbf09e1d76541ed4..ed7f46df082a80311c4eb99c54d18f1bb87d4f7e 100644 (file)
@@ -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);
index d52f4da231a54918dd7899b39c87d8d128fb0486..df2752bd939e91fb45deed4e2a539e423c37a40c 100644 (file)
@@ -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);
index 121550f86f55bd74cf53d718c216e169bdae897e..c37540e2b1416b7a381dd968510700cfe6f20b37 100644 (file)
@@ -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 ()
 {
index f35391cff5dd8b4d0738c685c267bcca2a3a1852..e1c6f4e7ea9b15e959a73a7793af23f79df97df6 100644 (file)
@@ -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)
 {
index aa1413ed3e48d00240e21edcbffbbf9b0ef2b424..ae6417f6c6d9e723daae56a150a72f81e3a25e57 100644 (file)
@@ -26,6 +26,7 @@
 
 struct MarkerSelection : public std::list<Marker*> 
 {
+    void range (nframes64_t& start, nframes64_t& end);
 };
 
 #endif /* __ardour_gtk_marker_selection_h__ */
index 2f9601fceca5355373c420acfa97f6f6ba3eb0ff..3f6c282d3afbfd6f018fc7e721e670baa7af200c 100644 (file)
@@ -608,6 +608,12 @@ Selection::set (boost::shared_ptr<Evoral::ControlList> ac)
        add (ac);
 }
 
+bool
+Selection::selected (Marker* m)
+{
+       return find (markers.begin(), markers.end(), m) != markers.end();
+}
+
 bool
 Selection::selected (TimeAxisView* tv)
 {
@@ -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);
+}
index c6923e663c6add8d22a39e2bbcb636267894830f..1e2257fc15fc934df2bbde8af2aac410e471a33e 100644 (file)
@@ -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*);
index f31ee1a10cb8c2016937029de76b175bd8496aa3..1f6d1f9da667cfbf6e8d13e5bc8692722fe73b5e 100644 (file)
@@ -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)) {
index 24d1db3eec5840232877682a287027839e969af3..78f4553d873deb764318913733ac60b42e5b2477 100644 (file)
@@ -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();
        }
        
index 53d9489823184ae8f645d341808f7b7ec0be9de0..d5b672a89d00fe95b9e6bea75032eb1ea0e36faa 100644 (file)
@@ -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;
index 32f47d42d7c39eeae36585291aac1729a84a223b..dc81de6374884b08580200347d6a22b13eb1bb94 100644 (file)
@@ -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();
 
index 98c42063015b842d55b0cd741ec45247eac21c41..ab3691d8d15b98f9bc6a60993859677332e3068a 100644 (file)
@@ -10,6 +10,8 @@
 #include <ardour/readable.h>
 #include <ardour/readable.h>
 
+#include <cstring>
+
 #include "i18n.h"
 
 using namespace std;
index 3654e03a9dcd7ab8081b272390c412e1fe8d7483..8dd4bbc636d129bd6f019719f296cf3abea37c77 100644 (file)
@@ -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);
+               }
+       }
+}
index 42564a8b5e9981d26201aa48dcdf42c4ea6b5c5d..25435024b331cb5aa5c368a0c25301db9e64437f 100644 (file)
@@ -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
index 1906d92b887dfe3f5c9f52e10927f43baa121300..c598a3d27965c060bfad00d9e5f2ff8c710a12ab 100644 (file)
@@ -24,7 +24,6 @@
 #include <cstring>
 #include <cmath>
 #include <cctype>
-#include <string>
 #include <cstring>
 #include <cerrno>
 #include <iostream>
index fcc29c9b56188484b682e2cf08a43745a32f3112..6141f10e4f084a434c6d111746a316e8e281adb3 100644 (file)
@@ -8,6 +8,8 @@ Import('env libraries install_prefix')
 
 evoral = env.Clone()
 evoral.Merge([
+       libraries['glib2'],
+       libraries['sigc2'],
        libraries['glibmm2'],
        libraries['xml'], 
        libraries['pbd'],       
index 45519955c5ecef60443b48fcc79b2727728a4e1b..bc994d90c857ca75da9995f69a9d6fd9b333aae8 100644 (file)
@@ -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);
 
index fde6399f2e1c5664e535fd3ab19ed844122b5295..67b33d69653f0748d7b7504b889b3efd4e5f1579 100644 (file)
@@ -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;
index 301a432bd0109726760ba6dfd03f90ea50eb59b5..a88483aec48aa2ac1679646b5707919712f00e97 100644 (file)
@@ -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; }
index 4880b5a04dcd0c5b7d741fa26ce753058637f874..fecc37be29d2e56fabc306eb963f527e7103f4e0 100644 (file)
@@ -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);
index e3e62e74026900dc5fa2d72f85631b183a806554..d4c9e92214adb1b8f6cb486ea204bd98e50ce0e5 100644 (file)
@@ -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'],
index 143ebc985659c92077296679fc4744049b761666..c19d145c73e4804d9a91129f7854adeee6ddf977 100644 (file)
@@ -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'],
index 5ef28d4549b6e7685dcee77c58ad96d901bb9fd0..4558dc641ceba183ce22548ffc4d28b7cfd84b5d 100644 (file)
@@ -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 );
index b01b5e0cf5f99ce59cae0a9464573291b5a641b6..adaeadd805661974fb6b66f4ceb508eb6fd30a3e 100644 (file)
@@ -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 ) );
        
index c1a79fe955f19d752a86c23df1c4e403711df028..3e01e2042b20d9d811eb4f12a474010b11e551c6 100644 (file)
@@ -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'],
index ff48eb64e3dbb0e3dce0d529fba279eb421616d1..31630fb2e01d81b1e3794a83a20f3a79000b2558 100644 (file)
@@ -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'],