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 <ardour/route.h>
22 #include <ardour/automation_control.h>
23 #include <pbd/memento_command.h>
24 #include <gtkmm2ext/barcontroller.h>
26 #include "ardour_ui.h"
27 #include "automation_time_axis.h"
28 #include "automation_line.h"
29 #include "public_editor.h"
30 #include "simplerect.h"
31 #include "selection.h"
32 #include "ghostregion.h"
33 #include "rgb_macros.h"
34 #include "automation_selectable.h"
35 #include "point_selection.h"
36 #include "canvas_impl.h"
41 using namespace ARDOUR;
44 using namespace Gtkmm2ext;
45 using namespace Editing;
47 Pango::FontDescription* AutomationTimeAxisView::name_font = 0;
48 bool AutomationTimeAxisView::have_name_font = false;
50 AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
51 boost::shared_ptr<Automatable> a, boost::shared_ptr<AutomationControl> c,
52 PublicEditor& e, TimeAxisView& rent,
53 ArdourCanvas::Canvas& canvas, const string & nom,
54 const string & state_name, const string & nomparent)
57 TimeAxisView (s, e, &rent, canvas),
61 _controller(AutomationController::create(s, c->list(), c)),
65 _state_name (state_name),
66 height_button (_("h")),
67 clear_button (_("clear")),
68 auto_button (X_("")) /* force addition of a label */
70 if (!have_name_font) {
71 name_font = get_font_for_style (X_("AutomationTrackName"));
72 have_name_font = true;
76 in_destructor = false;
81 ignore_state_request = false;
82 first_call_to_set_height = true;
84 _base_rect = new SimpleRect(*canvas_display);
85 _base_rect->property_x1() = 0.0;
86 _base_rect->property_y1() = 0.0;
87 _base_rect->property_x2() = editor.frame_to_pixel (max_frames);
88 _base_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackOutline.get();
90 /* outline ends and bottom */
91 _base_rect->property_outline_what() = (guint32) (0x1|0x2|0x8);
92 _base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackFill.get();
94 _base_rect->set_data ("trackview", this);
96 _base_rect->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_automation_track_event),
99 hide_button.add (*(manage (new Gtk::Image (::get_icon("hide")))));
101 height_button.set_name ("TrackSizeButton");
102 auto_button.set_name ("TrackVisualButton");
103 clear_button.set_name ("TrackVisualButton");
104 hide_button.set_name ("TrackRemoveButton");
106 controls_table.set_no_show_all();
108 ARDOUR_UI::instance()->tooltips().set_tip(height_button, _("track height"));
109 ARDOUR_UI::instance()->tooltips().set_tip(auto_button, _("automation state"));
110 ARDOUR_UI::instance()->tooltips().set_tip(clear_button, _("clear track"));
111 ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("hide track"));
113 /* rearrange the name display */
115 /* we never show these for automation tracks, so make
116 life easier and remove them.
121 /* move the name label over a bit */
123 string shortpname = _name;
124 bool shortened = false;
127 shortpname = fit_to_pixels (_name, 60, *name_font, ignore_width, true);
129 if (shortpname != _name ){
133 name_label.set_text (shortpname);
134 name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
136 if (nomparent.length()) {
138 /* limit the plug name string */
140 string pname = fit_to_pixels (nomparent, 60, *name_font, ignore_width, true);
141 if (pname != nomparent) {
145 plugname = new Label (pname);
146 plugname->set_name (X_("TrackPlugName"));
148 name_label.set_name (X_("TrackParameterName"));
149 controls_table.remove (name_hbox);
150 controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
151 plugname_packed = true;
152 controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
155 plugname_packed = false;
159 string tipname = nomparent;
160 if (!tipname.empty()) {
164 ARDOUR_UI::instance()->tooltips().set_tip(controls_ebox, tipname);
167 /* add the buttons */
168 controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
169 controls_table.attach (height_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
171 controls_table.attach (auto_button, 5, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
172 controls_table.attach (clear_button, 5, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
174 /* add bar controller */
175 controls_table.attach (*_controller.get(), 0, 8, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
177 controls_table.show_all ();
179 height_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::height_clicked));
180 clear_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::clear_clicked));
181 hide_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::hide_clicked));
182 auto_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::auto_clicked));
184 controls_base_selected_name = X_("AutomationTrackControlsBaseSelected");
185 controls_base_unselected_name = X_("AutomationTrackControlsBase");
186 controls_ebox.set_name (controls_base_unselected_name);
188 controls_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT);
190 XMLNode* xml_node = get_parent_with_state()->get_child_xml_node (_state_name);
193 set_state (*xml_node);
196 boost::shared_ptr<AutomationLine> line(new AutomationLine (
197 _control->list()->parameter().to_string(),
202 line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
203 line->queue_reset ();
206 /* make sure labels etc. are correct */
208 automation_state_changed ();
209 ColorsChanged.connect (mem_fun (*this, &AutomationTimeAxisView::color_handler));
212 AutomationTimeAxisView::~AutomationTimeAxisView ()
214 in_destructor = true;
216 for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
222 AutomationTimeAxisView::auto_clicked ()
224 using namespace Menu_Helpers;
226 if (automation_menu == 0) {
227 automation_menu = manage (new Menu);
228 automation_menu->set_name ("ArdourContextMenu");
229 MenuList& items (automation_menu->items());
231 items.push_back (MenuElem (_("Manual"),
232 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Off)));
233 items.push_back (MenuElem (_("Play"),
234 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Play)));
235 items.push_back (MenuElem (_("Write"),
236 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Write)));
237 items.push_back (MenuElem (_("Touch"),
238 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Touch)));
241 automation_menu->popup (1, gtk_get_current_event_time());
245 AutomationTimeAxisView::set_automation_state (AutoState state)
247 if (!ignore_state_request) {
248 if (_route == _automatable) { // FIXME: ew
249 _route->set_parameter_automation_state (
250 _control->list()->parameter(),
254 _control->list()->set_automation_state(state);
260 AutomationTimeAxisView::automation_state_changed ()
264 /* update button label */
269 state = _control->list()->automation_state ();
272 switch (state & (Off|Play|Touch|Write)) {
274 auto_button.set_label (_("Manual"));
276 ignore_state_request = true;
277 auto_off_item->set_active (true);
278 auto_play_item->set_active (false);
279 auto_touch_item->set_active (false);
280 auto_write_item->set_active (false);
281 ignore_state_request = false;
285 auto_button.set_label (_("Play"));
286 if (auto_play_item) {
287 ignore_state_request = true;
288 auto_play_item->set_active (true);
289 auto_off_item->set_active (false);
290 auto_touch_item->set_active (false);
291 auto_write_item->set_active (false);
292 ignore_state_request = false;
296 auto_button.set_label (_("Write"));
297 if (auto_write_item) {
298 ignore_state_request = true;
299 auto_write_item->set_active (true);
300 auto_off_item->set_active (false);
301 auto_play_item->set_active (false);
302 auto_touch_item->set_active (false);
303 ignore_state_request = false;
307 auto_button.set_label (_("Touch"));
308 if (auto_touch_item) {
309 ignore_state_request = true;
310 auto_touch_item->set_active (true);
311 auto_off_item->set_active (false);
312 auto_play_item->set_active (false);
313 auto_write_item->set_active (false);
314 ignore_state_request = false;
318 auto_button.set_label (_("???"));
324 AutomationTimeAxisView::height_clicked ()
330 AutomationTimeAxisView::clear_clicked ()
332 _session.begin_reversible_command (_("clear automation"));
334 _session.commit_reversible_command ();
338 AutomationTimeAxisView::set_height (TrackHeight ht)
340 uint32_t h = height_to_pixels (ht);
341 bool changed = (height != (uint32_t) h);
343 //bool changed_between_small_and_normal = ( (ht == Small || ht == Smaller) ^ (height_style == Small || height_style == Smaller) );
345 TimeAxisView* state_parent = get_parent_with_state ();
346 XMLNode* xml_node = state_parent->get_child_xml_node (_state_name);
348 TimeAxisView::set_height (ht);
349 _base_rect->property_y2() = h;
352 _line->set_y_position_and_height (0, h);
354 for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
361 xml_node->add_property ("track_height", "largest");
365 xml_node->add_property ("track_height", "large");
369 xml_node->add_property ("track_height", "larger");
373 xml_node->add_property ("track_height", "normal");
377 xml_node->add_property ("track_height", "smaller");
381 xml_node->add_property ("track_height", "small");
385 //if (changed_between_small_and_normal || first_call_to_set_height) {
386 first_call_to_set_height = false;
391 controls_table.remove (name_hbox);
394 if (plugname_packed) {
395 controls_table.remove (*plugname);
396 plugname_packed = false;
398 controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
399 plugname_packed = true;
400 controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
402 controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
406 name_hbox.show_all ();
409 height_button.show();
411 hide_button.show_all();
417 _controller->show ();
425 controls_table.remove (name_hbox);
427 if (plugname_packed) {
428 controls_table.remove (*plugname);
429 plugname_packed = false;
432 controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
433 controls_table.hide_all ();
436 name_hbox.show_all ();
439 height_button.hide();
448 /* only emit the signal if the height really changed */
449 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
454 AutomationTimeAxisView::set_samples_per_unit (double spu)
456 TimeAxisView::set_samples_per_unit (editor.get_current_zoom());
462 AutomationTimeAxisView::hide_clicked ()
464 // LAME fix for refreshing the hide button
465 hide_button.set_sensitive(false);
467 set_marked_for_display (false);
470 hide_button.set_sensitive(true);
474 AutomationTimeAxisView::build_display_menu ()
476 using namespace Menu_Helpers;
478 /* get the size menu ready */
484 TimeAxisView::build_display_menu ();
486 /* now fill it with our stuff */
488 MenuList& items = display_menu->items();
490 items.push_back (MenuElem (_("Height"), *size_menu));
491 items.push_back (SeparatorElem());
492 items.push_back (MenuElem (_("Hide"), mem_fun(*this, &AutomationTimeAxisView::hide_clicked)));
493 items.push_back (SeparatorElem());
494 items.push_back (MenuElem (_("Clear"), mem_fun(*this, &AutomationTimeAxisView::clear_clicked)));
495 items.push_back (SeparatorElem());
497 Menu* auto_state_menu = manage (new Menu);
498 auto_state_menu->set_name ("ArdourContextMenu");
499 MenuList& as_items = auto_state_menu->items();
501 as_items.push_back (CheckMenuElem (_("Manual"),
502 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Off)));
503 auto_off_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
505 as_items.push_back (CheckMenuElem (_("Play"),
506 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Play)));
507 auto_play_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
509 as_items.push_back (CheckMenuElem (_("Write"),
510 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Write)));
511 auto_write_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
513 as_items.push_back (CheckMenuElem (_("Touch"),
514 bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Touch)));
515 auto_touch_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
517 items.push_back (MenuElem (_("State"), *auto_state_menu));
519 /* make sure the automation menu state is correct */
521 automation_state_changed ();
525 AutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
529 canvas_display->w2i (x, y);
531 /* compute vertical fractional position */
533 y = 1.0 - (y / height);
537 _line->view_to_model_y (y);
539 _session.begin_reversible_command (_("add automation event"));
540 XMLNode& before = _control->list()->get_state();
542 _control->list()->add (when, y);
544 XMLNode& after = _control->list()->get_state();
545 _session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(*_control->list().get(), &before, &after));
547 _session.set_dirty ();
552 AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
554 return cut_copy_clear_one (*_line, selection, op);
558 AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& selection, CutCopyOp op)
560 AutomationList* what_we_got = 0;
561 boost::shared_ptr<AutomationList> alist (line.the_list());
564 XMLNode &before = alist->get_state();
568 if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
569 editor.get_cut_buffer().add (what_we_got);
570 _session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
575 if ((what_we_got = alist->copy (selection.time.front().start, selection.time.front().end)) != 0) {
576 editor.get_cut_buffer().add (what_we_got);
581 if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
582 _session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
591 for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
592 double foo = (*x)->value;
593 line.model_to_view_y (foo);
602 AutomationTimeAxisView::reset_objects (PointSelection& selection)
604 reset_objects_one (*_line, selection);
608 AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection& selection)
610 boost::shared_ptr<AutomationList> alist(line.the_list());
612 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), &alist->get_state(), 0));
614 for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
616 if (&(*i).track != this) {
620 alist->reset_range ((*i).start, (*i).end);
625 AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
627 return cut_copy_clear_objects_one (*_line, selection, op);
631 AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointSelection& selection, CutCopyOp op)
633 AutomationList* what_we_got = 0;
634 boost::shared_ptr<AutomationList> alist(line.the_list());
637 XMLNode &before = alist->get_state();
639 for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
641 if (&(*i).track != this) {
647 if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
648 editor.get_cut_buffer().add (what_we_got);
649 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
654 if ((what_we_got = alist->copy ((*i).start, (*i).end)) != 0) {
655 editor.get_cut_buffer().add (what_we_got);
660 if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
661 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
673 for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
674 double foo = (*x)->value;
675 line.model_to_view_y (foo);
684 AutomationTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size_t nth)
686 return paste_one (*_line, pos, times, selection, nth);
690 AutomationTimeAxisView::paste_one (AutomationLine& line, nframes_t pos, float times, Selection& selection, size_t nth)
692 AutomationSelection::iterator p;
693 boost::shared_ptr<AutomationList> alist(line.the_list());
695 for (p = selection.lines.begin(); p != selection.lines.end() && nth; ++p, --nth);
697 if (p == selection.lines.end()) {
701 /* Make a copy of the list because we have to scale the
702 values from view coordinates to model coordinates, and we're
703 not supposed to modify the points in the selection.
706 AutomationList copy (**p);
708 for (AutomationList::iterator x = copy.begin(); x != copy.end(); ++x) {
709 double foo = (*x)->value;
710 line.view_to_model_y (foo);
714 XMLNode &before = alist->get_state();
715 alist->paste (copy, pos, times);
716 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
722 AutomationTimeAxisView::add_ghost (GhostRegion* gr)
724 ghosts.push_back (gr);
725 gr->GoingAway.connect (mem_fun(*this, &AutomationTimeAxisView::remove_ghost));
729 AutomationTimeAxisView::remove_ghost (GhostRegion* gr)
735 list<GhostRegion*>::iterator i;
737 for (i = ghosts.begin(); i != ghosts.end(); ++i) {
746 AutomationTimeAxisView::get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable*>& results)
748 if (_line && touched (top, bot)) {
752 /* remember: this is X Window - coordinate space starts in upper left and moves down.
753 y_position is the "origin" or "top" of the track.
756 double mybot = y_position + height;
758 if (y_position >= top && mybot <= bot) {
760 /* y_position is below top, mybot is above bot, so we're fully
769 /* top and bot are within y_position .. mybot */
771 topfrac = 1.0 - ((top - y_position) / height);
772 botfrac = 1.0 - ((bot - y_position) / height);
775 _line->get_selectables (start, end, botfrac, topfrac, results);
780 AutomationTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& result)
782 _line->get_inverted_selectables (sel, result);
786 AutomationTimeAxisView::set_selected_points (PointSelection& points)
788 _line->set_selected_points (points);
792 AutomationTimeAxisView::clear_lines ()
795 automation_connection.disconnect ();
799 AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
803 assert(line->the_list() == _control->list());
805 automation_connection = _control->list()->automation_state_changed.connect
806 (mem_fun(*this, &AutomationTimeAxisView::automation_state_changed));
809 //_controller = AutomationController::create(_session, line->the_list(), _control);
811 line->set_y_position_and_height (0, height);
813 /* pick up the current state */
814 automation_state_changed ();
820 AutomationTimeAxisView::show_all_control_points ()
822 _line->show_all_control_points ();
826 AutomationTimeAxisView::hide_all_but_selected_control_points ()
828 _line->hide_all_but_selected_control_points ();
832 AutomationTimeAxisView::entered()
834 show_all_control_points ();
838 AutomationTimeAxisView::exited ()
840 hide_all_but_selected_control_points ();
844 AutomationTimeAxisView::set_colors ()
846 for (list<GhostRegion*>::iterator i=ghosts.begin(); i != ghosts.end(); i++ ) {
854 AutomationTimeAxisView::color_handler ()
860 AutomationTimeAxisView::set_state (const XMLNode& node)
862 TimeAxisView::set_state (node);
865 XMLNodeConstIterator iter;
867 kids = node.children ();
869 //snprintf (buf, sizeof(buf), "Port_%" PRIu32, param.id());
871 for (iter = kids.begin(); iter != kids.end(); ++iter) {
872 if ((*iter)->name() == _control->list()->parameter().to_string()) {
874 XMLProperty *shown = (*iter)->property("shown_editor");
876 if (shown && shown->value() == "yes") {
877 set_marked_for_display(true);
878 canvas_display->show(); /* FIXME: necessary? show_at? */
884 if (!_marked_for_display)
887 // FIXME: _xml_node = &node?
891 AutomationTimeAxisView::get_state_node ()
893 TimeAxisView* state_parent = get_parent_with_state ();
896 return state_parent->get_child_xml_node (_state_name);
903 AutomationTimeAxisView::ensure_xml_node ()
905 if ((_automatable != _route) && _xml_node == 0) {
906 if ((_xml_node = _automatable->extra_xml ("GUI")) == 0) {
907 _xml_node = new XMLNode ("GUI");
908 _automatable->add_extra_xml (*_xml_node);
914 AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
916 if (_automatable == _route)
923 XMLNodeList nlist = _xml_node->children ();
924 XMLNodeConstIterator i;
925 XMLNode * port_node = 0;
927 /* FIXME: these parsed XML node names need to go */
928 //snprintf (buf, sizeof(buf), "Port_%" PRIu32, _param.id());
930 for (i = nlist.begin(); i != nlist.end(); ++i) {
931 /* FIXME: legacy session loading */
932 if ((*i)->name() == _control->list()->parameter().to_string()) {
939 port_node = new XMLNode(buf);
940 _xml_node->add_child_nocopy(*port_node);
943 port_node->add_property ("shown_editor", editor_shown ? "yes": "no");
947 AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
949 update_extra_xml_shown (true);
951 return TimeAxisView::show_at (y, nth, parent);
955 AutomationTimeAxisView::hide ()
957 update_extra_xml_shown (false);
959 TimeAxisView::hide ();