Allow configuration of KDM filename format.
[dcpomatic.git] / src / lib / name_format.cc
1 /*
2     Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "name_format.h"
22 #include <boost/optional.hpp>
23 #include <boost/foreach.hpp>
24
25 using std::string;
26 using std::map;
27 using boost::optional;
28
29 static char
30 filter (char c)
31 {
32         if (c == '/' || c == ':') {
33                 c = '-';
34         } else if (c == ' ') {
35                 c = '_';
36         }
37
38         return c;
39 }
40
41 static string
42 filter (string c)
43 {
44         string o;
45
46         for (size_t i = 0; i < c.length(); ++i) {
47                 o += filter (c[i]);
48         }
49
50         return o;
51 }
52
53 void
54 NameFormat::add (string name, char placeholder, string title)
55 {
56         _components.push_back (Component (name, placeholder, title));
57 }
58
59 optional<NameFormat::Component>
60 NameFormat::component_by_placeholder (char p) const
61 {
62         BOOST_FOREACH (Component const & i, _components) {
63                 if (i.placeholder == p) {
64                         return i;
65                 }
66         }
67
68         return optional<Component> ();
69 }
70
71 string
72 NameFormat::get (Map values) const
73 {
74         string result;
75         for (size_t i = 0; i < _specification.length(); ++i) {
76                 bool done = false;
77                 if (_specification[i] == '%' && (i < _specification.length() - 1)) {
78                         optional<Component> c = component_by_placeholder (_specification[i + 1]);
79                         if (c) {
80                                 result += filter (values[c->name]);
81                                 ++i;
82                                 done = true;
83                         }
84                 }
85
86                 if (!done) {
87                         result += filter (_specification[i]);
88                 }
89         }
90
91         return result;
92 }
93
94 bool
95 operator== (NameFormat const & a, NameFormat const & b)
96 {
97         return a.specification() == b.specification();
98 }