1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2021 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <ags/X/editor/ags_automation_toolbar.h>
21 #include <ags/X/editor/ags_automation_toolbar_callbacks.h>
22 
23 #include <ags/X/ags_window.h>
24 #include <ags/X/ags_automation_window.h>
25 #include <ags/X/ags_menu_bar.h>
26 #include <ags/X/ags_automation_editor.h>
27 #include <ags/X/ags_automation_editor_callbacks.h>
28 #include <ags/X/ags_pad.h>
29 #include <ags/X/ags_line.h>
30 #include <ags/X/ags_line_member.h>
31 
32 #include <ags/X/editor/ags_select_acceleration_dialog.h>
33 #include <ags/X/editor/ags_ramp_acceleration_dialog.h>
34 #include <ags/X/editor/ags_position_automation_cursor_dialog.h>
35 
36 #include <ags/config.h>
37 #include <ags/i18n.h>
38 
39 void ags_automation_toolbar_class_init(AgsAutomationToolbarClass *automation_toolbar);
40 void ags_automation_toolbar_connectable_interface_init(AgsConnectableInterface *connectable);
41 void ags_automation_toolbar_init(AgsAutomationToolbar *automation_toolbar);
42 void ags_automation_toolbar_connect(AgsConnectable *connectable);
43 void ags_automation_toolbar_disconnect(AgsConnectable *connectable);
44 
45 /**
46  * SECTION:ags_automation_toolbar
47  * @short_description: automation toolbar
48  * @title: AgsAutomationToolbar
49  * @section_id:
50  * @include: ags/X/editor/ags_automation_toolbar.h
51  *
52  * The #AgsAutomationToolbar lets you choose edit tool.
53  */
54 
55 GType
ags_automation_toolbar_get_type(void)56 ags_automation_toolbar_get_type(void)
57 {
58   static volatile gsize g_define_type_id__volatile = 0;
59 
60   if(g_once_init_enter (&g_define_type_id__volatile)){
61     GType ags_type_automation_toolbar = 0;
62 
63     static const GTypeInfo ags_automation_toolbar_info = {
64       sizeof (AgsAutomationToolbarClass),
65       NULL, /* base_init */
66       NULL, /* base_finalize */
67       (GClassInitFunc) ags_automation_toolbar_class_init,
68       NULL, /* class_finalize */
69       NULL, /* class_data */
70       sizeof (AgsAutomationToolbar),
71       0,    /* n_preallocs */
72       (GInstanceInitFunc) ags_automation_toolbar_init,
73     };
74 
75     static const GInterfaceInfo ags_connectable_interface_info = {
76       (GInterfaceInitFunc) ags_automation_toolbar_connectable_interface_init,
77       NULL, /* interface_finalize */
78       NULL, /* interface_data */
79     };
80 
81     ags_type_automation_toolbar = g_type_register_static(GTK_TYPE_TOOLBAR,
82 							 "AgsAutomationToolbar", &ags_automation_toolbar_info,
83 							 0);
84 
85     g_type_add_interface_static(ags_type_automation_toolbar,
86 				AGS_TYPE_CONNECTABLE,
87 				&ags_connectable_interface_info);
88 
89     g_once_init_leave(&g_define_type_id__volatile, ags_type_automation_toolbar);
90   }
91 
92   return g_define_type_id__volatile;
93 }
94 
95 void
ags_automation_toolbar_class_init(AgsAutomationToolbarClass * automation_toolbar)96 ags_automation_toolbar_class_init(AgsAutomationToolbarClass *automation_toolbar)
97 {
98 }
99 
100 void
ags_automation_toolbar_connectable_interface_init(AgsConnectableInterface * connectable)101 ags_automation_toolbar_connectable_interface_init(AgsConnectableInterface *connectable)
102 {
103   connectable->is_ready = NULL;
104   connectable->is_connected = NULL;
105   connectable->connect = ags_automation_toolbar_connect;
106   connectable->disconnect = ags_automation_toolbar_disconnect;
107 }
108 
109 void
ags_automation_toolbar_init(AgsAutomationToolbar * automation_toolbar)110 ags_automation_toolbar_init(AgsAutomationToolbar *automation_toolbar)
111 {
112   GtkToolItem *tool_item;
113   GtkMenuToolButton *menu_tool_button;
114   GtkMenu *menu;
115   GtkMenuItem *item;
116   GtkLabel *label;
117   GtkCellRenderer *cell_renderer;
118   GtkHBox *hbox;
119 
120   /* position */
121   tool_item = gtk_tool_item_new();
122   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
123 		     (GtkWidget *) tool_item,
124 		     -1);
125 
126   automation_toolbar->position = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
127 								      "label", i18n("Position"),
128 								      "icon-name", "go-jump",
129 								      NULL);
130   gtk_container_add((GtkContainer *) tool_item,
131 		    (GtkWidget *) automation_toolbar->position);
132 
133   /* edit */
134   tool_item = gtk_tool_item_new();
135   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
136 		     (GtkWidget *) tool_item,
137 		     -1);
138 
139   automation_toolbar->edit = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
140 								  "label", i18n("Edit"),
141 								  "icon-name", "format-text-direction-ltr",
142 								  "active", TRUE,
143 								  NULL);
144   automation_toolbar->selected_edit_mode = automation_toolbar->edit;
145   gtk_container_add((GtkContainer *) tool_item,
146 		    (GtkWidget *) automation_toolbar->edit);
147 
148   /* clear */
149   tool_item = gtk_tool_item_new();
150   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
151 		     (GtkWidget *) tool_item,
152 		     -1);
153 
154   automation_toolbar->clear = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
155 								   "label", i18n("Clear"),
156 								   "icon-name", "edit-clear",
157 								   NULL);
158   gtk_container_add((GtkContainer *) tool_item,
159 		    (GtkWidget *) automation_toolbar->clear);
160 
161   /* select */
162   tool_item = gtk_tool_item_new();
163   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
164 		     (GtkWidget *) tool_item,
165 		     -1);
166 
167   automation_toolbar->select = (GtkToggleToolButton *) g_object_new(GTK_TYPE_TOGGLE_TOOL_BUTTON,
168 								    "label", i18n("Select"),
169 								    "icon-name", "edit-select-all",
170 								    NULL);
171   gtk_container_add((GtkContainer *) tool_item,
172 		    (GtkWidget *) automation_toolbar->select);
173 
174   /* copy */
175   tool_item = gtk_tool_item_new();
176   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
177 		     (GtkWidget *) tool_item,
178 		     -1);
179 
180   automation_toolbar->copy = (GtkToolButton *) g_object_new(GTK_TYPE_TOOL_BUTTON,
181 							    "label", i18n("Copy"),
182 							    "icon-name", "edit-copy",
183 							    NULL);
184   gtk_container_add((GtkContainer *) tool_item,
185 		    (GtkWidget *) automation_toolbar->copy);
186 
187   /* cut */
188   tool_item = gtk_tool_item_new();
189   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
190 		     (GtkWidget *) tool_item,
191 		     -1);
192 
193   automation_toolbar->cut = (GtkToolButton *) g_object_new(GTK_TYPE_TOOL_BUTTON,
194 							   "label", i18n("Cut"),
195 							   "icon-name", "edit-cut",
196 							   NULL);
197   gtk_container_add((GtkContainer *) tool_item,
198 		    (GtkWidget *) automation_toolbar->cut);
199 
200   /* paste */
201   tool_item = gtk_tool_item_new();
202   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
203 		     (GtkWidget *) tool_item,
204 		     -1);
205 
206   automation_toolbar->paste_tool = (GtkMenuToolButton *) g_object_new(GTK_TYPE_MENU_TOOL_BUTTON,
207 								      "label", i18n("Paste"),
208 								      "icon-name", "edit-paste",
209 								      NULL);
210 
211   menu = (GtkMenu *) gtk_menu_new();
212 
213   item = g_object_new(GTK_TYPE_CHECK_MENU_ITEM,
214 		      "label", "match line",
215 		      "active", TRUE,
216 		      NULL);
217   gtk_menu_shell_append((GtkMenuShell *) menu,
218 			(GtkWidget *) item);
219 
220   item = g_object_new(GTK_TYPE_CHECK_MENU_ITEM,
221 		      "label", "no duplicates",
222 		      "active", TRUE,
223 		      NULL);
224   gtk_menu_shell_append((GtkMenuShell *) menu,
225 			(GtkWidget *) item);
226 
227   gtk_menu_tool_button_set_menu(automation_toolbar->paste_tool,
228 				(GtkWidget *) menu);
229   gtk_widget_show_all((GtkWidget *) menu);
230 
231   gtk_container_add((GtkContainer *) tool_item,
232 		    (GtkWidget *) automation_toolbar->paste_tool);
233 
234   /* menu tool */
235   tool_item = gtk_tool_item_new();
236   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
237 		     (GtkWidget *) tool_item,
238 		     -1);
239 
240   automation_toolbar->menu_tool = (GtkMenuToolButton *) g_object_new(GTK_TYPE_MENU_TOOL_BUTTON,
241 								     "label", i18n("Tool"),
242 								     "icon-name", "system-run",
243 								     NULL);
244   gtk_container_add((GtkContainer *) tool_item,
245 		    (GtkWidget *) automation_toolbar->menu_tool);
246 
247   /* menu tool - tool popup */
248   automation_toolbar->tool_popup = ags_automation_toolbar_tool_popup_new(automation_toolbar);
249   gtk_menu_tool_button_set_menu(automation_toolbar->menu_tool,
250 				(GtkWidget *) automation_toolbar->tool_popup);
251 
252   /* menu tool - dialogs */
253   automation_toolbar->select_acceleration = (GtkDialog *) ags_select_acceleration_dialog_new(NULL);
254   automation_toolbar->ramp_acceleration = (GtkDialog *) ags_ramp_acceleration_dialog_new(NULL);
255   automation_toolbar->position_automation_cursor = (GtkDialog *) ags_position_automation_cursor_dialog_new(NULL);
256 
257   /*  */
258   tool_item = gtk_tool_item_new();
259   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
260 		     (GtkWidget *) tool_item,
261 		     -1);
262 
263   hbox = gtk_hbox_new(FALSE,
264 		      0);
265   gtk_container_add((GtkContainer *) tool_item,
266 		    (GtkWidget *) hbox);
267 
268 
269   label = (GtkLabel *) gtk_label_new(i18n("Zoom"));
270   gtk_box_pack_start(hbox,
271 		     (GtkWidget *) label,
272 		     FALSE, FALSE,
273 		     0);
274 
275   automation_toolbar->zoom_history = 2;
276   automation_toolbar->zoom = ags_zoom_combo_box_new();
277   gtk_combo_box_set_active(GTK_COMBO_BOX(automation_toolbar->zoom),
278 			   2);
279   gtk_box_pack_start(hbox,
280 		     (GtkWidget *) automation_toolbar->zoom,
281 		     FALSE, FALSE,
282 		     0);
283 
284   /* port */
285   tool_item = gtk_tool_item_new();
286   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
287 		     (GtkWidget *) tool_item,
288 		     -1);
289 
290   hbox = gtk_hbox_new(FALSE,
291 		      0);
292   gtk_container_add((GtkContainer *) tool_item,
293 		    (GtkWidget *) hbox);
294 
295   label = (GtkLabel *) gtk_label_new(i18n("Port"));
296   gtk_box_pack_start(hbox,
297 		     (GtkWidget *) label,
298 		     FALSE, FALSE,
299 		     0);
300 
301   automation_toolbar->port = (GtkComboBox *) gtk_combo_box_new();
302 
303   cell_renderer = gtk_cell_renderer_toggle_new();
304   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(automation_toolbar->port),
305 			     cell_renderer,
306 			     FALSE);
307   gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(automation_toolbar->port), cell_renderer,
308 				 "active", 0,
309 				 NULL);
310   gtk_cell_renderer_toggle_set_activatable(GTK_CELL_RENDERER_TOGGLE(cell_renderer),
311 					   TRUE);
312 
313   cell_renderer = gtk_cell_renderer_text_new();
314   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(automation_toolbar->port),
315 			     cell_renderer,
316 			     FALSE);
317   gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(automation_toolbar->port), cell_renderer,
318 				 "text", 1,
319 				 NULL);
320 
321   cell_renderer = gtk_cell_renderer_text_new();
322   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(automation_toolbar->port),
323 			     cell_renderer,
324 			     FALSE);
325   gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(automation_toolbar->port), cell_renderer,
326 				 "text", 2,
327 				 NULL);
328 
329   gtk_box_pack_start(hbox,
330 		     (GtkWidget *) automation_toolbar->port,
331 		     FALSE, FALSE,
332 		     0);
333 
334   /* opacity */
335   tool_item = gtk_tool_item_new();
336   gtk_toolbar_insert((GtkToolbar *) automation_toolbar,
337 		     (GtkWidget *) tool_item,
338 		     -1);
339 
340   hbox = gtk_hbox_new(FALSE,
341 		      0);
342   gtk_container_add((GtkContainer *) tool_item,
343 		    (GtkWidget *) hbox);
344 
345   label = (GtkLabel *) gtk_label_new(i18n("Opacity"));
346   gtk_box_pack_start(hbox,
347 		     (GtkWidget *) label,
348 		     FALSE, FALSE,
349 		     0);
350 
351   automation_toolbar->opacity = (GtkSpinButton *) gtk_spin_button_new_with_range(0.0, 1.0, 0.001);
352   gtk_spin_button_set_value(automation_toolbar->opacity, 0.3);
353   gtk_box_pack_start(hbox,
354 		     (GtkWidget *) automation_toolbar->opacity,
355 		     FALSE, FALSE,
356 		     0);
357 }
358 
359 
360 void
ags_automation_toolbar_connect(AgsConnectable * connectable)361 ags_automation_toolbar_connect(AgsConnectable *connectable)
362 {
363   AgsWindow *window;
364   AgsAutomationWindow *automation_window;
365   AgsAutomationEditor *automation_editor;
366   AgsAutomationToolbar *automation_toolbar;
367 
368   GList *list;
369 
370   automation_toolbar = AGS_AUTOMATION_TOOLBAR(connectable);
371 
372   if((AGS_AUTOMATION_TOOLBAR_CONNECTED & (automation_toolbar->flags)) != 0){
373     return;
374   }
375 
376   automation_toolbar->flags |= AGS_AUTOMATION_TOOLBAR_CONNECTED;
377 
378   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
379 								      AGS_TYPE_AUTOMATION_EDITOR);
380 
381   automation_window = (AgsAutomationWindow *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
382 								      AGS_TYPE_AUTOMATION_WINDOW);
383   window = (AgsWindow *) automation_window->parent_window;
384 
385   g_object_set(automation_toolbar->select_acceleration,
386 	       "main-window", window,
387 	       NULL);
388   g_object_set(automation_toolbar->ramp_acceleration,
389 	       "main-window", window,
390 	       NULL);
391   g_object_set(automation_toolbar->position_automation_cursor,
392 	       "main-window", window,
393 	       NULL);
394 
395   /*  */
396   g_signal_connect_after(G_OBJECT(automation_editor), "machine-changed",
397 			 G_CALLBACK(ags_automation_toolbar_machine_changed_callback), automation_toolbar);
398 
399   /* tool */
400   g_signal_connect_after((GObject *) automation_toolbar->position, "toggled",
401 			 G_CALLBACK(ags_automation_toolbar_position_callback), (gpointer) automation_toolbar);
402 
403   g_signal_connect_after((GObject *) automation_toolbar->edit, "toggled",
404 			 G_CALLBACK(ags_automation_toolbar_edit_callback), (gpointer) automation_toolbar);
405 
406   g_signal_connect_after((GObject *) automation_toolbar->clear, "toggled",
407 			 G_CALLBACK(ags_automation_toolbar_clear_callback), (gpointer) automation_toolbar);
408 
409   g_signal_connect_after((GObject *) automation_toolbar->select, "toggled",
410 			 G_CALLBACK(ags_automation_toolbar_select_callback), (gpointer) automation_toolbar);
411 
412   /* edit */
413   g_signal_connect((GObject *) automation_toolbar->copy, "clicked",
414 		   G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback), (gpointer) automation_toolbar);
415 
416   g_signal_connect((GObject *) automation_toolbar->cut, "clicked",
417 		   G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback), (gpointer) automation_toolbar);
418 
419   g_signal_connect((GObject *) automation_toolbar->paste_tool, "clicked",
420 		   G_CALLBACK(ags_automation_toolbar_paste_callback), (gpointer) automation_toolbar);
421 
422   list = gtk_container_get_children((GtkContainer *) gtk_menu_tool_button_get_menu(automation_toolbar->paste_tool));
423 
424   g_signal_connect_after(list->data, "activate",
425 			 G_CALLBACK(ags_automation_toolbar_match_line_callback), automation_toolbar);
426 
427   g_signal_connect_after(list->next->data, "activate",
428 			 G_CALLBACK(ags_automation_toolbar_no_duplicates_callback), automation_toolbar);
429 
430   g_list_free(list);
431 
432   /* additional tools */
433   ags_connectable_connect(AGS_CONNECTABLE(automation_toolbar->select_acceleration));
434 
435   ags_connectable_connect(AGS_CONNECTABLE(automation_toolbar->ramp_acceleration));
436 
437   ags_connectable_connect(AGS_CONNECTABLE(automation_toolbar->position_automation_cursor));
438 
439   /* zoom */
440   g_signal_connect_after((GObject *) automation_toolbar->zoom, "changed",
441 			 G_CALLBACK(ags_automation_toolbar_zoom_callback), (gpointer) automation_toolbar);
442 
443   /* port */
444   g_signal_connect_after(automation_toolbar->port, "changed",
445 			 G_CALLBACK(ags_automation_toolbar_port_callback), automation_toolbar);
446 
447   /* opacity */
448   g_signal_connect_after((GObject *) automation_toolbar->opacity, "value-changed",
449 			 G_CALLBACK(ags_automation_toolbar_opacity_callback), (gpointer) automation_toolbar);
450 }
451 
452 void
ags_automation_toolbar_disconnect(AgsConnectable * connectable)453 ags_automation_toolbar_disconnect(AgsConnectable *connectable)
454 {
455   AgsAutomationToolbar *automation_toolbar;
456 
457   GList *list;
458 
459   automation_toolbar = AGS_AUTOMATION_TOOLBAR(connectable);
460 
461   if((AGS_AUTOMATION_TOOLBAR_CONNECTED & (automation_toolbar->flags)) == 0){
462     return;
463   }
464 
465   automation_toolbar->flags &= (~AGS_AUTOMATION_TOOLBAR_CONNECTED);
466 
467   /* tool */
468   g_object_disconnect(G_OBJECT(automation_toolbar->position),
469 		      "any_signal::toggled",
470 		      G_CALLBACK(ags_automation_toolbar_position_callback),
471 		      automation_toolbar,
472 		      NULL);
473 
474   g_object_disconnect(G_OBJECT(automation_toolbar->edit),
475 		      "any_signal::toggled",
476 		      G_CALLBACK(ags_automation_toolbar_edit_callback),
477 		      automation_toolbar,
478 		      NULL);
479 
480   g_object_disconnect(G_OBJECT(automation_toolbar->clear),
481 		      "any_signal::toggled",
482 		      G_CALLBACK(ags_automation_toolbar_clear_callback),
483 		      automation_toolbar,
484 		      NULL);
485 
486   g_object_disconnect(G_OBJECT(automation_toolbar->select),
487 		      "any_signal::toggled",
488 		      G_CALLBACK(ags_automation_toolbar_select_callback),
489 		      automation_toolbar,
490 		      NULL);
491 
492   /* edit */
493   g_object_disconnect(G_OBJECT(automation_toolbar->copy),
494 		      "any_signal::clicked",
495 		      G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback),
496 		      automation_toolbar,
497 		      NULL);
498 
499   g_object_disconnect(G_OBJECT(automation_toolbar->cut),
500 		      "any_signal::clicked",
501 		      G_CALLBACK(ags_automation_toolbar_copy_or_cut_callback),
502 		      automation_toolbar,
503 		      NULL);
504 
505   g_object_disconnect(G_OBJECT(automation_toolbar->paste_tool),
506 		      "any_signal::clicked",
507 		      G_CALLBACK(ags_automation_toolbar_paste_callback),
508 		      automation_toolbar,
509 		      NULL);
510 
511   list = gtk_container_get_children((GtkContainer *) gtk_menu_tool_button_get_menu(automation_toolbar->paste_tool));
512 
513   g_object_disconnect(G_OBJECT(list->data),
514 		      "any_signal::activate",
515 		      G_CALLBACK(ags_automation_toolbar_match_line_callback),
516 		      automation_toolbar,
517 		      NULL);
518 
519   g_object_disconnect(G_OBJECT(list->next->data),
520 		      "any_signal::activate",
521 		      G_CALLBACK(ags_automation_toolbar_no_duplicates_callback),
522 		      automation_toolbar,
523 		      NULL);
524 
525   g_list_free(list);
526 
527   /* additional tools */
528   ags_connectable_disconnect(AGS_CONNECTABLE(automation_toolbar->select_acceleration));
529 
530   ags_connectable_disconnect(AGS_CONNECTABLE(automation_toolbar->ramp_acceleration));
531 
532   ags_connectable_disconnect(AGS_CONNECTABLE(automation_toolbar->position_automation_cursor));
533 
534   /* zoom */
535   g_object_disconnect(G_OBJECT(automation_toolbar->zoom),
536 		      "any_signal::changed",
537 		      G_CALLBACK(ags_automation_toolbar_zoom_callback),
538 		      automation_toolbar,
539 		      NULL);
540 
541   /* port */
542   g_object_disconnect(G_OBJECT(automation_toolbar->port),
543 		      "any_signal::changed",
544 		      G_CALLBACK(ags_automation_toolbar_port_callback),
545 		      automation_toolbar,
546 		      NULL);
547 
548   /* opacity */
549   g_object_disconnect(G_OBJECT(automation_toolbar->opacity),
550 		      "any_signal::value-changed",
551 		      G_CALLBACK(ags_automation_toolbar_opacity_callback),
552 		      automation_toolbar,
553 		      NULL);
554 }
555 
556 /**
557  * ags_automation_toolbar_load_port:
558  * @automation_toolbar: an #AgsAutomationToolbar
559  *
560  * Fill in port field with available ports.
561  *
562  * Since: 3.0.0
563  */
564 void
ags_automation_toolbar_load_port(AgsAutomationToolbar * automation_toolbar)565 ags_automation_toolbar_load_port(AgsAutomationToolbar *automation_toolbar)
566 {
567   AgsAutomationEditor *automation_editor;
568   AgsMachine *machine;
569 
570   GtkListStore *list_store;
571   GtkTreeIter iter;
572 
573   AgsChannel *start_channel;
574   AgsChannel *channel, *next_channel;
575 
576   GList *start_port, *port;
577 
578   gchar **collected_specifier;
579 
580   guint length;
581 
582   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
583 								      AGS_TYPE_AUTOMATION_EDITOR);
584   machine = automation_editor->selected_machine;
585 
586   if(machine == NULL){
587     gtk_combo_box_set_model(automation_toolbar->port,
588 			    NULL);
589     return;
590   }
591 
592   /*  */
593   list_store = gtk_list_store_new(3,
594 				  G_TYPE_BOOLEAN,
595 				  G_TYPE_STRING,
596 				  G_TYPE_STRING);
597   gtk_combo_box_set_model(automation_toolbar->port,
598 			  GTK_TREE_MODEL(list_store));
599 
600   collected_specifier = (gchar **) malloc(sizeof(gchar*));
601 
602   collected_specifier[0] = NULL;
603   length = 1;
604 
605   /* audio */
606   port =
607     start_port = ags_audio_collect_all_audio_ports(machine->audio);
608 
609   while(port != NULL){
610     AgsPluginPort *plugin_port;
611 
612     gchar *specifier;
613 
614     gboolean is_enabled;
615     gboolean contains_control_name;
616 
617     g_object_get(port->data,
618 		 "specifier", &specifier,
619 		 "plugin-port", &plugin_port,
620 		 NULL);
621 
622     if(specifier == NULL){
623       /* iterate */
624       port = port->next;
625 
626       continue;
627     }
628 
629 #ifdef HAVE_GLIB_2_44
630     contains_control_name = g_strv_contains(collected_specifier,
631 					    specifier);
632 #else
633     contains_control_name = ags_strv_contains(collected_specifier,
634 					      specifier);
635 #endif
636 
637     if(plugin_port != NULL &&
638        !contains_control_name){
639       /* create list store entry */
640       is_enabled = (ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
641 										    G_TYPE_NONE,
642 										    specifier)) ? TRUE: FALSE;
643 
644       gtk_list_store_append(list_store, &iter);
645       gtk_list_store_set(list_store, &iter,
646 			 0, is_enabled,
647 			 1, g_strdup("audio"),
648 			 2, g_strdup(specifier),
649 			 -1);
650 
651       /* add to collected specifier */
652       collected_specifier = (gchar **) realloc(collected_specifier,
653 					       (length + 1) * sizeof(gchar *));
654       collected_specifier[length - 1] = g_strdup(specifier);
655       collected_specifier[length] = NULL;
656 
657       length++;
658     }
659 
660     /* iterate */
661     port = port->next;
662   }
663 
664   g_list_free_full(start_port,
665 		   g_object_unref);
666 
667   /* output */
668   g_object_get(machine->audio,
669 	       "output", &start_channel,
670 	       NULL);
671 
672   channel = start_channel;
673   g_object_ref(channel);
674 
675   next_channel = NULL;
676 
677   while(channel != NULL){
678     /* output */
679     port =
680       start_port = ags_channel_collect_all_channel_ports(channel);
681 
682     while(port != NULL){
683       AgsPluginPort *plugin_port;
684 
685       gchar *specifier;
686 
687       gboolean is_enabled;
688       gboolean contains_control_name;
689 
690       g_object_get(port->data,
691 		   "specifier", &specifier,
692 		   "plugin-port", &plugin_port,
693 		   NULL);
694 
695       contains_control_name = g_strv_contains(collected_specifier,
696 					      specifier);
697 
698       if(plugin_port != NULL &&
699 	 !contains_control_name){
700 	/* create list store entry */
701 	is_enabled = (ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
702 										      AGS_TYPE_OUTPUT,
703 										      specifier)) ? TRUE: FALSE;
704 
705 	gtk_list_store_append(list_store, &iter);
706 	gtk_list_store_set(list_store, &iter,
707 			   0, is_enabled,
708 			   1, g_strdup("output"),
709 			   2, g_strdup(specifier),
710 			   -1);
711 
712 	/* add to collected specifier */
713 	collected_specifier = (gchar **) realloc(collected_specifier,
714 						 (length + 1) * sizeof(gchar *));
715 	collected_specifier[length - 1] = g_strdup(specifier);
716 	collected_specifier[length] = NULL;
717 
718 	length++;
719       }
720 
721       /* iterate */
722       port = port->next;
723     }
724 
725     g_list_free_full(start_port,
726 		     g_object_unref);
727 
728     /* iterate */
729     next_channel = ags_channel_next(channel);
730 
731     g_object_unref(channel);
732 
733     channel = next_channel;
734   }
735 
736   /* unref */
737   if(start_channel != NULL){
738     g_object_unref(start_channel);
739   }
740 
741   if(next_channel != NULL){
742     g_object_unref(next_channel);
743   }
744 
745   /* input */
746   g_object_get(machine->audio,
747 	       "input", &start_channel,
748 	       NULL);
749 
750   channel = start_channel;
751   g_object_ref(channel);
752 
753   next_channel = NULL;
754 
755   while(channel != NULL){
756     /* input */
757     port =
758       start_port = ags_channel_collect_all_channel_ports(channel);
759 
760     while(port != NULL){
761       AgsPluginPort *plugin_port;
762 
763       gchar *specifier;
764 
765       gboolean is_enabled;
766       gboolean contains_control_name;
767 
768       g_object_get(port->data,
769 		   "specifier", &specifier,
770 		   "plugin-port", &plugin_port,
771 		   NULL);
772 
773 #ifdef HAVE_GLIB_2_44
774       contains_control_name = g_strv_contains(collected_specifier,
775 					      specifier);
776 #else
777       contains_control_name = ags_strv_contains(collected_specifier,
778 						specifier);
779 #endif
780 
781       if(plugin_port != NULL &&
782 	 !contains_control_name){
783 	/* create list store entry */
784 	is_enabled = (ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
785 										      AGS_TYPE_INPUT,
786 										      specifier)) ? TRUE: FALSE;
787 
788 	gtk_list_store_append(list_store, &iter);
789 	gtk_list_store_set(list_store, &iter,
790 			   0, is_enabled,
791 			   1, g_strdup("input"),
792 			   2, g_strdup(specifier),
793 			   -1);
794 
795 	/* add to collected specifier */
796 	collected_specifier = (gchar **) realloc(collected_specifier,
797 						 (length + 1) * sizeof(gchar *));
798 	collected_specifier[length - 1] = g_strdup(specifier);
799 	collected_specifier[length] = NULL;
800 
801 	length++;
802       }
803 
804       /* iterate */
805       port = port->next;
806     }
807 
808     g_list_free_full(start_port,
809 		     g_object_unref);
810 
811     /* iterate */
812     next_channel = ags_channel_next(channel);
813 
814     g_object_unref(channel);
815 
816     channel = next_channel;
817   }
818 
819   /* unref */
820   if(start_channel != NULL){
821     g_object_unref(start_channel);
822   }
823 
824   if(next_channel != NULL){
825     g_object_unref(next_channel);
826   }
827 
828   g_strfreev(collected_specifier);
829 
830   gtk_list_store_append(list_store, &iter);
831   gtk_list_store_set(list_store, &iter,
832 		     0, FALSE,
833 		     1, g_strdup(""),
834 		     2, g_strdup(""),
835 		     -1);
836   gtk_combo_box_set_active_iter(automation_toolbar->port,
837 				&iter);
838 }
839 
840 /**
841  * ags_automation_toolbar_apply_port:
842  * @automation_toolbar: an #AgsAutomationToolbar
843  * @channel_type: the #GType of channel
844  * @control_name: the specifier as string
845  *
846  * Applies all port to appropriate #AgsMachine.
847  *
848  * Since: 3.0.0
849  */
850 void
ags_automation_toolbar_apply_port(AgsAutomationToolbar * automation_toolbar,GType channel_type,gchar * control_name)851 ags_automation_toolbar_apply_port(AgsAutomationToolbar *automation_toolbar,
852 				  GType channel_type, gchar *control_name)
853 {
854   AgsAutomationEditor *automation_editor;
855   AgsMachine *machine;
856 
857   GtkTreeModel *model;
858   GtkTreeIter iter;
859 
860   AgsChannel *start_channel;
861   AgsChannel *channel, *next_channel;
862 
863   AgsConfig *config;
864 
865   GList *start_automation, *automation;
866   GList *start_port, *port;
867 
868   gchar *str;
869 
870   gdouble gui_scale_factor;
871   guint length;
872   gboolean contains_specifier;
873   gboolean is_active;
874 
875   if(!g_ascii_strncasecmp(control_name,
876 			  "",
877 			  1)){
878     return;
879   }
880 
881   automation_editor = (AgsAutomationEditor *) gtk_widget_get_ancestor((GtkWidget *) automation_toolbar,
882 								      AGS_TYPE_AUTOMATION_EDITOR);
883   machine = automation_editor->selected_machine;
884 
885   model = gtk_combo_box_get_model(automation_toolbar->port);
886 
887   config = ags_config_get_instance();
888 
889   /* scale factor */
890   gui_scale_factor = 1.0;
891 
892   str = ags_config_get_value(config,
893 			     AGS_CONFIG_GENERIC,
894 			     "gui-scale");
895 
896   if(str != NULL){
897     gui_scale_factor = g_ascii_strtod(str,
898 				      NULL);
899 
900     g_free(str);
901   }
902 
903   /* update port combo box */
904   start_port = NULL;
905 
906   contains_specifier = FALSE;
907 
908   if(gtk_combo_box_get_active_iter(automation_toolbar->port, &iter)){
909     GType scope;
910     gchar *str, *specifier;
911 
912     GValue value = {0,};
913 
914     gtk_tree_model_get(model,
915 		       &iter,
916 		       1, &str,
917 		       2, &specifier,
918 		       -1);
919 
920     scope = G_TYPE_NONE;
921 
922     if(!g_ascii_strcasecmp("audio",
923 			   str)){
924       scope = G_TYPE_NONE;
925 
926       port = ags_audio_collect_all_audio_ports_by_specifier_and_context(machine->audio,
927 									control_name,
928 									TRUE);
929       start_port = port;
930 
931       port = ags_audio_collect_all_audio_ports_by_specifier_and_context(machine->audio,
932 									control_name,
933 									FALSE);
934 
935       if(start_port != NULL){
936 	start_port = g_list_concat(start_port,
937 				   port);
938       }else{
939 	start_port = port;
940       }
941     }else if(!g_ascii_strcasecmp("output",
942 				 str)){
943       scope = AGS_TYPE_OUTPUT;
944 
945       g_object_get(machine->audio,
946 		   "output", &start_channel,
947 		   NULL);
948 
949       channel = start_channel;
950       g_object_ref(channel);
951 
952       next_channel = NULL;
953 
954       start_port = NULL;
955 
956       while(channel != NULL){
957 	port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
958 									      control_name,
959 									      TRUE);
960 	if(start_port != NULL){
961 	  start_port = g_list_concat(start_port,
962 				     port);
963 	}else{
964 	  start_port = port;
965 	}
966 
967 	port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
968 									      control_name,
969 									      FALSE);
970 
971 	if(start_port != NULL){
972 	  start_port = g_list_concat(start_port,
973 				     port);
974 	}else{
975 	  start_port = port;
976 	}
977 
978 	/* iterate */
979 	next_channel = ags_channel_next(channel);
980 
981 	g_object_unref(channel);
982 
983 	channel = next_channel;
984       }
985 
986       /* unref */
987       if(start_channel != NULL){
988 	g_object_unref(start_channel);
989       }
990 
991       if(next_channel != NULL){
992 	g_object_unref(next_channel);
993       }
994     }else if(!g_ascii_strcasecmp("input",
995 				 str)){
996       scope = AGS_TYPE_INPUT;
997 
998       g_object_get(machine->audio,
999 		   "input", &start_channel,
1000 		   NULL);
1001 
1002       channel = start_channel;
1003       g_object_ref(channel);
1004 
1005       next_channel = NULL;
1006 
1007       start_port = NULL;
1008 
1009       while(channel != NULL){
1010 	port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
1011 									      control_name,
1012 									      TRUE);
1013 	if(start_port != NULL){
1014 	  start_port = g_list_concat(start_port,
1015 				     port);
1016 	}else{
1017 	  start_port = port;
1018 	}
1019 
1020 	port = ags_channel_collect_all_channel_ports_by_specifier_and_context(channel,
1021 									      control_name,
1022 									      FALSE);
1023 
1024 	if(start_port != NULL){
1025 	  start_port = g_list_concat(start_port,
1026 				     port);
1027 	}else{
1028 	  start_port = port;
1029 	}
1030 
1031 	/* iterate */
1032 	next_channel = ags_channel_next(channel);
1033 
1034 	g_object_unref(channel);
1035 
1036 	channel = next_channel;
1037       }
1038 
1039       /* unref */
1040       if(start_channel != NULL){
1041 	g_object_unref(start_channel);
1042       }
1043 
1044       if(next_channel != NULL){
1045 	g_object_unref(next_channel);
1046       }
1047     }
1048 
1049     if(scope == channel_type &&
1050        !g_ascii_strcasecmp(specifier,
1051 			   control_name)){
1052       gtk_tree_model_get_value(model,
1053 			       &iter,
1054 			       0, &value);
1055 
1056       if(g_value_get_boolean(&value)){
1057 	g_value_set_boolean(&value, FALSE);
1058       }else{
1059 	g_value_set_boolean(&value, TRUE);
1060 
1061 	contains_specifier = TRUE;
1062       }
1063 
1064       gtk_list_store_set_value(GTK_LIST_STORE(model),
1065 			       &iter,
1066 			       0,
1067 			       &value);
1068     }
1069   }
1070 
1071   /* add/remove enabled automation port */
1072   if(contains_specifier){
1073     machine->enabled_automation_port = g_list_prepend(machine->enabled_automation_port,
1074 						      ags_machine_automation_port_alloc(channel_type, control_name));
1075   }else{
1076     machine->enabled_automation_port = g_list_delete_link(machine->enabled_automation_port,
1077 							  ags_machine_automation_port_find_channel_type_with_control_name(machine->enabled_automation_port,
1078 															  channel_type, control_name));
1079   }
1080 
1081   g_object_get(machine->audio,
1082 	       "automation", &start_automation,
1083 	       NULL);
1084 
1085   /* apply */
1086   if(contains_specifier){
1087     AgsAutomationEdit *automation_edit;
1088     AgsScale *scale;
1089 
1090     AgsPluginPort *plugin_port;
1091 
1092     gchar *specifier;
1093 
1094     gdouble upper, lower;
1095     gdouble default_value;
1096 
1097     GValue *upper_value, *lower_value;
1098     GValue *value;
1099 
1100     /* scale */
1101     scale = ags_scale_new();
1102     g_object_set(scale,
1103 		 "scale-width", (guint) (gui_scale_factor * AGS_SCALE_DEFAULT_SCALE_WIDTH),
1104 		 "scale-height", (guint) (gui_scale_factor * AGS_SCALE_DEFAULT_SCALE_HEIGHT),
1105 		 NULL);
1106 
1107     /* get some fields */
1108     plugin_port = NULL;
1109 
1110     if(start_port != NULL){
1111       g_object_get(start_port->data,
1112 		   "plugin-port", &plugin_port,
1113 		   NULL);
1114     }
1115 
1116     if(plugin_port != NULL){
1117       g_object_get(plugin_port,
1118 		   "upper-value", &upper_value,
1119 		   "lower-value", &lower_value,
1120 		   "default-value", &value,
1121 		   NULL);
1122 
1123       upper = g_value_get_float(upper_value);
1124       lower = g_value_get_float(lower_value);
1125 
1126       default_value = g_value_get_float(value);
1127 
1128       g_object_unref(plugin_port);
1129     }else{
1130       upper = 1.0;
1131       lower = 0.0;
1132 
1133       default_value = 1.0;
1134     }
1135 
1136     specifier = g_strdup(control_name);
1137 
1138     /* apply scale */
1139     g_object_set(scale,
1140 		 "control-name", specifier,
1141 		 "upper", upper,
1142 		 "lower", lower,
1143 		 "default-value", default_value,
1144 		 NULL);
1145 
1146     if(channel_type == G_TYPE_NONE){
1147       gtk_box_pack_start((GtkBox *) automation_editor->audio_scrolled_scale_box->scale_box,
1148 			 (GtkWidget *) scale,
1149 			 FALSE, FALSE,
1150 			 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1151     }else if(channel_type == AGS_TYPE_OUTPUT){
1152       gtk_box_pack_start((GtkBox *) automation_editor->output_scrolled_scale_box->scale_box,
1153 			 (GtkWidget *) scale,
1154 			 FALSE, FALSE,
1155 			 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1156     }else if(channel_type == AGS_TYPE_INPUT){
1157       gtk_box_pack_start((GtkBox *) automation_editor->input_scrolled_scale_box->scale_box,
1158 			 (GtkWidget *) scale,
1159 			 FALSE, FALSE,
1160 			 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1161     }
1162 
1163     gtk_widget_show((GtkWidget *) scale);
1164 
1165     /* automation edit */
1166     automation_edit = ags_automation_edit_new();
1167 
1168     g_object_set(automation_edit,
1169 		 "channel-type", channel_type,
1170 		 "control-specifier", specifier,
1171 		 "control-name", control_name,
1172 		 "upper", upper,
1173 		 "lower", lower,
1174 		 "default-value", default_value,
1175 		 "upper", upper,
1176 		 "lower", lower,
1177 		 NULL);
1178 
1179     if(plugin_port != NULL &&
1180        ags_plugin_port_test_flags(plugin_port, AGS_PLUGIN_PORT_LOGARITHMIC)){
1181       automation_edit->flags |= AGS_AUTOMATION_EDIT_LOGARITHMIC;
1182     }
1183 
1184     if(channel_type == G_TYPE_NONE){
1185       gtk_box_pack_start((GtkBox *) automation_editor->audio_scrolled_automation_edit_box->automation_edit_box,
1186 			 (GtkWidget *) automation_edit,
1187 			 FALSE, FALSE,
1188 			 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1189     }else if(channel_type == AGS_TYPE_OUTPUT){
1190       gtk_box_pack_start((GtkBox *) automation_editor->output_scrolled_automation_edit_box->automation_edit_box,
1191 			 (GtkWidget *) automation_edit,
1192 			 FALSE, FALSE,
1193 			 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1194     }else if(channel_type == AGS_TYPE_INPUT){
1195       gtk_box_pack_start((GtkBox *) automation_editor->input_scrolled_automation_edit_box->automation_edit_box,
1196 			 (GtkWidget *) automation_edit,
1197 			 FALSE, FALSE,
1198 			 AGS_AUTOMATION_EDIT_DEFAULT_PADDING);
1199     }
1200 
1201     ags_connectable_connect(AGS_CONNECTABLE(automation_edit));
1202     gtk_widget_show((GtkWidget *) automation_edit);
1203 
1204     if(channel_type == G_TYPE_NONE){
1205       g_signal_connect_after((GObject *) automation_edit->hscrollbar, "value-changed",
1206 			     G_CALLBACK(ags_automation_editor_audio_automation_edit_hscrollbar_value_changed), (gpointer) automation_editor);
1207     }else if(channel_type == AGS_TYPE_OUTPUT){
1208       g_signal_connect_after((GObject *) automation_edit->hscrollbar, "value-changed",
1209 			     G_CALLBACK(ags_automation_editor_output_automation_edit_hscrollbar_value_changed), (gpointer) automation_editor);
1210     }else if(channel_type == AGS_TYPE_INPUT){
1211       g_signal_connect_after((GObject *) automation_edit->hscrollbar, "value-changed",
1212 			     G_CALLBACK(ags_automation_editor_input_automation_edit_hscrollbar_value_changed), (gpointer) automation_editor);
1213     }
1214 
1215     /* unset bypass */
1216     ags_audio_add_automation_port(machine->audio, control_name);
1217 
1218     automation = start_automation;
1219 
1220     while((automation = ags_automation_find_channel_type_with_control_name(automation,
1221 									   channel_type, control_name)) != NULL){
1222       ags_automation_unset_flags(automation->data,
1223 				 AGS_AUTOMATION_BYPASS);
1224 
1225       automation = automation->next;
1226     }
1227   }else{
1228     GList *list_start, *list;
1229 
1230     gint nth;
1231     gboolean success;
1232 
1233     /* audio */
1234     nth = -1;
1235     success = FALSE;
1236 
1237     list =
1238       list_start = NULL;
1239 
1240     if(channel_type == G_TYPE_NONE){
1241       list =
1242 	list_start = gtk_container_get_children((GtkContainer *) automation_editor->audio_scrolled_automation_edit_box->automation_edit_box);
1243     }else if(channel_type == AGS_TYPE_OUTPUT){
1244       list =
1245 	list_start = gtk_container_get_children((GtkContainer *) automation_editor->output_scrolled_automation_edit_box->automation_edit_box);
1246     }else if(channel_type == AGS_TYPE_INPUT){
1247       list =
1248 	list_start = gtk_container_get_children((GtkContainer *) automation_editor->input_scrolled_automation_edit_box->automation_edit_box);
1249     }
1250 
1251 
1252     while(list != NULL){
1253       nth++;
1254 
1255       if(AGS_AUTOMATION_EDIT(list->data)->channel_type == channel_type &&
1256 	 !g_strcmp0(AGS_AUTOMATION_EDIT(list->data)->control_name,
1257 		    control_name)){
1258 	gtk_widget_destroy(list->data);
1259 
1260 	success = TRUE;
1261 
1262 	break;
1263       }
1264 
1265       list = list->next;
1266     }
1267 
1268     g_list_free(list_start);
1269 
1270     if(success){
1271       if(channel_type == G_TYPE_NONE){
1272 	list_start = gtk_container_get_children((GtkContainer *) automation_editor->audio_scrolled_scale_box->scale_box);
1273       }else if(channel_type == AGS_TYPE_OUTPUT){
1274 	list_start = gtk_container_get_children((GtkContainer *) automation_editor->output_scrolled_scale_box->scale_box);
1275       }else if(channel_type == AGS_TYPE_INPUT){
1276 	list_start = gtk_container_get_children((GtkContainer *) automation_editor->input_scrolled_scale_box->scale_box);
1277       }
1278 
1279       list = g_list_nth(list_start,
1280 			nth);
1281 
1282       gtk_widget_destroy(list->data);
1283 
1284       g_list_free(list_start);
1285     }
1286 
1287     /* set bypass */
1288     ags_audio_remove_automation_port(machine->audio, control_name);
1289 
1290     automation = start_automation;
1291 
1292     while((automation = ags_automation_find_channel_type_with_control_name(automation,
1293 									   channel_type, control_name)) != NULL){
1294       ags_automation_set_flags(automation->data,
1295 			       AGS_AUTOMATION_BYPASS);
1296 
1297       automation = automation->next;
1298     }
1299   }
1300 
1301   g_list_free_full(start_automation,
1302 		   g_object_unref);
1303 
1304   g_list_free_full(start_port,
1305 		   g_object_unref);
1306 }
1307 
1308 /**
1309  * ags_automation_toolbar_tool_popup_new:
1310  * @automation_toolbar: the #AgsAutomationToolbar
1311  *
1312  * Create a new #GtkMenu suitable for menu tool button.
1313  *
1314  * Returns: a new #GtkMenu
1315  *
1316  * Since: 3.0.0
1317  */
1318 GtkMenu*
ags_automation_toolbar_tool_popup_new(AgsAutomationToolbar * automation_toolbar)1319 ags_automation_toolbar_tool_popup_new(AgsAutomationToolbar *automation_toolbar)
1320 {
1321   GtkMenu *tool_popup;
1322   GtkMenuItem *item;
1323 
1324   GList *list, *list_start;
1325 
1326   tool_popup = (GtkMenu *) gtk_menu_new();
1327 
1328   item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("select accelerations"));
1329   gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1330 
1331   item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("ramp accelerations"));
1332   gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1333 
1334   item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("position cursor"));
1335   gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1336 
1337   gtk_menu_shell_append((GtkMenuShell*) tool_popup,
1338 			(GtkWidget*) gtk_separator_menu_item_new());
1339 
1340   item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("enable all lines"));
1341   gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1342 
1343   item = (GtkMenuItem *) gtk_menu_item_new_with_label(i18n("disable all lines"));
1344   gtk_menu_shell_append((GtkMenuShell *) tool_popup, (GtkWidget *) item);
1345 
1346   /* connect */
1347   list_start =
1348     list = gtk_container_get_children((GtkContainer *) tool_popup);
1349 
1350   g_signal_connect(G_OBJECT(list->data), "activate",
1351 		   G_CALLBACK(ags_automation_toolbar_tool_popup_select_acceleration_callback), (gpointer) automation_toolbar);
1352 
1353   list = list->next;
1354   g_signal_connect(G_OBJECT(list->data), "activate",
1355 		   G_CALLBACK(ags_automation_toolbar_tool_popup_ramp_acceleration_callback), (gpointer) automation_toolbar);
1356 
1357   list = list->next;
1358   g_signal_connect(G_OBJECT(list->data), "activate",
1359 		   G_CALLBACK(ags_automation_toolbar_tool_popup_position_cursor_callback), (gpointer) automation_toolbar);
1360 
1361   list = list->next->next;
1362   g_signal_connect(G_OBJECT(list->data), "activate",
1363 		   G_CALLBACK(ags_automation_toolbar_tool_popup_enable_all_lines_callback), (gpointer) automation_toolbar);
1364 
1365   list = list->next;
1366   g_signal_connect(G_OBJECT(list->data), "activate",
1367 		   G_CALLBACK(ags_automation_toolbar_tool_popup_disable_all_lines_callback), (gpointer) automation_toolbar);
1368 
1369   g_list_free(list_start);
1370 
1371   /* show */
1372   gtk_widget_show_all((GtkWidget *) tool_popup);
1373 
1374   return(tool_popup);
1375 }
1376 
1377 /**
1378  * ags_automation_toolbar_new:
1379  *
1380  * Create a new instance of #AgsAutomationToolbar.
1381  *
1382  * Returns: the new #AgsAutomationToolbar
1383  *
1384  * Since: 3.0.0
1385  */
1386 AgsAutomationToolbar*
ags_automation_toolbar_new()1387 ags_automation_toolbar_new()
1388 {
1389   AgsAutomationToolbar *automation_toolbar;
1390 
1391   automation_toolbar = (AgsAutomationToolbar *) g_object_new(AGS_TYPE_AUTOMATION_TOOLBAR, NULL);
1392 
1393   return(automation_toolbar);
1394 }
1395