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