2 Copyright (C) 2000-2007 Paul Davis
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.
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.
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.
21 #include <gtkmm2ext/barcontroller.h>
22 #include "pbd/memento_command.h"
23 #include "ardour/automation_control.h"
24 #include "ardour/event_type_map.h"
25 #include "ardour/route.h"
27 #include "ardour_ui.h"
28 #include "automation_time_axis.h"
29 #include "automation_streamview.h"
30 #include "route_time_axis.h"
31 #include "automation_line.h"
32 #include "public_editor.h"
33 #include "simplerect.h"
34 #include "selection.h"
35 #include "rgb_macros.h"
36 #include "automation_selectable.h"
37 #include "point_selection.h"
38 #include "canvas_impl.h"
44 using namespace ARDOUR;
47 using namespace Gtkmm2ext;
48 using namespace Editing;
50 Pango::FontDescription* AutomationTimeAxisView::name_font = 0;
51 bool AutomationTimeAxisView::have_name_font = false;
52 const string AutomationTimeAxisView::state_node_name = "AutomationChild";
55 /** \a a the automatable object this time axis is to display data for.
56 * For route/track automation (e.g. gain) pass the route for both \r and \a.
57 * For route child (e.g. plugin) automation, pass the child for \a.
58 * For region automation (e.g. MIDI CC), pass null for \a.
60 AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
61 boost::shared_ptr<Automatable> a, boost::shared_ptr<AutomationControl> c,
62 PublicEditor& e, TimeAxisView& parent, bool show_regions,
63 ArdourCanvas::Canvas& canvas, const string & nom, const string & nomparent)
65 TimeAxisView (s, e, &parent, canvas),
69 _controller(AutomationController::create(a, c->parameter(), c)),
71 _view (show_regions ? new AutomationStreamView(*this) : NULL),
73 auto_button (X_("")) /* force addition of a label */
75 if (!have_name_font) {
76 name_font = get_font_for_style (X_("AutomationTrackName"));
77 have_name_font = true;
85 mode_discrete_item = 0;
88 ignore_state_request = false;
89 first_call_to_set_height = true;
91 _base_rect = new SimpleRect(*_canvas_display);
92 _base_rect->property_x1() = 0.0;
93 _base_rect->property_y1() = 0.0;
94 _base_rect->property_x2() = LONG_MAX - 2;
95 _base_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackOutline.get();
97 /* outline ends and bottom */
98 _base_rect->property_outline_what() = (guint32) (0x1|0x2|0x8);
99 _base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackFill.get();
101 _base_rect->set_data ("trackview", this);
103 _base_rect->signal_event().connect (bind (
104 mem_fun (_editor, &PublicEditor::canvas_automation_track_event),
108 _base_rect->lower_to_bottom();
111 hide_button.add (*(manage (new Gtk::Image (::get_icon("hide")))));
113 auto_button.set_name ("TrackVisualButton");
114 hide_button.set_name ("TrackRemoveButton");
116 auto_button.unset_flags (Gtk::CAN_FOCUS);
117 hide_button.unset_flags (Gtk::CAN_FOCUS);
119 controls_table.set_no_show_all();
121 ARDOUR_UI::instance()->tooltips().set_tip(auto_button, _("automation state"));
122 ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("hide track"));
124 /* rearrange the name display */
126 /* we never show these for automation tracks, so make
127 life easier and remove them.
132 /* move the name label over a bit */
134 string shortpname = _name;
135 bool shortened = false;
138 shortpname = fit_to_pixels (_name, 60, *name_font, ignore_width, true);
140 if (shortpname != _name ){
144 name_label.set_text (shortpname);
145 name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
147 if (nomparent.length()) {
149 /* limit the plug name string */
151 string pname = fit_to_pixels (nomparent, 60, *name_font, ignore_width, true);
152 if (pname != nomparent) {
156 plugname = new Label (pname);
157 plugname->set_name (X_("TrackPlugName"));
159 name_label.set_name (X_("TrackParameterName"));
160 controls_table.remove (name_hbox);
161 controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
162 plugname_packed = true;
163 controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
166 plugname_packed = false;
170 string tipname = nomparent;
171 if (!tipname.empty()) {
175 ARDOUR_UI::instance()->tooltips().set_tip(controls_ebox, tipname);
178 /* add the buttons */
179 controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
181 controls_table.attach (auto_button, 5, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
183 /* add bar controller */
184 controls_table.attach (*_controller.get(), 0, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
186 controls_table.show_all ();
188 hide_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::hide_clicked));
189 auto_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::auto_clicked));
191 controls_base_selected_name = X_("AutomationTrackControlsBaseSelected");
192 controls_base_unselected_name = X_("AutomationTrackControlsBase");
193 controls_ebox.set_name (controls_base_unselected_name);
195 XMLNode* xml_node = get_parent_with_state()->get_automation_child_xml_node (
196 _control->parameter());
199 set_state (*xml_node, Stateful::loading_state_version);
202 /* ask for notifications of any new RegionViews */
208 /* no regions, just a single line for the entire track (e.g. bus gain) */
210 boost::shared_ptr<AutomationLine> line(new AutomationLine (
211 ARDOUR::EventTypeMap::instance().to_symbol(_control->parameter()),
216 line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
217 line->queue_reset ();
221 /* make sure labels etc. are correct */
223 automation_state_changed ();
224 ColorsChanged.connect (mem_fun (*this, &AutomationTimeAxisView::color_handler));
227 AutomationTimeAxisView::~AutomationTimeAxisView ()
232 AutomationTimeAxisView::auto_clicked ()
234 using namespace Menu_Helpers;
236 if (automation_menu == 0) {
237 automation_menu = manage (new Menu);
238 automation_menu->set_name ("ArdourContextMenu");
239 MenuList& items (automation_menu->items());
241 items.push_back (MenuElem (_("Manual"), bind (mem_fun(*this,
242 &AutomationTimeAxisView::set_automation_state), (AutoState) Off)));
243 items.push_back (MenuElem (_("Play"), bind (mem_fun(*this,
244 &AutomationTimeAxisView::set_automation_state), (AutoState) Play)));
245 items.push_back (MenuElem (_("Write"), bind (mem_fun(*this,
246 &AutomationTimeAxisView::set_automation_state), (AutoState) Write)));
247 items.push_back (MenuElem (_("Touch"), bind (mem_fun(*this,
248 &AutomationTimeAxisView::set_automation_state), (AutoState) Touch)));
251 automation_menu->popup (1, gtk_get_current_event_time());
255 AutomationTimeAxisView::set_automation_state (AutoState state)
257 if (!ignore_state_request) {
259 _automatable->set_parameter_automation_state (_control->parameter(), state);
262 if (_route == _automatable) { // This is a time axis for route (not region) automation
263 _route->set_parameter_automation_state (_control->parameter(), state);
266 if (_control->list())
267 _control->alist()->set_automation_state(state);
272 _view->set_automation_state (state);
277 AutomationTimeAxisView::automation_state_changed ()
281 /* update button label */
286 state = _control->alist()->automation_state ();
289 switch (state & (Off|Play|Touch|Write)) {
291 auto_button.set_label (_("Manual"));
293 ignore_state_request = true;
294 auto_off_item->set_active (true);
295 auto_play_item->set_active (false);
296 auto_touch_item->set_active (false);
297 auto_write_item->set_active (false);
298 ignore_state_request = false;
302 auto_button.set_label (_("Play"));
303 if (auto_play_item) {
304 ignore_state_request = true;
305 auto_play_item->set_active (true);
306 auto_off_item->set_active (false);
307 auto_touch_item->set_active (false);
308 auto_write_item->set_active (false);
309 ignore_state_request = false;
313 auto_button.set_label (_("Write"));
314 if (auto_write_item) {
315 ignore_state_request = true;
316 auto_write_item->set_active (true);
317 auto_off_item->set_active (false);
318 auto_play_item->set_active (false);
319 auto_touch_item->set_active (false);
320 ignore_state_request = false;
324 auto_button.set_label (_("Touch"));
325 if (auto_touch_item) {
326 ignore_state_request = true;
327 auto_touch_item->set_active (true);
328 auto_off_item->set_active (false);
329 auto_play_item->set_active (false);
330 auto_write_item->set_active (false);
331 ignore_state_request = false;
335 auto_button.set_label (_("???"));
341 AutomationTimeAxisView::interpolation_changed ()
343 AutomationList::InterpolationStyle style = _control->list()->interpolation();
345 if (mode_line_item && mode_discrete_item) {
346 if (style == AutomationList::Discrete) {
347 mode_discrete_item->set_active(true);
348 mode_line_item->set_active(false);
350 mode_line_item->set_active(true);
351 mode_discrete_item->set_active(false);
356 _line->set_interpolation(style);
361 AutomationTimeAxisView::set_interpolation (AutomationList::InterpolationStyle style)
363 _control->list()->set_interpolation(style);
365 _line->set_interpolation(style);
370 AutomationTimeAxisView::clear_clicked ()
372 _session.begin_reversible_command (_("clear automation"));
376 _session.commit_reversible_command ();
380 AutomationTimeAxisView::set_height (uint32_t h)
382 bool changed = (height != (uint32_t) h) || first_call_to_set_height;
383 bool changed_between_small_and_normal = (
384 (height < hNormal && h >= hNormal)
385 || (height >= hNormal || h < hNormal) );
387 TimeAxisView* state_parent = get_parent_with_state ();
388 assert(state_parent);
389 XMLNode* xml_node = state_parent->get_automation_child_xml_node (_control->parameter());
391 TimeAxisView::set_height (h);
392 _base_rect->property_y2() = h;
395 _line->set_height(h);
398 _view->set_height(h);
399 _view->update_contents_height();
403 snprintf (buf, sizeof (buf), "%u", height);
405 xml_node->add_property ("height", buf);
408 if (changed_between_small_and_normal || first_call_to_set_height) {
410 first_call_to_set_height = false;
413 controls_table.remove (name_hbox);
416 if (plugname_packed) {
417 controls_table.remove (*plugname);
418 plugname_packed = false;
420 controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
421 plugname_packed = true;
422 controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
424 controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
428 name_hbox.show_all ();
431 hide_button.show_all();
433 } else if (h >= hSmall) {
434 controls_table.remove (name_hbox);
436 if (plugname_packed) {
437 controls_table.remove (*plugname);
438 plugname_packed = false;
441 controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
442 controls_table.hide_all ();
445 name_hbox.show_all ();
450 } else if (h >= hNormal){
451 cerr << "track grown, but neither changed_between_small_and_normal nor first_call_to_set_height set!" << endl;
455 /* only emit the signal if the height really changed */
456 _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
461 AutomationTimeAxisView::set_samples_per_unit (double spu)
463 TimeAxisView::set_samples_per_unit (spu);
469 _view->set_samples_per_unit (spu);
473 AutomationTimeAxisView::hide_clicked ()
475 // LAME fix for refreshing the hide button
476 hide_button.set_sensitive(false);
478 set_marked_for_display (false);
481 hide_button.set_sensitive(true);
485 AutomationTimeAxisView::build_display_menu ()
487 using namespace Menu_Helpers;
489 /* get the size menu ready */
495 TimeAxisView::build_display_menu ();
497 /* now fill it with our stuff */
499 MenuList& items = display_menu->items();
501 items.push_back (MenuElem (_("Height"), *size_menu));
502 items.push_back (SeparatorElem());
503 items.push_back (MenuElem (_("Hide"), mem_fun(*this, &AutomationTimeAxisView::hide_clicked)));
504 items.push_back (SeparatorElem());
505 items.push_back (MenuElem (_("Clear"), mem_fun(*this, &AutomationTimeAxisView::clear_clicked)));
506 items.push_back (SeparatorElem());
510 Menu* auto_state_menu = manage (new Menu);
511 auto_state_menu->set_name ("ArdourContextMenu");
512 MenuList& as_items = auto_state_menu->items();
514 as_items.push_back (CheckMenuElem (_("Manual"), bind (
515 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
517 auto_off_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
519 as_items.push_back (CheckMenuElem (_("Play"), bind (
520 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
522 auto_play_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
524 as_items.push_back (CheckMenuElem (_("Write"), bind (
525 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
526 (AutoState) Write)));
527 auto_write_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
529 as_items.push_back (CheckMenuElem (_("Touch"), bind (
530 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
531 (AutoState) Touch)));
532 auto_touch_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
534 items.push_back (MenuElem (_("State"), *auto_state_menu));
538 if (EventTypeMap::instance().is_midi_parameter(_control->parameter())) {
540 Menu* auto_mode_menu = manage (new Menu);
541 auto_mode_menu->set_name ("ArdourContextMenu");
542 MenuList& am_items = auto_mode_menu->items();
544 RadioMenuItem::Group group;
546 am_items.push_back (RadioMenuElem (group, _("Discrete"), bind (
547 mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
548 AutomationList::Discrete)));
549 mode_discrete_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
550 mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete);
552 am_items.push_back (RadioMenuElem (group, _("Linear"), bind (
553 mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
554 AutomationList::Linear)));
555 mode_line_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
557 // Set default interpolation type to linear if this isn't a (usually) discrete controller
558 if (EventTypeMap::instance().interpolation_of(_control->parameter()) == Evoral::ControlList::Linear) {
559 mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear);
562 items.push_back (MenuElem (_("Mode"), *auto_mode_menu));
565 /* make sure the automation menu state is correct */
567 automation_state_changed ();
568 interpolation_changed ();
572 AutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* /*item*/, GdkEvent* /*event*/, nframes_t when, double y)
579 _canvas_display->w2i (x, y);
581 /* compute vertical fractional position */
583 y = 1.0 - (y / height);
587 _line->view_to_model_coord (x, y);
589 _session.begin_reversible_command (_("add automation event"));
590 XMLNode& before = _control->alist()->get_state();
592 _control->alist()->add (when, y);
594 XMLNode& after = _control->alist()->get_state();
595 _session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(*_control->alist(), &before, &after));
597 _session.set_dirty ();
601 AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
603 return (_line ? cut_copy_clear_one (*_line, selection, op) : false);
607 AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& selection, CutCopyOp op)
609 boost::shared_ptr<Evoral::ControlList> what_we_got;
610 boost::shared_ptr<AutomationList> alist (line.the_list());
613 XMLNode &before = alist->get_state();
617 if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
618 _editor.get_cut_buffer().add (what_we_got);
619 _session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
624 if ((what_we_got = alist->copy (selection.time.front().start, selection.time.front().end)) != 0) {
625 _editor.get_cut_buffer().add (what_we_got);
630 if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
631 _session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
638 for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
639 double when = (*x)->when;
640 double val = (*x)->value;
641 line.model_to_view_coord (when, val);
651 AutomationTimeAxisView::reset_objects (PointSelection& selection)
653 reset_objects_one (*_line, selection);
657 AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection& selection)
659 boost::shared_ptr<AutomationList> alist(line.the_list());
661 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), &alist->get_state(), 0));
663 for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
665 if (&(*i).track != this) {
669 alist->reset_range ((*i).start, (*i).end);
674 AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
676 return cut_copy_clear_objects_one (*_line, selection, op);
680 AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointSelection& selection, CutCopyOp op)
682 boost::shared_ptr<Evoral::ControlList> what_we_got;
683 boost::shared_ptr<AutomationList> alist(line.the_list());
686 XMLNode &before = alist->get_state();
688 for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
690 if (&(*i).track != this) {
696 if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
697 _editor.get_cut_buffer().add (what_we_got);
698 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
703 if ((what_we_got = alist->copy ((*i).start, (*i).end)) != 0) {
704 _editor.get_cut_buffer().add (what_we_got);
709 if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
710 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
720 for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
721 double when = (*x)->when;
722 double val = (*x)->value;
723 line.model_to_view_coord (when, val);
733 AutomationTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size_t nth)
735 return paste_one (*_line, pos, times, selection, nth);
739 AutomationTimeAxisView::paste_one (AutomationLine& line, nframes_t pos, float times, Selection& selection, size_t nth)
741 AutomationSelection::iterator p;
742 boost::shared_ptr<AutomationList> alist(line.the_list());
744 for (p = selection.lines.begin(); p != selection.lines.end() && nth; ++p, --nth) {}
746 if (p == selection.lines.end()) {
750 /* Make a copy of the list because we have to scale the
751 values from view coordinates to model coordinates, and we're
752 not supposed to modify the points in the selection.
755 AutomationList copy (**p);
757 for (AutomationList::iterator x = copy.begin(); x != copy.end(); ++x) {
758 double when = (*x)->when;
759 double val = (*x)->value;
760 line.view_to_model_coord (when, val);
765 XMLNode &before = alist->get_state();
766 alist->paste (copy, pos, times);
767 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
773 AutomationTimeAxisView::get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable*>& results)
775 if (_line && touched (top, bot)) {
779 /* remember: this is X Window - coordinate space starts in upper left and moves down.
780 _y_position is the "origin" or "top" of the track.
783 double mybot = _y_position + height;
785 if (_y_position >= top && mybot <= bot) {
787 /* _y_position is below top, mybot is above bot, so we're fully
796 /* top and bot are within _y_position .. mybot */
798 topfrac = 1.0 - ((top - _y_position) / height);
799 botfrac = 1.0 - ((bot - _y_position) / height);
803 _line->get_selectables (start, end, botfrac, topfrac, results);
808 AutomationTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& result)
811 _line->get_inverted_selectables (sel, result);
815 AutomationTimeAxisView::set_selected_points (PointSelection& points)
818 _line->set_selected_points (points);
822 AutomationTimeAxisView::clear_lines ()
825 automation_connection.disconnect ();
829 AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
833 assert(line->the_list() == _control->list());
835 automation_connection = _control->alist()->automation_state_changed.connect
836 (mem_fun(*this, &AutomationTimeAxisView::automation_state_changed));
839 //_controller = AutomationController::create(_session, line->the_list(), _control);
841 line->set_height (height);
843 /* pick up the current state */
844 automation_state_changed ();
850 AutomationTimeAxisView::entered()
853 _line->track_entered();
857 AutomationTimeAxisView::exited ()
860 _line->track_exited();
864 AutomationTimeAxisView::color_handler ()
872 AutomationTimeAxisView::set_state (const XMLNode& node, int version)
874 TimeAxisView::set_state (node, version);
876 XMLProperty const * type = node.property ("automation-id");
877 if (type && type->value () == ARDOUR::EventTypeMap::instance().to_symbol (_control->parameter())) {
878 XMLProperty const * shown = node.property ("shown");
879 if (shown && shown->value () == "yes") {
880 set_marked_for_display (true);
881 _canvas_display->show (); /* FIXME: necessary? show_at? */
885 if (!_marked_for_display) {
893 AutomationTimeAxisView::get_state_node ()
895 TimeAxisView* state_parent = get_parent_with_state ();
898 return state_parent->get_automation_child_xml_node (_control->parameter());
905 AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
907 XMLNode* xml_node = get_state_node();
909 xml_node->add_property ("shown", editor_shown ? "yes" : "no");
914 AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
916 update_extra_xml_shown (true);
918 return TimeAxisView::show_at (y, nth, parent);
922 AutomationTimeAxisView::hide ()
924 update_extra_xml_shown (false);
926 TimeAxisView::hide ();