/*
- Copyright (C) 2004 Paul Davis
+ Copyright (C) 2004 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
#include <gtkmm/button.h>
-#include <gtkmm/ctree.h>
-#include <ardour/session_playlist.h>
-#include <ardour/diskstream.h>
-#include <ardour/playlist.h>
-#include <ardour/audio_track.h>
-#include <ardour/audioplaylist.h>
-#include <ardour/configuration.h>
+#include "ardour/session_playlist.h"
+#include "ardour/audio_diskstream.h"
+#include "ardour/playlist.h"
+#include "ardour/audio_track.h"
+#include "ardour/audioplaylist.h"
+#include "ardour/configuration.h"
#include <gtkmm2ext/gtk_ui.h>
#include "i18n.h"
using namespace std;
-using namespace sigc;
using namespace Gtk;
+using namespace Gtkmm2ext;
using namespace ARDOUR;
-
-static const gchar *tree_display_titles[] = {
- N_("Playlists grouped by track"),
- 0
-};
+using namespace PBD;
PlaylistSelector::PlaylistSelector ()
- : ArdourDialog ("playlist selector"),
- tree (internationalize (tree_display_titles)),
- close_button (_("close"))
+ : ArdourDialog (_("Playlists"))
{
rui = 0;
-
- set_position (Gtk::WIN_POS_MOUSE);
+
+ set_position (WIN_POS_MOUSE);
set_name ("PlaylistSelectorWindow");
- set_title (_("ardour: playlists"));
set_modal(true);
add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
set_size_request (300, 200);
- scroller.add_with_viewport (tree);
- scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ model = TreeStore::create (columns);
+ tree.set_model (model);
+ tree.append_column (_("Playlists grouped by track"), columns.text);
+
+ scroller.add (tree);
+ scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
+
+ get_vbox()->set_border_width (6);
+ get_vbox()->set_spacing (12);
- close_button.signal_clicked().connect (slot (*this, &PlaylistSelector::close_button_click));
+ get_vbox()->pack_start (scroller);
- vpacker.set_border_width (6);
- vpacker.set_spacing (12);
- vpacker.pack_start (scroller);
- vpacker.pack_start (close_button, false, false);
+ Button* b = add_button (_("close"), RESPONSE_CANCEL);
+ b->signal_clicked().connect (sigc::mem_fun(*this, &PlaylistSelector::close_button_click));
- add (vpacker);
}
PlaylistSelector::~PlaylistSelector ()
void
PlaylistSelector::clear_map ()
{
- for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
+ for (TrackPlaylistMap::iterator x = trpl_map.begin(); x != trpl_map.end(); ++x) {
delete x->second;
}
- dspl_map.clear ();
+ trpl_map.clear ();
+}
+
+bool
+PlaylistSelector::on_unmap_event (GdkEventAny* ev)
+{
+ clear_map ();
+ if (model) {
+ model->clear ();
+ }
+ return Dialog::on_unmap_event (ev);
}
void
PlaylistSelector::show_for (RouteUI* ruix)
{
- using namespace CTree_Helpers;
vector<const char*> item;
- RowList::iterator i;
- RowList::iterator tmpi;
- RowList::iterator others;
- DiskStream* this_ds;
string str;
rui = ruix;
- str = _("ardour: playlist for ");
- str += rui->route().name();
-
- set_title (str);
+ set_title (string_compose (_("Playlist for %1"), rui->route()->name()));
clear_map ();
select_connection.disconnect ();
- /* ---------------------------------------- */
- /* XXX MAKE ME A FUNCTION (no CTree::clear() in gtkmm 1.2) */
- gtk_ctree_remove_node (tree.gobj(), NULL);
- /* ---------------------------------------- */
-
- session->foreach_playlist (this, &PlaylistSelector::add_playlist_to_map);
+ model->clear ();
+
+ _session->playlists->foreach (this, &PlaylistSelector::add_playlist_to_map);
+
+ boost::shared_ptr<Track> this_track = rui->track();
+
+ TreeModel::Row others = *(model->append ());
- this_ds = rui->get_diskstream();
+ others[columns.text] = _("Other tracks");
+ boost::shared_ptr<Playlist> proxy = others[columns.playlist];
+ proxy.reset ();
- item.clear();
- item.push_back (_("Other tracks"));
- others = tree.rows().insert (tree.rows().begin(), Element (item));
+ for (TrackPlaylistMap::iterator x = trpl_map.begin(); x != trpl_map.end(); ++x) {
- for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (_session->route_by_id (x->first));
+
+ /* legacy sessions stored the diskstream ID as the original
+ * playlist owner. so try there instead.
+ */
- DiskStream* ds = session->diskstream_by_id (x->first);
+ if (tr == 0) {
+ tr = _session->track_by_diskstream_id (x->first);
+ }
- if (ds == 0) {
+ if (tr == 0) {
continue;
}
- /* add a node for the diskstream */
+ /* add a node for the track */
- item.clear ();
+ string nodename;
- if (ds->name().empty()) {
- item.push_back (_("unassigned"));
+ if (tr->name().empty()) {
+ nodename = _("unassigned");
} else {
- item.push_back (ds->name().c_str());
+ nodename = tr->name().c_str();
}
- if (ds == this_ds) {
- i = tree.rows().insert (tree.rows().begin(),
- Gtk::CTree_Helpers::Element (item));
+ TreeModel::Row row;
+ TreeModel::Row* selected_row = 0;
+ TreePath this_path;
+
+ if (tr == this_track) {
+ row = *(model->prepend());
+ row[columns.text] = nodename;
+ boost::shared_ptr<Playlist> proxy = row[columns.playlist];
+ proxy.reset ();
} else {
- i = others->subtree().insert (others->subtree().end(),
- Gtk::CTree_Helpers::Element (item));
+ row = *(model->append (others.children()));
+ row[columns.text] = nodename;
+ boost::shared_ptr<Playlist> proxy = row[columns.playlist];
+ proxy.reset ();
}
-
+
/* Now insert all the playlists for this diskstream/track in a subtree */
-
- list<Playlist*> *pls = x->second;
- for (list<Playlist*>::iterator p = pls->begin(); p != pls->end(); ++p) {
+ list<boost::shared_ptr<Playlist> >* pls = x->second;
+
+ for (list<boost::shared_ptr<Playlist> >::iterator p = pls->begin(); p != pls->end(); ++p) {
+
+ TreeModel::Row child_row;
+
+ child_row = *(model->append (row.children()));
+ child_row[columns.text] = (*p)->name();
+ child_row[columns.playlist] = *p;
+
+ if (*p == this_track->playlist()) {
+ selected_row = &child_row;
+ }
+ }
+
+ if (selected_row != 0) {
+ tree.get_selection()->select (*selected_row);
+ }
+ }
+
+ // Add unassigned (imported) playlists to the list
+ list<boost::shared_ptr<Playlist> > unassigned;
+ _session->playlists->unassigned (unassigned);
- item.clear ();
- item.push_back ((*p)->name().c_str());
+ TreeModel::Row row;
+ TreeModel::Row* selected_row = 0;
+ TreePath this_path;
- tmpi = i->subtree().insert (i->subtree().end(), Element (item));
+ row = *(model->append (others.children()));
+ row[columns.text] = _("Imported");
+ proxy = row[columns.playlist];
+ proxy.reset ();
- if (*p == this_ds->playlist()) {
- (*tmpi).select ();
- }
+ for (list<boost::shared_ptr<Playlist> >::iterator p = unassigned.begin(); p != unassigned.end(); ++p) {
+ TreeModel::Row child_row;
- (*tmpi).set_data (*p);
-
+ child_row = *(model->append (row.children()));
+ child_row[columns.text] = (*p)->name();
+ child_row[columns.playlist] = *p;
+
+ if (*p == this_track->playlist()) {
+ selected_row = &child_row;
}
- if (ds == this_ds) {
- i->expand ();
+ if (selected_row != 0) {
+ tree.get_selection()->select (*selected_row);
}
}
show_all ();
- select_connection = tree.tree_select_row.connect (slot (*this, &PlaylistSelector::row_selected));
+ select_connection = tree.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PlaylistSelector::selection_changed));
}
void
-PlaylistSelector::add_playlist_to_map (Playlist *pl)
+PlaylistSelector::add_playlist_to_map (boost::shared_ptr<Playlist> pl)
{
- AudioPlaylist* apl;
+ boost::shared_ptr<AudioPlaylist> apl;
if (pl->frozen()) {
return;
}
- if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+ if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
return;
}
- DSPL_Map::iterator x;
-
- if ((x = dspl_map.find (apl->get_orig_diskstream_id())) == dspl_map.end()) {
+ TrackPlaylistMap::iterator x;
- pair<ARDOUR::id_t,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>);
-
- x = dspl_map.insert (dspl_map.end(), newp);
+ if ((x = trpl_map.find (apl->get_orig_track_id())) == trpl_map.end()) {
+ x = trpl_map.insert (trpl_map.end(), make_pair (apl->get_orig_track_id(), new list<boost::shared_ptr<Playlist> >));
}
x->second->push_back (pl);
}
-void
-PlaylistSelector::set_session (Session* s)
-{
- ENSURE_GUI_THREAD(bind (slot (*this, &PlaylistSelector::set_session), s));
-
- session = s;
-
- if (session) {
- session->going_away.connect (bind (slot (*this, &PlaylistSelector::set_session), static_cast<Session*> (0)));
- }
-}
-
void
PlaylistSelector::close_button_click ()
{
}
void
-PlaylistSelector::row_selected (Gtk::CTree::Row row, gint col)
+PlaylistSelector::selection_changed ()
{
- Playlist *playlist;
-
- if ((playlist = (Playlist *) row.get_data()) != 0) {
-
- AudioTrack* at;
- AudioPlaylist* apl;
-
- if ((at = dynamic_cast<AudioTrack*> (&rui->route())) == 0) {
+ boost::shared_ptr<Playlist> playlist;
+
+ TreeModel::iterator iter = tree.get_selection()->get_selected();
+
+ if (!iter || rui == 0) {
+ /* nothing selected */
+ return;
+ }
+
+ if ((playlist = ((*iter)[columns.playlist])) != 0) {
+
+ boost::shared_ptr<AudioTrack> at;
+ boost::shared_ptr<AudioPlaylist> apl;
+
+ if ((at = rui->audio_track()) == 0) {
/* eh? */
return;
}
-
- if ((apl = dynamic_cast<AudioPlaylist*> (playlist)) == 0) {
+
+ if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (playlist)) == 0) {
/* eh? */
return;
}
-
- at->disk_stream().use_playlist (apl);
+
+ at->use_playlist (apl);
hide ();
}
}
-
+