ardour
playlist_selector.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 
19 */
20 
21 #include <gtkmm/button.h>
22 
23 #include "ardour/audio_track.h"
24 #include "ardour/audioplaylist.h"
25 #include "ardour/playlist.h"
27 
28 #include <gtkmm2ext/gtk_ui.h>
29 
30 #include "playlist_selector.h"
31 #include "route_ui.h"
32 #include "gui_thread.h"
33 
34 #include "i18n.h"
35 
36 using namespace std;
37 using namespace Gtk;
38 using namespace Gtkmm2ext;
39 using namespace ARDOUR;
40 using namespace PBD;
41 
43  : ArdourDialog (_("Playlists"))
44 {
45  rui = 0;
46 
47  set_name ("PlaylistSelectorWindow");
48  set_modal(true);
49  add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
50  set_size_request (300, 200);
51 
52  model = TreeStore::create (columns);
53  tree.set_model (model);
54  tree.append_column (_("Playlists grouped by track"), columns.text);
55 
56  scroller.add (tree);
57  scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
58 
59  get_vbox()->set_border_width (6);
60  get_vbox()->set_spacing (12);
61 
62  get_vbox()->pack_start (scroller);
63 
64  Button* b = add_button (_("Close"), RESPONSE_CANCEL);
65  b->signal_clicked().connect (sigc::mem_fun(*this, &PlaylistSelector::close_button_click));
66 
67 }
68 
70 {
71  clear_map ();
72 }
73 
74 void
76 {
77  for (TrackPlaylistMap::iterator x = trpl_map.begin(); x != trpl_map.end(); ++x) {
78  delete x->second;
79  }
80  trpl_map.clear ();
81 }
82 
83 bool
85 {
86  clear_map ();
87  if (model) {
88  model->clear ();
89  }
90  return Dialog::on_unmap_event (ev);
91 }
92 
93 void
95 {
96  vector<const char*> item;
97  string str;
98 
99  rui = ruix;
100 
101  set_title (string_compose (_("Playlist for %1"), rui->route()->name()));
102 
103  clear_map ();
104  select_connection.disconnect ();
105 
106  model->clear ();
107 
109 
110  boost::shared_ptr<Track> this_track = rui->track();
111 
112  TreeModel::Row others = *(model->append ());
113 
114  others[columns.text] = _("Other tracks");
116  proxy.reset ();
117 
118  for (TrackPlaylistMap::iterator x = trpl_map.begin(); x != trpl_map.end(); ++x) {
119 
121 
122  /* legacy sessions stored the diskstream ID as the original
123  * playlist owner. so try there instead.
124  */
125 
126  if (tr == 0) {
127  tr = _session->track_by_diskstream_id (x->first);
128  }
129 
130  if (tr == 0) {
131  continue;
132  }
133 
134  /* add a node for the track */
135 
136  string nodename;
137 
138  if (tr->name().empty()) {
139  nodename = _("unassigned");
140  } else {
141  nodename = tr->name().c_str();
142  }
143 
144  TreeModel::Row row;
145  TreeModel::Row selected_row;
146  bool have_selected = false;
147  TreePath this_path;
148 
149  if (tr == this_track) {
150  row = *(model->prepend());
151  row[columns.text] = nodename;
153  proxy.reset ();
154  } else {
155  row = *(model->append (others.children()));
156  row[columns.text] = nodename;
158  proxy.reset ();
159  }
160 
161  /* Now insert all the playlists for this diskstream/track in a subtree */
162 
163  list<boost::shared_ptr<Playlist> >* pls = x->second;
164 
165  for (list<boost::shared_ptr<Playlist> >::iterator p = pls->begin(); p != pls->end(); ++p) {
166 
167  TreeModel::Row child_row;
168 
169  child_row = *(model->append (row.children()));
170  child_row[columns.text] = (*p)->name();
171  child_row[columns.playlist] = *p;
172 
173  if (*p == this_track->playlist()) {
174  selected_row = child_row;
175  have_selected = true;
176  }
177  }
178 
179  if (have_selected) {
180  tree.get_selection()->select (selected_row);
181  }
182  }
183 
184  // Add unassigned (imported) playlists to the list
185  list<boost::shared_ptr<Playlist> > unassigned;
186  _session->playlists->unassigned (unassigned);
187 
188  TreeModel::Row row;
189  TreeModel::Row selected_row;
190  bool have_selected = false;
191  TreePath this_path;
192 
193  row = *(model->append (others.children()));
194  row[columns.text] = _("Imported");
195  proxy = row[columns.playlist];
196  proxy.reset ();
197 
198  for (list<boost::shared_ptr<Playlist> >::iterator p = unassigned.begin(); p != unassigned.end(); ++p) {
199  TreeModel::Row child_row;
200 
201  child_row = *(model->append (row.children()));
202  child_row[columns.text] = (*p)->name();
203  child_row[columns.playlist] = *p;
204 
205  if (*p == this_track->playlist()) {
206  selected_row = child_row;
207  have_selected = true;
208  }
209 
210  if (have_selected) {
211  tree.get_selection()->select (selected_row);
212  }
213  }
214 
215  show_all ();
216  select_connection = tree.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PlaylistSelector::selection_changed));
217 }
218 
219 void
221 {
223 
224  if (pl->frozen()) {
225  return;
226  }
227 
228  if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
229  return;
230  }
231 
232  TrackPlaylistMap::iterator x;
233 
234  if ((x = trpl_map.find (apl->get_orig_track_id())) == trpl_map.end()) {
235  x = trpl_map.insert (trpl_map.end(), make_pair (apl->get_orig_track_id(), new list<boost::shared_ptr<Playlist> >));
236  }
237 
238  x->second->push_back (pl);
239 }
240 
241 void
243 {
244  rui = 0;
245  hide ();
246 }
247 
248 void
250 {
252 
253  TreeModel::iterator iter = tree.get_selection()->get_selected();
254 
255  if (!iter || rui == 0) {
256  /* nothing selected */
257  return;
258  }
259 
260  if ((playlist = ((*iter)[columns.playlist])) != 0) {
261 
264 
265  if ((at = rui->audio_track()) == 0) {
266  /* eh? */
267  return;
268  }
269 
270  if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (playlist)) == 0) {
271  /* eh? */
272  return;
273  }
274 
275  at->use_playlist (apl);
276 
277  hide ();
278  }
279 
280 }
281 
ModelColumns columns
Gtk::TreeModelColumn< boost::shared_ptr< ARDOUR::Playlist > > playlist
bool frozen() const
Definition: playlist.h:115
boost::shared_ptr< Track > track_by_diskstream_id(PBD::ID)
Definition: session.cc:3352
boost::shared_ptr< Route > route_by_id(PBD::ID)
Definition: session.cc:3338
Glib::RefPtr< Gtk::TreeStore > model
Definition: ardour_ui.h:130
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
Definition: Beats.hpp:239
Gtk::TreeView tree
bool on_unmap_event(GdkEventAny *)
#define _(Text)
Definition: i18n.h:11
TrackPlaylistMap trpl_map
const PBD::ID & get_orig_track_id() const
Definition: playlist.h:214
int use_playlist(boost::shared_ptr< Playlist >)
Definition: track.cc:819
Definition: amp.h:29
WM::ProxyTemporary * proxy
Definition: ardour_dialog.h:52
boost::shared_ptr< ARDOUR::Track > track() const
Definition: route_ui.cc:1738
boost::shared_ptr< Playlist > playlist()
Definition: track.cc:590
Gtk::TreeModelColumn< std::string > text
Gtk::ScrolledWindow scroller
void add_playlist_to_map(boost::shared_ptr< ARDOUR::Playlist >)
std::string name() const
Definition: debug.h:30
boost::shared_ptr< SessionPlaylists > playlists
Definition: session.h:907
boost::shared_ptr< ARDOUR::AudioTrack > audio_track() const
Definition: route_ui.cc:1750
sigc::connection select_connection
void show_for(RouteUI *)
ARDOUR::Session * _session
boost::shared_ptr< ARDOUR::Route > route() const
Definition: route_ui.h:76
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208