make show all option on region list context menu work
[ardour.git] / gtk2_ardour / editor_region_list.cc
1 /*
2     Copyright (C) 2000-2005 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 #include <algorithm>
24 #include <string>
25
26 #include <pbd/basename.h>
27
28 #include <ardour/audioregion.h>
29 #include <ardour/session_region.h>
30
31 #include <gtkmm2ext/stop_signal.h>
32
33 #include "editor.h"
34 #include "editing.h"
35 #include "ardour_ui.h"
36 #include "gui_thread.h"
37 #include "actions.h"
38 #include "utils.h"
39
40 #include "i18n.h"
41
42 using namespace sigc;
43 using namespace ARDOUR;
44 using namespace Gtk;
45 using namespace Glib;
46 using namespace Editing;
47
48 #define wave_cursor_width 43
49 #define wave_cursor_height 61
50 #define wave_cursor_x_hot 0
51 #define wave_cursor_y_hot 25
52 static const gchar wave_cursor_bits[] = {
53    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00,
55    0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
56 0x00,
57    0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
58 0x00,
59    0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
60 0x00,
61    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
62 0x03,
63    0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
64 0x02,
65    0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
66 0x02,
67    0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
68 0x02,
69    0x02, 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x00, 0x04, 0x00,
70 0x02,
71    0x02, 0x04, 0x00, 0x04, 0x00, 0x02, 0x02, 0x0c, 0x08, 0x0c, 0x00,
72 0x02,
73    0x02, 0x1c, 0x08, 0x0c, 0x00, 0x02, 0x02, 0x1c, 0x08, 0x0c, 0x04,
74 0x02,
75    0x02, 0x3c, 0x18, 0x0c, 0x04, 0x02, 0x02, 0x7c, 0x18, 0x1c, 0x0c,
76 0x02,
77    0x82, 0xfc, 0x38, 0x1c, 0x0c, 0x02, 0xc2, 0xfc, 0x78, 0x3c, 0x1c,
78 0x02,
79    0xe2, 0xfd, 0xf9, 0x7d, 0x1c, 0x02, 0xf2, 0xff, 0xfb, 0xff, 0x1c,
80 0x02,
81    0xfa, 0xff, 0xfb, 0xff, 0x3f, 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff,
82 0x03,
83    0xfe, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfa, 0xff, 0xff, 0xff, 0x3f,
84 0x02,
85    0xf2, 0xff, 0xfb, 0xfd, 0x3c, 0x02, 0xe2, 0xfd, 0x7b, 0x7c, 0x1c,
86 0x02,
87    0xc2, 0xfc, 0x39, 0x3c, 0x1c, 0x02, 0x82, 0xfc, 0x18, 0x1c, 0x1c,
88 0x02,
89    0x02, 0xfc, 0x18, 0x1c, 0x0c, 0x02, 0x02, 0x7c, 0x18, 0x0c, 0x0c,
90 0x02,
91    0x02, 0x3c, 0x08, 0x0c, 0x04, 0x02, 0x02, 0x1c, 0x08, 0x0c, 0x04,
92 0x02,
93    0x02, 0x1c, 0x08, 0x0c, 0x00, 0x02, 0x02, 0x0c, 0x00, 0x04, 0x00,
94 0x02,
95    0x02, 0x04, 0x00, 0x04, 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00,
96 0x02,
97    0x02, 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
98 0x02,
99    0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
100 0x02,
101    0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
102 0x02,
103    0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff,
104 0x03,
105    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
106 0x00,
107    0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
108 0x00,
109    0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
110 0x00,
111    0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00,
113    0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
114
115 #define wave_cursor_mask_width 43
116 #define wave_cursor_mask_height 61
117 #define wave_cursor_mask_x_hot 0
118 #define wave_cursor_mask_y_hot 25
119 static const gchar wave_cursor_mask_bits[] = {
120    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00,
122    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00,
124    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00,
126    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00,
128    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00,
130    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00,
132    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00,
134    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00,
136    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
137 0x00,
138    0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x0c, 0x00,
139 0x00,
140    0x00, 0x1c, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x0c, 0x04,
141 0x00,
142    0x00, 0x3c, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x7c, 0x18, 0x1c, 0x0c,
143 0x00,
144    0x80, 0xfc, 0x38, 0x1c, 0x0c, 0x00, 0xc0, 0xfc, 0x78, 0x3c, 0x1c,
145 0x00,
146    0xe0, 0xfd, 0xf9, 0x7d, 0x1c, 0x00, 0xf0, 0xff, 0xfb, 0xff, 0x1c,
147 0x00,
148    0xf8, 0xff, 0xfb, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
149 0x07,
150    0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, 0xff, 0xff, 0xff, 0x3f,
151 0x00,
152    0xf0, 0xff, 0xfb, 0xfd, 0x3c, 0x00, 0xe0, 0xfd, 0x7b, 0x7c, 0x1c,
153 0x00,
154    0xc0, 0xfc, 0x39, 0x3c, 0x1c, 0x00, 0x80, 0xfc, 0x18, 0x1c, 0x1c,
155 0x00,
156    0x00, 0xfc, 0x18, 0x1c, 0x0c, 0x00, 0x00, 0x7c, 0x18, 0x0c, 0x0c,
157 0x00,
158    0x00, 0x3c, 0x08, 0x0c, 0x04, 0x00, 0x00, 0x1c, 0x08, 0x0c, 0x04,
159 0x00,
160    0x00, 0x1c, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00,
161 0x00,
162    0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
163 0x00,
164    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00,
166    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00,
168    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00,
170    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00,
172    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00,
174    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00,
176    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00,
178    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00,
180    0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
181
182 GdkCursor *wave_cursor = 0;
183
184 void
185 Editor::handle_audio_region_removed (AudioRegion* ignored)
186 {
187         redisplay_regions ();
188 }
189
190 void
191 Editor::handle_new_audio_region (AudioRegion *region)
192 {
193         /* don't copy region - the one we are being notified
194            about belongs to the session, and so it will
195            never be edited.
196         */
197         add_audio_region_to_region_display (region);
198 }
199
200 void
201 Editor::region_hidden (Region* r)
202 {
203         ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::region_hidden), r));    
204
205         redisplay_regions ();
206 }
207
208 void
209 Editor::add_audio_region_to_region_display (AudioRegion *region)
210 {
211         string str;
212         TreeModel::Row row;
213         Gdk::Color c;
214
215         if (!show_automatic_regions_in_region_list && region->automatic()) {
216                 return;
217         }
218
219         if (region->hidden()) {
220
221                 TreeModel::iterator iter = region_list_model->get_iter (_("/Hidden"));
222                 TreeModel::Row parent;
223                 TreeModel::Row child;
224
225                 if (iter == region_list_model->children().end()) {
226                         
227                         parent = *(region_list_model->append());
228                         
229                         parent[region_list_columns.name] = _("Hidden");
230                         parent[region_list_columns.region] = 0;
231                 } else {
232                         parent = *iter;
233                 }
234
235                 row = *(region_list_model->append (parent.children()));
236
237         } else if (region->whole_file()) {
238
239                 row = *(region_list_model->append());
240                 set_color(c, 65535, 0, 0);
241                 row[region_list_columns.color_] = c;
242
243                 if (region->source().name()[0] == '/') { // external file
244
245                         if (region->whole_file()) {
246                                 str = ".../";
247                                 str += PBD::basename_nosuffix (region->source().name());
248                                 
249                         } else {
250                                 str = region->name();
251                         }
252
253                 } else {
254
255                         str = region->name();
256
257                 }
258
259                 row[region_list_columns.name] = str;
260                 row[region_list_columns.region] = region;
261
262                 return;
263                 
264         } else {
265
266                 /* find parent node, add as new child */
267                 
268                 TreeModel::iterator i;
269                 TreeModel::Children rows = region_list_model->children();
270                 bool found_parent = false;
271
272                 for (i = rows.begin(); i != rows.end(); ++i) {
273
274                         Region* rr = (*i)[region_list_columns.region];
275                         AudioRegion* r = dynamic_cast<AudioRegion*>(rr);
276
277                         if (r && r->whole_file()) {
278                                 if (region->source_equivalent (*r)) {
279                                         row = *(region_list_model->append ((*i).children()));
280                                         found_parent = true;
281                                         break;
282                                 }
283                         }
284                 }
285
286                 if (!found_parent) {
287                         row = *(region_list_model->append());
288                 }
289
290                 
291         }
292         
293         row[region_list_columns.region] = region;
294         
295         if (region->n_channels() > 1) {
296                 row[region_list_columns.name] = string_compose("%1  [%2]", region->name(), region->n_channels());
297         } else {
298                 row[region_list_columns.name] = region->name();
299         }
300 }
301
302 void
303 Editor::region_list_selection_changed() 
304 {
305         bool selected;
306
307         if (region_list_display.get_selection()->count_selected_rows() > 0) {
308                 selected = true;
309         } else {
310                 selected = false;
311         }
312         
313         if (selected) {
314                 TreeView::Selection::ListHandle_Path rows = region_list_display.get_selection()->get_selected_rows ();
315                 TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
316                 TreeIter iter;
317
318                 /* just set the first selected region (in fact, the selection model might be SINGLE, which
319                    means there can only be one.
320                 */
321                 
322                 if ((iter = region_list_model->get_iter (*i))) {
323                         set_selected_regionview_from_region_list (*((*iter)[region_list_columns.region]), false);
324                 }
325         }
326 }
327
328 void
329 Editor::insert_into_tmp_audio_regionlist(AudioRegion* region)
330 {
331         /* keep all whole files at the beginning */
332         
333         if (region->whole_file()) {
334                 tmp_audio_region_list.push_front (region);
335         } else {
336                 tmp_audio_region_list.push_back (region);
337         }
338 }
339
340 void
341 Editor::redisplay_regions ()
342 {
343         if (session) {
344
345                 region_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
346                 region_list_model->clear ();
347
348                 /* now add everything we have, via a temporary list used to help with
349                    sorting.
350                 */
351                 
352                 tmp_audio_region_list.clear();
353                 session->foreach_audio_region (this, &Editor::insert_into_tmp_audio_regionlist);
354
355                 for (list<AudioRegion*>::iterator r = tmp_audio_region_list.begin(); r != tmp_audio_region_list.end(); ++r) {
356                         add_audio_region_to_region_display (*r);
357                 }
358                 
359                 region_list_display.set_model (region_list_model);
360         }
361 }
362
363 void
364 Editor::region_list_clear ()
365 {
366         region_list_model->clear();
367 }
368
369 void
370 Editor::build_region_list_menu ()
371 {
372         region_list_menu = dynamic_cast<Menu*>(ActionManager::get_widget ("/RegionListMenu"));
373                                                
374         /* now grab specific menu items that we need */
375
376         Glib::RefPtr<Action> act;
377
378         act = ActionManager::get_action (X_("RegionList"), X_("rlShowAll"));
379         if (act) {
380                 toggle_full_region_list_action = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
381         }
382
383         act = ActionManager::get_action (X_("RegionList"), X_("rlShowAuto"));
384         if (act) {
385                 toggle_show_auto_regions_action = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
386         }
387 }
388
389 void
390 Editor::toggle_show_auto_regions ()
391 {
392         show_automatic_regions_in_region_list = toggle_show_auto_regions_action->get_active();
393         redisplay_regions ();
394 }
395
396 void
397 Editor::toggle_full_region_list ()
398 {
399         if (toggle_full_region_list_action->get_active()) {
400                 region_list_display.expand_all ();
401         } else {
402                 region_list_display.collapse_all ();
403         }
404 }
405
406 void
407 Editor::show_region_list_display_context_menu (int button, int time)
408 {
409         if (region_list_menu == 0) {
410                 build_region_list_menu ();
411         }
412
413         if (region_list_display.get_selection()->count_selected_rows() > 0) {
414                 ActionManager::set_sensitive (ActionManager::region_list_selection_sensitive_actions, true);
415         } else {
416                 ActionManager::set_sensitive (ActionManager::region_list_selection_sensitive_actions, false);
417         }
418
419         region_list_menu->popup (button, time);
420 }
421
422 bool
423 Editor::region_list_display_key_press (GdkEventKey* ev)
424 {
425         return false;
426 }
427
428 bool
429 Editor::region_list_display_key_release (GdkEventKey* ev)
430 {
431         switch (ev->keyval) {
432         case GDK_Delete:
433                 remove_region_from_region_list ();
434                 return true;
435                 break;
436         default:
437                 break;
438         }
439
440         return false;
441 }
442
443 bool
444 Editor::region_list_display_button_press (GdkEventButton *ev)
445 {
446         Region* region;
447         TreeIter iter;
448         TreeModel::Path path;
449         TreeViewColumn* column;
450         int cellx;
451         int celly;
452
453         if (region_list_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
454                 if ((iter = region_list_model->get_iter (path))) {
455                         region = (*iter)[region_list_columns.region];
456                 }
457         }
458
459         if (region == 0) {
460                 return false;
461         }
462
463         if (Keyboard::is_delete_event (ev)) {
464                 session->remove_region_from_region_list (*region);
465                 return true;
466         }
467
468         if (Keyboard::is_context_menu_event (ev)) {
469                 show_region_list_display_context_menu (ev->button, ev->time);
470                 return true;
471         }
472
473         switch (ev->button) {
474         case 1:
475                 /* audition on double click */
476                 if (ev->type == GDK_2BUTTON_PRESS) {
477                         consider_auditioning (*region);
478                         return true;
479                 }
480                 return false;
481                 break;
482
483         case 2:
484                 if (!Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
485                         consider_auditioning (*region);
486                 }
487                 return true;
488                 break;
489
490         default:
491                 break; 
492         }
493
494         return false;
495 }       
496
497 bool
498 Editor::region_list_display_button_release (GdkEventButton *ev)
499 {
500         TreeIter iter;
501         TreeModel::Path path;
502         TreeViewColumn* column;
503         int cellx;
504         int celly;
505         Region* region = 0;
506
507         if (region_list_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
508                 if ((iter = region_list_model->get_iter (path))) {
509                         region = (*iter)[region_list_columns.region];
510                 }
511         }
512
513         if (region && Keyboard::is_delete_event (ev)) {
514                 session->remove_region_from_region_list (*region);
515                 return true;
516         }
517
518         return false;
519 }
520
521 void
522 Editor::consider_auditioning (Region& region)
523 {
524         AudioRegion* r = dynamic_cast<AudioRegion*> (&region);
525
526         if (r == 0) {
527                 session->cancel_audition ();
528                 return;
529         }
530
531         if (session->is_auditioning()) {
532                 session->cancel_audition ();
533                 if (r == last_audition_region) {
534                         return;
535                 }
536         }
537
538         session->audition_region (*r);
539         last_audition_region = r;
540 }
541
542 int
543 Editor::region_list_sorter (TreeModel::iterator a, TreeModel::iterator b)
544 {
545         int cmp = 0;
546
547         Region* r1 = (*a)[region_list_columns.region];
548         Region* r2 = (*b)[region_list_columns.region];
549
550         AudioRegion* region1 = dynamic_cast<AudioRegion*> (r1);
551         AudioRegion* region2 = dynamic_cast<AudioRegion*> (r2);
552
553         if (region1 == 0 || region2 == 0) {
554                 Glib::ustring s1;
555                 Glib::ustring s2;
556                 switch (region_list_sort_type) {
557                 case ByName:
558                         s1 = (*a)[region_list_columns.name];
559                         s2 = (*b)[region_list_columns.name];
560                         return (s1.compare (s2));
561                 default:
562                         return 0;
563                 }
564         }
565
566         switch (region_list_sort_type) {
567         case ByName:
568                 cmp = strcasecmp (region1->name().c_str(), region2->name().c_str());
569                 break;
570
571         case ByLength:
572                 cmp = region1->length() - region2->length();
573                 break;
574                 
575         case ByPosition:
576                 cmp = region1->position() - region2->position();
577                 break;
578                 
579         case ByTimestamp:
580                 cmp = region1->source().timestamp() - region2->source().timestamp();
581                 break;
582         
583         case ByStartInFile:
584                 cmp = region1->start() - region2->start();
585                 break;
586                 
587         case ByEndInFile:
588                 cmp = (region1->start() + region1->length()) - (region2->start() + region2->length());
589                 break;
590                 
591         case BySourceFileName:
592                 cmp = strcasecmp (region1->source().name().c_str(), region2->source().name().c_str());
593                 break;
594
595         case BySourceFileLength:
596                 cmp = region1->source().length() - region2->source().length();
597                 break;
598                 
599         case BySourceFileCreationDate:
600                 cmp = region1->source().timestamp() - region2->source().timestamp();
601                 break;
602
603         case BySourceFileFS:
604                 if (region1->source().name() == region2->source().name()) {
605                         cmp = strcasecmp (region1->name().c_str(),  region2->name().c_str());
606                 } else {
607                         cmp = strcasecmp (region1->source().name().c_str(),  region2->source().name().c_str());
608                 }
609                 break;
610         }
611
612         if (cmp < 0) {
613                 return -1;
614         } else if (cmp > 0) {
615                 return 1;
616         } else {
617                 return 0;
618         }
619 }
620
621 void
622 Editor::reset_region_list_sort_type (RegionListSortType type)
623 {
624         if (type != region_list_sort_type) {
625                 region_list_sort_type = type;
626                 region_list_model->set_sort_func (0, (mem_fun (*this, &Editor::region_list_sorter)));
627         }
628 }
629
630 void
631 Editor::reset_region_list_sort_direction (bool up)
632 {
633         region_list_model->set_sort_column (0, up ? SORT_ASCENDING : SORT_DESCENDING);
634 }
635
636 void
637 Editor::region_list_selection_mapover (slot<void,Region&> sl)
638 {
639         Glib::RefPtr<TreeSelection> selection = region_list_display.get_selection();
640         TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
641         TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
642
643         if (selection->count_selected_rows() == 0 || session == 0) {
644                 return;
645         }
646
647         for (; i != rows.end(); ++i) {
648                 TreeIter iter;
649
650                 if ((iter = region_list_model->get_iter (*i))) {
651                         sl (*((*iter)[region_list_columns.region]));
652                 }
653         }
654 }
655
656 void
657 Editor::hide_a_region (Region& r)
658 {
659         r.set_hidden (true);
660 }
661
662 void
663 Editor::remove_a_region (Region& r)
664 {
665         session->remove_region_from_region_list (r);
666 }
667
668 void
669 Editor::audition_region_from_region_list ()
670 {
671         region_list_selection_mapover (mem_fun (*this, &Editor::consider_auditioning));
672 }
673
674 void
675 Editor::hide_region_from_region_list ()
676 {
677         region_list_selection_mapover (mem_fun (*this, &Editor::hide_a_region));
678 }
679
680 void
681 Editor::remove_region_from_region_list ()
682 {
683         region_list_selection_mapover (mem_fun (*this, &Editor::remove_a_region));
684 }
685
686 void  
687 Editor::region_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
688                                                 int x, int y, 
689                                                 const SelectionData& data,
690                                                 guint info, guint time)
691 {
692         vector<string> paths;
693
694         if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) {
695                 do_embed_sndfiles (paths, false);
696                 context->drag_finish (true, false, time);
697         }
698 }
699