Show cursor in Cut mode on button press at cutting position
[ardour.git] / gtk2_ardour / instrument_selector.cc
1 /*
2   Copyright (C) 2003-2014 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 #include "pbd/convert.h"
20 #include "pbd/enumwriter.h"
21 #include "ardour/plugin_manager.h"
22 #include "gtkmm2ext/gui_thread.h"
23 #include "instrument_selector.h"
24
25 #include "pbd/i18n.h"
26
27 using namespace Gtk;
28 using namespace ARDOUR;
29
30 InstrumentSelector::InstrumentSelector()
31         : _reasonable_synth_id(0)
32 {
33         refill ();
34
35         PluginManager::instance ().PluginListChanged.connect (_update_connection, invalidator (*this), boost::bind (&InstrumentSelector::refill, this), gui_context());
36 }
37
38 void
39 InstrumentSelector::refill()
40 {
41         TreeModel::iterator iter = get_active();
42         std::string selected;
43         if (iter) {
44                 const TreeModel::Row& row = (*iter);
45                 selected = row[_instrument_list_columns.name];
46         }
47
48         unset_model ();
49         clear ();
50         build_instrument_list();
51         set_model(_instrument_list);
52         pack_start(_instrument_list_columns.name);
53         if (selected.empty ()) {
54                 set_active(_reasonable_synth_id);
55         } else {
56                 TreeModel::Children rows = _instrument_list->children();
57                 TreeModel::Children::iterator i;
58                 for (i = rows.begin(); i != rows.end(); ++i) {
59                         std::string cn = (*i)[_instrument_list_columns.name];
60                         if (cn == selected) {
61                                 set_active(*i);
62                                 break;
63                         }
64                 }
65         }
66         set_button_sensitivity(Gtk::SENSITIVITY_AUTO);
67 }
68
69 static bool
70 pluginsort (const PluginInfoPtr& a, const PluginInfoPtr& b)
71 {
72         return PBD::downcase(a->name) < PBD::downcase(b->name);
73 }
74
75 static bool
76 invalid_instrument (PluginInfoPtr p) {
77         const PluginManager& manager = PluginManager::instance();
78         if (manager.get_status(p) == PluginManager::Hidden) {
79                 return true;
80         }
81         return !p->is_instrument();
82 }
83
84 void
85 InstrumentSelector::build_instrument_list()
86 {
87         PluginManager& manager = PluginManager::instance();
88
89         PluginInfoList all_plugs;
90         all_plugs.insert(all_plugs.end(), manager.ladspa_plugin_info().begin(), manager.ladspa_plugin_info().end());
91         all_plugs.insert(all_plugs.end(), manager.lua_plugin_info().begin(), manager.lua_plugin_info().end());
92 #ifdef WINDOWS_VST_SUPPORT
93         all_plugs.insert(all_plugs.end(), manager.windows_vst_plugin_info().begin(), manager.windows_vst_plugin_info().end());
94 #endif
95 #ifdef LXVST_SUPPORT
96         all_plugs.insert(all_plugs.end(), manager.lxvst_plugin_info().begin(), manager.lxvst_plugin_info().end());
97 #endif
98 #ifdef MACVST_SUPPORT
99         all_plugs.insert(all_plugs.end(), manager.mac_vst_plugin_info().begin(), manager.mac_vst_plugin_info().end());
100 #endif
101 #ifdef AUDIOUNIT_SUPPORT
102         all_plugs.insert(all_plugs.end(), manager.au_plugin_info().begin(), manager.au_plugin_info().end());
103 #endif
104 #ifdef LV2_SUPPORT
105         all_plugs.insert(all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
106 #endif
107
108         all_plugs.remove_if (invalid_instrument);
109         all_plugs.sort (pluginsort);
110
111         _instrument_list = ListStore::create(_instrument_list_columns);
112
113         TreeModel::Row row = *(_instrument_list->append());
114         row[_instrument_list_columns.info_ptr] = PluginInfoPtr();
115         row[_instrument_list_columns.name]     = _("-none-");
116
117         uint32_t n = 1;
118         std::string prev;
119         for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end();) {
120                 PluginInfoPtr p = *i;
121                 ++i;
122                 bool suffix_type = prev == p->name;
123                 if (!suffix_type && i != all_plugs.end() && (*i)->name == p->name) {
124                         suffix_type = true;
125                 }
126
127                 row = *(_instrument_list->append());
128                 if (suffix_type) {
129                         std::string pt;
130                         switch (p->type) {
131                                 case AudioUnit:
132                                         pt = "AU";
133                                         break;
134                                 case Windows_VST:
135                                 case LXVST:
136                                 case MacVST:
137                                         pt = "VST";
138                                         break;
139                                 default:
140                                         pt = enum_2_string (p->type);
141                         }
142                         row[_instrument_list_columns.name]   = p->name + " (" + pt + ")";
143                 } else {
144                         row[_instrument_list_columns.name]   = p->name;
145                 }
146                 row[_instrument_list_columns.info_ptr] = p;
147                 if (p->unique_id == "https://community.ardour.org/node/7596") {
148                         _reasonable_synth_id = n;
149                 }
150                 prev = p->name;
151                 n++;
152         }
153 }
154
155 PluginInfoPtr
156 InstrumentSelector::selected_instrument()
157 {
158         TreeModel::iterator iter = get_active();
159         if (!iter) {
160                 return PluginInfoPtr();
161         }
162
163         const TreeModel::Row& row = (*iter);
164         return row[_instrument_list_columns.info_ptr];
165 }