enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / gtk2_ardour / region_layering_order_editor.cc
index f6bc74a6ffb1760ea708698c2b7a78e977aa7a68..e58c7c9768f2402ba6b5f6869e14c9cc98529904 100644 (file)
@@ -1,31 +1,52 @@
+/*
+    Copyright (C) 2011-2012 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include <gtkmm/table.h>
 #include <gtkmm/stock.h>
 #include <gtkmm/alignment.h>
-#include <ardour/region.h>
+
+#include "pbd/stateful_diff_command.h"
+
+#include "ardour/region.h"
 
 #include "gui_thread.h"
-#include "i18n.h"
 #include "keyboard.h"
 #include "public_editor.h"
 #include "region_layering_order_editor.h"
+#include "region_view.h"
 #include "utils.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace Gtk;
 using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
 
 RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor& pe)
-       : ArdourDialog (pe, _("RegionLayeringOrderEditor"), false, false)
-       , playlist ()
-       , position ()
+       : ArdourWindow (_("RegionLayeringOrderEditor"))
+       , position (0)
        , in_row_change (false)
         , regions_at_position (0)
-       , layering_order_columns ()
        , layering_order_model (Gtk::ListStore::create (layering_order_columns))
-       , layering_order_display ()
-        , clock ("layer dialog", true, "RegionLayeringOrderEditorClock", false, false, false)
-       , scroller ()
+        , clock ("layer dialog", true, "", false, false, false)
        , editor (pe)
+       , _time_axis_view (0)
 {
        set_name ("RegionLayeringOrderEditorWindow");
 
@@ -46,7 +67,7 @@ RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor& pe)
         scroller_table->attach (scroller, 0, 1, 0, 1);
         scroller_table->set_col_spacings (5);
         scroller_table->set_row_spacings (5);
-  
+
         track_label.set_name ("RegionLayeringOrderEditorLabel");
         track_label.set_text (_("Track:"));
        track_label.set_alignment (0, 0.5);
@@ -56,25 +77,27 @@ RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor& pe)
         track_name_label.set_name ("RegionLayeringOrderEditorNameLabel");
        track_name_label.set_alignment (0, 0.5);
         clock.set_mode (AudioClock::BBT);
-  
+
         Gtk::Table* info_table = manage (new Gtk::Table (2, 2));
         info_table->set_col_spacings (5);
         info_table->set_row_spacings (5);
         info_table->attach (track_label, 0, 1, 0, 1, FILL, FILL);
         info_table->attach (track_name_label, 1, 2, 0, 1, FILL, FILL);
         info_table->attach (clock_label, 0, 1, 1, 2, FILL, FILL);
-        info_table->attach (clock, 1, 2, 1, 2, FILL, FILL);
-        get_vbox()->set_spacing (12);
-        get_vbox()->pack_start (*info_table, false, false);
-        get_vbox()->pack_start (*scroller_table, true, true);
+        info_table->attach (clock, 1, 2, 1, 2, Gtk::AttachOptions(0), FILL);
+
+       Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox ());
+       vbox->set_spacing (12);
+       vbox->pack_start (*info_table, false, false);
+       vbox->pack_start (*scroller_table, true, true);
+       add (*vbox);
+
         info_table->set_name ("RegionLayeringOrderTable");
         scroller_table->set_name ("RegionLayeringOrderTable");
 
        layering_order_display.set_name ("RegionLayeringOrderDisplay");
-
-       layering_order_display.signal_row_activated ().connect (mem_fun (*this, &RegionLayeringOrderEditor::row_activated));
+       layering_order_display.get_selection()->set_mode (SELECTION_SINGLE);
+       layering_order_display.get_selection()->signal_changed ().connect (mem_fun (*this, &RegionLayeringOrderEditor::row_selected));
 
        layering_order_display.grab_focus ();
 
@@ -84,51 +107,60 @@ RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor& pe)
 
 RegionLayeringOrderEditor::~RegionLayeringOrderEditor ()
 {
+
 }
 
 void
-RegionLayeringOrderEditor::row_activated (const TreeModel::Path& path, TreeViewColumn* column)
+RegionLayeringOrderEditor::row_selected ()
 {
        if (in_row_change) {
                return;
        }
 
-       TreeModel::iterator iter = layering_order_model->get_iter (path);
+       Glib::RefPtr<TreeSelection> selection = layering_order_display.get_selection();
+       TreeModel::iterator iter = selection->get_selected(); // only used with Gtk::SELECTION_SINGLE
+
+       if (!iter) {
+               return;
+       }
 
-       if (iter) {
-               TreeModel::Row row = *iter;
-               boost::shared_ptr<Region> region = row[layering_order_columns.region];
+       TreeModel::Row row = *iter;
+       RegionView* rv = row[layering_order_columns.region_view];
 
-               region->raise_to_top ();
+       vector<RegionView*> eq;
+       editor.get_equivalent_regions (rv, eq, Properties::group_select.property_id);
+
+       /* XXX this should be reversible, really */
+
+       for (vector<RegionView*>::iterator i = eq.begin(); i != eq.end(); ++i) {
+               boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
+               if (pl) {
+                       pl->raise_region_to_top ((*i)->region());
+               }
        }
 }
 
