49d6b13a0ffd193d934f3270ef6cbd6bb9decc07
[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 ((group = (*iter)[group_columns.routegroup]) == 0) {
196                 return;
197         }
198
199         if ((*iter)[group_columns.is_visible]) {
200                 for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) {
201                         if ((*j)->edit_group() == group) {
202                                 show_track_in_display (**j);
203                         }
204                 }
205         } else {
206                 for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) {
207                         if ((*j)->edit_group() == group) {
208                                 hide_track_in_display (**j);
209                         }
210                 }
211         }
212
213         bool active = (*iter)[group_columns.is_active];
214         group->set_active (active, this);
215 }
216
217 void
218 Editor::add_edit_group (RouteGroup* group)
219 {
220         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::add_edit_group), group));
221
222         TreeModel::Row row = *(group_model->append());
223         row[group_columns.is_active] = group->is_active();
224         row[group_columns.is_visible] = true;
225         row[group_columns.text] = group->name();
226         row[group_columns.routegroup] = group;
227
228         group->FlagsChanged.connect (bind (mem_fun(*this, &Editor::group_flags_changed), group));
229 }
230
231 void
232 Editor::edit_groups_changed ()
233 {
234         ENSURE_GUI_THREAD (mem_fun (*this, &Editor::edit_groups_changed));
235
236         /* just rebuild the while thing */
237
238         edit_group_display.set_model (Glib::RefPtr<TreeModel>(0));
239         group_model->clear ();
240
241         {
242                 TreeModel::Row row;
243                 row = *(group_model->append());
244                 row[group_columns.is_active] = false;
245                 row[group_columns.is_visible] = true;
246                 row[group_columns.text] = (_("-all-"));
247                 row[group_columns.routegroup] = 0;
248         }
249
250         session->foreach_edit_group (mem_fun (*this, &Editor::add_edit_group));
251         edit_group_display.set_model (group_model);
252 }
253
254 void
255 Editor::group_flags_changed (void* src, RouteGroup* group)
256 {
257         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::group_flags_changed), src, group));
258
259         Gtk::TreeModel::Children children = group_model->children();
260         for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
261                 if (group == (*iter)[group_columns.routegroup]) {
262                         (*iter)[group_columns.is_active] = group->is_active();
263                 }
264         }
265 }
266
267