ardour
export_filename.cc
Go to the documentation of this file.
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 
31 #include "ardour/session.h"
33 #include "ardour/export_filename.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 &
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);
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
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())) {
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()) {
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
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 
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 ? "" : "_";
214  filename_empty = false;
215  }
216 
217  if (include_time) {
218  path += filename_empty ? "" : "_";
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
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
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
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
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
305 {
306  label = value;
307  include_label = !value.compare ("");
308 }
309 
310 bool
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 
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 
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
std::string to_string(T t, std::ios_base &(*f)(std::ios_base &))
Definition: convert.h:53
int atoi(const string &s)
Definition: convert.cc:140
bool set_folder(std::string path)
const std::string & value() const
Definition: xml++.h:159
const std::string root_path() const
#define enum_2_string(e)
Definition: enumwriter.h:97
FieldPair get_field(XMLNode const &node, std::string const &name)
LIBARDOUR_API const char * revision
Definition: revision.cc:2
std::string name() const
Definition: session.h:166
LIBPBD_API Transmitter warning
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
int set_state(const XMLNode &)
XMLNode * add_child(const char *)
Definition: xml++.cc:351
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
std::string get_time_format_str(TimeFormat format) const
#define _(Text)
Definition: i18n.h:11
std::string get_path(ExportFormatSpecPtr format) const
XMLProperty * property(const char *)
Definition: xml++.cc:413
#define string_2_enum(str, e)
Definition: enumwriter.h:98
ExportChannelConfigPtr channel_config
std::string get_formatted_time(std::string const &format) const
bool string_is_affirmative(const std::string &str)
Definition: convert.cc:282
Definition: amp.h:29
ExportTimespanPtr timespan
XMLProperty * add_property(const char *name, const std::string &value)
const std::string export_path() const
void set_date_format(DateFormat format)
const char * name
void set_time_format(TimeFormat format)
LIBARDOUR_API std::string legalize_for_universal_path(const std::string &str)
XMLNode * instant_xml(const std::string &str)
Definition: xml++.h:95
XMLNode * extra_xml(const std::string &str, bool add_if_missing=false)
Definition: stateful.cc:77
Definition: debug.h:30
XMLNode * child(const char *) const
Definition: xml++.cc:309
const SessionDirectory & session_directory() const
Definition: session.h:182
void add_extra_xml(XMLNode &)
Definition: stateful.cc:66
void add_field(XMLNode *node, std::string const &name, bool enabled, std::string const &value="")
void set_label(std::string value)
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
std::pair< bool, std::string > FieldPair
std::string get_date_format_str(DateFormat format) const