2 Copyright (C) 2002-2009 Paul Davis
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.
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.
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.
20 #include "port_group.h"
22 #include "ardour/session.h"
23 #include "ardour/audio_track.h"
24 #include "ardour/midi_track.h"
25 #include "ardour/audioengine.h"
26 #include <boost/shared_ptr.hpp>
32 /** Add a port to a group.
33 * @param p Port name, with or without prefix.
36 PortGroup::add (std::string const & p)
38 if (prefix.empty() == false && p.substr (0, prefix.length()) == prefix) {
39 ports.push_back (p.substr (prefix.length()));
45 /** PortGroupUI constructor.
46 * @param m PortMatrix to work for.
47 * @Param g PortGroup to represent.
50 PortGroupUI::PortGroupUI (PortMatrix& m, PortGroup& g)
53 , _ignore_check_button_toggle (false)
54 , _visibility_checkbutton (g.name)
56 _port_group.visible = true;
57 _ignore_check_button_toggle = false;
58 _visibility_checkbutton.signal_toggled().connect (sigc::mem_fun (*this, &PortGroupUI::visibility_checkbutton_toggled));
61 /** The visibility of a PortGroupUI has been toggled */
63 PortGroupUI::visibility_checkbutton_toggled ()
65 _port_group.visible = _visibility_checkbutton.get_active ();
68 /** @return Checkbutton used to toggle visibility */
70 PortGroupUI::get_visibility_checkbutton ()
72 return _visibility_checkbutton;
76 /** Handle a toggle of a port check button */
78 PortGroupUI::port_checkbutton_toggled (CheckButton* b, int r, int c)
80 if (_ignore_check_button_toggle == false) {
81 // _port_matrix.hide_group (_port_group);
85 /** Set up visibility of the port group according to PortGroup::visible */
87 PortGroupUI::setup_visibility ()
89 if (_visibility_checkbutton.get_active () != _port_group.visible) {
90 _visibility_checkbutton.set_active (_port_group.visible);
94 /** PortGroupList constructor.
95 * @param session Session to get ports from.
96 * @param type Type of ports to offer (audio or MIDI)
97 * @param offer_inputs true to offer output ports, otherwise false.
98 * @param mask Mask of groups to make visible by default.
101 PortGroupList::PortGroupList (ARDOUR::Session & session, ARDOUR::DataType type, bool offer_inputs, Mask mask)
102 : _session (session), _type (type), _offer_inputs (offer_inputs),
103 _buss (_("Bus"), "ardour:", mask & BUSS),
104 _track (_("Track"), "ardour:", mask & TRACK),
105 _system (_("System"), "system:", mask & SYSTEM),
106 _other (_("Other"), "", mask & OTHER)
111 /** Find or re-find all our ports and set up our lists */
113 PortGroupList::refresh ()
117 _buss.ports.clear ();
118 _track.ports.clear ();
119 _system.ports.clear ();
120 _other.ports.clear ();
122 /* Find the ports provided by ardour; we can't derive their type just from their
123 names, so we'll have to be more devious.
126 boost::shared_ptr<ARDOUR::Session::RouteList> routes = _session.get_routes ();
128 for (ARDOUR::Session::RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) {
132 if (_type == ARDOUR::DataType::AUDIO) {
134 if (boost::dynamic_pointer_cast<ARDOUR::AudioTrack> (*i)) {
136 } else if (!boost::dynamic_pointer_cast<ARDOUR::MidiTrack>(*i)) {
141 } else if (_type == ARDOUR::DataType::MIDI) {
143 if (boost::dynamic_pointer_cast<ARDOUR::MidiTrack> (*i)) {
147 /* No MIDI busses yet */
151 ARDOUR::PortSet const & p = _offer_inputs ? ((*i)->inputs()) : ((*i)->outputs());
152 for (uint32_t j = 0; j < p.num_ports(); ++j) {
153 g->add (p.port(j)->name ());
156 std::sort (g->ports.begin(), g->ports.end());
160 /* XXX: inserts, sends, plugin inserts? */
162 /* Now we need to find the non-ardour ports; we do this by first
163 finding all the ports that we can connect to.
166 const char **ports = _session.engine().get_ports ("", _type.to_jack_type(), _offer_inputs ?
167 JackPortIsInput : JackPortIsOutput);
171 string client_matching_string;
173 client_matching_string = _session.engine().client_name();
174 client_matching_string += ':';
177 std::string const p = ports[n];
179 if (p.substr(0, strlen ("system:")) == "system:") {
183 if (p.substr(0, client_matching_string.length()) != client_matching_string) {
184 /* other (non-ardour) prefix */
195 push_back (&_system);
202 PortGroupList::n_visible_ports () const
206 for (const_iterator i = begin(); i != end(); ++i) {
208 n += (*i)->ports.size();
216 PortGroupList::get_port_by_index (int n, bool with_prefix) const
218 /* XXX: slightly inefficient algorithm */
220 for (const_iterator i = begin(); i != end(); ++i) {
221 for (std::vector<std::string>::const_iterator j = (*i)->ports.begin(); j != (*i)->ports.end(); ++j) {
224 return (*i)->prefix + *j;
237 PortGroupList::set_type (ARDOUR::DataType t)
243 PortGroupList::set_offer_inputs (bool i)