-typedef boost::shared_ptr<Region> RegionPtr;
-
-struct RegionCompareByLayer {
-    bool operator() (RegionPtr a, RegionPtr b) const {
-           return a->layer() > b->layer();
-    }
+struct RegionViewCompareByLayer {
+       bool operator() (RegionView* a, RegionView* b) const {
+               return a->region()->layer() > b->region()->layer();
+       }
 };
 
 void
 RegionLayeringOrderEditor::refill ()
 {
-       regions_at_position = 0;
-
-       if (!playlist) {
-               return;
-       }
-
-       typedef Playlist::RegionList RegionList;
+       assert (_time_axis_view);
 
+       regions_at_position = 0;
        in_row_change = true;
-
        layering_order_model->clear ();
 
-       boost::shared_ptr<RegionList> region_list(playlist->regions_at (position));
+       RegionSelection region_list;
+       TrackViewList ts;
+       ts.push_back (_time_axis_view);
+       editor.get_regions_at (region_list, position, ts);
 
-       regions_at_position = region_list->size();
+       regions_at_position = region_list.size ();
 
        if (regions_at_position < 2) {
                playlist_modified_connection.disconnect ();
@@ -137,15 +169,15 @@ RegionLayeringOrderEditor::refill ()
                return;
        }
 
-       RegionCompareByLayer cmp;
-       region_list->sort (cmp);
+       RegionViewCompareByLayer cmp;
+       region_list.sort (cmp);
 
-       for (RegionList::const_iterator i = region_list->begin(); i != region_list->end(); ++i) {
+       for (RegionSelection::const_iterator i = region_list.begin(); i != region_list.end(); ++i) {
                TreeModel::Row newrow = *(layering_order_model->append());
-               newrow[layering_order_columns.name] = (*i)->name();
-               newrow[layering_order_columns.region] = *i;
+               newrow[layering_order_columns.name] = (*i)->region()->name();
+               newrow[layering_order_columns.region_view] = *i;
 
-               if (i == region_list->begin()) {
+               if (i == region_list.begin()) {
                        layering_order_display.get_selection()->select(newrow);
                }
        }
@@ -154,17 +186,18 @@ RegionLayeringOrderEditor::refill ()
 }
 
 void
-RegionLayeringOrderEditor::set_context (const string& a_name, Session* s, const boost::shared_ptr<Playlist>  & pl, framepos_t pos)
+RegionLayeringOrderEditor::set_context (const string& a_name, Session* s, TimeAxisView* tav, boost::shared_ptr<Playlist> pl, framepos_t pos)
 {
         track_name_label.set_text (a_name);
 
        clock.set_session (s);
-       clock.set (pos, true, 0, 0);
+       clock.set (pos, true);
 
        playlist_modified_connection.disconnect ();
-       playlist = pl;
-       playlist->ContentsChanged.connect (playlist_modified_connection, invalidator (*this), boost::bind
-                                           (&RegionLayeringOrderEditor::playlist_modified, this), gui_context());
+       pl->ContentsChanged.connect (playlist_modified_connection, invalidator (*this), boost::bind
+                                    (&RegionLayeringOrderEditor::playlist_modified, this), gui_context());
+
+       _time_axis_view = tav;
 
        position = pos;
        refill ();
@@ -185,20 +218,20 @@ RegionLayeringOrderEditor::on_key_press_event (GdkEventKey* ev)
        */
 
        if (ev->keyval == GDK_Return) {
-               handled = ArdourDialog::on_key_press_event (ev);
+               handled = ArdourWindow::on_key_press_event (ev);
        }
-       
+
        if (!handled) {
-               handled = key_press_focus_accelerator_handler (editor, ev);
+               handled = relay_key_press (ev, this);
        }
 
        if (!handled) {
-               handled = ArdourDialog::on_key_press_event (ev);
+               handled = ArdourWindow::on_key_press_event (ev);
        }
-       
+
        return handled;
 }
-       
+
 void
 RegionLayeringOrderEditor::maybe_present ()
 {