size-based scrolling and right-click pages for editor notebook
[ardour.git] / gtk2_ardour / editor_ops.cc
index 10603152b639bc59975c282a9dda878f20b8dfe9..77d9506a82976f6628906cd44cdaa233fbc0d326 100644 (file)
 #include "streamview.h"
 #include "regionview.h"
 #include "rgb_macros.h"
-#include "extra_bind.h"
 #include "selection_templates.h"
 #include "selection.h"
-#include "library_ui.h"
+#include "sfdb_ui.h"
 #include "editing.h"
 #include "gtk-custom-hruler.h"
 
@@ -185,11 +184,11 @@ Do you really want to destroy %1 ?"),
 
        Gtkmm2ext::Choice prompter (prompt, choices);
 
-       prompter.chosen.connect (Gtk::Main::quit.slot());
+       prompter.chosen.connect (ptr_fun (Main::quit));
        prompter.show_all ();
 
-       Gtk::Main::run ();
-
+       Main::run ();
+               
        if (prompter.get_choice() != 0) {
                return;
        }
@@ -548,7 +547,7 @@ Editor::build_region_boundary_cache ()
                        }
                }
 
-               rpos = (jack_nframes_t) floor ( (float) rpos / speed );
+               rpos = track_frame_to_session_frame(rpos, speed);
 
                if (region_boundary_cache.empty() || rpos != region_boundary_cache.back()) {
                        if (snap_type == SnapToRegionBoundary) {
@@ -584,7 +583,7 @@ Editor::find_next_region (jack_nframes_t frame, RegionPoint point, int32_t dir,
                                track_speed = atav->get_diskstream()->speed();
                }
 
-               track_frame = (jack_nframes_t) floor ( (float) frame * track_speed );
+               track_frame = session_frame_to_track_frame(frame, track_speed);
 
                if ((r = (*i)->find_next_region (track_frame, point, dir)) == 0) {
                        continue;
@@ -603,8 +602,8 @@ Editor::find_next_region (jack_nframes_t frame, RegionPoint point, int32_t dir,
                        rpos = r->adjust_to_sync (r->first_frame());
                        break;
                }
-               // rpos is a "track frame", converting it to "time frame"
-               rpos = (jack_nframes_t) floor ( (float) rpos / track_speed );
+               // rpos is a "track frame", converting it to "session frame"
+               rpos = track_frame_to_session_frame(rpos, track_speed);
 
                if (rpos > frame) {
                        distance = rpos - frame;
@@ -682,8 +681,7 @@ Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
                }
        }
 
-       pos = (jack_nframes_t) floor ( (float) pos / speed );
-       
+       pos = track_frame_to_session_frame(pos, speed);
        
        if (cursor == playhead_cursor) {
                session->request_locate (pos);
@@ -975,8 +973,7 @@ Editor::scroll_tracks_down ()
                cnt = (int) floor (prefix);
        }
 
-       Gtk::Adjustment *adj = track_canvas_scroller.get_vadjustment();
-       adj->set_value (adj->get_value() + (cnt * adj->get_page_size()));
+       vertical_adjustment.set_value (vertical_adjustment.get_value() + (cnt * vertical_adjustment.get_page_size()));
 }
 
 void
@@ -992,20 +989,21 @@ Editor::scroll_tracks_up ()
                cnt = (int) floor (prefix);
        }
 
-       Gtk::Adjustment *adj = track_canvas_scroller.get_vadjustment();
-       adj->set_value (adj->get_value() - (cnt * adj->get_page_size()));
+       vertical_adjustment.set_value (vertical_adjustment.get_value() - (cnt * vertical_adjustment.get_page_size()));
 }
 
 void
 Editor::scroll_tracks_down_line ()
 {
-       edit_vscrollbar.default_vmotion (0, 10);
+        Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
+       adj->set_value (adj->get_value() + 10);
 }
 
 void
 Editor::scroll_tracks_up_line ()
 {
-       edit_vscrollbar.default_vmotion (0, -10);
+        Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
+       adj->set_value (adj->get_value() - 10);
 }
 
 /* ZOOM */
