don't use PluginSelector::vst_refiller if VST_SUPPORT not defined
[ardour.git] / gtk2_ardour / plugin_selector.cc
1 /*
2     Copyright (C) 2000 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 <cstdio>
21 #include <lrdf.h>
22
23 #include <gtkmm/table.h>
24 #include <gtkmm/stock.h>
25 #include <gtkmm/button.h>
26 #include <gtkmm/notebook.h>
27
28 #include <ardour/plugin_manager.h>
29 #include <ardour/plugin.h>
30 #include <ardour/configuration.h>
31
32 #include "ardour_ui.h"
33 #include "plugin_selector.h"
34 #include "gui_thread.h"
35
36 #include "i18n.h"
37
38 using namespace ARDOUR;
39 using namespace PBD;
40 using namespace Gtk;
41
42 PluginSelector::PluginSelector (PluginManager *mgr)
43         : ArdourDialog (_("ardour: plugins"), true, false)
44 {
45         set_position (Gtk::WIN_POS_MOUSE);
46         set_name ("PluginSelectorWindow");
47         add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
48
49         manager = mgr;
50         session = 0;
51         o_selected_plug = -1;
52         i_selected_plug = 0;
53
54         lmodel = Gtk::ListStore::create(lcols);
55         ladspa_display.set_model (lmodel);
56         ladspa_display.append_column (_("Available LADSPA Plugins"), lcols.name);
57         ladspa_display.append_column (_("Type"), lcols.type);
58         ladspa_display.append_column (_("# Inputs"),lcols.ins);
59         ladspa_display.append_column (_("# Outputs"), lcols.outs);
60         ladspa_display.set_headers_visible (true);
61         ladspa_display.set_reorderable (false);
62         lscroller.set_border_width(10);
63         lscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
64         lscroller.add(ladspa_display);
65
66         amodel = Gtk::ListStore::create(acols);
67         added_list.set_model (amodel);
68         added_list.append_column (_("Plugins to be Connected to Insert"), acols.text);
69         added_list.set_headers_visible (true);
70         added_list.set_reorderable (false);
71
72         for (int i = 0; i <=3; i++) {
73                 Gtk::TreeView::Column* column = ladspa_display.get_column(i);
74                 column->set_sort_column(i);
75         }
76
77 #ifdef VST_SUPPORT
78         vmodel = ListStore::create(vcols);
79         vst_display.set_model (vmodel);
80         vst_display.append_column (_("Available plugins"), vcols.name);
81         vst_display.append_column (_("# Inputs"), vcols.ins);
82         vst_display.append_column (_("# Outputs"), vcols.outs);
83         vst_display.set_headers_visible (true);
84         vst_display.set_reorderable (false);
85         vscroller.set_border_width(10);
86         vscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
87         vscroller.add(vst_display);
88
89         for (int i = 0; i <=2; i++) {
90                 Gtk::TreeView::Column* column = vst_display.get_column(i);
91                 column->set_sort_column(i);
92         }
93 #endif
94         ascroller.set_border_width(10);
95         ascroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
96         ascroller.add(added_list);
97         btn_add = manage(new Gtk::Button(Stock::ADD));
98         ARDOUR_UI::instance()->tooltips().set_tip(*btn_add, _("Add a plugin to the effect list"));
99         btn_add->set_sensitive (false);
100         btn_remove = manage(new Gtk::Button(Stock::REMOVE));
101         btn_remove->set_sensitive (false);
102         ARDOUR_UI::instance()->tooltips().set_tip(*btn_remove, _("Remove a plugin from the effect list"));
103         Gtk::Button *btn_update = manage(new Gtk::Button(Stock::REFRESH));
104         ARDOUR_UI::instance()->tooltips().set_tip(*btn_update, _("Update available plugins"));
105
106         btn_add->set_name("PluginSelectorButton");
107         btn_remove->set_name("PluginSelectorButton");
108
109         Gtk::Table* table = manage(new Gtk::Table(7, 10));
110         table->set_size_request(750, 500);
111         table->attach(notebook, 0, 7, 0, 5);
112
113         table->attach(*btn_add, 1, 2, 5, 6, Gtk::FILL, Gtk::FILL, 5, 5);
114         table->attach(*btn_remove, 3, 4, 5, 6, Gtk::FILL, Gtk::FILL, 5, 5);
115         table->attach(*btn_update, 5, 6, 5, 6, Gtk::FILL, Gtk::FILL, 5, 5);
116
117         table->attach(ascroller, 0, 7, 7, 9);
118
119         add_button (Stock::CANCEL, RESPONSE_CANCEL);
120         add_button (Stock::CONNECT, RESPONSE_APPLY);
121         set_default_response (RESPONSE_APPLY);
122         set_response_sensitive (RESPONSE_APPLY, false);
123         get_vbox()->pack_start (*table);
124
125         using namespace Gtk::Notebook_Helpers;
126         notebook.pages().push_back (TabElem (lscroller, _("LADSPA")));
127 #ifdef VST_SUPPORT
128         if (Config->get_use_vst()) {
129                 notebook.pages().push_back (TabElem (vscroller, _("VST")));
130         }
131 #endif
132
133         table->set_name("PluginSelectorTable");
134         ladspa_display.set_name("PluginSelectorDisplay");
135         //ladspa_display.set_name("PluginSelectorList");
136         added_list.set_name("PluginSelectorList");
137
138         ladspa_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
139 #ifdef VST_SUPPORT
140         if (Config->get_use_vst()) {
141                 vst_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
142                 vst_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::vst_display_selection_changed));
143         }
144 #endif
145         
146         btn_update->signal_clicked().connect (mem_fun(*this, &PluginSelector::btn_update_clicked));
147         btn_add->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_add_clicked));
148         btn_remove->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_remove_clicked));
149         ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed));
150         added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed));
151
152         input_refiller ();
153 #ifdef VST_SUPPORT
154         vst_refiller ();
155 #endif
156 }
157
158 void
159 PluginSelector::row_clicked(GdkEventButton* event)
160 {
161         if (event->type == GDK_2BUTTON_PRESS)
162                 btn_add_clicked();
163 }
164
165 void
166 PluginSelector::set_session (Session* s)
167 {
168         ENSURE_GUI_THREAD(bind (mem_fun(*this, &PluginSelector::set_session), s));
169         
170         session = s;
171
172         if (session) {
173                 session->going_away.connect (bind (mem_fun(*this, &PluginSelector::set_session), static_cast<Session*> (0)));
174         }
175 }
176
177 void
178 PluginSelector::_input_refiller (void *arg)
179 {
180         ((PluginSelector *) arg)->input_refiller ();
181 }
182
183 int compare(const void *left, const void *right)
184 {
185   return strcmp(*((char**)left), *((char**)right));
186 }
187
188 void
189 PluginSelector::input_refiller ()
190 {
191         guint row;
192         list<PluginInfo *> &plugs = manager->ladspa_plugin_info ();
193         list<PluginInfo *>::iterator i;
194         char ibuf[16], obuf[16];
195         lmodel->clear();
196 #ifdef VST_SUPPORT
197         vmodel->clear();
198 #endif
199         // Insert into GTK list
200         for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
201                 snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
202                 snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs);         
203                 
204                 Gtk::TreeModel::Row newrow = *(lmodel->append());
205                 newrow[lcols.name] = (*i)->name.c_str();
206                 newrow[lcols.type] = (*i)->category.c_str();
207                 newrow[lcols.ins] = ibuf;
208                 newrow[lcols.outs] = obuf;
209                 newrow[lcols.plugin] = *i;
210         }
211
212         lmodel->set_sort_column (0, Gtk::SORT_ASCENDING);
213 }
214
215 #ifdef VST_SUPPORT
216
217 void
218 PluginSelector::_vst_refiller (void *arg)
219 {
220         ((PluginSelector *) arg)->vst_refiller ();
221 }
222
223 void
224 PluginSelector::vst_refiller ()
225 {
226         guint row;
227         list<PluginInfo *> &plugs = manager->vst_plugin_info ();
228         list<PluginInfo *>::iterator i;
229         char ibuf[16], obuf[16];
230         
231         // Insert into GTK list
232         for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
233
234                 snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
235                 snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs);         
236                 
237                 Gtk::TreeModel::Row newrow = *(vmodel->append());
238                 newrow[vcols.name] = (*i)->name.c_str();
239                 newrow[vcols.ins] = ibuf;
240                 newrow[vcols.outs] = obuf;
241                 newrow[vcols.plugin] = *i;
242         }
243         vmodel->set_sort_column (0, Gtk::SORT_ASCENDING);
244 }
245 #endif
246
247 void
248 PluginSelector::use_plugin (PluginInfo* pi)
249 {
250         list<PluginInfo *>::iterator i;
251
252         if (pi == 0 || session == 0) {
253                 return;
254         }
255
256         Plugin *plugin = manager->load (*session, pi);
257
258         if (plugin) {
259                 PluginCreated (plugin);
260         }
261 }
262
263 void
264 PluginSelector::btn_add_clicked()
265 {
266         bool vst = notebook.get_current_page(); // 0 = LADSPA, 1 = VST
267         std::string name;
268         ARDOUR::PluginInfo *pi;
269         Gtk::TreeModel::Row newrow = *(amodel->append());
270         
271         if (vst) {
272 #ifdef VST_SUPPORT
273                 Gtk::TreeModel::Row row = *(vst_display.get_selection()->get_selected());
274                 name = row[vcols.name];
275                 pi = row[vcols.plugin];
276                 added_plugins.push_back (row[vcols.plugin]);
277 #endif
278         } else {
279                 Gtk::TreeModel::Row row = *(ladspa_display.get_selection()->get_selected());
280                 name = row[lcols.name];
281                 pi = row[lcols.plugin];
282                 added_plugins.push_back (row[lcols.plugin]);
283         }
284         newrow[acols.text] = name;
285         newrow[acols.plugin] = pi;
286
287         if (!amodel->children().empty()) {
288           set_response_sensitive (RESPONSE_APPLY, true);
289         }
290 }
291
292 void
293 PluginSelector::btn_remove_clicked()
294 {
295         list<PluginInfo*>::iterator i;
296         Gtk::TreeModel::iterator iter = added_list.get_selection()->get_selected();
297         for (i = added_plugins.begin(); (*i) != (*iter)[acols.plugin]; ++i);
298
299         added_plugins.erase(i); 
300         amodel->erase(iter);
301         if (amodel->children().empty()) {
302           set_response_sensitive (RESPONSE_APPLY, false);
303         }
304
305
306 }
307
308 void
309 PluginSelector::btn_update_clicked()
310 {
311         manager->refresh ();
312         input_refiller ();
313 #ifdef VST_SUPPORT
314         vst_refiller ();
315 #endif  
316 }
317
318 #ifdef VST_SUPPORT
319 void
320 PluginSelector::vst_display_selection_changed()
321 {
322   if (vst_display.get_selection()->count_selected_rows() != 0) {
323     btn_add->set_sensitive (true);
324   } else {
325     btn_add->set_sensitive (false);
326   }
327 }
328 #endif
329
330 void
331 PluginSelector::ladspa_display_selection_changed()
332 {
333   if (ladspa_display.get_selection()->count_selected_rows() != 0) {
334     btn_add->set_sensitive (true);
335   } else {
336     btn_add->set_sensitive (false);
337   }
338 }
339
340 void
341 PluginSelector::added_list_selection_changed()
342 {
343   if (added_list.get_selection()->count_selected_rows() != 0) {
344     btn_remove->set_sensitive (true);
345   } else {
346     btn_remove->set_sensitive (false);
347   }
348 }
349
350 int
351 PluginSelector::run ()
352 {
353         ResponseType r;
354         list<PluginInfo*>::iterator i;
355
356         r = (ResponseType) Dialog::run ();
357
358         switch (r) {
359         case RESPONSE_APPLY:
360                 for (i = added_plugins.begin(); i != added_plugins.end(); ++i){
361                         use_plugin (*i);
362                 }
363                 break;
364
365         default:
366                 break;
367         }
368
369         cleanup ();
370
371         return (int) r;
372 }
373
374 void
375 PluginSelector::cleanup ()
376 {
377         hide();
378         added_plugins.clear();
379         amodel->clear();
380 }
381