fix merge conflicts with master
[ardour.git] / gtk2_ardour / global_port_matrix.cc
1 /*
2     Copyright (C) 2009 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 <gtkmm/image.h>
21 #include <gtkmm/stock.h>
22
23 #include "global_port_matrix.h"
24 #include "utils.h"
25
26 #include "ardour/bundle.h"
27 #include "ardour/session.h"
28 #include "ardour/audioengine.h"
29 #include "ardour/port.h"
30
31 #include "i18n.h"
32
33 using namespace std;
34 using namespace ARDOUR;
35
36 GlobalPortMatrix::GlobalPortMatrix (Gtk::Window* p, Session* s, DataType t)
37         : PortMatrix (p, s, t)
38 {
39         setup_all_ports ();
40         init ();
41 }
42
43 void
44 GlobalPortMatrix::setup_ports (int dim)
45 {
46         if (!_session) {
47                 return;
48         }
49
50         _ports[dim].suspend_signals ();
51         _ports[dim].gather (_session, type(), dim == IN, false, show_only_bundles ());
52         _ports[dim].resume_signals ();
53 }
54
55 void
56 GlobalPortMatrix::set_state (BundleChannel c[2], bool s)
57 {
58         if (!_session) {
59                 return;
60         }
61
62         Bundle::PortList const & in_ports = c[IN].bundle->channel_ports (c[IN].channel);
63         Bundle::PortList const & out_ports = c[OUT].bundle->channel_ports (c[OUT].channel);
64
65         for (Bundle::PortList::const_iterator i = in_ports.begin(); i != in_ports.end(); ++i) {
66                 for (Bundle::PortList::const_iterator j = out_ports.begin(); j != out_ports.end(); ++j) {
67
68                         boost::shared_ptr<Port> p = _session->engine().get_port_by_name (*i);
69                         boost::shared_ptr<Port> q = _session->engine().get_port_by_name (*j);
70
71                         if (p) {
72                                 if (s) {
73                                         p->connect (*j);
74                                 } else {
75                                         p->disconnect (*j);
76                                 }
77                         } else if (q) {
78                                 if (s) {
79                                         q->connect (*i);
80                                 } else {
81                                         q->disconnect (*i);
82                                 }
83                         } else {
84                                 /* two non-Ardour ports */
85                                 if (s) {
86                                         AudioEngine::instance()->connect (*j, *i);
87                                 } else {
88                                         AudioEngine::instance()->disconnect (*j, *i);
89                                 }
90                         }
91                 }
92         }
93 }
94
95 PortMatrixNode::State
96 GlobalPortMatrix::get_state (BundleChannel c[2]) const
97 {
98         if (_session == 0) {
99                 return PortMatrixNode::NOT_ASSOCIATED;
100         }
101
102         if (c[0].bundle->nchannels() == ChanCount::ZERO || c[1].bundle->nchannels() == ChanCount::ZERO) {
103                 return PortMatrixNode::NOT_ASSOCIATED;
104         }
105
106         Bundle::PortList const & in_ports = c[IN].bundle->channel_ports (c[IN].channel);
107         Bundle::PortList const & out_ports = c[OUT].bundle->channel_ports (c[OUT].channel);
108         if (in_ports.empty() || out_ports.empty()) {
109                 /* we're looking at a bundle with no parts associated with this channel,
110                    so nothing to connect */
111                 return PortMatrixNode::NOT_ASSOCIATED;
112         }
113
114         for (Bundle::PortList::const_iterator i = in_ports.begin(); i != in_ports.end(); ++i) {
115                 for (Bundle::PortList::const_iterator j = out_ports.begin(); j != out_ports.end(); ++j) {
116
117                         boost::shared_ptr<Port> p = AudioEngine::instance()->get_port_by_name (*i);
118                         boost::shared_ptr<Port> q = AudioEngine::instance()->get_port_by_name (*j);
119
120                         if (!p && !q) {
121                                 /* two non-Ardour ports; things are slightly more involved */
122
123                                 /* get a port handle for one of them .. */
124
125                                 PortEngine::PortHandle ph = AudioEngine::instance()->port_engine().get_port_by_name (*i);
126                                 if (!ph) {
127                                         return PortMatrixNode::NOT_ASSOCIATED;
128                                 }
129
130                                 /* see if it is connected to the other one ... */
131
132                                 if (AudioEngine::instance()->port_engine().connected_to (ph, *j, false)) {
133                                         return PortMatrixNode::ASSOCIATED;
134                                 }
135
136                                 return PortMatrixNode::NOT_ASSOCIATED;
137                         }
138
139                         if (p && p->connected_to (*j) == false) {
140                                 return PortMatrixNode::NOT_ASSOCIATED;
141                         } else if (q && q->connected_to (*i) == false) {
142                                 return PortMatrixNode::NOT_ASSOCIATED;
143                         }
144
145                 }
146         }
147
148         return PortMatrixNode::ASSOCIATED;
149 }
150
151 GlobalPortMatrixWindow::GlobalPortMatrixWindow (Session* s, DataType t)
152         : ArdourWindow (X_("reset me soon"))
153         , _port_matrix (this, s, t)
154 {
155         switch (t) {
156         case DataType::AUDIO:
157                 set_title (_("Audio Connection Manager"));
158                 break;
159         case DataType::MIDI:
160                 set_title (_("MIDI Connection Manager"));
161                 break;
162         }
163
164         signal_key_press_event().connect (sigc::mem_fun (_port_matrix, &PortMatrix::key_press));
165
166         add (_port_matrix);
167         _port_matrix.show ();
168 }
169
170 void
171 GlobalPortMatrixWindow::on_show ()
172 {
173         Gtk::Window::on_show ();
174         pair<uint32_t, uint32_t> const pm_max = _port_matrix.max_size ();
175         resize_window_to_proportion_of_monitor (this, pm_max.first, pm_max.second);
176 }
177
178 void
179 GlobalPortMatrixWindow::set_session (Session* s)
180 {
181         _port_matrix.set_session (s);
182
183         if (!s) {
184                 hide ();
185         }
186 }
187
188 void
189 GlobalPortMatrix::set_session (Session *s)
190 {
191         SessionHandlePtr::set_session (s);
192         if (!s) return;
193         setup_all_ports ();
194         init();
195 }
196
197 string
198 GlobalPortMatrix::disassociation_verb () const
199 {
200         return _("Disconnect");
201 }
202
203 string
204 GlobalPortMatrix::channel_noun () const
205 {
206         return _("port");
207 }
208