@@ -1120,7 +1118,7 @@ Editor::temporal_zoom_session ()
 }
 
 void
-Editor::temporal_zoom_by_frame (jack_nframes_t start, jack_nframes_t end, string op)
+Editor::temporal_zoom_by_frame (jack_nframes_t start, jack_nframes_t end, stringcr_t op)
 {
        if (!session) return;
 
@@ -1462,7 +1460,7 @@ Editor::clear_locations ()
 void
 Editor::insert_region_list_drag (AudioRegion& region)
 {
-       gint x, y;
+       int x, y;
        double wx, wy;
        double cx, cy;
        TimeAxisView *tv;
@@ -1470,10 +1468,9 @@ Editor::insert_region_list_drag (AudioRegion& region)
        AudioTimeAxisView *atv = 0;
        Playlist *playlist;
        
-       track_canvas->get_pointer (x, y);
+       track_canvas.get_pointer (x, y);
+       track_canvas.window_to_world (x, y, wx, wy);
 
-       gnome_canvas_window_to_world (GNOME_CANVAS(track_gnome_canvas), x, y, &wx, &wy);
-       
        GdkEvent event;
        event.type = GDK_BUTTON_RELEASE;
        event.button.x = wx;
@@ -1527,13 +1524,14 @@ Editor::insert_region_list_selection (float times)
                return;
        }
        
-       Gtk::CTree_Helpers::SelectionList& selected = region_list_display.selection();
+       Glib::RefPtr<TreeSelection> selected = region_list_display.get_selection();
        
-       if (selected.empty()) {
+       if (selected->count_selected_rows() != 1) {
                return;
        }
        
-       Region* region = reinterpret_cast<Region *> (selected.front().get_data ());
+       TreeModel::iterator i = region_list_display.get_selection()->get_selected();
+       Region* region = (*i)[region_list_columns.region];
 
        begin_reversible_command (_("insert region"));
        session->add_undo (playlist->get_memento());
@@ -1758,16 +1756,14 @@ Editor::rename_region ()
 
        region_renamed = false;
 
-       entry.activate.connect (bind (mem_fun(*this, &Editor::rename_region_finished), true));
+       entry.signal_activate().connect (bind (mem_fun(*this, &Editor::rename_region_finished), true));
        ok_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::rename_region_finished), true));
        cancel_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::rename_region_finished), false));
 
        /* recurse */
 
        dialog.show_all ();
-       ARDOUR_UI::instance()->allow_focus (true);
        Main::run ();
-       ARDOUR_UI::instance()->allow_focus (false);
 
        if (region_renamed) {
                (*selection->audio_regions.begin())->region.set_name (entry.get_text());
@@ -1820,23 +1816,21 @@ Editor::audition_playlist_region_standalone (AudioRegion& region)
 void
 Editor::build_interthread_progress_window ()
 {
-       interthread_progress_window = new ArdourDialog (X_("interthread progress"));
+       interthread_progress_window = new ArdourDialog (X_("interthread progress"), true);
 
-       interthread_progress_bar.set_orientation (GTK_PROGRESS_LEFT_TO_RIGHT);
+       interthread_progress_bar.set_orientation (Gtk::PROGRESS_LEFT_TO_RIGHT);
        
-       interthread_progress_vbox.set_border_width (10);
-       interthread_progress_vbox.set_spacing (5);
-       interthread_progress_vbox.pack_start (interthread_progress_label, false, false);
-       interthread_progress_vbox.pack_start (interthread_progress_bar,false, false);
-       interthread_progress_vbox.pack_start (interthread_cancel_button,false, false);
+       interthread_progress_window->get_vbox()->pack_start (interthread_progress_label, false, false);
+       interthread_progress_window->get_vbox()->pack_start (interthread_progress_bar,false, false);
+
+       // GTK2FIX: this button needs a modifiable label
+
+       Button* b = interthread_progress_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
+       b->signal_clicked().connect (mem_fun(*this, &Editor::interthread_cancel_clicked));
 
        interthread_cancel_button.add (interthread_cancel_label);
 
-       interthread_cancel_button.signal_clicked().connect (mem_fun(*this, &Editor::interthread_cancel_clicked));
-       
-       interthread_progress_window->set_modal (true);
        interthread_progress_window->set_default_size (200, 100);
-       interthread_progress_window->add (interthread_progress_vbox);
 }
 
 void
@@ -1875,10 +1869,10 @@ Editor::import_progress_timeout (void *arg)
        }
 
        if (import_status.doing_what == "building peak files") {
-               interthread_progress_bar.set_activity_mode (true);
+               interthread_progress_bar.pulse ();
                return FALSE;
        } else {
-               interthread_progress_bar.set_percentage (import_status.progress);
+               interthread_progress_bar.set_fraction (import_status.progress/100);
        }
 
        return !(import_status.done || import_status.cancel);
