new files from sakari, missed last time
[ardour.git] / libs / ardour / export_filename.cc
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 #include <ardour/export_filename.h>
22
23 #include <pbd/xml++.h>
24 #include <pbd/convert.h>
25 #include <pbd/enumwriter.h>
26
27 #include <ardour/session.h>
28 #include <ardour/session_directory.h>
29 #include <ardour/export_timespan.h>
30 #include <ardour/export_format_specification.h>
31 #include <ardour/export_channel_configuration.h>
32 #include <ardour/export_failed.h>
33
34 #include "i18n.h"
35
36 using namespace PBD;
37
38 namespace ARDOUR
39 {
40
41 ExportFilename::ExportFilename (Session & session) :
42   include_label (false),
43   include_session (false),
44   include_revision (false),
45   include_channel_config (false),
46   include_channel (false),
47   include_timespan (true), // Include timespan name always
48   include_time (false),
49   include_date (false),
50   session (session),
51   revision (1)
52 {
53         time_t rawtime;
54         std::time (&rawtime);
55         time_struct = localtime (&rawtime);
56         
57         folder = session.session_directory().export_path().to_string();
58         
59         XMLNode * instant_node = session.instant_xml ("ExportFilename");
60         if (instant_node) {
61                 set_state (*instant_node);
62         }
63 }
64
65 XMLNode &
66 ExportFilename::get_state ()
67 {
68         XMLNode * node = new XMLNode ("ExportFilename");
69         XMLNode * child;
70         
71         FieldPair dir = analyse_folder();
72         child = node->add_child ("Folder");
73         child->add_property ("relative", dir.first ? "true" : "false");
74         child->add_property ("path", dir.second);
75         
76         add_field (node, "label", include_label, label);
77         add_field (node, "session", include_session);
78         add_field (node, "revision", include_revision);
79         add_field (node, "time", include_time, enum_2_string (time_format));
80         add_field (node, "date", include_date, enum_2_string (date_format));
81         
82         XMLNode * instant_node = new XMLNode ("ExportRevision");
83         instant_node->add_property ("revision", to_string (revision, std::dec));
84         session.add_instant_xml (*instant_node);
85         
86         return *node;
87 }
88
89 int
90 ExportFilename::set_state (const XMLNode & node)
91 {
92         XMLNode * child;
93         XMLProperty * prop;
94         FieldPair pair;
95         
96         child = node.child ("Folder");
97         if (!child) { return -1; }
98         
99         folder = "";
100         
101         if ((prop = child->property ("relative"))) {
102                 if (!prop->value().compare ("true")) {
103                         folder = session.session_directory().root_path().to_string();
104                 }
105         }
106         
107         if ((prop = child->property ("path"))) {
108                 folder += prop->value();
109         }
110         
111         
112         pair = get_field (node, "label");
113         include_label = pair.first;
114         label = pair.second;
115         
116         pair = get_field (node, "session");
117         include_session = pair.first;
118         
119         pair = get_field (node, "revision");
120         include_revision = pair.first;
121         
122         pair = get_field (node, "time");
123         include_time = pair.first;
124         time_format = (TimeFormat) string_2_enum (pair.second, time_format);
125         
126         pair = get_field (node, "date");
127         include_date = pair.first;
128         date_format = (DateFormat) string_2_enum (pair.second, date_format);
129
130         XMLNode * instant_node = session.instant_xml ("ExportRevision");
131         if (instant_node && (prop = instant_node->property ("revision"))) {
132                 revision = atoi (prop->value());
133         }
134
135         return 0;
136 }
137
138 ustring
139 ExportFilename::get_path (FormatPtr format) const 
140 {
141         ustring path = folder;
142         bool filename_empty = true;
143         
144         path += "/";
145         
146         if (include_session) {
147                 path += filename_empty ? "" : "_";
148                 path += session.name();
149                 filename_empty = false;
150         }
151         
152         if (include_label) {
153                 path += filename_empty ? "" : "_";
154                 path += label;
155                 filename_empty = false;
156         }
157         
158         if (include_revision) {
159                 path += filename_empty ? "" : "_";
160                 path += "r";
161                 path += to_string (revision, std::dec);
162                 filename_empty = false;
163         }
164         
165         if (include_timespan && timespan) {
166                 path += filename_empty ? "" : "_";
167                 path += timespan->name();
168                 filename_empty = false;
169         }
170         
171         if (include_channel_config && channel_config) {
172                 path += filename_empty ? "" : "_";
173                 path += channel_config->name();
174                 filename_empty = false;
175         }
176         
177         if (include_channel) {
178                 path += filename_empty ? "" : "_";
179                 path += "channel";
180                 path += to_string (channel, std::dec);
181                 filename_empty = false;
182         }
183         
184         if (include_date) {
185                 path += filename_empty ? "" : "_";
186                 path += get_date_format_str (date_format);
187                 filename_empty = false;
188         }
189         
190         if (include_time) {
191                 path += filename_empty ? "" : "_";
192                 path += get_time_format_str (time_format);
193                 filename_empty = false;
194         }
195         
196         path += ".";
197         path += format->extension ();
198         
199         return path;
200 }
201
202 ustring
203 ExportFilename::get_time_format_str (TimeFormat format) const
204 {
205         switch ( format ) {
206           case T_None:
207                 return _("No Time");
208         
209           case T_NoDelim:
210                 return get_formatted_time ("%H%M");
211         
212           case T_Delim:
213                 return get_formatted_time ("%H.%M");
214         
215           default:
216                 return _("Invalid time format");
217         }
218 }
219
220 ustring
221 ExportFilename::get_date_format_str (DateFormat format) const
222 {
223         switch (format) {
224           case D_None:
225                 return _("No Date");
226         
227           case D_BE:
228                 return get_formatted_time ("%Y%m%d");
229         
230           case D_ISO:
231                 return get_formatted_time ("%Y-%m-%d");
232         
233           case D_BEShortY:
234                 return get_formatted_time ("%y%m%d");
235         
236           case D_ISOShortY:
237                 return get_formatted_time ("%y-%m-%d");
238         
239           default:
240                 return _("Invalid date format");
241         }
242 }
243
244 void
245 ExportFilename::set_time_format (TimeFormat format)
246 {
247         time_format = format;
248         
249         if (format == T_None) {
250                 include_time = false;
251         } else {
252                 include_time = true;
253         }
254 }
255
256 void
257 ExportFilename::set_date_format (DateFormat format)
258 {
259         date_format = format;
260         
261         if (format == D_None) {
262                 include_date = false;
263         } else {
264                 include_date = true;
265         }
266 }
267
268 void
269 ExportFilename::set_label (ustring value)
270 {
271         label = value;
272         include_label = !value.compare ("");
273 }
274
275 bool
276 ExportFilename::set_folder (ustring path)
277 {
278         // TODO check folder existence
279         folder = path;
280         return true;
281 }
282
283 ustring
284 ExportFilename::get_formatted_time (ustring const & format) const
285 {
286         char buffer [80];
287         strftime (buffer, 80, format.c_str(), time_struct);
288         
289         ustring return_value (buffer);
290         return return_value;
291 }
292
293 void
294 ExportFilename::add_field (XMLNode * node, ustring const & name, bool enabled, ustring const & value)
295 {
296         XMLNode * child = node->add_child ("Field");
297         
298         if (!child) {
299                 std::cerr << "Error adding a field to ExportFilename XML-tree" << std::endl;
300                 return;
301         }
302         
303         child->add_property ("name", name);
304         child->add_property ("enabled", enabled ? "true" : "false");
305         if (!value.empty()) {
306                 child->add_property ("value", value);
307         }
308 }
309
310 ExportFilename::FieldPair
311 ExportFilename::get_field (XMLNode const & node, ustring const & name)
312 {
313         FieldPair pair;
314         pair.first = false;
315
316         XMLNodeList children = node.children();
317         
318         for (XMLNodeList::iterator it = children.begin(); it != children.end(); ++it) {
319                 XMLProperty * prop = (*it)->property ("name");
320                 if (prop && !prop->value().compare (name)) {
321                         
322                         prop = (*it)->property ("enabled");
323                         if (prop && !prop->value().compare ("true")) {
324                                 pair.first = true;
325                         } else {
326                                 pair.first = false;
327                         }
328                         
329                         prop = (*it)->property ("value");
330                         if (prop) {
331                                 pair.second = prop->value();
332                         }
333                         
334                         return pair;
335                 }
336         }
337         
338         return pair;
339 }
340
341 ExportFilename::FieldPair
342 ExportFilename::analyse_folder ()
343 {
344         FieldPair pair;
345         
346         ustring session_dir = session.session_directory().root_path().to_string();
347         ustring::size_type session_dir_len = session_dir.length();
348         
349         ustring folder_beginning = folder.substr (0, session_dir_len);
350         
351         if (!folder_beginning.compare (session_dir)) {
352                 pair.first = true;
353                 pair.second = folder.substr (session_dir_len);
354         } else {
355                 pair.first = false;
356                 pair.second = folder;
357         }
358         
359         return pair;
360 }
361
362 } // namespace ARDOUR