0047999f71e69c31da8362ceded6af9c866de854
[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         session->add_edit_group ("");
81 }
82
83 void
84 Editor::remove_selected_edit_group ()
85 {
86         Glib::RefPtr<TreeSelection> selection = edit_group_display.get_selection();
87         TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
88
89         if (rows.empty()) {
90                 return;
91         }
92
93         TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
94         TreeIter iter;
95         
96         /* selection mode is single, so rows.begin() is it */
97
98         if ((iter = group_model->get_iter (*i))) {
99
100                 RouteGroup* rg = (*iter)[group_columns.routegroup];
101
102                 if (rg) {
103                         session->remove_edit_group (*rg);
104                 }
105         }
106 }
107
108 void
109 Editor::edit_group_list_button_clicked ()
110 {
111         new_edit_group ();
112 }
113
114 gint
115 Editor::edit_group_list_button_press_event (GdkEventButton* ev)
116 {
117         if (Keyboard::is_context_menu_event (ev)) {
118                 if (edit_group_list_menu == 0) {
119                         build_edit_group_list_menu ();
120                 }
121                 edit_group_list_menu->popup (1, 0);
122                 return true;
123         }
124
125
126         RouteGroup* group;
127         TreeIter iter;
128         TreeModel::Path path;
129         TreeViewColumn* column;
130         int cellx;
131         int celly;
132
133         if (!edit_group_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
134                 return false;
135         }
136
137         switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
138         case 0:
139                 if (Keyboard::is_edit_event (ev)) {
140                         if ((iter = group_model->get_iter (path))) {
141                                 if ((group = (*iter)[group_columns.routegroup]) != 0) {
142                                         // edit_route_group (group);
143                                         return true;
144                                 }
145                         }
146                         
147                 } 
148                 break;
149
150         case 1:
151                 if ((iter = group_model->get_iter (path))) {
152                         bool active = (*iter)[group_columns.is_active];
153                         (*iter)[group_columns.is_active] = !active;
154                         return true;
155                 }
156                 break;
157                 
158         case 2:
159                 if ((iter = group_model->get_iter (path))) {
160                         bool visible = (*iter)[group_columns.is_visible];
161                         (*iter)[group_columns.is_visible] = !visible;
162                         return true;
163                 }
164                 break;
165
166         default:
167                 break;
168         }
169         
170         return false;
171  }
172
173 void 
174 Editor::edit_group_row_change (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter)
175 {
176         RouteGroup* group;
177
178         if (in_edit_group_row_change) {
179                 return;
180         }
181
182         if ((group = (*iter)[group_columns.routegroup]) == 0) {
183                 return;
184         }
185
186         if ((*iter)[group_columns.is_visible]) {
187                 for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) {
188                         if ((*j)->edit_group() == group) {
189                                 show_track_in_display (**j);
190                         }
191                 }
192         } else {
193                 for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) {
194                         if ((*j)->edit_group() == group) {
195                                 hide_track_in_display (**j);
196                         }
197                 }
198         }
199
200         bool active = (*iter)[group_columns.is_active];
201         group->set_active (active, this);
202
203
204         string name = (*iter)[group_columns.text];
205
206         if (name != group->name()) {
207                 group->set_name (name);
208         }
209 }
210
211 void
212 Editor::add_edit_group (RouteGroup* group)
213 {
214         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::add_edit_group), group));
215         bool focus = false;
216
217         TreeModel::Row row = *(group_model->append());
218         row[group_columns.is_active] = group->is_active();
219         row[group_columns.is_visible] = !group->is_hidden();
220
221         in_edit_group_row_change = true;
222
223         row[group_columns.routegroup] = group;
224
225         if (!group->name().empty()) {
226                 row[group_columns.text] = group->name();
227         } else {
228                 row[group_columns.text] = _("unnamed");
229                 focus = true;
230         }
231
232         group->FlagsChanged.connect (bind (mem_fun(*this, &Editor::group_flags_changed), group));
233
234         if (focus) {
235                 TreeViewColumn* col = edit_group_display.get_column (0);
236                 CellRendererText* name_cell = dynamic_cast<CellRendererText*>(edit_group_display.get_column_cell_renderer (0));
237                 edit_group_display.set_cursor (group_model->get_path (row), *col, *name_cell, true);
238         }
239
240         in_edit_group_row_change = false;
241 }
242
243 void
244 Editor::edit_groups_changed ()
245 {
246         ENSURE_GUI_THREAD (mem_fun (*this, &Editor::edit_groups_changed));
247
248         /* just rebuild the while thing */
249
250         group_model->clear ();
251
252         {
253                 TreeModel::Row row;
254                 row = *(group_model->append());
255                 row[group_columns.is_active] = false;
256                 row[group_columns.is_visible] = true;
257                 row[group_columns.text] = (_("-all-"));
258                 row[group_columns.routegroup] = 0;
259         }
260
261         session->foreach_edit_group (mem_fun (*this, &Editor::add_edit_group));
262 }
263
264 void
265 Editor::group_flags_changed (void* src, RouteGroup* group)
266 {
267         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::group_flags_changed), src, group));
268
269         in_edit_group_row_change = true;
270
271         Gtk::TreeModel::Children children = group_model->children();
272         for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
273                 if (group == (*iter)[group_columns.routegroup]) {
274                         (*iter)[group_columns.is_active] = group->is_active();
275                         (*iter)[group_columns.is_visible] = !group->is_hidden();
276                         (*iter)[group_columns.text] = group->name();
277                 }
278         }
279
280         in_edit_group_row_change = false;
281 }
282
283 void
284 Editor::edit_group_name_edit (const Glib::ustring& path, const Glib::ustring& new_text)
285 {
286         RouteGroup* group;
287         TreeIter iter;
288         
289         if ((iter = group_model->get_iter (path))) {
290         
291                 if ((group = (*iter)[group_columns.routegroup]) == 0) {
292                         return;
293                 }
294                 
295                 if (new_text != group->name()) {
296                         group->set_name (new_text);
297                 }
298         }
299 }