@@ -1892,20 +1886,18 @@ Editor::import_audio (bool as_tracks)
                return;
        }
 
-       SoundFileSelector& sfdb (ARDOUR_UI::instance()->get_sfdb_window());
-       sigc::connection c;
        string str;
 
        if (as_tracks) {
-               c = sfdb.Action.connect (bind (mem_fun(*this, &Editor::do_import), true));
                str =_("Import selected as tracks");
        } else {
-               c = sfdb.Action.connect (bind (mem_fun(*this, &Editor::do_import), false));
                str = _("Import selected to region list");
        }
 
-       sfdb.run (str, true);
-       c.disconnect ();
+       SoundFileOmega sfdb (str);
+       sfdb.Imported.connect (bind (mem_fun (*this, &Editor::do_import), as_tracks));
+
+       sfdb.run();
 }
 
 void
@@ -1933,7 +1925,7 @@ Editor::do_import (vector<string> paths, bool split, bool as_tracks)
        interthread_progress_window->set_title (_("ardour: audio import in progress"));
        interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
        interthread_progress_window->show_all ();
-       interthread_progress_bar.set_percentage (0.0f);
+       interthread_progress_bar.set_fraction (0.0f);
        interthread_cancel_label.set_text (_("Cancel Import"));
        current_interthread_info = &import_status;
 
@@ -1950,7 +1942,7 @@ Editor::do_import (vector<string> paths, bool split, bool as_tracks)
                import_status.done = 0.0;
                
                interthread_progress_connection = 
-                       Gtk::Main::timeout.connect (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100);
+                 Glib::signal_timeout().connect (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100);
                
                last_audio_region = 0;
                
@@ -1978,7 +1970,7 @@ Editor::do_import (vector<string> paths, bool split, bool as_tracks)
 }
 
 int
-Editor::reject_because_rate_differs (string path, SF_INFO& finfo, string action, bool multiple_pending)
+Editor::reject_because_rate_differs (stringcr_t path, SF_INFO& finfo, stringcr_t action, bool multiple_pending)
 {
        if (!session) {
                return 1;
@@ -2004,7 +1996,7 @@ Editor::reject_because_rate_differs (string path, SF_INFO& finfo, string action,
                        string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
                        choices);
 
-               rate_choice.chosen.connect (Main::quit.slot());
+               rate_choice.chosen.connect (ptr_fun (Main::quit));
                rate_choice.show_all ();
 
                Main::run ();
@@ -2033,12 +2025,10 @@ Editor::embed_audio ()
                return;
        }
 
-       SoundFileSelector& sfdb (ARDOUR_UI::instance()->get_sfdb_window());
-       sigc::connection c = sfdb.Action.connect (mem_fun(*this, &Editor::do_embed_sndfiles));
-
-       sfdb.run (_("Add to External Region list"), true);
+       SoundFileOmega sfdb (_("Add to External Region list"));
+       sfdb.Embedded.connect (mem_fun (*this, &Editor::do_embed_sndfiles));
 
-       c.disconnect ();
+       sfdb.run ();
 }
 
 void
