Fix DSP load sorting with inactive plugins
[ardour.git] / gtk2_ardour / gui_object.cc
1 /*
2  * Copyright (C) 2011-2012 Carl Hetherington <carl@carlh.net>
3  * Copyright (C) 2011-2016 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2015-2016 Robin Gareus <robin@gareus.org>
5  *
6  * This program 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  * This program 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 along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include <iostream>
22 #include <sstream>
23
24 #include "gui_object.h"
25 #include "pbd/i18n.h"
26
27 using std::string;
28
29 /*static*/ XMLNode *
30 GUIObjectState::get_node (const XMLNode* parent, const string& id)
31 {
32         XMLNodeList const & children = parent->children ();
33         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
34                 if ((*i)->name() != X_("Object")) {
35                         continue;
36                 }
37                 if ((*i)->has_property_with_value(X_("id"), id)) {
38                         return *i;
39                 }
40         }
41         return 0;
42 }
43
44 /*static*/ XMLNode *
45 GUIObjectState::get_or_add_node (XMLNode* parent, const string& id)
46 {
47         XMLNode* child = get_node (parent, id);
48         if (!child) {
49                 child = new XMLNode (X_("Object"));
50                 child->set_property (X_("id"), id);
51                 parent->add_child_nocopy (*child);
52         }
53         return child;
54 }
55
56
57 const string GUIObjectState::xml_node_name (X_("GUIObjectState"));
58
59 GUIObjectState::GUIObjectState ()
60         : _state (X_("GUIObjectState"))
61 {
62 }
63
64 XMLNode *
65 GUIObjectState::get_or_add_node (const string& id)
66 {
67         std::map <std::string, XMLNode*>::iterator i = object_map.find (id);
68         if (i != object_map.end()) {
69                 return i->second;
70         }
71         //assert (get_node (&_state, id) == 0); // XXX performance penalty due to get_node()
72         XMLNode* child = new XMLNode (X_("Object"));
73         child->set_property (X_("id"), id);
74         _state.add_child_nocopy (*child);
75         object_map[id] = child;
76         return child;
77 }
78
79 void
80 GUIObjectState::remove_node (const std::string& id)
81 {
82         object_map.erase (id);
83         _state.remove_nodes_and_delete(X_("id"), id );
84 }
85
86 string
87 GUIObjectState::get_string (const string& id, const string& prop_name, bool* empty)
88 {
89         std::map <std::string, XMLNode*>::const_iterator i = object_map.find (id);
90         if (i == object_map.end()) {
91                 //assert (get_node (&_state, id) == 0); // XXX performance penalty due to get_node()
92                 if (empty) {
93                         *empty = true;
94                 }
95                 return string ();
96         }
97         //assert (get_node (&_state, id) == i->second); // XXX performance penalty due to get_node()
98
99         XMLProperty const * p (i->second->property (prop_name));
100         if (!p) {
101                 if (empty) {
102                         *empty = true;
103                 }
104                 return string ();
105         }
106
107         if (empty) {
108                 *empty = false;
109         }
110
111         return p->value ();
112 }
113
114 XMLNode&
115 GUIObjectState::get_state () const
116 {
117         return *new XMLNode (_state);
118 }
119
120 int
121 GUIObjectState::set_state (const XMLNode& node)
122 {
123         if (node.name() != xml_node_name) {
124                 return -1;
125         }
126
127         object_map.clear ();
128         _state = node;
129
130         XMLNodeList const & children (_state.children ());
131         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
132                 if ((*i)->name() != X_("Object")) {
133                         continue;
134                 }
135                 XMLProperty const * prop = (*i)->property (X_("id"));
136                 if (!prop) {
137                         continue;
138                 }
139                 object_map[prop->value ()] = *i;
140         }
141         return 0;
142 }
143
144 void
145 GUIObjectState::load (const XMLNode& node)
146 {
147         (void) set_state (node);
148 }
149
150 std::list<string>
151 GUIObjectState::all_ids () const
152 {
153         std::list<string> ids;
154         for (std::map <std::string, XMLNode*>::const_iterator i = object_map.begin ();
155                         i != object_map.end (); ++i) {
156                 ids.push_back (i->first);
157         }
158         return ids;
159 }