Move Playlist GUI functions to RouteUI
This allows to re-use playlist editing in all RouteUI derivatives, not just the main editor time axis header. The change is mostly a NO-OP, simply moving methods from RouteTimeAxisView (is-a RouteUI), to RouteUI.
This commit is contained in:
parent
e78de225d4
commit
cf6e785ed3
|
@ -4329,12 +4329,12 @@ Editor::restore_editing_space ()
|
|||
*/
|
||||
|
||||
void
|
||||
Editor::new_playlists (TimeAxisView* v)
|
||||
Editor::new_playlists (RouteUI* rui)
|
||||
{
|
||||
begin_reversible_command (_("new playlists"));
|
||||
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
|
||||
_session->playlists()->get (playlists);
|
||||
mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), v, ARDOUR::Properties::group_select.property_id);
|
||||
mapover_routes (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), rui, ARDOUR::Properties::group_select.property_id);
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -4345,12 +4345,12 @@ Editor::new_playlists (TimeAxisView* v)
|
|||
*/
|
||||
|
||||
void
|
||||
Editor::copy_playlists (TimeAxisView* v)
|
||||
Editor::copy_playlists (RouteUI* rui)
|
||||
{
|
||||
begin_reversible_command (_("copy playlists"));
|
||||
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
|
||||
_session->playlists()->get (playlists);
|
||||
mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), v, ARDOUR::Properties::group_select.property_id);
|
||||
mapover_routes (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), rui, ARDOUR::Properties::group_select.property_id);
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
|
@ -4360,31 +4360,31 @@ Editor::copy_playlists (TimeAxisView* v)
|
|||
*/
|
||||
|
||||
void
|
||||
Editor::clear_playlists (TimeAxisView* v)
|
||||
Editor::clear_playlists (RouteUI* rui)
|
||||
{
|
||||
begin_reversible_command (_("clear playlists"));
|
||||
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
|
||||
_session->playlists()->get (playlists);
|
||||
mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::group_select.property_id);
|
||||
mapover_routes (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), rui, ARDOUR::Properties::group_select.property_id);
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mapped_use_new_playlist (RouteTimeAxisView& atv, uint32_t sz, vector<boost::shared_ptr<ARDOUR::Playlist> > const & playlists)
|
||||
Editor::mapped_use_new_playlist (RouteUI& rui, uint32_t sz, vector<boost::shared_ptr<ARDOUR::Playlist> > const & playlists)
|
||||
{
|
||||
atv.use_new_playlist (sz > 1 ? false : true, playlists, false);
|
||||
rui.use_new_playlist (sz > 1 ? false : true, playlists, false);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mapped_use_copy_playlist (RouteTimeAxisView& atv, uint32_t sz, vector<boost::shared_ptr<ARDOUR::Playlist> > const & playlists)
|
||||
Editor::mapped_use_copy_playlist (RouteUI& rui, uint32_t sz, vector<boost::shared_ptr<ARDOUR::Playlist> > const & playlists)
|
||||
{
|
||||
atv.use_new_playlist (sz > 1 ? false : true, playlists, true);
|
||||
rui.use_new_playlist (sz > 1 ? false : true, playlists, true);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mapped_clear_playlist (RouteTimeAxisView& atv, uint32_t /*sz*/)
|
||||
Editor::mapped_clear_playlist (RouteUI& rui, uint32_t /*sz*/)
|
||||
{
|
||||
atv.clear_playlist ();
|
||||
rui.clear_playlist ();
|
||||
}
|
||||
|
||||
double
|
||||
|
|
|
@ -332,9 +332,9 @@ public:
|
|||
PlaylistSelector& playlist_selector() const;
|
||||
void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>);
|
||||
|
||||
void new_playlists (TimeAxisView* v);
|
||||
void copy_playlists (TimeAxisView* v);
|
||||
void clear_playlists (TimeAxisView* v);
|
||||
void new_playlists (RouteUI* v);
|
||||
void copy_playlists (RouteUI* v);
|
||||
void clear_playlists (RouteUI* v);
|
||||
|
||||
void get_onscreen_tracks (TrackViewList&);
|
||||
|
||||
|
@ -763,14 +763,14 @@ private:
|
|||
RegionView* regionview_from_region (boost::shared_ptr<ARDOUR::Region>) const;
|
||||
RouteTimeAxisView* rtav_from_route (boost::shared_ptr<ARDOUR::Route>) const;
|
||||
|
||||
void mapover_tracks (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
|
||||
void mapover_tracks_with_unique_playlists (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
|
||||
|
||||
/* functions to be passed to mapover_tracks(), possibly with sigc::bind()-supplied arguments */
|
||||
void mapover_tracks_with_unique_playlists (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
|
||||
void mapped_get_equivalent_regions (RouteTimeAxisView&, uint32_t, RegionView*, std::vector<RegionView*>*) const;
|
||||
void mapped_use_new_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
|
||||
void mapped_use_copy_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
|
||||
void mapped_clear_playlist (RouteTimeAxisView&, uint32_t);
|
||||
|
||||
void mapover_routes (sigc::slot<void, RouteUI&, uint32_t> sl, RouteUI*, PBD::PropertyID) const;
|
||||
void mapped_use_new_playlist (RouteUI&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
|
||||
void mapped_use_copy_playlist (RouteUI&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
|
||||
void mapped_clear_playlist (RouteUI&, uint32_t);
|
||||
|
||||
void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type);
|
||||
bool button_release_can_deselect;
|
||||
|
|
|
@ -407,36 +407,30 @@ Editor::get_onscreen_tracks (TrackViewList& tvl)
|
|||
*/
|
||||
|
||||
void
|
||||
Editor::mapover_tracks (sigc::slot<void, RouteTimeAxisView&, uint32_t> sl, TimeAxisView* basis, PBD::PropertyID prop) const
|
||||
Editor::mapover_routes (sigc::slot<void, RouteUI&, uint32_t> sl, RouteUI* basis, PBD::PropertyID prop) const
|
||||
{
|
||||
RouteTimeAxisView* route_basis = dynamic_cast<RouteTimeAxisView*> (basis);
|
||||
set<RouteUI*> routes;
|
||||
routes.insert (basis);
|
||||
|
||||
if (route_basis == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
set<RouteTimeAxisView*> tracks;
|
||||
tracks.insert (route_basis);
|
||||
|
||||
RouteGroup* group = route_basis->route()->route_group();
|
||||
RouteGroup* group = basis->route()->route_group();
|
||||
|
||||
if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id)) {
|
||||
|
||||
/* the basis is a member of an active route group, with the appropriate
|
||||
properties; find other members */
|
||||
* properties; find other members */
|
||||
|
||||
for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
||||
RouteTimeAxisView* v = dynamic_cast<RouteTimeAxisView*> (*i);
|
||||
RouteUI* v = dynamic_cast<RouteUI*> (*i);
|
||||
if (v && v->route()->route_group() == group) {
|
||||
tracks.insert (v);
|
||||
routes.insert (v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* call the slots */
|
||||
uint32_t const sz = tracks.size ();
|
||||
uint32_t const sz = routes.size ();
|
||||
|
||||
for (set<RouteTimeAxisView*>::iterator i = tracks.begin(); i != tracks.end(); ++i) {
|
||||
for (set<RouteUI*>::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
sl (**i, sz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -288,9 +288,9 @@ public:
|
|||
virtual void reset_zoom (samplecnt_t) = 0;
|
||||
virtual PlaylistSelector& playlist_selector() const = 0;
|
||||
virtual void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>) = 0;
|
||||
virtual void new_playlists (TimeAxisView*) = 0;
|
||||
virtual void copy_playlists (TimeAxisView*) = 0;
|
||||
virtual void clear_playlists (TimeAxisView*) = 0;
|
||||
virtual void new_playlists (RouteUI*) = 0;
|
||||
virtual void copy_playlists (RouteUI*) = 0;
|
||||
virtual void clear_playlists (RouteUI*) = 0;
|
||||
virtual void select_all_visible_lanes () = 0;
|
||||
virtual void select_all_tracks () = 0;
|
||||
virtual void deselect_all () = 0;
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#include "ardour/profile.h"
|
||||
#include "ardour/route_group.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/session_playlists.h"
|
||||
#include "ardour/track.h"
|
||||
|
||||
#include "canvas/debug.h"
|
||||
|
@ -85,7 +84,6 @@
|
|||
#include "keyboard.h"
|
||||
#include "paste_context.h"
|
||||
#include "patch_change_widget.h"
|
||||
#include "playlist_selector.h"
|
||||
#include "point_selection.h"
|
||||
#include "public_editor.h"
|
||||
#include "region_view.h"
|
||||
|
@ -118,7 +116,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, ArdourCan
|
|||
, automation_action_menu (0)
|
||||
, plugins_submenu_item (0)
|
||||
, route_group_menu (0)
|
||||
, playlist_action_menu (0)
|
||||
, overlaid_menu_item (0)
|
||||
, stacked_menu_item (0)
|
||||
, gm (sess, true, 75, 14)
|
||||
|
@ -348,7 +345,6 @@ RouteTimeAxisView::~RouteTimeAxisView ()
|
|||
delete *i;
|
||||
}
|
||||
|
||||
delete playlist_action_menu;
|
||||
delete automation_action_menu;
|
||||
|
||||
delete _view;
|
||||
|
@ -1051,167 +1047,6 @@ RouteTimeAxisView::set_align_choice (RadioMenuItem* mitem, AlignChoice choice, b
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::rename_current_playlist ()
|
||||
{
|
||||
Prompter prompter (true);
|
||||
string name;
|
||||
|
||||
boost::shared_ptr<Track> tr = track();
|
||||
if (!tr) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> pl = tr->playlist();
|
||||
if (!pl) {
|
||||
return;
|
||||
}
|
||||
|
||||
prompter.set_title (_("Rename Playlist"));
|
||||
prompter.set_prompt (_("New name for playlist:"));
|
||||
prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
|
||||
prompter.set_initial_text (pl->name());
|
||||
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
||||
|
||||
while (true) {
|
||||
if (prompter.run () != Gtk::RESPONSE_ACCEPT) {
|
||||
break;
|
||||
}
|
||||
prompter.get_result (name);
|
||||
if (name.length()) {
|
||||
if (_session->playlists()->by_name (name)) {
|
||||
MessageDialog msg (_("Given playlist name is not unique."));
|
||||
msg.run ();
|
||||
prompter.set_initial_text (Playlist::bump_name (name, *_session));
|
||||
} else {
|
||||
pl->set_name (name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
RouteTimeAxisView::resolve_new_group_playlist_name(std::string &basename, vector<boost::shared_ptr<Playlist> > const & playlists)
|
||||
{
|
||||
std::string ret (basename);
|
||||
|
||||
std::string const group_string = "." + route_group()->name() + ".";
|
||||
|
||||
// iterate through all playlists
|
||||
int maxnumber = 0;
|
||||
for (vector<boost::shared_ptr<Playlist> >::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
std::string tmp = (*i)->name();
|
||||
|
||||
std::string::size_type idx = tmp.find(group_string);
|
||||
// find those which belong to this group
|
||||
if (idx != string::npos) {
|
||||
tmp = tmp.substr(idx + group_string.length());
|
||||
|
||||
// and find the largest current number
|
||||
int x = atoi(tmp);
|
||||
if (x > maxnumber) {
|
||||
maxnumber = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maxnumber++;
|
||||
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof(buf), "%d", maxnumber);
|
||||
|
||||
ret = this->name() + "." + route_group()->name () + "." + buf;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::use_new_playlist (bool prompt, vector<boost::shared_ptr<Playlist> > const & playlists_before_op, bool copy)
|
||||
{
|
||||
string name;
|
||||
|
||||
boost::shared_ptr<Track> tr = track ();
|
||||
if (!tr) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<const Playlist> pl = tr->playlist();
|
||||
if (!pl) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = pl->name();
|
||||
|
||||
if (route_group() && route_group()->is_active() && route_group()->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
name = resolve_new_group_playlist_name(name,playlists_before_op);
|
||||
}
|
||||
|
||||
while (_session->playlists()->by_name(name)) {
|
||||
name = Playlist::bump_name (name, *_session);
|
||||
}
|
||||
|
||||
if (prompt) {
|
||||
// TODO: The prompter "new" button should be de-activated if the user
|
||||
// specifies a playlist name which already exists in the session.
|
||||
|
||||
Prompter prompter (true);
|
||||
|
||||
if (copy) {
|
||||
prompter.set_title (_("New Copy Playlist"));
|
||||
prompter.set_prompt (_("Name for playlist copy:"));
|
||||
} else {
|
||||
prompter.set_title (_("New Playlist"));
|
||||
prompter.set_prompt (_("Name for new playlist:"));
|
||||
}
|
||||
prompter.set_initial_text (name);
|
||||
prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
|
||||
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
|
||||
prompter.show_all ();
|
||||
|
||||
while (true) {
|
||||
if (prompter.run () != Gtk::RESPONSE_ACCEPT) {
|
||||
return;
|
||||
}
|
||||
prompter.get_result (name);
|
||||
if (name.length()) {
|
||||
if (_session->playlists()->by_name (name)) {
|
||||
MessageDialog msg (_("Given playlist name is not unique."));
|
||||
msg.run ();
|
||||
prompter.set_initial_text (Playlist::bump_name (name, *_session));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length()) {
|
||||
if (copy) {
|
||||
tr->use_copy_playlist ();
|
||||
} else {
|
||||
tr->use_default_new_playlist ();
|
||||
}
|
||||
tr->playlist()->set_name (name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::clear_playlist ()
|
||||
{
|
||||
boost::shared_ptr<Track> tr = track ();
|
||||
if (!tr) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> pl = tr->playlist();
|
||||
if (!pl) {
|
||||
return;
|
||||
}
|
||||
|
||||
_editor.clear_playlist (pl);
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::speed_changed ()
|
||||
{
|
||||
|
@ -1529,174 +1364,10 @@ RouteTimeAxisView::paste (samplepos_t pos, const Selection& selection, PasteCont
|
|||
}
|
||||
|
||||
|
||||
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 ()
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
if (!is_track()) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete playlist_action_menu;
|
||||
playlist_action_menu = new Menu;
|
||||
playlist_action_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
MenuList& playlist_items = playlist_action_menu->items();
|
||||
playlist_action_menu->set_name ("ArdourContextMenu");
|
||||
playlist_items.clear();
|
||||
|
||||
RadioMenuItem::Group playlist_group;
|
||||
boost::shared_ptr<Track> tr = track ();
|
||||
|
||||
vector<boost::shared_ptr<Playlist> > playlists_tr = _session->playlists()->playlists_for_track (tr);
|
||||
|
||||
/* sort the playlists */
|
||||
PlaylistSorter cmp;
|
||||
sort (playlists_tr.begin(), playlists_tr.end(), cmp);
|
||||
|
||||
/* add the playlists to the menu */
|
||||
for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists_tr.begin(); i != playlists_tr.end(); ++i) {
|
||||
playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name()));
|
||||
RadioMenuItem *item = static_cast<RadioMenuItem*>(&playlist_items.back());
|
||||
item->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist), item, boost::weak_ptr<Playlist> (*i)));
|
||||
|
||||
if (tr->playlist()->id() == (*i)->id()) {
|
||||
item->set_active();
|
||||
}
|
||||
}
|
||||
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Rename..."), sigc::mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
|
||||
if (!route_group() || !route_group()->is_active() || !route_group()->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
playlist_items.push_back (MenuElem (_("New..."), sigc::bind(sigc::mem_fun(_editor, &PublicEditor::new_playlists), this)));
|
||||
playlist_items.push_back (MenuElem (_("New Copy..."), sigc::bind(sigc::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"), sigc::bind(sigc::mem_fun(_editor, &PublicEditor::new_playlists), this)));
|
||||
playlist_items.push_back (MenuElem (_("Copy Take"), sigc::bind(sigc::mem_fun(_editor, &PublicEditor::copy_playlists), this)));
|
||||
|
||||
}
|
||||
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Clear Current"), sigc::bind(sigc::mem_fun(_editor, &PublicEditor::clear_playlists), this)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
|
||||
playlist_items.push_back (MenuElem(_("Select from All..."), sigc::mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
|
||||
}
|
||||
|
||||
void
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (track()->playlist() == pl) {
|
||||
// exit when use_playlist is called by the creation of the playlist menu
|
||||
// or the playlist choice is unchanged
|
||||
return;
|
||||
}
|
||||
|
||||
track()->use_playlist (track()->data_type(), pl);
|
||||
|
||||
RouteGroup* rg = route_group();
|
||||
|
||||
if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
std::string group_string = "." + rg->name() + ".";
|
||||
|
||||
std::string take_name = pl->name();
|
||||
std::string::size_type idx = take_name.find(group_string);
|
||||
|
||||
if (idx == std::string::npos)
|
||||
return;
|
||||
|
||||
take_name = take_name.substr(idx + group_string.length()); // find the bit containing the take number / name
|
||||
|
||||
boost::shared_ptr<RouteList> rl (rg->route_list());
|
||||
|
||||
for (RouteList::const_iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||
if ((*i) == this->route()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string playlist_name = (*i)->name()+group_string+take_name;
|
||||
|
||||
boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track>(*i);
|
||||
if (!track) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (track->freeze_state() == Track::Frozen) {
|
||||
/* Don't change playlists of frozen tracks */
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> ipl = session()->playlists()->by_name(playlist_name);
|
||||
if (!ipl) {
|
||||
// No playlist for this track for this take yet, make it
|
||||
track->use_default_new_playlist();
|
||||
track->playlist()->set_name(playlist_name);
|
||||
} else {
|
||||
track->use_playlist(track->data_type(), ipl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::update_playlist_tip ()
|
||||
{
|
||||
RouteGroup* rg = route_group ();
|
||||
if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
string group_string = "." + rg->name() + ".";
|
||||
|
||||
string take_name = track()->playlist()->name();
|
||||
string::size_type idx = take_name.find(group_string);
|
||||
|
||||
if (idx != string::npos) {
|
||||
/* find the bit containing the take number / name */
|
||||
take_name = take_name.substr (idx + group_string.length());
|
||||
|
||||
/* set the playlist button tooltip to the take name */
|
||||
set_tooltip (
|
||||
playlist_button,
|
||||
string_compose(_("Take: %1.%2"),
|
||||
Gtkmm2ext::markup_escape_text (rg->name()),
|
||||
Gtkmm2ext::markup_escape_text (take_name))
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the playlist button tooltip to the playlist name */
|
||||
set_tooltip (playlist_button, _("Playlist") + std::string(": ") + Gtkmm2ext::markup_escape_text (track()->playlist()->name()));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RouteTimeAxisView::show_playlist_selector ()
|
||||
{
|
||||
_editor.playlist_selector().show_for (this);
|
||||
set_tooltip (playlist_button, playlist_tip ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -118,15 +118,6 @@ public:
|
|||
void toggle_automation_track (const Evoral::Parameter& param);
|
||||
void fade_range (TimeSelection&);
|
||||
|
||||
/* The editor calls these when mapping an operation across multiple tracks */
|
||||
void use_new_playlist (bool prompt, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &, bool copy);
|
||||
void clear_playlist ();
|
||||
|
||||
/* group playlist name resolving */
|
||||
std::string resolve_new_group_playlist_name(std::string &, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
|
||||
|
||||
void build_playlist_menu ();
|
||||
|
||||
void add_underlay (StreamView*, bool update_xml = true);
|
||||
void remove_underlay (StreamView*);
|
||||
void build_underlay_menu(Gtk::Menu*);
|
||||
|
@ -231,11 +222,8 @@ protected:
|
|||
void set_align_choice (Gtk::RadioMenuItem*, ARDOUR::AlignChoice, bool apply_to_selection = false);
|
||||
|
||||
bool playlist_click (GdkEventButton *);
|
||||
void show_playlist_selector ();
|
||||
void playlist_changed ();
|
||||
|
||||
void rename_current_playlist ();
|
||||
|
||||
bool automation_click (GdkEventButton *);
|
||||
|
||||
void timestretch (samplepos_t start, samplepos_t end);
|
||||
|
@ -263,12 +251,9 @@ protected:
|
|||
Gtk::Menu* automation_action_menu;
|
||||
Gtk::MenuItem* plugins_submenu_item;
|
||||
RouteGroupMenu* route_group_menu;
|
||||
Gtk::Menu* playlist_action_menu;
|
||||
Gtk::MenuItem* overlaid_menu_item;
|
||||
Gtk::MenuItem* stacked_menu_item;
|
||||
|
||||
void use_playlist (Gtk::RadioMenuItem *item, boost::weak_ptr<ARDOUR::Playlist> wpl);
|
||||
|
||||
ArdourCanvas::Rectangle* timestretch_rect;
|
||||
|
||||
/** Information about all automatable processor parameters that apply to
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "ardour/send.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/session_playlists.h"
|
||||
#include "ardour/template_utils.h"
|
||||
|
||||
#include "gtkmm2ext/gtk_ui.h"
|
||||
|
@ -79,6 +80,7 @@
|
|||
#include "mixer_strip.h"
|
||||
#include "mixer_ui.h"
|
||||
#include "patch_change_widget.h"
|
||||
#include "playlist_selector.h"
|
||||
#include "plugin_pin_dialog.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "route_time_axis.h"
|
||||
|
@ -114,6 +116,7 @@ RouteUI::RouteUI (ARDOUR::Session* sess)
|
|||
, comment_area(0)
|
||||
, input_selector (0)
|
||||
, output_selector (0)
|
||||
, playlist_action_menu (0)
|
||||
, _invert_menu(0)
|
||||
{
|
||||
if (program_port_prefix.empty()) {
|
||||
|
@ -148,6 +151,7 @@ RouteUI::~RouteUI()
|
|||
delete output_selector;
|
||||
delete monitor_input_button;
|
||||
delete monitor_disk_button;
|
||||
delete playlist_action_menu;
|
||||
delete _invert_menu;
|
||||
|
||||
send_blink_connection.disconnect ();
|
||||
|
@ -2357,3 +2361,336 @@ RouteUI::set_disk_io_point (DiskIOPoint diop)
|
|||
track()->set_disk_io_point (diop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
RouteUI::playlist_tip () const
|
||||
{
|
||||
if (!is_track()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
RouteGroup* rg = route_group ();
|
||||
if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
string group_string = "." + rg->name() + ".";
|
||||
|
||||
string take_name = track()->playlist()->name();
|
||||
string::size_type idx = take_name.find(group_string);
|
||||
|
||||
if (idx != string::npos) {
|
||||
/* find the bit containing the take number / name */
|
||||
take_name = take_name.substr (idx + group_string.length());
|
||||
|
||||
/* set the playlist button tooltip to the take name */
|
||||
return string_compose(_("Take: %1.%2"),
|
||||
Gtkmm2ext::markup_escape_text (rg->name()),
|
||||
Gtkmm2ext::markup_escape_text (take_name));
|
||||
}
|
||||
}
|
||||
|
||||
/* set the playlist button tooltip to the playlist name */
|
||||
return _("Playlist") + std::string(": ") + Gtkmm2ext::markup_escape_text (track()->playlist()->name());
|
||||
}
|
||||
|
||||
std::string
|
||||
RouteUI::resolve_new_group_playlist_name (std::string const& basename, vector<boost::shared_ptr<Playlist> > const& playlists)
|
||||
{
|
||||
std::string ret (basename);
|
||||
|
||||
std::string const group_string = "." + route_group()->name() + ".";
|
||||
|
||||
// iterate through all playlists
|
||||
int maxnumber = 0;
|
||||
for (vector<boost::shared_ptr<Playlist> >::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
std::string tmp = (*i)->name();
|
||||
|
||||
std::string::size_type idx = tmp.find(group_string);
|
||||
// find those which belong to this group
|
||||
if (idx != string::npos) {
|
||||
tmp = tmp.substr(idx + group_string.length());
|
||||
|
||||
// and find the largest current number
|
||||
int x = atoi(tmp);
|
||||
if (x > maxnumber) {
|
||||
maxnumber = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maxnumber++;
|
||||
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof(buf), "%d", maxnumber);
|
||||
|
||||
ret = _route->name() + "." + route_group()->name () + "." + buf;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::use_new_playlist (bool prompt, vector<boost::shared_ptr<Playlist> > const& playlists_before_op, bool copy)
|
||||
{
|
||||
string name;
|
||||
|
||||
boost::shared_ptr<Track> tr = track ();
|
||||
if (!tr) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<const Playlist> pl = tr->playlist();
|
||||
if (!pl) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = pl->name();
|
||||
|
||||
if (route_group() && route_group()->is_active() && route_group()->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
name = resolve_new_group_playlist_name (name, playlists_before_op);
|
||||
}
|
||||
|
||||
while (_session->playlists()->by_name(name)) {
|
||||
name = Playlist::bump_name (name, *_session);
|
||||
}
|
||||
|
||||
if (prompt) {
|
||||
// TODO: The prompter "new" button should be de-activated if the user
|
||||
// specifies a playlist name which already exists in the session.
|
||||
|
||||
Prompter prompter (true);
|
||||
|
||||
if (copy) {
|
||||
prompter.set_title (_("New Copy Playlist"));
|
||||
prompter.set_prompt (_("Name for playlist copy:"));
|
||||
} else {
|
||||
prompter.set_title (_("New Playlist"));
|
||||
prompter.set_prompt (_("Name for new playlist:"));
|
||||
}
|
||||
prompter.set_initial_text (name);
|
||||
prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
|
||||
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
|
||||
prompter.show_all ();
|
||||
|
||||
while (true) {
|
||||
if (prompter.run () != Gtk::RESPONSE_ACCEPT) {
|
||||
return;
|
||||
}
|
||||
prompter.get_result (name);
|
||||
if (name.length()) {
|
||||
if (_session->playlists()->by_name (name)) {
|
||||
MessageDialog msg (_("Given playlist name is not unique."));
|
||||
msg.run ();
|
||||
prompter.set_initial_text (Playlist::bump_name (name, *_session));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length()) {
|
||||
if (copy) {
|
||||
tr->use_copy_playlist ();
|
||||
} else {
|
||||
tr->use_default_new_playlist ();
|
||||
}
|
||||
tr->playlist()->set_name (name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::clear_playlist ()
|
||||
{
|
||||
boost::shared_ptr<Track> tr = track ();
|
||||
if (!tr) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> pl = tr->playlist();
|
||||
if (!pl) {
|
||||
return;
|
||||
}
|
||||
|
||||
ARDOUR_UI::instance()->the_editor().clear_playlist (pl);
|
||||
}
|
||||
|
||||
|
||||
struct PlaylistSorter {
|
||||
bool operator() (boost::shared_ptr<Playlist> a, boost::shared_ptr<Playlist> b) const {
|
||||
return a->sort_id() < b->sort_id();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
RouteUI::build_playlist_menu ()
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
if (!is_track()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PublicEditor* editor = &ARDOUR_UI::instance()->the_editor();
|
||||
|
||||
delete playlist_action_menu;
|
||||
playlist_action_menu = new Menu;
|
||||
playlist_action_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
MenuList& playlist_items = playlist_action_menu->items();
|
||||
playlist_action_menu->set_name ("ArdourContextMenu");
|
||||
playlist_items.clear();
|
||||
|
||||
RadioMenuItem::Group playlist_group;
|
||||
boost::shared_ptr<Track> tr = track ();
|
||||
|
||||
vector<boost::shared_ptr<Playlist> > playlists_tr = _session->playlists()->playlists_for_track (tr);
|
||||
|
||||
/* sort the playlists */
|
||||
PlaylistSorter cmp;
|
||||
sort (playlists_tr.begin(), playlists_tr.end(), cmp);
|
||||
|
||||
/* add the playlists to the menu */
|
||||
for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists_tr.begin(); i != playlists_tr.end(); ++i) {
|
||||
playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name()));
|
||||
RadioMenuItem *item = static_cast<RadioMenuItem*>(&playlist_items.back());
|
||||
item->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::use_playlist), item, boost::weak_ptr<Playlist> (*i)));
|
||||
|
||||
if (tr->playlist()->id() == (*i)->id()) {
|
||||
item->set_active();
|
||||
}
|
||||
}
|
||||
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Rename..."), sigc::mem_fun(*this, &RouteUI::rename_current_playlist)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
|
||||
if (!route_group() || !route_group()->is_active() || !route_group()->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
playlist_items.push_back (MenuElem (_("New..."), sigc::bind(sigc::mem_fun(editor, &PublicEditor::new_playlists), this)));
|
||||
playlist_items.push_back (MenuElem (_("New Copy..."), sigc::bind(sigc::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"), sigc::bind(sigc::mem_fun(editor, &PublicEditor::new_playlists), this)));
|
||||
playlist_items.push_back (MenuElem (_("Copy Take"), sigc::bind(sigc::mem_fun(editor, &PublicEditor::copy_playlists), this)));
|
||||
|
||||
}
|
||||
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Clear Current"), sigc::bind(sigc::mem_fun(editor, &PublicEditor::clear_playlists), this)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
|
||||
playlist_items.push_back (MenuElem(_("Select from All..."), sigc::mem_fun(*this, &RouteUI::show_playlist_selector)));
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (track()->playlist() == pl) {
|
||||
// exit when use_playlist is called by the creation of the playlist menu
|
||||
// or the playlist choice is unchanged
|
||||
return;
|
||||
}
|
||||
|
||||
track()->use_playlist (track()->data_type(), pl);
|
||||
|
||||
RouteGroup* rg = route_group();
|
||||
|
||||
if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::group_select.property_id)) {
|
||||
std::string group_string = "." + rg->name() + ".";
|
||||
|
||||
std::string take_name = pl->name();
|
||||
std::string::size_type idx = take_name.find(group_string);
|
||||
|
||||
if (idx == std::string::npos)
|
||||
return;
|
||||
|
||||
take_name = take_name.substr(idx + group_string.length()); // find the bit containing the take number / name
|
||||
|
||||
boost::shared_ptr<RouteList> rl (rg->route_list());
|
||||
|
||||
for (RouteList::const_iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||
if ((*i) == this->route()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string playlist_name = (*i)->name()+group_string+take_name;
|
||||
|
||||
boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track>(*i);
|
||||
if (!track) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (track->freeze_state() == Track::Frozen) {
|
||||
/* Don't change playlists of frozen tracks */
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> ipl = session()->playlists()->by_name(playlist_name);
|
||||
if (!ipl) {
|
||||
// No playlist for this track for this take yet, make it
|
||||
track->use_default_new_playlist();
|
||||
track->playlist()->set_name(playlist_name);
|
||||
} else {
|
||||
track->use_playlist(track->data_type(), ipl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::show_playlist_selector ()
|
||||
{
|
||||
ARDOUR_UI::instance()->the_editor().playlist_selector().show_for (this);
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::rename_current_playlist ()
|
||||
{
|
||||
Prompter prompter (true);
|
||||
string name;
|
||||
|
||||
boost::shared_ptr<Track> tr = track();
|
||||
if (!tr) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> pl = tr->playlist();
|
||||
if (!pl) {
|
||||
return;
|
||||
}
|
||||
|
||||
prompter.set_title (_("Rename Playlist"));
|
||||
prompter.set_prompt (_("New name for playlist:"));
|
||||
prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
|
||||
prompter.set_initial_text (pl->name());
|
||||
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
||||
|
||||
while (true) {
|
||||
if (prompter.run () != Gtk::RESPONSE_ACCEPT) {
|
||||
break;
|
||||
}
|
||||
prompter.get_result (name);
|
||||
if (name.length()) {
|
||||
if (_session->playlists()->by_name (name)) {
|
||||
MessageDialog msg (_("Given playlist name is not unique."));
|
||||
msg.run ();
|
||||
prompter.set_initial_text (Playlist::bump_name (name, *_session));
|
||||
} else {
|
||||
pl->set_name (name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,6 +211,12 @@ public:
|
|||
void build_mute_menu(void);
|
||||
void init_mute_menu(ARDOUR::MuteMaster::MutePoint, Gtk::CheckMenuItem*);
|
||||
|
||||
/* The editor calls these when mapping an operation across multiple tracks */
|
||||
void use_new_playlist (bool prompt, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &, bool copy);
|
||||
void clear_playlist ();
|
||||
|
||||
std::string resolve_new_group_playlist_name(std::string const&, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const&);
|
||||
|
||||
int set_color_from_route ();
|
||||
|
||||
void route_rename();
|
||||
|
@ -333,6 +339,14 @@ protected:
|
|||
|
||||
ControlSlaveUI* csu;
|
||||
|
||||
std::string playlist_tip () const;
|
||||
void build_playlist_menu ();
|
||||
void use_playlist (Gtk::RadioMenuItem *item, boost::weak_ptr<ARDOUR::Playlist> wpl);
|
||||
void show_playlist_selector ();
|
||||
void rename_current_playlist ();
|
||||
|
||||
Gtk::Menu* playlist_action_menu;
|
||||
|
||||
private:
|
||||
void setup_invert_buttons ();
|
||||
void invert_menu_toggled (uint32_t);
|
||||
|
|
Loading…
Reference in New Issue