@@ -2109,7 +2099,7 @@ Editor::embed_sndfile (string path, bool split, bool multiple_files, bool& check
                }
        }
 
-       track_canvas_scroller.get_window().set_cursor (GDK_WATCH);
+       track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
        ARDOUR_UI::instance()->flush_pending ();
 
        /* make the proper number of channels in the region */
@@ -2146,28 +2136,30 @@ Editor::embed_sndfile (string path, bool split, bool multiple_files, bool& check
                
                /* make sure we can see it in the list */
 
-               Gtk::CTree_Helpers::RowList::iterator external_node;
-               external_node = region_list_display.rows().begin();
-               ++external_node; /* its the second node, always */
-               external_node->expand_recursive ();
+                /* its the second node, always */
+
+               // GTK2FIX ?? is it still always the 2nd node
+
+               TreeModel::Path path ("2");
+               region_list_display.expand_row (path, true);
 
                ARDOUR_UI::instance()->flush_pending ();
        }
 
   out:
-       track_canvas_scroller.get_window().set_cursor (current_canvas_cursor);
+       track_canvas.get_window()->set_cursor (*current_canvas_cursor);
 }
 
 void
 Editor::insert_sndfile (bool as_tracks)
 {
-       SoundFileSelector& sfdb (ARDOUR_UI::instance()->get_sfdb_window());
+//     SoundFileSelector& sfdb (ARDOUR_UI::instance()->get_sfdb_window());
        sigc::connection c;
        string str;
 
        if (as_tracks) {
 
-               c = sfdb.Action.connect (mem_fun(*this, &Editor::insert_paths_as_new_tracks));
+//             c = sfdb.Action.connect (mem_fun(*this, &Editor::insert_paths_as_new_tracks));
                str = _("Insert selected as new tracks");
 
        } else {
@@ -2182,12 +2174,12 @@ Editor::insert_sndfile (bool as_tracks)
                        return;
                }
 
-               c = sfdb.Action.connect (bind (mem_fun(*this, &Editor::do_insert_sndfile), pos));
+//             c = sfdb.Action.connect (bind (mem_fun(*this, &Editor::do_insert_sndfile), pos));
                str = _("Insert selected");
        }
 
-       sfdb.run (str, false);
-       c.disconnect ();
+//     sfdb.run (str, false);
+//     c.disconnect ();
 }
 
 void
@@ -2268,7 +2260,7 @@ Editor::do_insert_sndfile (vector<string> paths, bool split, jack_nframes_t pos)
 }
 
 void
-Editor::insert_sndfile_into (string path, bool multi, AudioTimeAxisView* tv, jack_nframes_t& pos, bool prompt)
+Editor::insert_sndfile_into (stringcr_t path, bool multi, AudioTimeAxisView* tv, jack_nframes_t& pos, bool prompt)
 {
        SndFileSource *source = 0; /* keep g++ quiet */
        AudioRegion::SourceList sources;
@@ -2293,7 +2285,7 @@ Editor::insert_sndfile_into (string path, bool multi, AudioTimeAxisView* tv, jac
                return;
        }
 
-       track_canvas_scroller.get_window().set_cursor (GDK_WATCH);
+       track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
        ARDOUR_UI::instance()->flush_pending ();
 
        /* make the proper number of channels in the region */
@@ -2336,7 +2328,7 @@ Editor::insert_sndfile_into (string path, bool multi, AudioTimeAxisView* tv, jac
        }
 
   out:
-       track_canvas_scroller.get_window().set_cursor (current_canvas_cursor);
+       track_canvas.get_window()->set_cursor (*current_canvas_cursor);
        return;
 }
 
@@ -2603,13 +2595,14 @@ Editor::region_fill_selection ()
 
        Region *region;
 
