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