summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-04-01 16:49:42 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-04-01 16:49:42 +0000
commitbc3b41703ef41f4dfedeb7d97570db13d6cfa23b (patch)
tree5a36a1708a24a3158ee779ad9c57138e0b27023f
parent9d415be53e8bc1e9b1da145bcfb3293e995cdcdb (diff)
insert time operation
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3203 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour.menus1
-rw-r--r--gtk2_ardour/ardour2_ui_dark.rc.in1
-rw-r--r--gtk2_ardour/ardour2_ui_light.rc.in1
-rw-r--r--gtk2_ardour/audio_clock.cc20
-rw-r--r--gtk2_ardour/audio_clock.h4
-rw-r--r--gtk2_ardour/editing.h13
-rw-r--r--gtk2_ardour/editing_syms.h3
-rw-r--r--gtk2_ardour/editor.h3
-rw-r--r--gtk2_ardour/editor_actions.cc4
-rw-r--r--gtk2_ardour/editor_ops.cc114
-rw-r--r--gtk2_ardour/mnemonic-us.bindings.in1
-rw-r--r--libs/ardour/ardour/playlist.h4
-rw-r--r--libs/ardour/ardour/region.h1
-rw-r--r--libs/ardour/playlist.cc57
-rw-r--r--libs/ardour/region.cc18
-rw-r--r--svn_revision.h2
16 files changed, 238 insertions, 9 deletions
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index 868e2a1171..a6f42d9281 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -232,6 +232,7 @@
<menu action='TrackMenu'>
<menuitem action='AddTrackBus'/>
+ <menuitem action='insert-time'/>
<menu action='TrackHeightMenu'>
<menuitem action='track-height-largest'/>
<menuitem action='track-height-large'/>
diff --git a/gtk2_ardour/ardour2_ui_dark.rc.in b/gtk2_ardour/ardour2_ui_dark.rc.in
index 1af6c0f68c..9d354c6348 100644
--- a/gtk2_ardour/ardour2_ui_dark.rc.in
+++ b/gtk2_ardour/ardour2_ui_dark.rc.in
@@ -1341,6 +1341,7 @@ widget "*EditPointClock" style:highest "default_clock_display"
widget "*PreRollClock" style:highest "default_clock_display"
widget "*PostRollClock" style:highest "default_clock_display"
widget "*NudgeClock" style:highest "default_clock_display"
+widget "*InsertTimeClock" style:highest "default_clock_display"
widget "*ZoomRangeClock" style:highest "default_clock_display"
widget "*SMPTEOffsetClock" style:highest "default_clock_display"
widget "*TransportLabel" style:highest "small_bold_text"
diff --git a/gtk2_ardour/ardour2_ui_light.rc.in b/gtk2_ardour/ardour2_ui_light.rc.in
index 5a5ab6cc3f..68474b12d1 100644
--- a/gtk2_ardour/ardour2_ui_light.rc.in
+++ b/gtk2_ardour/ardour2_ui_light.rc.in
@@ -1344,6 +1344,7 @@ widget "*EditPointClock" style:highest "default_clock_display"
widget "*PreRollClock" style:highest "default_clock_display"
widget "*PostRollClock" style:highest "default_clock_display"
widget "*NudgeClock" style:highest "default_clock_display"
+widget "*InsertTimeClock" style:highest "default_clock_display"
widget "*ZoomRangeClock" style:highest "default_clock_display"
widget "*SMPTEOffsetClock" style:highest "default_clock_display"
widget "*TransportLabel" style:highest "small_bold_text"
diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc
index b00a4c9214..bbdebf097d 100644
--- a/gtk2_ardour/audio_clock.cc
+++ b/gtk2_ardour/audio_clock.cc
@@ -83,7 +83,8 @@ AudioClock::AudioClock (std::string clock_name, bool transient, std::string widg
key_entry_state = 0;
ops_menu = 0;
dragging = false;
-
+ bbt_reference_time = -1;
+
if (with_info) {
frames_upper_info_label = manage (new Label);
frames_lower_info_label = manage (new Label);
@@ -641,7 +642,16 @@ AudioClock::set_bbt (nframes_t when, bool force)
ticks_label.set_text (buf);
if (bbt_upper_info_label) {
- TempoMap::Metric m (session->tempo_map().metric_at (when));
+ nframes64_t pos;
+
+ if (bbt_reference_time < 0) {
+ pos = when;
+ } else {
+ pos = bbt_reference_time;
+ }
+
+ TempoMap::Metric m (session->tempo_map().metric_at (pos));
+
sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
if (bbt_lower_info_label->get_text() != buf) {
bbt_lower_info_label->set_text (buf);
@@ -1995,3 +2005,9 @@ AudioClock::set_size_requests ()
}
}
+
+void
+AudioClock::set_bbt_reference (nframes64_t pos)
+{
+ bbt_reference_time = pos;
+}
diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h
index f9060b8933..06ec43f621 100644
--- a/gtk2_ardour/audio_clock.h
+++ b/gtk2_ardour/audio_clock.h
@@ -50,7 +50,8 @@ class AudioClock : public Gtk::HBox
void set (nframes_t, bool force = false, nframes_t offset = 0, int which = 0);
void set_mode (Mode);
-
+ void set_bbt_reference (nframes64_t);
+
void set_widget_name (std::string);
std::string name() const { return _name; }
@@ -154,6 +155,7 @@ class AudioClock : public Gtk::HBox
Gtk::EventBox clock_base;
Gtk::Frame clock_frame;
+ nframes64_t bbt_reference_time;
nframes_t last_when;
bool last_pdelta;
bool last_sdelta;
diff --git a/gtk2_ardour/editing.h b/gtk2_ardour/editing.h
index bdd8e92f10..e1876b1151 100644
--- a/gtk2_ardour/editing.h
+++ b/gtk2_ardour/editing.h
@@ -38,6 +38,7 @@
#define EDITPOINT(a) /*empty*/
#define WAVEFORMSCALE(a) /*empty*/
#define WAVEFORMSHAPE(a) /*empty*/
+#define INSERTTIMEOPT(a) /*empty*/
namespace Editing {
@@ -186,6 +187,18 @@ enum WaveformShape {
#undef WAVEFORMSHAPE
#define WAVEFORMSHAPE(a) /*empty*/
+
+// INSERTTIMEOPT
+#undef INSERTTIMEOPT
+#define INSERTTIMEOPT(a) a,
+enum InsertTimeOption {
+ #include "editing_syms.h"
+};
+
+#undef INSERTTIMEOPT
+#define INSERTTIMEOPT(a) /*empty*/
+
+
/////////////////////
// These don't need their state saved. yet...
enum CutCopyOp {
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index 6820b16b12..e540d57c3e 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -102,3 +102,6 @@ WAVEFORMSHAPE(Traditional)
WAVEFORMSHAPE(Rectified)
+INSERTTIMEOPT(LeaveIntersected)
+INSERTTIMEOPT(MoveIntersected)
+INSERTTIMEOPT(SplitIntersected)
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 2d7ce4c10d..3b4ba9e5ff 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1012,6 +1012,9 @@ class Editor : public PublicEditor
void denormalize_region ();
void adjust_region_scale_amplitude (bool up);
+ void do_insert_time ();
+ void insert_time (nframes64_t pos, nframes64_t distance, Editing::InsertTimeOption opt, bool ignore_music_glue);
+
void tab_to_transient (bool forward);
void use_region_as_bar ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 520f5205c6..54ebd6f95f 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -502,6 +502,10 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "remove-last-capture", _("Remove Last Capture"), (mem_fun(*this, &Editor::remove_last_capture)));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "insert-time", _("Insert Time"), (mem_fun(*this, &Editor::do_insert_time)));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "toggle-track-active", _("Toggle Active"), (mem_fun(*this, &Editor::toggle_tracks_active)));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::track_selection_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index be3f5f77f6..0f4d1d2f6d 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -5639,4 +5639,118 @@ Editor::set_waveform_scale (WaveformScale ws)
}
}
}
+
+void
+Editor::do_insert_time ()
+{
+ if (selection->tracks.empty()) {
+ return;
+ }
+
+ nframes64_t pos = get_preferred_edit_position ();
+ ArdourDialog d (*this, _("Insert Time"));
+ VButtonBox button_box;
+ VBox option_box;
+ RadioButtonGroup group;
+ RadioButton leave_button (group, _("Stay in position"));
+ RadioButton move_button (group, _("Move"));
+ RadioButton split_button (group, _("Split & Later Section Moves"));
+ Label intersect_option_label (_("Intersected regions should:"));
+ ToggleButton glue_button (_("Move Glued Regions"));
+ AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, true, true);
+ HBox clock_box;
+
+ clock.set (0);
+ clock.set_session (session);
+ clock.set_bbt_reference (pos);
+
+ clock_box.pack_start (clock, false, true);
+
+ option_box.set_spacing (6);
+ option_box.pack_start (intersect_option_label, false, false);
+ option_box.pack_start (button_box, false, false);
+ option_box.pack_start (glue_button, false, false);
+
+ button_box.pack_start (leave_button, false, false);
+ button_box.pack_start (move_button, false, false);
+ button_box.pack_start (split_button, false, false);
+
+ d.get_vbox()->set_border_width (12);
+ d.get_vbox()->pack_start (clock_box, false, false);
+ d.get_vbox()->pack_start (option_box, false, false);
+
+ leave_button.show ();
+ move_button.show ();
+ split_button.show ();
+ intersect_option_label.show ();
+ option_box.show ();
+ button_box.show ();
+ glue_button.show ();
+ clock.show_all();
+ clock_box.show ();
+
+ d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+ d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
+ d.show ();
+
+ int response = d.run ();
+
+ if (response != RESPONSE_OK) {
+ return;
+ }
+
+ nframes_t distance = clock.current_duration (pos);
+
+ if (distance == 0) {
+ return;
+ }
+
+ InsertTimeOption opt;
+
+ if (leave_button.get_active()) {
+ opt = LeaveIntersected;
+ } else if (move_button.get_active()) {
+ opt = MoveIntersected;
+ } else {
+ opt = SplitIntersected;
+ }
+
+ insert_time (pos, distance, opt, glue_button.get_active());
+}
+void
+Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, bool ignore_music_glue)
+{
+ bool commit = false;
+
+ if (Config->get_edit_mode() == Lock) {
+ return;
+ }
+
+ begin_reversible_command (_("insert time"));
+
+ for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
+ boost::shared_ptr<Playlist> pl = (*x)->playlist();
+
+ if (!pl) {
+ continue;
+ }
+
+ XMLNode &before = pl->get_state();
+
+ if (opt == SplitIntersected) {
+ pl->split (pos);
+ }
+
+ pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
+
+ XMLNode &after = pl->get_state();
+
+ session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
+ commit = true;
+ }
+
+ if (commit) {
+ commit_reversible_command ();
+ }
+}
diff --git a/gtk2_ardour/mnemonic-us.bindings.in b/gtk2_ardour/mnemonic-us.bindings.in
index 0799f1b06c..dd5e2d38d4 100644
--- a/gtk2_ardour/mnemonic-us.bindings.in
+++ b/gtk2_ardour/mnemonic-us.bindings.in
@@ -57,6 +57,7 @@
(gtk_accel_path "<Actions>/Editor/redo" "<%PRIMARY%>r")
(gtk_accel_path "<Actions>/Transport/Record" "<%TERTIARY%>r")
(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
+(gtk_accel_path "<Actions>/Editor/insert-time" "<%PRIMARY%>t")
(gtk_accel_path "<Actions>/Editor/select-all-between-cursors" "u")
(gtk_accel_path "<Actions>/Editor/insert-region" "i")
(gtk_accel_path "<Actions>/Editor/invert-selection" "<%TERTIARY%>i")
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 0e7bf4eff9..232c0c15d4 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -89,6 +89,8 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos);
void split_region (boost::shared_ptr<Region>, nframes_t position);
+ void split (nframes64_t at);
+ void shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue);
void partition (nframes_t start, nframes_t end, bool just_top_level);
void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
void nudge_after (nframes_t start, nframes_t distance, bool forwards);
@@ -276,6 +278,8 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
void unset_freeze_child (Playlist*);
void timestamp_layer_op (boost::shared_ptr<Region>);
+
+ void _split_region (boost::shared_ptr<Region>, nframes_t position);
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 19600f3db6..e4d913082e 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -128,6 +128,7 @@ class Region : public PBD::StatefulDestructible, public Readable, public boost::
PositionLockStyle positional_lock_style() const { return _positional_lock_style; }
void set_position_lock_style (PositionLockStyle ps);
+ void recompute_position_from_lock_style ();
virtual bool should_save_state () const { return !(_flags & DoNotSaveState); };
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 09fd035c6e..9052f873db 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1014,10 +1014,67 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
}
void
+Playlist::shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue)
+{
+ RegionLock rlock (this);
+ RegionList copy (regions);
+ RegionList fixup;
+
+ for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
+
+ if ((*r)->last_frame() < at) {
+ /* too early */
+ continue;
+ }
+
+ if (at > (*r)->first_frame() && at < (*r)->last_frame()) {
+ /* intersected region */
+ if (!move_intersected) {
+ continue;
+ }
+ }
+
+ /* do not move regions glued to music time - that
+ has to be done separately.
+ */
+
+ if (!ignore_music_glue && (*r)->positional_lock_style() != Region::AudioTime) {
+ fixup.push_back (*r);
+ continue;
+ }
+
+ (*r)->set_position ((*r)->position() + distance, this);
+ }
+
+ for (RegionList::iterator r = fixup.begin(); r != fixup.end(); ++r) {
+ (*r)->recompute_position_from_lock_style ();
+ }
+}
+
+void
+Playlist::split (nframes64_t at)
+{
+ RegionLock rlock (this);
+ RegionList copy (regions);
+
+ /* use a copy since this operation can modify the region list
+ */
+
+ for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
+ _split_region (*r, at);
+ }
+}
+
+void
Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_position)
{
RegionLock rl (this);
+ _split_region (region, playlist_position);
+}
+void
+Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_position)
+{
if (!region->covers (playlist_position)) {
return;
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 0819704bcf..3f41662000 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -352,11 +352,8 @@ Region::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
_length = max_frames - _position;
}
- if (allow_bbt_recompute && _positional_lock_style == MusicTime) {
- boost::shared_ptr<Playlist> pl (playlist());
- if (pl) {
- pl->session().tempo_map().bbt_time (_position, _bbt_time);
- }
+ if (allow_bbt_recompute) {
+ recompute_position_from_lock_style ();
}
invalidate_transients ();
@@ -395,6 +392,17 @@ Region::set_position_on_top (nframes_t pos, void *src)
}
void
+Region::recompute_position_from_lock_style ()
+{
+ if (_positional_lock_style == MusicTime) {
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (pl) {
+ pl->session().tempo_map().bbt_time (_position, _bbt_time);
+ }
+ }
+}
+
+void
Region::nudge_position (nframes64_t n, void *src)
{
if (_flags & Locked) {
diff --git a/svn_revision.h b/svn_revision.h
index bada45458b..35346c9267 100644
--- a/svn_revision.h
+++ b/svn_revision.h
@@ -1,4 +1,4 @@
#ifndef __ardour_svn_revision_h__
#define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "3200";
+static const char* ardour_svn_revision = "3201";
#endif