1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2020 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/ags_link_editor_callbacks.h>
21 
22 #include <ags/X/ags_window.h>
23 #include <ags/X/ags_machine.h>
24 #include <ags/X/ags_machine_editor.h>
25 #include <ags/X/ags_line_editor.h>
26 
27 #include <ags/i18n.h>
28 
29 int ags_link_editor_file_chooser_response_callback(GtkWidget *widget, guint response, AgsLinkEditor *link_editor);
30 
31 #define AGS_LINK_EDITOR_OPEN_SPIN_BUTTON "AgsLinkEditorOpenSpinButton"
32 
33 void
ags_link_editor_parent_set_callback(GtkWidget * widget,GtkWidget * old_parent,AgsLinkEditor * link_editor)34 ags_link_editor_parent_set_callback(GtkWidget *widget, GtkWidget *old_parent, AgsLinkEditor *link_editor)
35 {
36   AgsMachine *machine;
37   AgsLineEditor *line_editor;
38 
39   AgsAudio *audio;
40   AgsChannel *channel;
41 
42   GtkTreeModel *model;
43 
44   if(old_parent != NULL){
45     return;
46   }
47 
48   //TODO:JK: missing mutex
49   line_editor = (AgsLineEditor *) gtk_widget_get_ancestor(widget, AGS_TYPE_LINE_EDITOR);
50 
51   if(line_editor != NULL){
52     channel = line_editor->channel;
53 
54     if(channel != NULL){
55       GtkTreeIter iter;
56 
57       g_object_get(channel,
58 		   "audio", &audio,
59 		   NULL);
60 
61       if(audio != NULL){
62 	//FIXME:JK: don't access AgsAudio to obtain widget
63 	machine = AGS_MACHINE(audio->machine_widget);
64 
65 	model = GTK_TREE_MODEL(ags_machine_get_possible_links(machine));
66 
67 	if(AGS_IS_INPUT(line_editor->channel) &&
68 	   (AGS_MACHINE_TAKES_FILE_INPUT & (machine->flags)) != 0 &&
69 	   ((AGS_MACHINE_ACCEPT_WAV & (machine->file_input_flags)) != 0 ||
70 	    ((AGS_MACHINE_ACCEPT_OGG & (machine->file_input_flags)) != 0))){
71 	  AgsFileLink *file_link;
72 
73 	  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
74 
75 	  g_object_get(channel,
76 		       "file-link", &file_link,
77 		       NULL);
78 
79 	  if(file_link != NULL){
80 	    gchar *filename;
81 
82 	    /* get some fields */
83 	    g_object_get(file_link,
84 			 "filename", &filename,
85 			 NULL);
86 
87 	    gtk_list_store_set(GTK_LIST_STORE(model), &iter,
88 			       0, g_strdup_printf("file://%s", filename),
89 			       1, NULL,
90 			       -1);
91 	    //FIXME:JK:
92 	    //	    gtk_combo_box_set_active_iter(link_editor->combo,
93 	    //				  &iter);
94 
95 	    g_free(filename);
96 
97 	    g_object_unref(file_link);
98 	  }else{
99 	    gtk_list_store_set(GTK_LIST_STORE(model), &iter,
100 			       0, "file://",
101 			       1, NULL,
102 			       -1);
103 	  }
104 
105 	}
106 
107 	gtk_combo_box_set_model(link_editor->combo,
108 				model);
109 
110 	g_object_unref(audio);
111       }
112     }
113   }
114 }
115 
116 void
ags_link_editor_combo_callback(GtkComboBox * combo,AgsLinkEditor * link_editor)117 ags_link_editor_combo_callback(GtkComboBox *combo, AgsLinkEditor *link_editor)
118 {
119   GtkTreeIter iter;
120 
121   if(gtk_combo_box_get_active_iter(link_editor->combo,
122 				   &iter)){
123     AgsMachine *machine, *link_machine;
124     AgsLineEditor *line_editor;
125 
126     AgsAudio *audio;
127     AgsChannel *channel;
128 
129     GtkTreeModel *model;
130 
131     line_editor = AGS_LINE_EDITOR(gtk_widget_get_ancestor(GTK_WIDGET(link_editor),
132 							  AGS_TYPE_LINE_EDITOR));
133 
134     channel = line_editor->channel;
135 
136     g_object_get(channel,
137 		 "audio", &audio,
138 		 NULL);
139 
140     g_object_unref(audio);
141 
142     //FIXME:JK: don't access AgsAudio to obtain widget
143     machine = AGS_MACHINE(audio->machine_widget);
144 
145     model = gtk_combo_box_get_model(link_editor->combo);
146 
147     if(!((AGS_MACHINE_TAKES_FILE_INPUT & (machine->flags)) != 0 &&
148 	 ((AGS_MACHINE_ACCEPT_WAV & (machine->file_input_flags)) != 0 ||
149 	  ((AGS_MACHINE_ACCEPT_OGG & (machine->file_input_flags)) != 0)) &&
150 	 AGS_IS_INPUT(channel) &&
151 	 gtk_combo_box_get_active(link_editor->combo) + 1 == gtk_tree_model_iter_n_children(model,
152 											    NULL))){
153       gtk_widget_set_sensitive((GtkWidget *) link_editor->spin_button,
154 			       TRUE);
155 
156       /* set machine link */
157       gtk_tree_model_get(model,
158 			 &iter,
159 			 1, &link_machine,
160 			 -1);
161 
162       if(link_machine == NULL){
163 	gtk_spin_button_set_value(link_editor->spin_button, 0.0);
164       }else{
165 	if(AGS_IS_INPUT(channel)){
166 	  gtk_spin_button_set_range(link_editor->spin_button, 0.0, (gdouble) (link_machine->audio->output_lines - 1));
167 	}else{
168 	  gtk_spin_button_set_range(link_editor->spin_button, 0.0, (gdouble) (link_machine->audio->input_lines - 1));
169 	}
170       }
171     }else{
172       GtkBox *hbox;
173       GtkLabel *label;
174       GtkSpinButton *spin_button;
175       gchar *str, *tmp;
176 
177       /* set file link */
178       if(link_editor->file_chooser != NULL || (AGS_LINK_EDITOR_BLOCK_FILE_CHOOSER & (link_editor->flags)) != 0){
179 	return;
180       }
181 
182       gtk_widget_set_sensitive((GtkWidget *) link_editor->spin_button,
183 				 FALSE);
184 
185       link_editor->file_chooser = (GtkFileChooserDialog *) gtk_file_chooser_dialog_new(i18n("select audio file"),
186 										       (GtkWindow *) gtk_widget_get_toplevel((GtkWidget *) link_editor),
187 										       GTK_FILE_CHOOSER_ACTION_OPEN,
188 										       "_Cancel", GTK_RESPONSE_CANCEL,
189 										       "_Open", GTK_RESPONSE_ACCEPT,
190 										       NULL);
191       gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(link_editor->file_chooser),
192 					   FALSE);
193 
194       /* extra widget */
195       hbox = (GtkBox *) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,
196 				    0);
197       gtk_file_chooser_set_extra_widget((GtkFileChooser *) link_editor->file_chooser,
198 					(GtkWidget *) hbox);
199 
200       label = (GtkLabel *) gtk_label_new(i18n("audio channel: "));
201       gtk_box_pack_start(hbox,
202 			 (GtkWidget *) label,
203 			 FALSE, FALSE,
204 			 0);
205 
206       spin_button = (GtkSpinButton *) gtk_spin_button_new_with_range(0.0,
207 								     256.0,
208 								     1.0);
209       g_object_set_data((GObject *) link_editor->file_chooser,
210 			AGS_LINK_EDITOR_OPEN_SPIN_BUTTON, spin_button);
211       gtk_box_pack_start(hbox,
212 			 (GtkWidget *) spin_button,
213 			 FALSE, FALSE,
214 			 0);
215 
216       /*  */
217       gtk_tree_model_get(model,
218 			 &iter,
219 			 0, &str,
220 			 -1);
221 
222       tmp = g_strdup(str + 7);
223 
224       if(g_strcmp0(tmp, "")){
225 	char *tmp0, *name, *dir;
226 
227 	tmp0 = g_strrstr(tmp, "/");
228 	name = g_strdup(tmp0 + 1);
229 	dir = g_strndup(tmp, tmp0 - tmp);
230 
231 	gtk_file_chooser_set_current_folder((GtkFileChooser *) link_editor->file_chooser, dir);
232 	gtk_file_chooser_set_current_name((GtkFileChooser *) link_editor->file_chooser, name);
233       }
234 
235       g_signal_connect((GObject *) link_editor->file_chooser, "response",
236 		       G_CALLBACK(ags_link_editor_file_chooser_response_callback), (gpointer) link_editor);
237 
238       gtk_widget_show_all((GtkWidget *) link_editor->file_chooser);
239     }
240   }
241 }
242 
243 int
ags_link_editor_option_changed_callback(GtkWidget * widget,AgsLinkEditor * link_editor)244 ags_link_editor_option_changed_callback(GtkWidget *widget, AgsLinkEditor *link_editor)
245 {
246   /*
247   AgsLineEditor *line_editor;
248   AgsMachine *machine;
249 
250   machine = (AgsMachine *) g_object_get_data((GObject *) link_editor->option->menu_item, g_type_name(AGS_TYPE_MACHINE));
251 
252   if(machine == NULL)
253     return;
254 
255   line_editor = (AgsLineEditor *) gtk_widget_get_ancestor((GtkWidget *) link_editor, AGS_TYPE_LINE_EDITOR);
256   link_editor->spin_button->adjustment->upper = (gdouble) (AGS_IS_OUTPUT(line_editor->channel) ? machine->audio->input_lines - 1: machine->audio->output_lines - 1);
257   */
258 
259   return(0);
260 }
261 
262 int
ags_link_editor_file_chooser_response_callback(GtkWidget * widget,guint response,AgsLinkEditor * link_editor)263 ags_link_editor_file_chooser_response_callback(GtkWidget *widget, guint response, AgsLinkEditor *link_editor)
264 {
265   GtkFileChooserDialog *file_chooser;
266 
267   char *name;
268 
269   file_chooser = link_editor->file_chooser;
270 
271   if(response == GTK_RESPONSE_ACCEPT){
272     GtkSpinButton *spin_button;
273 
274     GtkTreeModel *model;
275     GtkTreeIter iter;
276 
277     /* set filename in combo box */
278     model = gtk_combo_box_get_model(link_editor->combo);
279 
280     name = gtk_file_chooser_get_filename((GtkFileChooser *) file_chooser);
281 
282     gtk_tree_model_iter_nth_child(model,
283 				  &iter,
284 				  NULL,
285 				  gtk_tree_model_iter_n_children(model,
286 								 NULL) - 1);
287     gtk_list_store_set(GTK_LIST_STORE(model), &iter,
288 		       0, g_strdup_printf("file://%s", name),
289 		       -1);
290 
291     /* set audio channel */
292     spin_button = (GtkSpinButton *) g_object_get_data((GObject *) file_chooser, AGS_LINK_EDITOR_OPEN_SPIN_BUTTON);
293 
294     gtk_spin_button_set_value(link_editor->spin_button,
295 			      gtk_spin_button_get_value(spin_button));
296   }
297 
298   link_editor->file_chooser = NULL;
299   gtk_widget_destroy((GtkWidget *) file_chooser);
300 
301   return(0);
302 }
303