1 /*
2  * Sweep, a sound wave editor.
3  *
4  * Copyright (C) 2000 Conrad Parker
5  * Copyright (C) 2002 Commonwealth Scientific and Industrial Research
6  * Organisation (CSIRO), Australia
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <glib.h>
32 #include <gdk/gdkkeysyms.h>
33 #include <gtk/gtk.h>
34 
35 #include <sweep/sweep_i18n.h>
36 #include <sweep/sweep_types.h>
37 #include <sweep/sweep_sample.h>
38 
39 #include "interface.h"
40 
41 #include "sw_chooser.h"
42 
43 typedef struct {
44   int number;
45   char * name;
46 } sw_choice;
47 
48 /* first choice must be _("Custom") */
49 
50 static sw_choice samplerate_choices[] = {
51   {     -1, N_("Custom") },
52   { 192000, N_("192000 Hz (Studio quality)") },
53   {  96000, N_(" 96000 Hz (High quality)") },
54   {  48000, N_(" 48000 Hz (DAT quality)") },
55   {  44100, N_(" 44100 Hz (CD quality)") },
56   {  32000, N_(" 32000 Hz (Ultra-wideband voice quality)") },
57   {  22050, N_(" 22050 Hz") },
58   {  16000, N_(" 16000 Hz (Wideband voice quality)") },
59   {  11025, N_(" 11025 Hz") },
60   {   8000, N_("  8000 Hz (Narrowband voice quality)") },
61   {   4000, N_("  4000 Hz (Low quality)") },
62   {      0, NULL }
63 };
64 
65 static sw_choice channelcount_choices[] = {
66   { -1, N_("Custom") },
67   {  1, N_("Mono") },
68   {  2, N_("Stereo") },
69   {  4, N_("Quadraphonic") },
70   /*  {  6, N_("5.1") },*/
71   {  0, NULL }
72 };
73 
74 enum {
75   NUMBER_CHANGED_SIGNAL,
76   LAST_SIGNAL
77 };
78 
79 static gint sw_chooser_signals[LAST_SIGNAL] = { 0 };
80 
81 static void
sw_chooser_class_init(SWChooserClass * class)82 sw_chooser_class_init(SWChooserClass * class)
83 {
84   GtkObjectClass *object_class;
85 
86   object_class = (GtkObjectClass *) class;
87 
88   sw_chooser_signals[NUMBER_CHANGED_SIGNAL] = g_signal_new ("number-changed",
89 					 			  G_TYPE_FROM_CLASS (class),
90 	                              G_SIGNAL_RUN_FIRST,
91 	                              G_STRUCT_OFFSET (SWChooserClass, number_changed),
92                                   NULL,
93                                   NULL,
94 					 			  g_cclosure_marshal_VOID__INT,
95                                   G_TYPE_NONE, 1,
96 								  G_TYPE_INT);
97 
98 
99   class->number_changed = NULL;
100 }
101 
102 static void
sw_chooser_init(GtkWidget * chooser)103 sw_chooser_init (GtkWidget * chooser)
104 {
105 }
106 
107 
108 GType
sw_chooser_get_type(void)109 sw_chooser_get_type (void)
110 {
111   static GType sw_chooser_type = 0;
112 
113   if (!sw_chooser_type)
114     {
115       static const GTypeInfo sw_chooser_info =
116       {
117 
118       sizeof(SWChooserClass),
119 	NULL, /* base_init */
120 	NULL, /* base_finalize */
121 	(GClassInitFunc) sw_chooser_class_init,
122 	NULL, /* class_finalize */
123 	NULL, /* class_data */
124 	sizeof (SWChooser),
125 	0,    /* n_preallocs */
126 	(GInstanceInitFunc) sw_chooser_init,
127 
128     };
129 
130       sw_chooser_type = g_type_register_static (GTK_TYPE_FRAME, "SWChooser", &sw_chooser_info, 0);
131   }
132 
133   return sw_chooser_type;
134 }
135 
136 
137 static int
chooser_get_number(GtkWidget * chooser)138 chooser_get_number (GtkWidget * chooser)
139 {
140   return
141     GPOINTER_TO_INT (g_object_get_data (G_OBJECT(chooser), "number"));
142 }
143 
144 static int
chooser_set_number_direct(GtkWidget * chooser,int number)145 chooser_set_number_direct (GtkWidget * chooser, int number)
146 {
147   GtkWidget * direct_entry;
148 #define BUF_LEN 16
149   char buf[BUF_LEN];
150 
151   direct_entry =
152     GTK_WIDGET (g_object_get_data (G_OBJECT(chooser), "direct_entry"));
153 
154   /*
155    * Print the number in the direct_entry, but leave it blank for zero.
156    * (otherwise, if zero is printed as '0', the GtkEntry behaves wierdly).
157    */
158   if (number > 0) {
159     snprintf (buf, BUF_LEN, "%d", number);
160   } else {
161     buf[0] = '\0';
162   }
163 
164   gtk_entry_set_text (GTK_ENTRY(direct_entry), buf);
165 
166   g_object_set_data (G_OBJECT(chooser), "number",
167 		       GINT_TO_POINTER(number));
168   g_signal_emit(G_OBJECT(chooser), sw_chooser_signals[NUMBER_CHANGED_SIGNAL], 0, number);
169 
170   return number;
171 }
172 
173 static int
chooser_set_number(GtkWidget * chooser,int number,sw_choice * choices)174 chooser_set_number (GtkWidget * chooser, int number, sw_choice * choices)
175 {
176   GtkWidget * combo_entry;
177   int i;
178 
179   combo_entry =
180     GTK_WIDGET (g_object_get_data (G_OBJECT(chooser), "combo_entry"));
181 
182   for (i = 0; choices[i].name != NULL; i++) {
183     if (number == choices[i].number) {
184       gtk_entry_set_text (GTK_ENTRY(combo_entry), _(choices[i].name));
185       return number;
186     }
187   }
188 
189   /* not in the entry -- assume first choice is "Custom" and set that */
190   gtk_entry_set_text (GTK_ENTRY(combo_entry), _(choices[0].name));
191 
192   return chooser_set_number_direct (chooser, number);;
193 }
194 
195 static void
chooser_combo_changed_cb(GtkWidget * widget,gpointer data)196 chooser_combo_changed_cb (GtkWidget * widget, gpointer data)
197 {
198   GtkWidget * chooser = (GtkWidget *)data;
199   sw_choice * choices;
200   GtkWidget * direct_hbox;
201   const gchar * text;
202   int i, number = -1;
203 
204   /* find what number the chosen menu string corresponds to */
205 
206   text = gtk_entry_get_text (GTK_ENTRY(widget));
207 
208   choices = g_object_get_data (G_OBJECT(chooser), "choices");
209 
210   for (i = 0; choices[i].name != NULL; i++) {
211     if (strcmp (text, _(choices[i].name)) == 0) {
212       number = choices[i].number;
213       break;
214     }
215   }
216 
217   /* set the direct hbox sensitive if "Custom", else insensitive */
218 
219   direct_hbox =
220     GTK_WIDGET(g_object_get_data (G_OBJECT(chooser), "direct_hbox"));
221 
222   if (number == -1) {
223     gtk_widget_set_sensitive (direct_hbox, TRUE);
224   } else {
225     gtk_widget_set_sensitive (direct_hbox, FALSE);
226 
227     /* change the direct_entry to reflect the new value */
228     chooser_set_number_direct (chooser, number);
229   }
230 }
231 
232 static void
chooser_entry_changed_cb(GtkWidget * widget,gpointer data)233 chooser_entry_changed_cb (GtkWidget * widget, gpointer data)
234 {
235   GtkWidget * chooser = (GtkWidget *)data;
236   GtkWidget * combo_entry;
237   sw_choice * choices;
238 
239   const gchar * text;
240   int number = -1;
241 
242   text = gtk_entry_get_text (GTK_ENTRY(widget));
243   number = atoi (text);
244 
245   choices = g_object_get_data (G_OBJECT(chooser), "choices");
246 
247   combo_entry =
248     GTK_WIDGET (g_object_get_data (G_OBJECT(chooser), "combo_entry"));
249 
250 	g_signal_handlers_block_matched (GTK_OBJECT(widget), G_SIGNAL_MATCH_DATA, 0,
251 									0, 0, 0, chooser);
252 	g_signal_handlers_block_matched (GTK_OBJECT(combo_entry), G_SIGNAL_MATCH_DATA, 0,
253 									0, 0, 0, chooser);
254   chooser_set_number (chooser, number, choices);
255 
256     g_signal_handlers_unblock_matched (GTK_OBJECT(combo_entry), G_SIGNAL_MATCH_DATA, 0,
257 									0, 0, 0, chooser);
258     g_signal_handlers_unblock_matched (GTK_OBJECT(widget), G_SIGNAL_MATCH_DATA, 0,
259 									0, 0, 0, chooser);
260 }
261 
262 static void
sw_chooser_build(GtkWidget * chooser)263 sw_chooser_build (GtkWidget * chooser)
264 {
265   GtkWidget * frame;
266   GtkWidget * vbox;
267   GList * choice_names = NULL;
268   GtkWidget * combo;
269   GtkWidget * hbox;
270   GtkWidget * combo_entry, * direct_entry;
271   GtkWidget * label;
272   sw_choice * choices;
273 
274   int i;
275 
276   frame = chooser;
277   gtk_frame_set_label (GTK_FRAME (frame), SW_CHOOSER(chooser)->title);
278 
279   vbox = gtk_vbox_new (FALSE, 0);
280   gtk_container_add (GTK_CONTAINER(frame), vbox);
281   gtk_container_set_border_width (GTK_CONTAINER(vbox), 8);
282   gtk_widget_show (vbox);
283 
284   choices = (sw_choice *) (SW_CHOOSER(chooser)->choices);
285 
286   choice_names = NULL;
287   for (i = 0; choices[i].name != NULL; i++) {
288     choice_names = g_list_append (choice_names, _(choices[i].name));
289   }
290 
291   combo = gtk_combo_new ();
292   gtk_combo_set_popdown_strings (GTK_COMBO(combo), choice_names);
293   gtk_combo_set_value_in_list (GTK_COMBO(combo), TRUE, FALSE);
294 
295   combo_entry = GTK_COMBO(combo)->entry;
296 
297   gtk_editable_set_editable (GTK_EDITABLE(combo_entry), FALSE);
298 
299   gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, FALSE, 4);
300   gtk_widget_show (combo);
301 
302   hbox = gtk_hbox_new (FALSE, 0);
303   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
304   gtk_widget_show (hbox);
305 
306   label = gtk_label_new (_("Custom: "));
307   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4);
308   gtk_widget_show (label);
309 
310   direct_entry = gtk_entry_new ();
311   gtk_box_pack_start (GTK_BOX (hbox), direct_entry, FALSE, FALSE, 4);
312   gtk_widget_show (direct_entry);
313 
314   if (SW_CHOOSER(chooser)->units != NULL) {
315     label = gtk_label_new (SW_CHOOSER(chooser)->units);
316     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4);
317     gtk_widget_show (label);
318   }
319 
320   g_signal_connect (G_OBJECT(combo_entry), "changed",
321 		      G_CALLBACK(chooser_combo_changed_cb), chooser);
322 
323   g_signal_connect (G_OBJECT(direct_entry), "changed",
324 		      G_CALLBACK(chooser_entry_changed_cb), chooser);
325 
326   g_object_set_data (G_OBJECT(chooser), "combo_entry", combo_entry);
327   g_object_set_data (G_OBJECT(chooser), "direct_entry", direct_entry);
328   g_object_set_data (G_OBJECT(chooser), "direct_hbox", hbox);
329   g_object_set_data (G_OBJECT(chooser), "choices", choices);
330 
331   /* fake a change event to set the number data */
332   chooser_combo_changed_cb (combo_entry, chooser);
333 }
334 
335 
336 GtkWidget *
samplerate_chooser_new(gchar * title)337 samplerate_chooser_new (gchar * title)
338 {
339   SWChooser * chooser = SW_CHOOSER (g_object_new (sw_chooser_get_type (), NULL));
340 
341   chooser->title = title ? title : _("Sampling rate");
342   chooser->choices = (gpointer)samplerate_choices;
343   chooser->units = _("Hz");
344 
345   sw_chooser_build (GTK_WIDGET (chooser));
346 
347   return GTK_WIDGET (chooser);
348 }
349 
350 int
samplerate_chooser_get_rate(GtkWidget * chooser)351 samplerate_chooser_get_rate (GtkWidget * chooser)
352 {
353   return chooser_get_number (chooser);
354 }
355 
356 int
samplerate_chooser_set_rate(GtkWidget * chooser,int rate)357 samplerate_chooser_set_rate (GtkWidget * chooser, int rate)
358 {
359   return chooser_set_number (chooser, rate, samplerate_choices);
360 }
361 
362 GtkWidget *
channelcount_chooser_new(gchar * title)363 channelcount_chooser_new (gchar * title)
364 {
365   SWChooser * chooser = SW_CHOOSER (g_object_new (sw_chooser_get_type (), NULL));
366 
367   chooser->title = title ? title : _("Channels");
368   chooser->choices = channelcount_choices;
369   chooser->units = _("channels");
370 
371   sw_chooser_build (GTK_WIDGET (chooser));
372 
373   return GTK_WIDGET (chooser);
374 }
375 
376 int
channelcount_chooser_get_count(GtkWidget * chooser)377 channelcount_chooser_get_count (GtkWidget * chooser)
378 {
379   return chooser_get_number (chooser);
380 }
381 
382 int
channelcount_chooser_set_count(GtkWidget * chooser,int count)383 channelcount_chooser_set_count (GtkWidget * chooser, int count)
384 {
385   return chooser_set_number (chooser, count, channelcount_choices);
386 }
387