+
+void
+Editor::toggle_waveform_visibility ()
+{
+ Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformVisibility"));
+ if (act) {
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+ set_show_waveforms (tact->get_active());
+ }
+}
+
+void
+Editor::toggle_waveforms_while_recording ()
+{
+ Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformVisibility"));
+ if (act) {
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+ set_show_waveforms_recording (tact->get_active());
+ }
+}
+
+void
+Editor::toggle_measure_visibility ()
+{
+ Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleMeasureVisibility"));
+ if (act) {
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+ set_show_measures (tact->get_active());
+ }
+}
+
+void
+Editor::set_crossfade_model (CrossfadeModel model)
+{
+ RefPtr<Action> act;
+
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ switch (model) {
+ case FullCrossfade:
+ act = ActionManager::get_action (X_("Editor"), X_("CrossfadesFull"));
+ break;
+ case ShortCrossfade:
+ act = ActionManager::get_action (X_("Editor"), X_("CrossfadesShort"));
+ break;
+ }
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && ract->get_active()) {
+ Config->set_xfade_model (model);
+ }
+ }
+}
+
+void
+Editor::update_crossfade_model ()
+{
+ RefPtr<Action> act;
+
+ switch (Config->get_xfade_model()) {
+ case FullCrossfade:
+ act = ActionManager::get_action (X_("Editor"), X_("CrossfadesFull"));
+ break;
+ case ShortCrossfade:
+ act = ActionManager::get_action (X_("Editor"), X_("CrossfadesShort"));
+ break;
+ }
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && !ract->get_active()) {
+ ract->set_active (true);
+ }
+ }
+}
+
+void
+Editor::update_smpte_mode ()
+{
+ ENSURE_GUI_THREAD(mem_fun(*this, &Editor::update_smpte_mode));
+
+ RefPtr<Action> act;
+ const char* action = 0;
+
+ float frames = Config->get_smpte_frames_per_second();
+ bool drop = Config->get_smpte_drop_frames();
+
+ if ((frames < 23.976 * 1.0005) && !drop)
+ action = X_("Smpte23976");
+ else if ((frames < 24 * 1.0005) && !drop)
+ action = X_("Smpte24");
+ else if ((frames < 24.976 * 1.0005) && !drop)
+ action = X_("Smpte24976");
+ else if ((frames < 25 * 1.0005) && !drop)
+ action = X_("Smpte25");
+ else if ((frames < 29.97 * 1.0005) && !drop)
+ action = X_("Smpte2997");
+ else if ((frames < 29.97 * 1.0005) && drop)
+ action = X_("Smpte2997drop");
+ else if ((frames < 30 * 1.0005) && !drop)
+ action = X_("Smpte30");
+ else if ((frames < 30 * 1.0005) && drop)
+ action = X_("Smpte30drop");
+ else if ((frames < 59.94 * 1.0005) && !drop)
+ action = X_("Smpte5994");
+ else if ((frames < 60 * 1.0005) && !drop)
+ action = X_("Smpte60");
+ else {
+ fatal << string_compose (_("programming error: Unexpected SMPTE value (%1, drop = %2) in update_smpte_mode. Menu is probably wrong."),
+ frames, drop) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Editor"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && !ract->get_active()) {
+ ract->set_active (true);
+ }
+ }
+}
+
+void
+Editor::update_video_pullup ()
+{
+ ENSURE_GUI_THREAD (mem_fun(*this, &Editor::update_video_pullup));
+
+ RefPtr<Action> act;
+ const char* action = 0;
+
+ float pullup = Config->get_video_pullup();
+
+ if ( pullup < (-4.1667 - 0.1) * 0.99) {
+ action = X_("PullupMinus4Minus1");
+ } else if ( pullup < (-4.1667) * 0.99 ) {
+ action = X_("PullupMinus4");
+ } else if ( pullup < (-4.1667 + 0.1) * 0.99 ) {
+ action = X_("PullupMinus4Plus1");
+ } else if ( pullup < (-0.1) * 0.99 ) {
+ action = X_("PullupMinus1");
+ } else if (pullup > (4.1667 + 0.1) * 0.99 ) {
+ action = X_("PullupPlus4Plus1");
+ } else if ( pullup > (4.1667) * 0.99 ) {
+ action = X_("PullupPlus4");
+ } else if ( pullup > (4.1667 - 0.1) * 0.99) {
+ action = X_("PullupPlus4Minus1");
+ } else if ( pullup > (0.1) * 0.99 ) {
+ action = X_("PullupPlus1");
+ } else {
+ action = X_("PullupNone");
+ }
+
+ act = ActionManager::get_action (X_("Editor"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && !ract->get_active()) {
+ ract->set_active (true);
+ }
+ }
+}
+
+void
+Editor::update_layering_model ()
+{
+ RefPtr<Action> act;
+
+ switch (Config->get_layer_model()) {
+ case LaterHigher:
+ act = ActionManager::get_action (X_("Editor"), X_("LayerLaterHigher"));
+ break;
+ case MoveAddHigher:
+ act = ActionManager::get_action (X_("Editor"), X_("LayerMoveAddHigher"));
+ break;
+ case AddHigher:
+ act = ActionManager::get_action (X_("Editor"), X_("LayerAddHigher"));
+ break;
+ }
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && !ract->get_active()) {
+ ract->set_active (true);
+ }
+ }
+}
+
+void
+Editor::set_layer_model (LayerModel model)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ RefPtr<Action> act;
+
+ switch (model) {
+ case LaterHigher:
+ act = ActionManager::get_action (X_("Editor"), X_("LayerLaterHigher"));
+ break;
+ case MoveAddHigher:
+ act = ActionManager::get_action (X_("Editor"), X_("LayerMoveAddHigher"));
+ break;
+ case AddHigher:
+ act = ActionManager::get_action (X_("Editor"), X_("LayerAddHigher"));
+ break;
+ }
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && ract->get_active() && Config->get_layer_model() != model) {
+ Config->set_layer_model (model);
+ }
+ }
+}
+
+RefPtr<RadioAction>
+Editor::snap_type_action (SnapType type)
+{
+
+ const char* action = 0;
+ RefPtr<Action> act;
+
+ switch (type) {
+ case Editing::SnapToFrame:
+ action = "snap-to-frame";
+ break;
+ case Editing::SnapToCDFrame:
+ action = "snap-to-cd-frame";
+ break;
+ case Editing::SnapToSMPTEFrame:
+ action = "snap-to-smpte-frame";
+ break;
+ case Editing::SnapToSMPTESeconds:
+ action = "snap-to-smpte-seconds";
+ break;
+ case Editing::SnapToSMPTEMinutes:
+ action = "snap-to-smpte-minutes";
+ break;
+ case Editing::SnapToSeconds:
+ action = "snap-to-seconds";
+ break;
+ case Editing::SnapToMinutes:
+ action = "snap-to-minutes";
+ break;
+ case Editing::SnapToAThirtysecondBeat:
+ action = "snap-to-thirtyseconds";
+ break;
+ case Editing::SnapToASixteenthBeat:
+ action = "snap-to-asixteenthbeat";
+ break;
+ case Editing::SnapToAEighthBeat:
+ action = "snap-to-eighths";
+ break;
+ case Editing::SnapToAQuarterBeat:
+ action = "snap-to-quarters";
+ break;
+ case Editing::SnapToAThirdBeat:
+ action = "snap-to-thirds";
+ break;
+ case Editing::SnapToBeat:
+ action = "snap-to-beat";
+ break;
+ case Editing::SnapToBar:
+ action = "snap-to-bar";
+ break;
+ case Editing::SnapToMark:
+ action = "snap-to-mark";
+ break;
+ case Editing::SnapToEditCursor:
+ action = "snap-to-edit-cursor";
+ break;
+ case Editing::SnapToRegionStart:
+ action = "snap-to-region-start";
+ break;
+ case Editing::SnapToRegionEnd:
+ action = "snap-to-region-end";
+ break;
+ case Editing::SnapToRegionSync:
+ action = "snap-to-region-sync";
+ break;
+ case Editing::SnapToRegionBoundary:
+ action = "snap-to-region-boundary";
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible snap-to type", (int) type) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Snap"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ return ract;
+
+ } else {
+ error << string_compose (_("programming error: %1"), "Editor::snap_type_chosen could not find action to match type.") << endmsg;
+ return RefPtr<RadioAction>();
+ }
+}
+
+void
+Editor::snap_type_chosen (SnapType type)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ RefPtr<RadioAction> ract = snap_type_action (type);
+
+ if (ract && ract->get_active()) {
+ set_snap_to (type);
+ }
+}
+
+RefPtr<RadioAction>
+Editor::snap_mode_action (SnapMode mode)
+{
+ const char* action = 0;
+ RefPtr<Action> act;
+
+ switch (mode) {
+ case Editing::SnapNormal:
+ action = X_("snap-normal");
+ break;
+ case Editing::SnapMagnetic:
+ action = X_("snap-magnetic");
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible snap mode type", (int) mode) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Editor"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ return ract;
+
+ } else {
+ error << string_compose (_("programming error: %1: %2"), "Editor::snap_mode_chosen could not find action to match mode.", action) << endmsg;
+ return RefPtr<RadioAction> ();
+ }
+}
+
+void
+Editor::snap_mode_chosen (SnapMode mode)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ RefPtr<RadioAction> ract = snap_mode_action (mode);
+
+ if (ract && ract->get_active()) {
+ set_snap_mode (mode);
+ }
+}
+
+
+RefPtr<RadioAction>
+Editor::zoom_focus_action (ZoomFocus focus)
+{
+ const char* action = 0;
+ RefPtr<Action> act;
+
+ switch (focus) {
+ case ZoomFocusLeft:
+ action = X_("zoom-focus-left");
+ break;
+ case ZoomFocusRight:
+ action = X_("zoom-focus-right");
+ break;
+ case ZoomFocusCenter:
+ action = X_("zoom-focus-center");
+ break;
+ case ZoomFocusPlayhead:
+ action = X_("zoom-focus-playhead");
+ break;
+ case ZoomFocusEdit:
+ action = X_("zoom-focus-edit");
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible focus type", (int) focus) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Zoom"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ return ract;
+ } else {
+ error << string_compose (_("programming error: %1: %2"), "Editor::zoom_focus_action could not find action to match focus.", action) << endmsg;
+ }
+
+ return RefPtr<RadioAction> ();
+}
+
+void
+Editor::zoom_focus_chosen (ZoomFocus focus)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ RefPtr<RadioAction> ract = zoom_focus_action (focus);
+
+ if (ract && ract->get_active()) {
+ set_zoom_focus (focus);
+ }
+}
+
+void
+Editor::smpte_fps_chosen (Session::SmpteFormat format)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ if (session) {
+
+ float fps = 10;
+ bool drop = false;
+
+ RefPtr<Action> act;
+
+ switch (format) {
+ case Session::smpte_23976: {
+ fps=23.976;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte23976"));
+ } break;
+ case Session::smpte_24: {
+ fps=24;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte24"));
+ } break;
+ case Session::smpte_24976: {
+ fps=24.976;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte24976"));
+ } break;
+ case Session::smpte_25: {
+ fps=25;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte25"));
+ } break;
+ case Session::smpte_2997: {
+ fps=29.97;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte2997"));
+ } break;
+ case Session::smpte_2997drop: {
+ fps=29.97;
+ drop = true;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte2997drop"));
+ } break;
+ case Session::smpte_30: {
+ fps=30;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte30"));
+ } break;
+ case Session::smpte_30drop: {
+ fps=30;
+ drop = true;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte30drop"));
+ } break;
+ case Session::smpte_5994: {
+ fps=59.94;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte5994"));
+ } break;
+ case Session::smpte_60: {
+ fps=60;
+ drop = false;
+ act = ActionManager::get_action (X_("Editor"), X_("Smpte60"));
+ } break;
+ default:
+ cerr << "Editor received unexpected smpte type" << endl;
+ }
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && ract->get_active()) {
+ session->set_smpte_type (fps, drop);
+ }
+ }
+ }
+}
+
+void
+Editor::video_pullup_chosen (Session::PullupFormat pullup)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ const char* action = 0;
+
+ RefPtr<Action> act;
+
+ float pull = 0.0;
+
+ switch (pullup) {
+ case Session::pullup_Plus4Plus1:
+ pull = 4.1667 + 0.1;
+ action = X_("PullupPlus4Plus1");
+ break;
+ case Session::pullup_Plus4:
+ pull = 4.1667;
+ action = X_("PullupPlus4");
+ break;
+ case Session::pullup_Plus4Minus1:
+ pull = 4.1667 - 0.1;
+ action = X_("PullupPlus4Minus1");
+ break;
+ case Session::pullup_Plus1:
+ pull = 0.1;
+ action = X_("PullupPlus1");
+ break;
+ case Session::pullup_None:
+ pull = 0.0;
+ action = X_("PullupNone");
+ break;
+ case Session::pullup_Minus1:
+ pull = -0.1;
+ action = X_("PullupMinus1");
+ break;
+ case Session::pullup_Minus4Plus1:
+ pull = -4.1667 + 0.1;
+ action = X_("PullupMinus4Plus1");
+ break;
+ case Session::pullup_Minus4:
+ pull = -4.1667;
+ action = X_("PullupMinus4");
+ break;
+ case Session::pullup_Minus4Minus1:
+ pull = -4.1667 - 0.1;
+ action = X_("PullupMinus4Minus1");
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1"), "Session received unexpected pullup type") << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Editor"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ if (ract && ract->get_active()) {
+ Config->set_video_pullup ( pull );
+ }
+
+ } else {
+ error << string_compose (_("programming error: %1"), "Editor::video_pullup_chosen could not find action to match pullup.") << endmsg;
+ }
+}
+
+void
+Editor::toggle_auto_xfade ()
+{
+ ActionManager::toggle_config_state ("Editor", "toggle-auto-xfades", &Configuration::set_auto_xfade, &Configuration::get_auto_xfade);
+}
+
+void
+Editor::toggle_xfades_active ()
+{
+ ActionManager::toggle_config_state ("Editor", "toggle-xfades-active", &Configuration::set_xfades_active, &Configuration::get_xfades_active);
+}
+
+void
+Editor::toggle_xfade_visibility ()
+{
+ ActionManager::toggle_config_state ("Editor", "toggle-xfades-visibility", &Configuration::set_xfades_visible, &Configuration::get_xfades_visible);
+}
+
+void
+Editor::parameter_changed (const char* parameter_name)
+{
+#define PARAM_IS(x) (!strcmp (parameter_name, (x)))
+
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::parameter_changed), parameter_name));
+
+ if (PARAM_IS ("auto-loop")) {
+ update_loop_range_view (true);
+ } else if (PARAM_IS ("punch-in")) {
+ update_punch_range_view (true);
+ } else if (PARAM_IS ("punch-out")) {
+ update_punch_range_view (true);
+ } else if (PARAM_IS ("layer-model")) {
+ update_layering_model ();
+ } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
+ update_smpte_mode ();
+ update_just_smpte ();
+ } else if (PARAM_IS ("video-pullup")) {
+ update_video_pullup ();
+ } else if (PARAM_IS ("xfades-active")) {
+ ActionManager::map_some_state ("Editor", "toggle-xfades-active", &Configuration::get_xfades_active);
+ } else if (PARAM_IS ("xfades-visible")) {
+ ActionManager::map_some_state ("Editor", "toggle-xfades-visible", &Configuration::get_xfades_visible);
+ } else if (PARAM_IS ("auto-xfade")) {
+ ActionManager::map_some_state ("Editor", "toggle-auto-xfades", &Configuration::get_auto_xfade);
+ } else if (PARAM_IS ("xfade-model")) {
+ update_crossfade_model ();
+ } else if (PARAM_IS ("edit-mode")) {
+ edit_mode_selector.set_active_text (edit_mode_to_string (Config->get_edit_mode()));
+ }
+
+#undef PARAM_IS
+}