correct check for presence of / or \ in a session name
[ardour.git] / gtk2_ardour / route_time_axis.cc
index 1a85ef0307faa310535b10a78adab7cb5805f9cc..63abdc2516d647dbf42ea4da4ca333d9b5cca1b4 100644 (file)
@@ -396,13 +396,9 @@ RouteTimeAxisView::playlist_click ()
 void
 RouteTimeAxisView::automation_click ()
 {
-       if (automation_action_menu == 0) {
-               /* this seems odd, but the automation action
-                  menu is built as part of the display menu.
-               */
-               build_display_menu ();
-       }
        conditionally_add_to_selection ();
+       if (!automation_action_menu)
+               build_automation_action_menu ();
        automation_action_menu->popup (1, gtk_get_current_event_time());
 }
 
@@ -453,6 +449,7 @@ RouteTimeAxisView::build_display_menu ()
        if (!Profile->get_sae()) {
                build_remote_control_menu ();
                items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu));
+               /* rebuild this every time */
                build_automation_action_menu ();
                items.push_back (MenuElem (_("Automation"), *automation_action_menu));
                items.push_back (SeparatorElem());
@@ -1357,6 +1354,12 @@ RouteTimeAxisView::get_child_list()
 }
 
 
+struct PlaylistSorter {
+    bool operator() (boost::shared_ptr<Playlist> a, boost::shared_ptr<Playlist> b) const {
+        return a->sort_id() < b->sort_id();
+    }
+};
+
 void
 RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
 {
@@ -1370,33 +1373,32 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
        menu->set_name ("ArdourContextMenu");
        playlist_items.clear();
 
-       if (playlist_menu) {
-               delete playlist_menu;
-       }
-
-       playlist_menu = new Menu;
-       playlist_menu->set_name ("ArdourContextMenu");
-
-       vector<boost::shared_ptr<Playlist> > playlists;
+       vector<boost::shared_ptr<Playlist> > playlists, playlists_ds;
        boost::shared_ptr<Diskstream> ds = get_diskstream();
        RadioMenuItem::Group playlist_group;
-
-       _session.get_playlists (playlists);
        
-       for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+       _session.get_playlists (playlists);
 
-               if ((*i)->get_orig_diskstream_id() == ds->id()) {
-                       playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist),
-                                                                                                    boost::weak_ptr<Playlist> (*i))));
+    /* find the playlists for this diskstream */
+       for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               if (((*i)->get_orig_diskstream_id() == ds->id()) || (ds->playlist()->id() == (*i)->id())) {
+            playlists_ds.push_back(*i);
+       }
+       }
+       
+       /* sort the playlists */
+       PlaylistSorter cmp;
+       sort(playlists_ds.begin(), playlists_ds.end(), cmp);
+       
+       /* add the playlists to the menu */
+       for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists_ds.begin(); i != playlists_ds.end(); ++i) {
+               playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name()));
+               RadioMenuItem *item = static_cast<RadioMenuItem*>(&playlist_items.back());
 
-                       if (ds->playlist()->id() == (*i)->id()) {
-                               static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
-                       }
-               } else if (ds->playlist()->id() == (*i)->id()) {
-                       playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), 
-                                                                                                    boost::weak_ptr<Playlist>(*i))));
-                       static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
-                       
+               item->signal_toggled().connect(bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), item, boost::weak_ptr<Playlist> (*i)));
+               
+               if (ds->playlist()->id() == (*i)->id()) {
+                       item->set_active();
                }
        }
 
@@ -1407,26 +1409,28 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
        if (!edit_group() || !edit_group()->is_active()) {
                playlist_items.push_back (MenuElem (_("New"), bind(mem_fun(editor, &PublicEditor::new_playlists), this)));
                playlist_items.push_back (MenuElem (_("New Copy"), bind(mem_fun(editor, &PublicEditor::copy_playlists), this)));
-
        } else {
                // Use a label which tells the user what is happening
                playlist_items.push_back (MenuElem (_("New Take"), bind(mem_fun(editor, &PublicEditor::new_playlists), this)));
                playlist_items.push_back (MenuElem (_("Copy Take"), bind(mem_fun(editor, &PublicEditor::copy_playlists), this)));
-               
        }
 
        playlist_items.push_back (SeparatorElem());
        playlist_items.push_back (MenuElem (_("Clear Current"), bind(mem_fun(editor, &PublicEditor::clear_playlists), this)));
        playlist_items.push_back (SeparatorElem());
-
        playlist_items.push_back (MenuElem(_("Select from all ..."), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
 }
 
 void
-RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
+RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist> wpl)
 {
        assert (is_track());
 
+       // exit if we were triggered by deactivating the old playlist
+       if (!item->get_active()) {
+               return;
+       }
+       
        boost::shared_ptr<Playlist> pl (wpl.lock());
 
        if (!pl) {
@@ -1437,13 +1441,13 @@ RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
        
        if (apl) {
                if (get_diskstream()->playlist() == apl) {
-                       // radio button cotnrols mean this function is called for both the 
-                       // old and new playlist
+                       // exit when use_playlist is called by the creation of the playlist menu
+                       // or the playlist choice is unchanged
                        return;
                }
+               
                get_diskstream()->use_playlist (apl);
 
-
                if (edit_group() && edit_group()->is_active()) {
                        //PBD::stacktrace(cerr, 20);
                        std::string group_string = "."+edit_group()->name()+".";
@@ -1465,7 +1469,6 @@ RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
 
                                Track *track = dynamic_cast<Track *>(*i);
                                if (!track) {
-                                       std::cerr << "route " << (*i)->name() << " is not a Track" << std::endl;
                                        continue;
                                }
 
@@ -1844,10 +1847,12 @@ RouteTimeAxisView::redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutoma
        if (showit != ran->view->marked_for_display()) {
 
                if (showit) {
+                       ran->menu_item->set_active(true);
                        ran->view->set_marked_for_display (true);
                        ran->view->canvas_display->show();
                        ran->view->canvas_background->show();
                } else {
+                       ran->menu_item->set_active(false);
                        rai->redirect->mark_automation_visible (ran->what, true);
                        ran->view->set_marked_for_display (false);
                        ran->view->hide ();
@@ -1888,7 +1893,7 @@ RouteTimeAxisView::redirects_changed (void *src)
                ++tmp;
 
                if (!(*i)->valid) {
-
+                       
                        delete *i;
                        redirect_automation.erase (i);