Undef SearchPath where needed as it is defined via windows.h
[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
32 #include "pbd/uuid.h"
33 #include "pbd/file_utils.h"
34 #include "pbd/xml++.h"
35
36 #include "ardour/filesystem_paths.h"
37 #include "ardour/location.h"
38 #include "ardour/types.h"
39 #include "ardour/export_handler.h"
40
41 #ifdef SearchPath
42 #undef SearchPath
43 #endif
44
45 namespace ARDOUR
46 {
47
48 class ExportHandler;
49 class Location;
50 class Session;
51
52 /// Manages (de)serialization of export profiles and related classes
53 class ExportProfileManager
54 {
55   public:
56
57         enum ExportType {
58                 RegularExport,
59                 RangeExport,
60                 SelectionExport,
61                 RegionExport,
62                 StemExport
63         };
64
65         ExportProfileManager (Session & s, ExportType type);
66         ~ExportProfileManager ();
67
68         void load_profile ();
69         void prepare_for_export ();
70
71         typedef std::list<ExportPresetPtr> PresetList;
72
73         PresetList const & get_presets () { return preset_list; }
74         bool load_preset (ExportPresetPtr preset);
75         ExportPresetPtr new_preset (std::string const & name);
76         ExportPresetPtr save_preset (std::string const & name);
77         void remove_preset ();
78
79   private:
80         typedef boost::shared_ptr<ExportHandler> HandlerPtr;
81
82         typedef std::pair<PBD::UUID, std::string> FilePair;
83         typedef std::map<PBD::UUID, std::string> FileMap;
84
85         ExportType type;
86         std::string xml_node_name;
87         HandlerPtr  handler;
88         Session &   session;
89
90         std::string preset_filename (std::string const & preset_name);
91         void load_presets ();
92         void load_preset_from_disk (std::string const & path);
93
94         bool set_state (XMLNode const & root);
95         bool set_global_state (XMLNode const & root);
96         bool set_local_state (XMLNode const & root);
97
98         void serialize_profile (XMLNode & root);
99         void serialize_global_profile (XMLNode & root);
100         void serialize_local_profile (XMLNode & root);
101
102         PresetList      preset_list;
103         ExportPresetPtr current_preset;
104         FileMap         preset_file_map;
105
106         std::vector<std::string> find_file (std::string const & pattern);
107
108         std::string  export_config_dir;
109         PBD::SearchPath search_path;
110
111 /* Timespans */
112   public:
113
114         typedef std::list<ExportTimespanPtr> TimespanList;
115         typedef boost::shared_ptr<TimespanList> TimespanListPtr;
116         typedef std::list<Location *> LocationList;
117
118         enum TimeFormat {
119                 Timecode,
120                 BBT,
121                 MinSec,
122                 Frames,
123         };
124
125         struct TimespanState {
126                 TimespanListPtr timespans;
127                 TimeFormat      time_format;
128
129                 boost::shared_ptr<Location> selection_range;
130                 boost::shared_ptr<LocationList> ranges;
131
132                 TimespanState (boost::shared_ptr<Location> selection_range,
133                                boost::shared_ptr<LocationList> ranges)
134                   : timespans (new TimespanList ())
135                   , time_format (Timecode)
136                   , selection_range (selection_range)
137                   , ranges (ranges)
138                 {}
139         };
140
141         typedef boost::shared_ptr<TimespanState> TimespanStatePtr;
142         typedef std::list<TimespanStatePtr> TimespanStateList;
143
144         void set_selection_range (framepos_t start = 0, framepos_t end = 0);
145         std::string set_single_range (framepos_t start, framepos_t end, std::string name);
146         TimespanStateList const & get_timespans () { return check_list (timespans); }
147
148   private:
149
150         TimespanStateList timespans;
151
152         bool init_timespans (XMLNodeList nodes);
153
154         TimespanStatePtr deserialize_timespan (XMLNode & root);
155         XMLNode & serialize_timespan (TimespanStatePtr state);
156
157         /* Locations */
158
159         void update_ranges ();
160
161         boost::shared_ptr<Location>     selection_range;
162         boost::shared_ptr<LocationList> ranges;
163
164         bool                            single_range_mode;
165         boost::shared_ptr<Location>     single_range;
166
167 /* Channel Configs */
168   public:
169
170         struct ChannelConfigState {
171                 ExportChannelConfigPtr config;
172
173                 ChannelConfigState (ExportChannelConfigPtr ptr) : config (ptr) {}
174         };
175         typedef boost::shared_ptr<ChannelConfigState> ChannelConfigStatePtr;
176         typedef std::list<ChannelConfigStatePtr> ChannelConfigStateList;
177
178         ChannelConfigStateList const & get_channel_configs () { return check_list (channel_configs); }
179         void clear_channel_configs () { channel_configs.clear(); }
180         ChannelConfigStatePtr add_channel_config ();
181
182   private:
183
184         ChannelConfigStateList channel_configs;
185
186         bool init_channel_configs (XMLNodeList nodes);
187
188 /* Formats */
189   public:
190
191         typedef std::list<ExportFormatSpecPtr> FormatList;
192
193         struct FormatState {
194                 boost::shared_ptr<FormatList const> list;
195                 ExportFormatSpecPtr                     format;
196
197                 FormatState (boost::shared_ptr<FormatList const> list, ExportFormatSpecPtr format) :
198                   list (list), format (format) {}
199         };
200         typedef boost::shared_ptr<FormatState> FormatStatePtr;
201         typedef std::list<FormatStatePtr> FormatStateList;
202
203         FormatStateList const & get_formats () { return check_list (formats); }
204         FormatStatePtr duplicate_format_state (FormatStatePtr state);
205         void remove_format_state (FormatStatePtr state);
206
207         std::string save_format_to_disk (ExportFormatSpecPtr format);
208         void remove_format_profile (ExportFormatSpecPtr format);
209         ExportFormatSpecPtr get_new_format (ExportFormatSpecPtr original);
210
211         PBD::Signal0<void> FormatListChanged;
212
213   private:
214
215         FormatStateList formats;
216
217         bool init_formats (XMLNodeList nodes);
218         FormatStatePtr deserialize_format (XMLNode & root);
219         XMLNode & serialize_format (FormatStatePtr state);
220
221         void load_formats ();
222
223         ExportFormatSpecPtr load_format (XMLNode & node);
224         void load_format_from_disk (std::string const & path);
225
226         boost::shared_ptr<FormatList> format_list;
227         FileMap                       format_file_map;
228
229 /* Filenames */
230   public:
231
232         struct FilenameState {
233                 ExportFilenamePtr  filename;
234
235                 FilenameState (ExportFilenamePtr ptr) : filename (ptr) {}
236         };
237         typedef boost::shared_ptr<FilenameState> FilenameStatePtr;
238         typedef std::list<FilenameStatePtr> FilenameStateList;
239
240         FilenameStateList const & get_filenames () { return check_list (filenames); }
241         FilenameStatePtr duplicate_filename_state (FilenameStatePtr state);
242         void remove_filename_state (FilenameStatePtr state);
243
244         std::string get_sample_filename_for_format (ExportFilenamePtr filename, ExportFormatSpecPtr format);
245
246   private:
247
248         FilenameStateList filenames;
249
250         bool init_filenames (XMLNodeList nodes);
251         ExportFilenamePtr load_filename (XMLNode & node);
252
253 /* Warnings */
254   public:
255         struct Warnings {
256                 std::list<std::string> errors;
257                 std::list<std::string> warnings;
258                 std::list<std::string> conflicting_filenames;
259         };
260
261         boost::shared_ptr<Warnings> get_warnings ();
262
263   private:
264         void check_config (boost::shared_ptr<Warnings> warnings,
265                            TimespanStatePtr timespan_state,
266                            ChannelConfigStatePtr channel_config_state,
267                            FormatStatePtr format_state,
268                            FilenameStatePtr filename_state);
269
270         bool check_format (ExportFormatSpecPtr format, uint32_t channels);
271         bool check_sndfile_format (ExportFormatSpecPtr format, unsigned int channels);
272
273  /* Utilities */
274
275         void build_filenames(std::list<std::string> & result, ExportFilenamePtr filename,
276                              TimespanListPtr timespans, ExportChannelConfigPtr channel_config,
277                              ExportFormatSpecPtr format);
278
279         /* Element state lists should never be empty, this is used to check them */
280         template<typename T>
281         std::list<T> const &
282         check_list (std::list<T> const & list)
283         {
284                 if (list.empty()) {
285                         throw std::runtime_error ("Programming error: Uninitialized list in ExportProfileManager");
286                 }
287                 return list;
288         }
289
290 };
291
292
293 } // namespace ARDOUR
294
295 #endif /* __ardour_export_profile_manager_h__ */