OMNIBUS COMMIT: prefer const XMLNode::property method (and provide a real one)
[ardour.git] / gtk2_ardour / gui_object.cc
1 /*
2     Copyright (C) 2011 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 <iostream>
21 #include <sstream>
22
23 #include "gui_object.h"
24 #include "i18n.h"
25
26 using std::string;
27
28 /*static*/ XMLNode *
29 GUIObjectState::get_node (const XMLNode* parent, const string& id)
30 {
31         XMLNodeList const & children = parent->children ();
32         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
33                 if ((*i)->name() != X_("Object")) {
34                         continue;
35                 }
36                 if ((*i)->has_property_with_value(X_("id"), id)) {
37                         return *i;
38                 }
39         }
40         return 0;
41 }
42
43 /*static*/ XMLNode *
44 GUIObjectState::get_or_add_node (XMLNode* parent, const string& id)
45 {
46         XMLNode* child = get_node (parent, id);
47         if (!child) {
48                 child = new XMLNode (X_("Object"));
49                 child->add_property (X_("id"), id);
50                 parent->add_child_nocopy (*child);
51         }
52         return child;
53 }
54
55
56 const string GUIObjectState::xml_node_name (X_("GUIObjectState"));
57
58 GUIObjectState::GUIObjectState ()
59         : _state (X_("GUIObjectState"))
60 {
61 }
62
63 XMLNode *
64 GUIObjectState::get_or_add_node (const string& id)
65 {
66         std::map <std::string, XMLNode*>::iterator i = object_map.find (id);
67         if (i != object_map.end()) {
68                 return i->second;
69         }
70         //assert (get_node (&_state, id) == 0); // XXX
71         XMLNode* child = new XMLNode (X_("Object"));
72         child->add_property (X_("id"), id);
73         _state.add_child_nocopy (*child);
74         object_map[id] = child;
75         return child;
76 }
77
78 void
79 GUIObjectState::remove_node (const std::string& id)
80 {
81         object_map.erase (id);
82         _state.remove_nodes_and_delete(X_("id"), id );
83 }
84
85 string
86 GUIObjectState::get_string (const string& id, const string& prop_name, bool* empty)
87 {
88         std::map <std::string, XMLNode*>::const_iterator i = object_map.find (id);
89         if (i == object_map.end()) {
90                 //assert (get_node (&_state, id) == 0); // XXX
91                 if (empty) {
92                         *empty = true;
93                 }
94                 return string ();
95         }
96
97         XMLProperty const * p (i->second->property (prop_name));
98         if (!p) {
99                 if (empty) {
100                         *empty = true;
101                 }
102                 return string ();
103         }
104
105         if (empty) {
106                 *empty = false;
107         }
108
109         return p->value ();
110 }
111
112 XMLNode&
113 GUIObjectState::get_state () const
114 {
115         return *new XMLNode (_state);
116 }
117
118 int
119 GUIObjectState::set_state (const XMLNode& node)
120 {
121         if (node.name() != xml_node_name) {
122                 return -1;
123         }
124
125         object_map.clear ();
126         _state = node;
127
128         XMLNodeList const & children (_state.children ());
129         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
130                 if ((*i)->name() != X_("Object")) {
131                         continue;
132                 }
133                 XMLProperty const * prop = (*i)->property (X_("id"));
134                 if (!prop) {
135                         continue;
136                 }
137                 object_map[prop->value ()] = *i;
138         }
139         return 0;
140 }
141
142 void
143 GUIObjectState::load (const XMLNode& node)
144 {
145         (void) set_state (node);
146 }
147
148 std::list<string>
149 GUIObjectState::all_ids () const
150 {
151         std::list<string> ids;
152         for (std::map <std::string, XMLNode*>::const_iterator i = object_map.begin ();
153                         i != object_map.end (); ++i) {
154                 ids.push_back (i->first);
155         }
156         return ids;
157 }