Save templates as directories with plugin state, if
[ardour.git] / libs / ardour / template_utils.cc
1 #include <algorithm>
2 #include <cstring>
3
4 #include <glibmm.h>
5
6 #include "pbd/filesystem.h"
7 #include "pbd/basename.h"
8 #include "pbd/pathscanner.h"
9 #include "pbd/xml++.h"
10
11 #include "ardour/template_utils.h"
12 #include "ardour/directory_names.h"
13 #include "ardour/filesystem_paths.h"
14 #include "ardour/filename_extensions.h"
15 #include "ardour/io.h"
16
17 using namespace std;
18 using namespace PBD;
19
20 namespace ARDOUR {
21
22 sys::path
23 system_template_directory ()
24 {
25         SearchPath spath(system_data_search_path());
26         spath.add_subdirectory_to_paths(templates_dir_name);
27
28         // just return the first directory in the search path that exists
29         SearchPath::const_iterator i = std::find_if(spath.begin(), spath.end(), sys::exists);
30
31         if (i == spath.end()) return sys::path();
32
33         return *i;
34 }
35
36 sys::path
37 system_route_template_directory ()
38 {
39         SearchPath spath(system_data_search_path());
40         spath.add_subdirectory_to_paths(route_templates_dir_name);
41
42         // just return the first directory in the search path that exists
43         SearchPath::const_iterator i = std::find_if(spath.begin(), spath.end(), sys::exists);
44
45         if (i == spath.end()) return sys::path();
46
47         return *i;
48 }
49
50 sys::path
51 user_template_directory ()
52 {
53         sys::path p(user_config_directory());
54         p /= templates_dir_name;
55
56         return p;
57 }
58
59 sys::path
60 user_route_template_directory ()
61 {
62         sys::path p(user_config_directory());
63         p /= route_templates_dir_name;
64
65         return p;
66 }
67
68 static bool
69 template_filter (const string &str, void */*arg*/)
70 {
71         if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) {
72                 return false;
73         }
74         
75         return true;
76 }
77
78 string
79 session_template_dir_to_file (string const & dir)
80 {
81         sys::path dir_path = dir;
82         sys::path file_path = dir;
83         file_path /= dir_path.leaf() + template_suffix;
84         return file_path.to_string ();
85 }
86
87
88 void
89 find_session_templates (vector<TemplateInfo>& template_names)
90 {
91         vector<string *> *templates;
92         PathScanner scanner;
93         SearchPath spath (system_template_directory());
94         spath += user_template_directory ();
95
96         templates = scanner (spath.to_string(), template_filter, 0, true, true);
97
98         if (!templates) {
99                 cerr << "Found nothing along " << spath.to_string() << endl;
100                 return;
101         }
102
103         cerr << "Found " << templates->size() << " along " << spath.to_string() << endl;
104
105         for (vector<string*>::iterator i = templates->begin(); i != templates->end(); ++i) {
106                 string file = session_template_dir_to_file (**i);
107
108                 XMLTree tree;
109
110                 if (!tree.read (file.c_str())) {
111                         continue;
112                 }
113
114                 TemplateInfo rti;
115
116                 rti.name = basename_nosuffix (**i);
117                 rti.path = **i;
118
119                 template_names.push_back (rti);
120         }
121
122         delete templates;
123 }
124
125 void
126 find_route_templates (vector<TemplateInfo>& template_names)
127 {
128         vector<string *> *templates;
129         PathScanner scanner;
130         SearchPath spath (system_route_template_directory());
131         spath += user_route_template_directory ();
132
133         templates = scanner (spath.to_string(), template_filter, 0, false, true);
134
135         if (!templates) {
136                 return;
137         }
138
139         for (vector<string*>::iterator i = templates->begin(); i != templates->end(); ++i) {
140                 string fullpath = *(*i);
141
142                 XMLTree tree;
143
144                 if (!tree.read (fullpath.c_str())) {
145                         continue;
146                 }
147
148                 XMLNode* root = tree.root();
149
150                 TemplateInfo rti;
151
152                 rti.name = IO::name_from_state (*root->children().front());
153                 rti.path = fullpath;
154
155                 template_names.push_back (rti);
156         }
157
158         delete templates;
159 }
160
161 }