new mix group interface, not yet finished and still to propagate to edit_group
[ardour.git] / gtk2_ardour / editor_edit_groups.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     $Id$
19 */
20
21 #include <cstdlib>
22 #include <cmath>
23
24 #include <gtkmm2ext/stop_signal.h>
25 #include <gtkmm2ext/gtk_ui.h>
26 #include <ardour/route_group.h>
27
28 #include "editor.h"
29 #include "keyboard.h"
30 #include "marker.h"
31 #include "time_axis_view.h"
32 #include "prompter.h"
33 #include "gui_thread.h"
34
35 #include <ardour/route.h>
36
37 #include "i18n.h"
38
39 using namespace sigc;
40 using namespace ARDOUR;
41 using namespace Gtk;
42
43 void
44 Editor::build_edit_group_list_menu ()
45 {
46         using namespace Gtk::Menu_Helpers;
47
48         edit_group_list_menu = new Menu;
49         edit_group_list_menu->set_name ("ArdourContextMenu");
50         MenuList& items = edit_group_list_menu->items();
51
52         items.push_back (MenuElem (_("Activate All"), mem_fun(*this, &Editor::activate_all_edit_groups)));
53         items.push_back (MenuElem (_("Disable All"), mem_fun(*this, &Editor::disable_all_edit_groups)));
54         items.push_back (SeparatorElem());
55         items.push_back (MenuElem (_("Add group"), mem_fun(*this, &Editor::new_edit_group)));
56         
57 }
58
59 void
60 Editor::activate_all_edit_groups ()
61 {
62         Gtk::TreeModel::Children children = group_model->children();
63         for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
64                 (*iter)[group_columns.is_active] = true;
65         }
66 }
67
68 void
69 Editor::disable_all_edit_groups ()
70 {
71         Gtk::TreeModel::Children children = group_model->children();
72         for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
73                 (*iter)[group_columns.is_active] = false;
74         }
75 }
76
77 void
78 Editor::new_edit_group ()
79 {
80         if (session == 0) {
81                 return;
82         }
83
84         ArdourPrompter prompter;
85         string result;
86
87         prompter.set_prompt (_("Name for new edit group"));
88         prompter.show_all ();
89
90         switch (prompter.run ()) {
91         case Gtk::RESPONSE_ACCEPT:
92             prompter.get_result (result);
93                 if (result.length()) {
94                         session->add_edit_group (result);
95                 }
96                 break;
97         }
98 }
99
100 void
101 Editor::remove_selected_edit_group ()
102 {
103         Glib::RefPtr<TreeSelection> selection = edit_group_display.get_selection();
104         TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
105
106         if (rows.empty()) {
107                 return;
108         }
109
110         TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
111         TreeIter iter;
112         
113         /* selection mode is single, so rows.begin() is it */
114
115         if ((iter = group_model->get_iter (*i))) {
116
117                 RouteGroup* rg = (*iter)[group_columns.routegroup];
118
119                 if (rg) {
120                         session->remove_edit_group (*rg);
121                 }
122         }
123 }
124
125 void
126 Editor::edit_group_list_button_clicked ()
127 {
128         new_edit_group ();
129 }
130
131 gint
132 Editor::edit_group_list_button_press_event (GdkEventButton* ev)
133 {
134         if (Keyboard::is_context_menu_event (ev)) {
135                 if (edit_group_list_menu == 0) {
136                         build_edit_group_list_menu ();
137                 }
138                 edit_group_list_menu->popup (1, 0);
139                 return true;
140         }
141
142
143         RouteGroup* group;
144         TreeIter iter;
145         TreeModel::Path path;
146         TreeViewColumn* column;
147         int cellx;
148         int celly;
149
150         if (!edit_group_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
151                 return false;
152         }
153
154         switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
155         case 2:
156                 if (Keyboard::is_edit_event (ev)) {
157                         if ((iter = group_model->get_iter (path))) {
158                                 if ((group = (*iter)[group_columns.routegroup]) != 0) {
159                                         // edit_route_group (group);
160                                         return true;
161                                 }
162                         }
163                         
164                 } 
165                 break;
166
167         case 1:
168                 if ((iter = group_model->get_iter (path))) {
169                         bool visible = (*iter)[group_columns.is_visible];
170                         (*iter)[group_columns.is_visible] = !visible;
171                         return true;
172                 }
173                 break;
174
175         case 0:
176                 if ((iter = group_model->get_iter (path))) {
177                         bool active = (*iter)[group_columns.is_active];
178                         (*iter)[group_columns.is_active] = !active;
179                         return true;
180                 }
181                 break;
182                 
183         default:
184                 break;
185         }
186         
187         return false;
188  }
189
190 void 
191 Editor::edit_group_row_change (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter)
192 {
193         RouteGroup* group;
194
195         if (in_edit_group_row_change) {
196                 return;
197         }
198
199         if ((group = (*iter)[group_columns.routegroup]) == 0) {
200                 return;
201         }
202
203         if ((*iter)[group_columns.is_visible]) {
204                 for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) {
205                         if ((*j)->edit_group() == group) {
206                                 show_track_in_display (**j);
207                         }
208                 }
209         } else {
210                 for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) {
211                         if ((*j)->edit_group() == group) {
212                                 hide_track_in_display (**j);
213                         }
214                 }
215         }
216
217         bool active = (*iter)[group_columns.is_active];
218         group->set_active (active, this);
219
220
221         string name = (*iter)[group_columns.text];
222
223         cerr << "Row change, name = " << name << endl;
224
225         if (name != group->name()) {
226                 group->set_name (name);
227         }
228 }
229
230 void
231 Editor::add_edit_group (RouteGroup* group)
232 {
233         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::add_edit_group), group));
234
235         TreeModel::Row row = *(group_model->append());
236         row[group_columns.is_active] = group->is_active();
237         row[group_columns.is_visible] = !group->is_hidden();
238         row[group_columns.text] = group->name();
239         row[group_columns.routegroup] = group;
240
241         group->FlagsChanged.connect (bind (mem_fun(*this, &Editor::group_flags_changed), group));
242 }
243
244 void
245 Editor::edit_groups_changed ()
246 {
247         ENSURE_GUI_THREAD (mem_fun (*this, &Editor::edit_groups_changed));
248
249         /* just rebuild the while thing */
250
251         edit_group_display.set_model (Glib::RefPtr<TreeModel>(0));
252         group_model->clear ();
253
254         {
255                 TreeModel::Row row;
256                 row = *(group_model->append());
257                 row[group_columns.is_active] = false;
258                 row[group_columns.is_visible] = true;
259                 row[group_columns.text] = (_("-all-"));
260                 row[group_columns.routegroup] = 0;
261         }
262
263         session->foreach_edit_group (mem_fun (*this, &Editor::add_edit_group));
264         edit_group_display.set_model (group_model);
265 }
266
267 void
268 Editor::group_flags_changed (void* src, RouteGroup* group)
269 {
270         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::group_flags_changed), src, group));
271
272         in_edit_group_row_change = true;
273
274         Gtk::TreeModel::Children children = group_model->children();
275         for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
276                 if (group == (*iter)[group_columns.routegroup]) {
277                         (*iter)[group_columns.is_active] = group->is_active();
278                         (*iter)[group_columns.is_visible] = !group->is_hidden();
279                         (*iter)[group_columns.text] = group->name();
280                 }
281         }
282
283         in_edit_group_row_change = false;
284 }
285
286