-       Gtk::CTree_Helpers::SelectionList& selected = region_list_display.selection();
-       
-       if (selected.empty()) {
+       Glib::RefPtr<TreeSelection> selected = region_list_display.get_selection();
+
+       if (selected->count_selected_rows() != 1) {
                return;
        }
 
-       region = reinterpret_cast<Region *> (selected.front().get_data());
+       TreeModel::iterator i = region_list_display.get_selection()->get_selected();
+       region = (*i)[region_list_columns.region];
 
        jack_nframes_t start = selection->time[clicked_selection].start;
        jack_nframes_t end = selection->time[clicked_selection].end;
@@ -2832,7 +2825,7 @@ Editor::trim_region_to_edit_cursor ()
 
        begin_reversible_command (_("trim to edit"));
        session->add_undo (region.playlist()->get_memento());
-       region.trim_end ( (jack_nframes_t) floor( (float)edit_cursor->current_frame * speed), this);
+       region.trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
        session->add_redo_no_execute (region.playlist()->get_memento());
        commit_reversible_command ();
 }
@@ -2857,7 +2850,7 @@ Editor::trim_region_from_edit_cursor ()
 
        begin_reversible_command (_("trim to edit"));
        session->add_undo (region.playlist()->get_memento());
-       region.trim_front ( (jack_nframes_t) floor( (float)edit_cursor->current_frame * speed), this);
+       region.trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
        session->add_redo_no_execute (region.playlist()->get_memento());
        commit_reversible_command ();
 }
@@ -2889,7 +2882,7 @@ Editor::freeze_thread ()
 gint
 Editor::freeze_progress_timeout (void *arg)
 {
-       interthread_progress_bar.set_percentage (current_interthread_info->progress);
+       interthread_progress_bar.set_fraction (current_interthread_info->progress/100);
        return !(current_interthread_info->done || current_interthread_info->cancel);
 }
 
@@ -2909,13 +2902,13 @@ Editor::freeze_route ()
        interthread_progress_window->set_title (_("ardour: freeze"));
        interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
        interthread_progress_window->show_all ();
-       interthread_progress_bar.set_percentage (0.0f);
+       interthread_progress_bar.set_fraction (0.0f);
        interthread_progress_label.set_text ("");
        interthread_cancel_label.set_text (_("Cancel Freeze"));
        current_interthread_info = &itt;
 
        interthread_progress_connection = 
-               Gtk::Main::timeout.connect (bind (mem_fun(*this, &Editor::freeze_progress_timeout), (gpointer) 0), 100);
+         Glib::signal_timeout().connect (bind (mem_fun(*this, &Editor::freeze_progress_timeout), (gpointer) 0), 100);
 
        itt.done = false;
        itt.cancel = false;
@@ -2923,7 +2916,7 @@ Editor::freeze_route ()
 
        pthread_create (&itt.thread, 0, _freeze_thread, this);
 
-       track_canvas_scroller.get_window().set_cursor (GDK_WATCH);
+       track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
 
        while (!itt.done && !itt.cancel) {
                gtk_main_iteration ();
@@ -2932,7 +2925,7 @@ Editor::freeze_route ()
        interthread_progress_connection.disconnect ();
        interthread_progress_window->hide_all ();
        current_interthread_info = 0;
-       track_canvas_scroller.get_window().set_cursor (current_canvas_cursor);
+       track_canvas.get_window()->set_cursor (*current_canvas_cursor);
 }
 
 void
