Whitespace.
[ardour.git] / libs / pbd / stateful.cc
1 /*
2     Copyright (C) 2000-2001 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     $Id: stateful.cc 629 2006-06-21 23:01:03Z paul $
19 */
20
21 #include <unistd.h>
22
23 #include "pbd/stateful.h"
24 #include "pbd/filesystem.h"
25 #include "pbd/xml++.h"
26 #include "pbd/error.h"
27
28 #include "i18n.h"
29
30 using namespace std;
31
32 namespace PBD {
33
34 int Stateful::current_state_version = 0;
35 int Stateful::loading_state_version = 0;
36
37 Stateful::Stateful ()
38 {
39         _extra_xml = 0;
40         _instant_xml = 0;
41 }
42
43 Stateful::~Stateful ()
44 {
45         // Do not delete _extra_xml.  The use of add_child_nocopy() 
46         // means it needs to live on indefinately.
47
48         delete _instant_xml;
49 }
50
51 void
52 Stateful::add_extra_xml (XMLNode& node)
53 {
54         if (_extra_xml == 0) {
55                 _extra_xml = new XMLNode ("Extra");
56         }
57
58         _extra_xml->remove_nodes (node.name());
59         _extra_xml->add_child_nocopy (node);
60 }
61
62 XMLNode *
63 Stateful::extra_xml (const string& str)
64 {
65         if (_extra_xml == 0) {
66                 return 0;
67         }
68
69         const XMLNodeList& nlist = _extra_xml->children();
70         XMLNodeConstIterator i;
71
72         for (i = nlist.begin(); i != nlist.end(); ++i) {
73                 if ((*i)->name() == str) {
74                         return (*i);
75                 }
76         }
77
78         return 0;
79 }
80
81 void
82 Stateful::add_instant_xml (XMLNode& node, const sys::path& directory_path)
83 {
84         sys::create_directories (directory_path); // may throw
85
86         if (_instant_xml == 0) {
87                 _instant_xml = new XMLNode ("instant");
88         }
89
90         _instant_xml->remove_nodes_and_delete (node.name());
91         _instant_xml->add_child_copy (node);
92
93         sys::path instant_xml_path(directory_path);
94
95         instant_xml_path /= "instant.xml";
96         
97         XMLTree tree;
98         tree.set_filename(instant_xml_path.to_string());
99
100         /* Important: the destructor for an XMLTree deletes
101            all of its nodes, starting at _root. We therefore
102            cannot simply hand it our persistent _instant_xml 
103            node as its _root, because we will lose it whenever
104            the Tree goes out of scope.
105
106            So instead, copy the _instant_xml node (which does 
107            a deep copy), and hand that to the tree.
108         */
109
110         XMLNode* copy = new XMLNode (*_instant_xml);
111         tree.set_root (copy);
112
113         if (!tree.write()) {
114                 error << string_compose(_("Error: could not write %1"), instant_xml_path.to_string()) << endmsg;
115         }
116 }
117
118 XMLNode *
119 Stateful::instant_xml (const string& str, const sys::path& directory_path)
120 {
121         if (_instant_xml == 0) {
122
123                 sys::path instant_xml_path(directory_path);
124                 instant_xml_path /= "instant.xml";
125
126                 if (exists(instant_xml_path)) {
127                         XMLTree tree;
128                         if (tree.read(instant_xml_path.to_string())) {
129                                 _instant_xml = new XMLNode(*(tree.root()));
130                         } else {
131                                 warning << string_compose(_("Could not understand XML file %1"), instant_xml_path.to_string()) << endmsg;
132                                 return 0;
133                         }
134                 } else {
135                         return 0;
136                 }
137         }
138
139         const XMLNodeList& nlist = _instant_xml->children();
140         XMLNodeConstIterator i;
141
142         for (i = nlist.begin(); i != nlist.end(); ++i) {
143                 if ((*i)->name() == str) {
144                         return (*i);
145                 }
146         }
147
148         return 0;
149 }
150
151 } // namespace PBD