Merge branch 'master' into windows
[ardour.git] / libs / ardour / template_utils.cc
1 /*
2     Copyright (C) 2012 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <algorithm>
21 #include <cstring>
22
23 #include <glibmm.h>
24
25 #include "pbd/basename.h"
26 #include "pbd/pathscanner.h"
27 #include "pbd/xml++.h"
28
29 #include "ardour/template_utils.h"
30 #include "ardour/directory_names.h"
31 #include "ardour/filesystem_paths.h"
32 #include "ardour/filename_extensions.h"
33 #include "ardour/io.h"
34
35 #ifdef SearchPath
36 #undef SearchPath
37 #endif
38
39 using namespace std;
40 using namespace PBD;
41
42 namespace ARDOUR {
43
44 SearchPath
45 template_search_path ()
46 {
47         SearchPath spath (ardour_data_search_path());
48         spath.add_subdirectory_to_paths(templates_dir_name);
49         return spath;
50 }
51
52 SearchPath
53 route_template_search_path ()
54 {
55         SearchPath spath (ardour_data_search_path());
56         spath.add_subdirectory_to_paths(route_templates_dir_name);
57         return spath;
58 }
59
60 std::string
61 user_template_directory ()
62 {
63         return Glib::build_filename (user_config_directory(), templates_dir_name);
64 }
65
66 std::string
67 user_route_template_directory ()
68 {
69         return Glib::build_filename (user_config_directory(), route_templates_dir_name);
70 }
71
72 static bool
73 template_filter (const string &str, void */*arg*/)
74 {
75         if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) {
76                 return false;
77         }
78         
79         return true;
80 }
81
82 static bool
83 route_template_filter (const string &str, void */*arg*/)
84 {
85         if (str.find (template_suffix) == str.length() - strlen (template_suffix)) {
86                 return true;
87         }
88         
89         return false;
90 }
91
92 string
93 session_template_dir_to_file (string const & dir)
94 {
95         return Glib::build_filename (dir, Glib::path_get_basename(dir) + template_suffix);
96 }
97
98
99 void
100 find_session_templates (vector<TemplateInfo>& template_names)
101 {
102         vector<string *> *templates;
103         PathScanner scanner;
104         SearchPath spath (template_search_path());
105
106         templates = scanner (spath.to_string(), template_filter, 0, true, true);
107
108         if (!templates) {
109                 cerr << "Found nothing along " << spath.to_string() << endl;
110                 return;
111         }
112
113         cerr << "Found " << templates->size() << " along " << spath.to_string() << endl;
114
115         for (vector<string*>::iterator i = templates->begin(); i != templates->end(); ++i) {
116                 string file = session_template_dir_to_file (**i);
117
118                 XMLTree tree;
119
120                 if (!tree.read (file.c_str())) {
121                         continue;
122                 }
123
124                 TemplateInfo rti;
125
126                 rti.name = basename_nosuffix (**i);
127                 rti.path = **i;
128
129                 template_names.push_back (rti);
130         }
131
132         delete templates;
133 }
134
135 void
136 find_route_templates (vector<TemplateInfo>& template_names)
137 {
138         vector<string *> *templates;
139         PathScanner scanner;
140         SearchPath spath (route_template_search_path());
141
142         templates = scanner (spath.to_string(), route_template_filter, 0, false, true);
143
144         if (!templates) {
145                 return;
146         }
147
148         for (vector<string*>::iterator i = templates->begin(); i != templates->end(); ++i) {
149                 string fullpath = *(*i);
150
151                 XMLTree tree;
152
153                 if (!tree.read (fullpath.c_str())) {
154                         continue;
155                 }
156
157                 XMLNode* root = tree.root();
158
159                 TemplateInfo rti;
160
161                 rti.name = IO::name_from_state (*root->children().front());
162                 rti.path = fullpath;
163
164                 template_names.push_back (rti);
165         }
166
167         delete templates;
168 }
169
170 }