@@ -3075,7 +3068,7 @@ Editor::cut_copy_points (CutCopyOp op)
 void
 Editor::cut_copy_regions (CutCopyOp op)
 {
-       typedef map<AudioPlaylist*,AudioPlaylist*> PlaylistMapping;
+        typedef std::map<AudioPlaylist*,AudioPlaylist*> PlaylistMapping;
        PlaylistMapping pmap;
        jack_nframes_t first_position = max_frames;
        set<Playlist*> freezelist;
@@ -3169,12 +3162,10 @@ Editor::paste (float times)
 void
 Editor::mouse_paste ()
 {
-       gint x, y;
+       int x, y;
        double wx, wy;
-       track_canvas->get_pointer (x, y);
-
-       gnome_canvas_window_to_world (GNOME_CANVAS(track_gnome_canvas), x, y, &wx, &wy);
-       
+       track_canvas.get_pointer (x, y);
+       track_canvas.window_to_world (x, y, wx, wy);
        GdkEvent event;
        event.type = GDK_BUTTON_RELEASE;
        event.button.x = wx;
@@ -3220,14 +3211,17 @@ Editor::paste_internal (jack_nframes_t position, float times)
 void
 Editor::paste_named_selection (float times)
 {
-       Gtk::CList_Helpers::SelectionList& selected = named_selection_display.selection();
-       TrackSelection::iterator i;
+       TrackSelection::iterator t;
+
+       Glib::RefPtr<TreeSelection> selected = named_selection_display.get_selection();
 
-       if (selected.empty() || selection->tracks.empty()) {
+       if (selected->count_selected_rows() != 1 || selection->tracks.empty()) {
                return;
        }
 
-       NamedSelection* ns = static_cast<NamedSelection*> (selected.front()->get_data ());
+       TreeModel::iterator i = selected->get_selected();
+       NamedSelection* ns = (*i)[named_selection_columns.selection];
+
        list<Playlist*>::iterator chunk;
        list<Playlist*>::iterator tmp;
 
@@ -3235,13 +3229,13 @@ Editor::paste_named_selection (float times)
                
        begin_reversible_command (_("paste chunk"));
 
-       for (i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+       for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
                
                AudioTimeAxisView* atv;
                Playlist* pl;
                AudioPlaylist* apl;
 
-               if ((atv = dynamic_cast<AudioTimeAxisView*> (*i)) == 0) {
+               if ((atv = dynamic_cast<AudioTimeAxisView*> (*t)) == 0) {
                        continue;
                }
 
@@ -3433,17 +3427,17 @@ Editor::remove_last_capture ()
 
                choices.push_back (_("Yes, destroy it."));
                choices.push_back (_("No, do nothing."));
-
+               
                Gtkmm2ext::Choice prompter (prompt, choices);
-
-               prompter.chosen.connect (Gtk::Main::quit.slot());
+               prompter.chosen.connect (ptr_fun (Main::quit));
                prompter.show_all ();
 
-               Gtk::Main::run ();
-
+               Main::run ();
+               
                if (prompter.get_choice() == 0) {
                        session->remove_last_capture ();
                }
+
        } else {
                session->remove_last_capture();
        }
@@ -3462,7 +3456,7 @@ Editor::normalize_region ()
 
        begin_reversible_command (_("normalize"));
 
-       track_canvas_scroller.get_window().set_cursor (wait_cursor);
+       track_canvas.get_window()->set_cursor (*wait_cursor);
        gdk_flush ();
 
        for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
@@ -3472,7 +3466,7 @@ Editor::normalize_region ()
        }
 
        commit_reversible_command ();
-       gdk_window_set_cursor (track_canvas_scroller.get_window(), current_canvas_cursor);
+       track_canvas.get_window()->set_cursor (*current_canvas_cursor);
 }
 
 
@@ -3519,7 +3513,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
 
        begin_reversible_command (command);
 
-       track_canvas_scroller.get_window().set_cursor (wait_cursor);
+       track_canvas.get_window()->set_cursor (*wait_cursor);
        gdk_flush ();
 
        for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ) {
@@ -3548,7 +3542,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
        selection->audio_regions.clear ();
 
   out:
-       gdk_window_set_cursor (track_canvas_scroller.get_window(), current_canvas_cursor);
+       track_canvas.get_window()->set_cursor (*current_canvas_cursor);
 }
 
 void