refactor playlist sources to allow for MIDI and upcoming work on save/restore
[ardour.git] / libs / ardour / playlist_source.cc
1 /*
2     Copyright (C) 2011 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 #ifdef WAF_BUILD
20 #include "libardour-config.h"
21 #endif
22
23 #include <vector>
24 #include <cstdio>
25
26 #include <glibmm/fileutils.h>
27 #include <glibmm/miscutils.h>
28
29 #include "pbd/error.h"
30 #include "pbd/convert.h"
31 #include "pbd/enumwriter.h"
32
33 #include "ardour/playlist.h"
34 #include "ardour/playlist_source.h"
35 #include "ardour/session.h"
36 #include "ardour/session_playlists.h"
37 #include "ardour/source_factory.h"
38
39 #include "i18n.h"
40
41 using namespace std;
42 using namespace ARDOUR;
43 using namespace PBD;
44
45 PlaylistSource::PlaylistSource (Session& s, const std::string& name, boost::shared_ptr<Playlist> p, DataType type,
46                                 frameoffset_t begin, framecnt_t len, Source::Flag flags)
47         : Source (s, type, name)
48         , _playlist (p)
49 {
50         /* PlaylistSources are never writable, renameable, removable or destructive */
51         _flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
52
53         _playlist = p;
54         _playlist_offset = begin;
55         _playlist_length = len;
56
57         _level = _playlist->max_source_level () + 1;
58 }
59
60 PlaylistSource::PlaylistSource (Session& s, const XMLNode& node)
61         : Source (s, DataType::AUDIO, "toBeRenamed")
62 {
63         /* PlaylistSources are never writable, renameable, removable or destructive */
64         _flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
65         
66
67         if (set_state (node, Stateful::loading_state_version)) {
68                 throw failed_constructor ();
69         }
70 }
71
72 PlaylistSource::~PlaylistSource ()
73 {
74 }
75
76 void
77 PlaylistSource::add_state (XMLNode& node)
78 {
79         char buf[64];
80
81         _playlist->id().print (buf, sizeof (buf));
82         node.add_property ("playlist", buf);
83         snprintf (buf, sizeof (buf), "%" PRIi64, _playlist_offset);
84         node.add_property ("offset", buf);
85         snprintf (buf, sizeof (buf), "%" PRIu64, _playlist_length);
86         node.add_property ("length", buf);
87 }
88
89 int
90 PlaylistSource::set_state (const XMLNode& node, int version) 
91 {
92         /* get playlist ID */
93
94         const XMLProperty *prop = node.property (X_("playlist"));
95
96         if (!prop) {
97                 throw failed_constructor ();
98         }
99
100         PBD::ID id (prop->value());
101
102         /* get playlist */
103
104         boost::shared_ptr<Playlist> p = _session.playlists->by_id (id);
105
106         if (!_playlist) {
107                 throw failed_constructor ();
108         }
109
110         /* other properties */
111
112         if ((prop = node.property (X_("name"))) == 0) {
113                 throw failed_constructor ();
114         }
115         
116         set_name (prop->value());
117
118         if ((prop = node.property (X_("offset"))) == 0) {
119                 throw failed_constructor ();
120         }
121         sscanf (prop->value().c_str(), "%" PRIi64, &_playlist_offset);
122
123         if ((prop = node.property (X_("length"))) == 0) {
124                 throw failed_constructor ();
125         }
126
127         sscanf (prop->value().c_str(), "%" PRIu64, &_playlist_length);
128
129         _level = _playlist->max_source_level () + 1;
130
131         return 0;
132 }