Properly create new presets, i.e. without duplicate id's on save-after-rename
[ardour.git] / libs / ardour / ardour / export_profile_manager.h
1 /*
2     Copyright (C) 2008 Paul Davis
3     Author: Sakari Bergen
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #ifndef __ardour_export_profile_manager_h__
22 #define __ardour_export_profile_manager_h__
23
24 #include <list>
25 #include <vector>
26 #include <map>
27 #include <stdexcept>
28 #include <string>
29
30 #include <boost/shared_ptr.hpp>
31 #include <boost/weak_ptr.hpp>
32
33 #include "pbd/uuid.h"
34 #include "pbd/file_utils.h"
35 #include "pbd/xml++.h"
36
37 #include "ardour/filesystem_paths.h"
38 #include "ardour/location.h"
39 #include "ardour/types.h"
40
41 namespace ARDOUR
42 {
43
44 class ExportHandler;
45 class ExportTimespan;
46 class ExportChannelConfiguration;
47 class ExportFormatSpecification;
48 class ExportFilename;
49 class ExportPreset;
50 class Location;
51 class Session;
52
53 /// Manages (de)serialization of export profiles and related classes
54 class ExportProfileManager
55 {
56   public:
57
58         ExportProfileManager (Session & s, std::string xml_node_name);
59         ~ExportProfileManager ();
60
61         void load_profile ();
62         void prepare_for_export ();
63
64         typedef boost::shared_ptr<ExportPreset> PresetPtr;
65         typedef std::list<PresetPtr> PresetList;
66
67         PresetList const & get_presets () { return preset_list; }
68         bool load_preset (PresetPtr preset);
69         PresetPtr new_preset (std::string const & name);
70         PresetPtr save_preset (std::string const & name);
71         void remove_preset ();
72
73   private:
74         typedef boost::shared_ptr<ExportHandler> HandlerPtr;
75
76         typedef std::pair<PBD::UUID, PBD::sys::path> FilePair;
77         typedef std::map<PBD::UUID, PBD::sys::path> FileMap;
78
79         std::string const xml_node_name;
80         HandlerPtr  handler;
81         Session &   session;
82
83         std::string preset_filename (std::string const & preset_name);
84         void load_presets ();
85         void load_preset_from_disk (PBD::sys::path const & path);
86
87         bool set_state (XMLNode const & root);
88         bool set_global_state (XMLNode const & root);
89         bool set_local_state (XMLNode const & root);
90
91         void serialize_profile (XMLNode & root);
92         void serialize_global_profile (XMLNode & root);
93         void serialize_local_profile (XMLNode & root);
94
95         PresetList preset_list;
96         PresetPtr  current_preset;
97         FileMap    preset_file_map;
98
99         std::vector<PBD::sys::path> find_file (std::string const & pattern);
100
101         PBD::sys::path  export_config_dir;
102         PBD::SearchPath search_path;
103
104 /* Timespans */
105   public:
106
107         typedef boost::shared_ptr<ExportTimespan> TimespanPtr;
108         typedef std::list<TimespanPtr> TimespanList;
109         typedef boost::shared_ptr<TimespanList> TimespanListPtr;
110         typedef std::list<Location *> LocationList;
111
112         enum TimeFormat {
113                 Timecode,
114                 BBT,
115                 MinSec,
116                 Frames,
117                 Off
118         };
119
120         struct TimespanState {
121                 TimespanListPtr timespans;
122                 TimeFormat      time_format;
123
124                 boost::shared_ptr<Location> session_range;
125                 boost::shared_ptr<Location> selection_range;
126                 boost::shared_ptr<LocationList> ranges;
127
128                 TimespanState (boost::shared_ptr<Location> session_range,
129                                boost::shared_ptr<Location> selection_range,
130                                boost::shared_ptr<LocationList> ranges)
131                   : timespans (new TimespanList ())
132                   , time_format (Timecode)
133                   , session_range (session_range)
134                   , selection_range (selection_range)
135                   , ranges (ranges)
136                 {}
137         };
138
139         typedef boost::shared_ptr<TimespanState> TimespanStatePtr;
140         typedef std::list<TimespanStatePtr> TimespanStateList;
141
142         void set_selection_range (framepos_t start = 0, framepos_t end = 0);
143         std::string set_single_range (framepos_t start, framepos_t end, std::string name);
144         TimespanStateList const & get_timespans () { return check_list (timespans); }
145
146   private:
147
148         TimespanStateList timespans;
149
150         bool init_timespans (XMLNodeList nodes);
151
152         TimespanStatePtr deserialize_timespan (XMLNode & root);
153         XMLNode & serialize_timespan (TimespanStatePtr state);
154
155         /* Locations */
156
157         void update_ranges ();
158
159         boost::shared_ptr<Location>     session_range;
160         boost::shared_ptr<Location>     selection_range;
161         boost::shared_ptr<LocationList> ranges;
162
163         bool                            single_range_mode;
164         boost::shared_ptr<Location>     single_range;
165
166 /* Channel Configs */
167   public:
168
169         typedef boost::shared_ptr<ExportChannelConfiguration> ChannelConfigPtr;
170
171         struct ChannelConfigState {
172                 ChannelConfigPtr config;
173
174                 ChannelConfigState (ChannelConfigPtr ptr) : config (ptr) {}
175         };
176         typedef boost::shared_ptr<ChannelConfigState> ChannelConfigStatePtr;
177         typedef std::list<ChannelConfigStatePtr> ChannelConfigStateList;
178
179         ChannelConfigStateList const & get_channel_configs () { return check_list (channel_configs); }
180         void clear_channel_configs () { channel_configs.clear(); }
181         ChannelConfigStatePtr add_channel_config ();
182
183   private:
184
185         ChannelConfigStateList channel_configs;
186
187         bool init_channel_configs (XMLNodeList nodes);
188
189 /* Formats */
190   public:
191
192         typedef boost::shared_ptr<ExportFormatSpecification> FormatPtr;
193         typedef std::list<FormatPtr> FormatList;
194
195         struct FormatState {
196                 boost::shared_ptr<FormatList const> list;
197                 FormatPtr                           format;
198
199                 FormatState (boost::shared_ptr<FormatList const> list, FormatPtr format) :
200                   list (list), format (format) {}
201         };
202         typedef boost::shared_ptr<FormatState> FormatStatePtr;
203         typedef std::list<FormatStatePtr> FormatStateList;
204
205         FormatStateList const & get_formats () { return check_list (formats); }
206         FormatStatePtr duplicate_format_state (FormatStatePtr state);
207         void remove_format_state (FormatStatePtr state);
208
209         PBD::sys::path save_format_to_disk (FormatPtr format);
210         void remove_format_profile (FormatPtr format);
211         FormatPtr get_new_format (FormatPtr original);
212
213         PBD::Signal0<void> FormatListChanged;
214
215   private:
216
217         FormatStateList formats;
218
219         bool init_formats (XMLNodeList nodes);
220         FormatStatePtr deserialize_format (XMLNode & root);
221         XMLNode & serialize_format (FormatStatePtr state);
222
223         void load_formats ();
224
225         FormatPtr load_format (XMLNode & node);
226         void load_format_from_disk (PBD::sys::path const & path);
227
228         boost::shared_ptr<FormatList> format_list;
229         FileMap                       format_file_map;
230
231 /* Filenames */
232   public:
233
234         typedef boost::shared_ptr<ExportFilename> FilenamePtr;
235
236         struct FilenameState {
237                 FilenamePtr  filename;
238
239                 FilenameState (FilenamePtr ptr) : filename (ptr) {}
240         };
241         typedef boost::shared_ptr<FilenameState> FilenameStatePtr;
242         typedef std::list<FilenameStatePtr> FilenameStateList;
243
244         FilenameStateList const & get_filenames () { return check_list (filenames); }
245         FilenameStatePtr duplicate_filename_state (FilenameStatePtr state);
246         void remove_filename_state (FilenameStatePtr state);
247
248   private:
249
250         FilenameStateList filenames;
251
252         bool init_filenames (XMLNodeList nodes);
253         FilenamePtr load_filename (XMLNode & node);
254
255 /* Warnings */
256   public:
257         struct Warnings {
258                 std::list<std::string> errors;
259                 std::list<std::string> warnings;
260                 std::list<std::string> conflicting_filenames;
261         };
262
263         boost::shared_ptr<Warnings> get_warnings ();
264
265   private:
266         void check_config (boost::shared_ptr<Warnings> warnings,
267                            TimespanStatePtr timespan_state,
268                            ChannelConfigStatePtr channel_config_state,
269                            FormatStatePtr format_state,
270                            FilenameStatePtr filename_state);
271         
272         bool check_format (FormatPtr format, uint32_t channels);
273         bool check_sndfile_format (FormatPtr format, unsigned int channels);
274
275  /* Utilities */
276
277         /* Element state lists should never be empty, this is used to check them */
278         template<typename T>
279         std::list<T> const &
280         check_list (std::list<T> const & list)
281         {
282                 if (list.empty()) {
283                         throw std::runtime_error ("Programming error: Uninitialized list in ExportProfileManager");
284                 }
285                 return list;
286         }
287
288 };
289
290
291 } // namespace ARDOUR
292
293 #endif /* __ardour_export_profile_manager_h__ */