1 /*
2  * Sweep, a sound wave editor.
3  *
4  * Copyright (C) 2000 Conrad Parker
5  *
6  * This program 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 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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 this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 /*
22  * Thu Oct 22 2000 - Added 1:1 and Normal zooms from
23  *                   Steve Harris <steve@totl.net>
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #  include <config.h>
28 #endif
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include <gdk/gdkkeysyms.h>
35 #include <gtk/gtk.h>
36 
37 #include <sweep/sweep_i18n.h>
38 #include <sweep/sweep_types.h>
39 #include <sweep/sweep_typeconvert.h>
40 #include <sweep/sweep_sample.h>
41 #include <sweep/sweep_undo.h>
42 
43 #include "view.h"
44 
45 #include "about_dialog.h"
46 #include "sample.h"
47 #include "callbacks.h"
48 #include "channelops.h"
49 #include "interface.h"
50 #include "print.h"
51 #include "param.h"
52 #include "record.h"
53 #include "sample-display.h"
54 #include "file_dialogs.h"
55 #include "question_dialogs.h"
56 #include "driver.h"
57 #include "notes.h"
58 #include "db_ruler.h"
59 #include "time_ruler.h"
60 #include "cursors.h"
61 #include "head.h"
62 #include "view_pixmaps.h"
63 
64 /*#define DEBUG*/
65 
66 #define USER_GTKRC
67 
68 /* #define SCROLL_SMOOTHLY */
69 
70 /* Default initial dimensions.
71  *
72  * Golden ratio. Oath.
73  * (sqrt(5)-1)/2 = 0.61803398874989484820
74  * 2/(sqrt(5)-1) = 1.61803398874989484820
75  *
76  * Keep width:height ratio equal to one of these
77  * for pleasing dimensions.
78  */
79 #define VIEW_MIN_WIDTH 197
80 #if 0
81 #define VIEW_MAX_WIDTH 517
82 #define VIEW_DEFAULT_HEIGHT 320
83 #else
84 #define VIEW_MAX_WIDTH 1034
85 #define VIEW_DEFAULT_HEIGHT_PER_CHANNEL 320
86 #endif
87 
88 #define DEFAULT_MIN_ZOOM 8
89 
90 #define NO_TIME ""
91 
92 #define NOREADY(w) \
93   (view->noready_widgets = g_list_append (view->noready_widgets, (w)))
94 
95 #define NOMODIFY(w) \
96   (view->nomodify_widgets = g_list_append (view->nomodify_widgets, (w)))
97 
98 #define NOALLOC(w) \
99   (view->noalloc_widgets = g_list_append (view->noalloc_widgets, (w)))
100 
101 
102 #ifdef HAVE_LIBSAMPLERATE
103 void samplerate_dialog_new_cb (GtkWidget * widget, gpointer data);
104 #endif
105 
106 static GtkWidget * create_view_menu_item(GtkWidget * menu, gchar * label, gchar * accel_path,
107                                                   sw_view *view,gpointer callback, gboolean nomodify,
108 												  guint accel_key, GdkModifierType accel_mods, gpointer user_data);
109 
110 void
111 view_set_vzoom (sw_view * view, sw_audio_t low, sw_audio_t high);
112 
113 extern GList * plugins;
114 extern GdkCursor * sweep_cursors[];
115 
116 extern GtkRecentManager *recent_manager;
117 
118 extern GtkStyle * style_wb;
119 extern GtkStyle * style_LCD;
120 extern GtkStyle * style_light_grey;
121 extern GtkStyle * style_green_grey;
122 extern GtkStyle * style_red_grey;
123 extern GtkStyle * style_dark_grey;
124 
125 /* Global */
126 sw_view * last_tmp_view = NULL; /* last used tmp_view */
127 
128 /* proc_instance:
129  * a type for applying a procedure to a sample
130  */
131 typedef struct _sw_proc_instance sw_proc_instance;
132 
133 struct _sw_proc_instance {
134   sw_procedure * proc;
135   sw_view * view;
136 };
137 
138 static sw_proc_instance *
sw_proc_instance_new(sw_procedure * proc,sw_view * view)139 sw_proc_instance_new (sw_procedure * proc, sw_view * view)
140 {
141   sw_proc_instance * pi;
142 
143   /* XXX: where to clean this up? */
144   pi = g_malloc (sizeof (sw_proc_instance));
145   pi->proc = proc;
146   pi->view = view;
147 
148   return pi;
149 }
150 
151 static void
apply_procedure_cb(GtkWidget * widget,gpointer data)152 apply_procedure_cb (GtkWidget * widget, gpointer data)
153 {
154   sw_proc_instance * pi = (sw_proc_instance *)data;
155   sw_procedure * proc = pi->proc;
156   sw_sample * sample = pi->view->sample;
157   sw_param_set pset;
158 
159   if (proc->nr_params == 0) {
160     pset = NULL;
161     proc->apply (sample, pset, proc->custom_data);
162   } else {
163     pset = sw_param_set_new (proc);
164     if (proc->suggest)
165       proc->suggest (sample, pset, proc->custom_data);
166     create_param_set_adjuster (proc, pi->view, pset);
167   }
168 
169 }
170 
171 static void
create_proc_menuitem(sw_procedure * proc,sw_view * view,GtkWidget * submenu,GtkAccelGroup * accel_group)172 create_proc_menuitem (sw_procedure * proc, sw_view * view,
173 		      GtkWidget * submenu, GtkAccelGroup * accel_group)
174 {
175   sw_proc_instance * pi;
176   GtkWidget * menuitem;
177 
178   pi = sw_proc_instance_new (proc, view);
179 
180   menuitem = gtk_menu_item_new_with_label(_(proc->name));
181   gtk_menu_append(GTK_MENU(submenu), menuitem);
182   g_signal_connect (G_OBJECT(menuitem), "activate",
183 		     G_CALLBACK(apply_procedure_cb), pi);
184   gtk_widget_show(menuitem);
185 /* these accels are not editable */
186  /*   gtk_widget_add_accelerator (menuitem, "activate", accel_group,
187 				proc->accel_key, proc->accel_mods,
188 				GTK_ACCEL_VISIBLE); */
189 }
190 
191 static GtkWidget *
create_proc_menu(sw_view * view,GtkAccelGroup * accel_group)192 create_proc_menu (sw_view * view, GtkAccelGroup * accel_group)
193 {
194   GtkWidget * menu, * submenu, * menuitem = NULL, * label, * hbox;
195   GList * gl;
196   sw_procedure * proc;
197   gboolean use_submenus = FALSE;
198   gint i = 0, li = 0;
199   gchar first_name[32], last_name[32];
200   gchar * title;
201 
202   menu = gtk_menu_new ();
203 
204   if (g_list_length (plugins) > 10) {
205     use_submenus = TRUE;
206   }
207 
208   submenu = menu;
209 
210 #if 0
211   first_name[4] = '\0';
212   last_name[4] = '\0';
213 #endif
214 
215   if (plugins)
216     /*strncpy (first_name, ((sw_procedure *)plugins->data)->name, 4);*/
217     sscanf (_(((sw_procedure *)plugins->data)->name), "%s", first_name);
218 
219   /* Filter plugins */
220   for (gl = plugins; gl; gl = gl->next) {
221     proc = (sw_procedure *)gl->data;
222 
223     if (use_submenus && ((i % 10) == 0)) {
224       if (menuitem) {
225 	hbox = gtk_hbox_new (FALSE, 0);
226 	gtk_container_add (GTK_CONTAINER(menuitem), hbox);
227 	gtk_widget_show (hbox);
228 
229 	title = g_strdup_printf ("%s  ...  %s", first_name, last_name);
230 	label = gtk_label_new (title);
231 	gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
232 	/*menuitem = gtk_menu_item_new_with_label (title);*/
233 	gtk_widget_show (label);
234 
235 	/*strncpy (first_name, proc->name, 4);*/
236 	sscanf (_(proc->name), "%s", first_name);
237 	li = i;
238       }
239 
240       menuitem = gtk_menu_item_new ();
241       gtk_menu_append (GTK_MENU(menu), menuitem);
242       gtk_widget_show (menuitem);
243       submenu = gtk_menu_new ();
244       gtk_menu_item_set_submenu (GTK_MENU_ITEM(menuitem), submenu);
245     }
246 
247     create_proc_menuitem (proc, view, submenu, accel_group);
248     /*strncpy (last_name, proc->name, 4);*/
249     sscanf (_(proc->name), "%s", last_name);
250     i++;
251   }
252 
253   if (menuitem) {
254     hbox = gtk_hbox_new (FALSE, 0);
255     gtk_container_add (GTK_CONTAINER(menuitem), hbox);
256     gtk_widget_show (hbox);
257 
258     label = gtk_label_new (g_strdup_printf ("%s ... %s", first_name,
259 					    last_name));
260     gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
261     gtk_widget_show (label);
262   }
263 
264   return menu;
265 }
266 
267 static void view_store_cb (GtkWidget * widget, gpointer data);
268 static void view_retrieve_cb (GtkWidget * widget, gpointer data);
269 
270 static GtkWidget *
view_refresh_channelops_menu(sw_view * view)271 view_refresh_channelops_menu (sw_view * view)
272 {
273   GtkWidget * submenu, * menuitem = NULL;
274   GList * gl;
275   int old_channels, channels;
276   GtkAccelGroup *accel_group;
277 
278   channels = view->sample->sounddata->format->channels;
279 
280   if (view->channelops_submenu != NULL) {
281     old_channels = GPOINTER_TO_INT
282       (g_object_get_data (G_OBJECT(view->channelops_submenu), "default"));
283 
284     /* If there's no need to change the submenu, don't */
285     if ((old_channels == channels) ||
286 	(old_channels > 2 && channels > 2)) {
287       return view->channelops_submenu;
288     }
289   }
290 
291   /* Remove references to old channelops widgets from sensitivity updates */
292   for (gl = view->channelops_widgets; gl; gl = gl->next) {
293     view->nomodify_widgets = g_list_remove (view->nomodify_widgets, gl->data);
294 #if 0
295     view->noready_widgets = g_list_remove (view->noready_widgets, gl->data);
296     view->noalloc_widgets = g_list_remove (view->noalloc_widgets, gl->data);
297 #endif
298   }
299   g_list_free (view->channelops_widgets);
300   view->channelops_widgets = NULL;
301 
302   /* Create the new channelops submenu */
303   submenu = gtk_menu_new ();
304   accel_group = GTK_ACCEL_GROUP(g_object_get_data(G_OBJECT(view->window), "accel_group"));
305   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
306 
307 
308   g_object_set_data (G_OBJECT(submenu), "default", GINT_TO_POINTER(channels));
309 
310   if (channels == 1) {
311 	menuitem = create_view_menu_item (submenu, _("Duplicate to stereo"),
312                                        "<Sweep-View>/Sample/Channels/Duplicate to stereo",
313 	                                   view,
314                                        dup_stereo_cb, TRUE,
315                                        0, 0, view);
316       view->channelops_widgets =
317       g_list_append (view->channelops_widgets, menuitem);
318 
319     menuitem = create_view_menu_item (submenu, _("Duplicate to multichannel"),
320                                        "<Sweep-View>/Channels/Duplicate to multichannel",
321 	                                   view,
322                                        dup_channels_dialog_new_cb, TRUE,
323                                        0, 0, view);
324     view->channelops_widgets =
325       g_list_append (view->channelops_widgets, menuitem);
326 
327   }
328 
329   if (channels == 2) {
330 
331 	menuitem = create_view_menu_item (submenu, _("Swap left and right"),
332                                        "<Sweep-View>/Sample/Channels/Swap left and right",
333 	                                   view,
334                                        stereo_swap_cb, TRUE,
335                                        0, 0, view);
336     view->channelops_widgets =
337       g_list_append (view->channelops_widgets, menuitem);
338 
339 
340 	menuitem = create_view_menu_item (submenu, _("Remove left channel"),
341                                        "<Sweep-View>/Sample/Channels/Remove left channel",
342 	                                   view,
343                                        remove_left_cb, TRUE,
344                                        0, 0, view);
345     view->channelops_widgets =
346       g_list_append (view->channelops_widgets, menuitem);
347 
348 
349 	menuitem = create_view_menu_item (submenu, _("Remove right channel"),
350                                        "<Sweep-View>/Sample/Channels/Remove right channel",
351 	                                   view,
352                                        remove_right_cb, TRUE,
353                                        0, 0, view);
354     view->channelops_widgets =
355       g_list_append (view->channelops_widgets, menuitem);
356 
357   }
358 
359   if (channels > 1) {
360 
361 	menuitem = create_view_menu_item (submenu, _("Mix down to mono"),
362                                        "<Sweep-View>/Sample/Channels/Mix down to mono",
363 	                                   view,
364                                        mono_mixdown_cb, TRUE,
365                                        0, 0, view);
366     view->channelops_widgets =
367       g_list_append (view->channelops_widgets, menuitem);
368   }
369 
370 
371   menuitem = create_view_menu_item (submenu, _("Add/Remove channels"),
372                                        "<Sweep-View>/Sample/Channels/Add/Remove channels",
373                                        view,
374                                        channels_dialog_new_cb, TRUE,
375                                        0, 0, view);
376 
377   view->channelops_widgets =
378     g_list_append (view->channelops_widgets, menuitem);
379 
380 
381   gtk_menu_item_set_submenu (GTK_MENU_ITEM(view->channelops_menuitem),
382 			     submenu);
383 
384   view->channelops_submenu = submenu;
385 
386   return submenu;
387 }
388 
389 /*
390  * Convenience function to Create and setup individual menuitems
391  */
392 
create_view_menu_item(GtkWidget * menu,gchar * label,gchar * accel_path,sw_view * view,gpointer callback,gboolean nomodify,guint accel_key,GdkModifierType accel_mods,gpointer user_data)393 static GtkWidget * create_view_menu_item(GtkWidget * menu, gchar * label, gchar * accel_path,
394                                                   sw_view *view,gpointer callback, gboolean nomodify,
395 												  guint accel_key, GdkModifierType accel_mods, gpointer user_data)
396 {
397 	GtkWidget * menuitem;
398 
399 	menuitem = gtk_menu_item_new_with_label(label);
400 	/* register accel path enabling runtime changes by the user */
401 	gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem), accel_path);
402 	gtk_menu_append(GTK_MENU(menu), menuitem);
403 	 g_signal_connect (G_OBJECT(menuitem), "activate",
404 		     G_CALLBACK(callback), user_data);
405 
406     /* register default key binding (if one is supplied */
407 	if (accel_key)
408 		 gtk_accel_map_add_entry  (accel_path, accel_key, accel_mods);
409 
410 	if (nomodify)
411 	  NOMODIFY(menuitem);
412 
413 	gtk_widget_show(menuitem);
414 
415 	return menuitem;
416 }
417 
418 /*
419  * Populate a GtkMenu or GtkMenubar m
420  */
421 static GtkAccelGroup *
create_view_menu(sw_view * view,GtkWidget * m)422 create_view_menu (sw_view * view, GtkWidget * m)
423 {
424   GtkWidget * menuitem;
425   GtkWidget * submenu, *subsubmenu;
426   GtkAccelGroup *accel_group;
427   SampleDisplay * s = SAMPLE_DISPLAY(view->display);
428 
429 
430 #define MENU_APPEND(w,c) \
431   if (GTK_IS_MENU_BAR(w)) {                           \
432     gtk_menu_bar_append(GTK_MENU_BAR(w), c);          \
433   } else if (GTK_IS_MENU(w)) {                        \
434     gtk_menu_append(GTK_MENU(w), c);                  \
435   }
436 
437   /* Create a GtkAccelGroup and add it to the window. */
438   accel_group = gtk_accel_group_new();
439   g_object_set_data(G_OBJECT(view->window), "accel_group", accel_group);
440 #if 0
441   if (GTK_IS_MENU(m))
442     gtk_window_add_accel_group (GTK_WINDOW(view->window), accel_group);
443 #endif
444 
445   /* File */
446   menuitem = gtk_menu_item_new_with_label(_("File"));
447   MENU_APPEND(m, menuitem);
448   gtk_widget_show(menuitem);
449   submenu = gtk_menu_new();
450   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
451 
452   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
453 
454   create_view_menu_item (submenu, _("New ..."), "<Sweep-View>/File/New ...", view,
455                                                   sample_new_empty_cb, FALSE,
456 												  GDK_n, GDK_CONTROL_MASK, view);
457 
458   create_view_menu_item (submenu, _("Open ..."), "<Sweep-View>/File/Open ...", view,
459                                                   sample_load_cb, FALSE,
460 												  GDK_o, GDK_CONTROL_MASK, view->window);
461 
462 #if GTK_CHECK_VERSION (2, 10, 0)
463 
464   GtkWidget *recent_menu;
465   GtkRecentFilter * filter;
466 
467   if (recent_manager != NULL) {
468     recent_menu =
469           gtk_recent_chooser_menu_new_for_manager(recent_manager);
470     gtk_widget_show(recent_menu);
471 
472     g_signal_connect(G_OBJECT(recent_menu),
473                      "item-activated",
474                      G_CALLBACK(recent_chooser_menu_activated_cb),
475                      NULL);
476 
477     gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER(recent_menu), 20);
478     gtk_recent_chooser_set_show_tips (GTK_RECENT_CHOOSER(recent_menu), TRUE);
479     gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER(recent_menu),
480                                       GTK_RECENT_SORT_MRU);
481 
482     filter = gtk_recent_filter_new();
483     gtk_recent_filter_add_application(filter, g_get_application_name());
484 
485     gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(recent_menu), filter);
486 
487 
488     menuitem = gtk_menu_item_new_with_label(_("Open Recent"));
489     gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem),
490                                 "<Sweep-View>/File/Open Recent");
491     gtk_menu_append(GTK_MENU(submenu), menuitem);
492 
493     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), recent_menu);
494 
495     gtk_widget_show(GTK_WIDGET(menuitem));
496 
497   }
498 
499 #endif
500 
501   create_view_menu_item (submenu, _("Save"), "<Sweep-View>/File/Save", view,
502                                                   sample_save_cb, TRUE,
503 												  GDK_s, GDK_CONTROL_MASK, view);
504 
505   create_view_menu_item (submenu, _("Save As ..."), "<Sweep-View>/File/Save As ...", view,
506                                                   sample_save_as_cb, TRUE,
507 												  0, 0, view);
508 
509   create_view_menu_item (submenu, _("Revert"), "<Sweep-View>/File/Revert", view,
510                                                   sample_revert_cb, TRUE,
511 												  0, 0, view);
512 
513   menuitem = gtk_menu_item_new(); /* Separator */
514   gtk_menu_append(GTK_MENU(submenu), menuitem);
515   gtk_widget_show(menuitem);
516 
517   create_view_menu_item (submenu, _("Properties ..."), "<Sweep-View>/File/Properties ...", view,
518                                                   show_info_dialog_cb, FALSE,
519 												  0, 0, view);
520 
521   menuitem = gtk_menu_item_new(); /* Separator */
522   gtk_menu_append(GTK_MENU(submenu), menuitem);
523   gtk_widget_show(menuitem);
524 
525   create_view_menu_item (submenu, _("Close"), "<Sweep-View>/File/Close", view,
526                                                   exit_cb, FALSE,
527 												  GDK_q, GDK_CONTROL_MASK, s);
528 
529   create_view_menu_item (submenu, _("Quit"), "<Sweep-View>/File/Quit", view,
530                                                   view_close_cb, FALSE,
531 												  GDK_w, GDK_CONTROL_MASK, s);
532 
533 
534   /* Edit */
535   menuitem = gtk_menu_item_new_with_label(_("Edit"));
536   MENU_APPEND(m, menuitem);
537   gtk_widget_show(menuitem);
538   submenu = gtk_menu_new();
539   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
540   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem), "<Sweep-View>/Edit");
541   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
542 
543   menuitem = create_view_menu_item (submenu, _("Cancel"), "<Sweep-View>/Edit/Cancel", view,
544                                                   cancel_cb, FALSE,
545 												  GDK_Escape, GDK_BUTTON1_MASK, view);
546   NOREADY(menuitem);
547 
548   create_view_menu_item (submenu, _("Undo"), "<Sweep-View>/Edit/Undo", view,
549                                                   undo_cb, TRUE,
550 												  GDK_z, GDK_CONTROL_MASK, view);
551 
552   create_view_menu_item (submenu, _("Redo"), "<Sweep-View>/Edit/Redo", view,
553                                                   redo_cb, TRUE,
554 												  GDK_r, GDK_CONTROL_MASK, view);
555 
556   create_view_menu_item (submenu, _("Show history ..."), "<Sweep-View>/Edit/Show history ...", view,
557                                                   show_undo_dialog_cb, FALSE,
558 												  0, 0, view);
559 
560   menuitem = gtk_menu_item_new(); /* Separator */
561   gtk_menu_append(GTK_MENU(submenu), menuitem);
562   gtk_widget_show(menuitem);
563 
564   create_view_menu_item (submenu, _("Delete"), "<Sweep-View>/Edit/Delete", view,
565                                                   delete_cb, TRUE,
566 												  0, 0, view);
567 
568   create_view_menu_item (submenu, _("Cut"), "<Sweep-View>/Edit/Cut", view,
569                                                   cut_cb, TRUE,
570 												  GDK_x, GDK_CONTROL_MASK, view);
571 
572   create_view_menu_item (submenu, _("Copy"), "<Sweep-View>/Edit/Copy", view,
573                                                   copy_cb, TRUE,
574 												  GDK_c, GDK_CONTROL_MASK, view);
575 
576   create_view_menu_item (submenu, _("Clear"), "<Sweep-View>/Edit/Clear", view,
577                                                   clear_cb, TRUE,
578 												  0, 0, view);
579 
580   create_view_menu_item (submenu, _("Crop"), "<Sweep-View>/Edit/Crop", view,
581                                                   crop_cb, TRUE,
582 												  0, 0, view);
583 
584   menuitem = gtk_menu_item_new(); /* Separator */
585   gtk_menu_append(GTK_MENU(submenu), menuitem);
586   gtk_widget_show(menuitem);
587 
588   create_view_menu_item (submenu, _("Paste: Insert"), "<Sweep-View>/Edit/Paste: Insert", view,
589                                                   paste_cb, TRUE,
590 												  GDK_v, GDK_CONTROL_MASK, view);
591 
592   create_view_menu_item (submenu, _("Paste: Mix"), "<Sweep-View>/Edit/Paste: Mix", view,
593                                                   paste_mix_cb, TRUE,
594 												  GDK_m, GDK_CONTROL_MASK, view);
595 
596   create_view_menu_item (submenu, _("Paste: Crossfade"), "<Sweep-View>/Edit/Paste: Crossfade", view,
597                                                   paste_xfade_cb, TRUE,
598 												  GDK_f, GDK_CONTROL_MASK, view);
599 
600   create_view_menu_item (submenu, _("Paste as New"), "<Sweep-View>/Edit/Paste as New", view,
601                                                   paste_as_new_cb, TRUE,
602 												  GDK_e, GDK_CONTROL_MASK, view);
603 
604   menuitem = gtk_menu_item_new(); /* Separator */
605   gtk_menu_append(GTK_MENU(submenu), menuitem);
606   gtk_widget_show(menuitem);
607 
608   create_view_menu_item (submenu, _("Preview Cut/Cursor"), "<Sweep-View>/Edit/Preview Cut-Cursor", view,
609                                                   preview_cut_cb, FALSE,
610 												  GDK_k, GDK_CONTROL_MASK, view);
611 
612   create_view_menu_item (submenu, _("Pre-roll to Cursor"), "<Sweep-View>/Edit/Pre-roll to Cursor", view,
613                                                   preroll_cb, FALSE,
614 												  GDK_k, GDK_SHIFT_MASK|GDK_CONTROL_MASK, view);
615 
616 
617   /* Select */
618   menuitem = gtk_menu_item_new_with_label(_("Select"));
619   MENU_APPEND(m, menuitem);
620   gtk_widget_show(menuitem);
621   submenu = gtk_menu_new();
622   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
623 
624   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
625 
626   create_view_menu_item (submenu, _("Invert"), "<Sweep-View>/Select/Invert", view,
627                                                   select_invert_cb, TRUE,
628 												  GDK_i, GDK_CONTROL_MASK, s);
629 
630   create_view_menu_item (submenu, _("All"), "<Sweep-View>/Select/All", view,
631                                                   select_all_cb, TRUE,
632 												  GDK_a, GDK_CONTROL_MASK, s);
633 
634   create_view_menu_item (submenu, _("None"), "<Sweep-View>/Select/None", view,
635                                                   select_none_cb, TRUE,
636 												  GDK_a, GDK_SHIFT_MASK|GDK_CONTROL_MASK, s);
637 
638   menuitem = gtk_menu_item_new(); /* Separator */
639   gtk_menu_append(GTK_MENU(submenu), menuitem);
640   gtk_widget_show(menuitem);
641 
642   create_view_menu_item (submenu, _("Halve"), "<Sweep-View>/Select/Halve", view,
643                                                   selection_halve_cb, TRUE,
644 												  GDK_semicolon, GDK_BUTTON1_MASK, s);
645 
646   create_view_menu_item (submenu, _("Double"), "<Sweep-View>/Select/Double", view,
647                                                   selection_double_cb, TRUE,
648 												  GDK_quoteright, GDK_BUTTON1_MASK, s);
649 
650   create_view_menu_item (submenu, _("Shift left"), "<Sweep-View>/Select/Shift left", view,
651                                                   select_shift_left_cb, TRUE,
652 												  GDK_less, GDK_BUTTON1_MASK, s);
653 
654   create_view_menu_item (submenu, _("Shift right"), "<Sweep-View>/Select/Shift right", view,
655                                                   select_shift_right_cb, TRUE,
656 												  GDK_greater, GDK_BUTTON1_MASK, s);
657 
658   /* View */
659   menuitem = gtk_menu_item_new_with_label(_("View"));
660   MENU_APPEND(m, menuitem);
661   gtk_widget_show(menuitem);
662   submenu = gtk_menu_new();
663   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
664   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
665 
666   menuitem = gtk_check_menu_item_new_with_label(_("Autoscroll: follow playback cursor"));
667   gtk_menu_item_set_accel_path(GTK_MENU_ITEM(menuitem), "<Sweep-View>/View/Autoscroll: follow playback cursor");
668   gtk_menu_append(GTK_MENU(submenu), menuitem);
669   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem),
670 				  view->following);
671   g_signal_connect (G_OBJECT(menuitem), "activate",
672                     G_CALLBACK(follow_toggle_cb), view);
673   gtk_widget_show(menuitem);
674   view->follow_checkmenu = menuitem;
675 
676   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem),
677 				  view->following);
678   view->follow_checkmenu = menuitem;
679 
680   menuitem = gtk_menu_item_new(); /* Separator */
681   gtk_menu_append(GTK_MENU(submenu), menuitem);
682   gtk_widget_show(menuitem);
683 
684   create_view_menu_item (submenu, _("Center"), "<Sweep-View>/View/Center", view,
685                                                   zoom_center_cb, FALSE,
686 												  GDK_slash, GDK_BUTTON1_MASK, s);
687 
688   menuitem = gtk_menu_item_new(); /* Separator */
689   gtk_menu_append(GTK_MENU(submenu), menuitem);
690   gtk_widget_show(menuitem);
691 
692   create_view_menu_item (submenu, _("Zoom in"), "<Sweep-View>/View/Zoom in", view,
693                                                   zoom_in_cb, FALSE,
694 												  GDK_equal, GDK_BUTTON1_MASK, view);
695 
696   create_view_menu_item (submenu, _("Zoom out"), "<Sweep-View>/View/Zoom out", view,
697                                                   zoom_out_cb, FALSE,
698 												  GDK_minus, GDK_BUTTON1_MASK, view);
699 
700   create_view_menu_item (submenu, _("Zoom to selection"), "<Sweep-View>/View/Zoom to selection", view,
701                                                   zoom_to_sel_cb, FALSE,
702 												  0, 0, s);
703 
704 
705 #if 0
706   create_view_menu_item (submenu, _("Left"), "<Sweep-View>/View/Left", view,
707                                                   zoom_left_cb, FALSE,
708 												  GDK_Left, GDK_BUTTON1_MASK, s);
709 
710   create_view_menu_item (submenu, _("Right"), "<Sweep-View>/View/Right", view,
711                                                   zoom_right_cb, FALSE,
712 												  GDK_Right, GDK_BUTTON1_MASK, s);
713 #endif
714 
715   create_view_menu_item (submenu, _("Zoom normal"), "<Sweep-View>/View/Zoom normal", view,
716                                                   zoom_norm_cb, FALSE,
717 												  0, 0, s);
718 
719   create_view_menu_item (submenu, _("Zoom all"), "<Sweep-View>/View/Zoom all", view,
720                                                   zoom_all_cb, FALSE,
721 												  GDK_1, GDK_CONTROL_MASK, view);
722 
723   create_view_menu_item (submenu, _("1:1"), "<Sweep-View>/View/1:1", view,
724                                                   zoom_1to1_cb, FALSE,
725 												  0, 0, s);
726 
727   menuitem = gtk_menu_item_new(); /* Separator */
728   gtk_menu_append(GTK_MENU(submenu), menuitem);
729   gtk_widget_show(menuitem);
730 
731   /* Store view */
732 
733   menuitem = gtk_menu_item_new_with_label(_("Remember as"));
734   gtk_menu_append(GTK_MENU(submenu), menuitem);
735   gtk_widget_show(menuitem);
736   subsubmenu = gtk_menu_new();
737   gtk_menu_set_accel_group (GTK_MENU (subsubmenu), accel_group);
738   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), subsubmenu);
739 
740 
741 #define REMEMBER_AS(title,index,accel_path) \
742   menuitem = gtk_menu_item_new_with_label ((title));                         \
743   g_object_set_data (G_OBJECT(menuitem), "default", GINT_TO_POINTER((index))); \
744   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);                          \
745   gtk_widget_show (menuitem);                                                \
746   g_signal_connect (G_OBJECT(menuitem), "activate",                       \
747 		     G_CALLBACK(view_store_cb), view);                  \
748   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem), accel_path); \
749   gtk_accel_map_add_entry  (accel_path,             \
750 			      GDK_KP_##index, GDK_CONTROL_MASK);
751 
752   REMEMBER_AS(_("Area 1"), 1, "<Sweep-View>/View/Remember As/Area 1");
753   REMEMBER_AS(_("Area 2"), 2, "<Sweep-View>/View/Remember As/Area 2");
754   REMEMBER_AS(_("Area 3"), 3, "<Sweep-View>/View/Remember As/Area 3");
755   REMEMBER_AS(_("Area 4"), 4, "<Sweep-View>/View/Remember As/Area 4");
756   REMEMBER_AS(_("Area 5"), 5, "<Sweep-View>/View/Remember As/Area 5");
757   REMEMBER_AS(_("Area 6"), 6, "<Sweep-View>/View/Remember As/Area 6");
758   REMEMBER_AS(_("Area 7"), 7, "<Sweep-View>/View/Remember As/Area 7");
759   REMEMBER_AS(_("Area 8"), 8, "<Sweep-View>/View/Remember As/Area 8");
760   REMEMBER_AS(_("Area 9"), 9, "<Sweep-View>/View/Remember As/Area 9");
761   REMEMBER_AS(_("Area 10"), 0, "<Sweep-View>/View/Remember As/Area 10");
762 
763   /* Retrieve view */
764 
765   menuitem = gtk_menu_item_new_with_label(_("Zoom to"));
766   gtk_menu_append(GTK_MENU(submenu), menuitem);
767   gtk_widget_show(menuitem);
768   subsubmenu = gtk_menu_new();
769   gtk_menu_set_accel_group (GTK_MENU (subsubmenu), accel_group);
770   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), subsubmenu);
771 
772 #define ZOOM_TO(title,index,accel_path) \
773   menuitem = gtk_menu_item_new_with_label ((title));                         \
774   g_object_set_data (G_OBJECT(menuitem), "default", GINT_TO_POINTER((index))); \
775   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);                          \
776   gtk_widget_show (menuitem);                                                \
777   g_signal_connect (G_OBJECT(menuitem), "activate",                       \
778 		     G_CALLBACK(view_retrieve_cb), view);               \
779   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem), accel_path); \
780   gtk_accel_map_add_entry  (accel_path,             \
781 			      GDK_KP_##index, GDK_BUTTON1_MASK);
782 
783   ZOOM_TO(_("Area 1"), 1, "<Sweep-View>/View/Zoom To/Area 1");
784   ZOOM_TO(_("Area 2"), 2, "<Sweep-View>/View/Zoom To/Area 2");
785   ZOOM_TO(_("Area 3"), 3, "<Sweep-View>/View/Zoom To/Area 3");
786   ZOOM_TO(_("Area 4"), 4, "<Sweep-View>/View/Zoom To/Area 4");
787   ZOOM_TO(_("Area 5"), 5, "<Sweep-View>/View/Zoom To/Area 5");
788   ZOOM_TO(_("Area 6"), 6, "<Sweep-View>/View/Zoom To/Area 6");
789   ZOOM_TO(_("Area 7"), 7, "<Sweep-View>/View/Zoom To/Area 7");
790   ZOOM_TO(_("Area 8"), 8, "<Sweep-View>/View/Zoom To/Area 8");
791   ZOOM_TO(_("Area 9"), 9, "<Sweep-View>/View/Zoom To/Area 9");
792   ZOOM_TO(_("Area 10"), 0, "<Sweep-View>/View/Zoom To/Area 10");
793 
794   menuitem = gtk_menu_item_new(); /* Separator */
795   gtk_menu_append(GTK_MENU(submenu), menuitem);
796   gtk_widget_show(menuitem);
797 
798   menuitem = gtk_menu_item_new_with_label(_("Color scheme"));
799   gtk_menu_append(GTK_MENU(submenu), menuitem);
800   gtk_widget_show(menuitem);
801   subsubmenu = gtk_menu_new();
802   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), subsubmenu);
803 
804   menuitem = gtk_menu_item_new_with_label (_("Decoder Red"));
805   g_object_set_data (G_OBJECT(menuitem), "default",
806 			    GINT_TO_POINTER(VIEW_COLOR_RED));
807   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
808   gtk_widget_show (menuitem);
809   g_signal_connect (G_OBJECT(menuitem), "activate",
810 		     G_CALLBACK(sample_set_color_cb), view);
811 
812   menuitem = gtk_menu_item_new_with_label (_("Orangeboom"));
813   g_object_set_data (G_OBJECT(menuitem), "default",
814 			    GINT_TO_POINTER(VIEW_COLOR_ORANGE));
815   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
816   gtk_widget_show (menuitem);
817   g_signal_connect (G_OBJECT(menuitem), "activate",
818 		     G_CALLBACK(sample_set_color_cb), view);
819 
820   menuitem = gtk_menu_item_new_with_label (_("Lame Yellow"));
821   g_object_set_data (G_OBJECT(menuitem), "default",
822 			    GINT_TO_POINTER(VIEW_COLOR_YELLOW));
823   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
824   gtk_widget_show (menuitem);
825   g_signal_connect (G_OBJECT(menuitem), "activate",
826 		     G_CALLBACK(sample_set_color_cb), view);
827 
828   menuitem = gtk_menu_item_new_with_label (_("Coogee Bay Blue"));
829   g_object_set_data (G_OBJECT(menuitem), "default",
830 			    GINT_TO_POINTER(VIEW_COLOR_BLUE));
831   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
832   gtk_widget_show (menuitem);
833   g_signal_connect (G_OBJECT(menuitem), "activate",
834 		     G_CALLBACK(sample_set_color_cb), view);
835 
836   menuitem = gtk_menu_item_new_with_label (_("Blackwattle"));
837   g_object_set_data (G_OBJECT(menuitem), "default",
838 			    GINT_TO_POINTER(VIEW_COLOR_BLACK));
839   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
840   gtk_widget_show (menuitem);
841   g_signal_connect (G_OBJECT(menuitem), "activate",
842 		     G_CALLBACK(sample_set_color_cb), view);
843 
844   menuitem = gtk_menu_item_new_with_label (_("Frigid"));
845   g_object_set_data (G_OBJECT(menuitem), "default",
846 			    GINT_TO_POINTER(VIEW_COLOR_WHITE));
847   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
848   gtk_widget_show (menuitem);
849   g_signal_connect (G_OBJECT(menuitem), "activate",
850 		     G_CALLBACK(sample_set_color_cb), view);
851 
852   menuitem = gtk_menu_item_new_with_label (_("Radar"));
853   g_object_set_data (G_OBJECT(menuitem), "default",
854 			    GINT_TO_POINTER(VIEW_COLOR_RADAR));
855   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
856   gtk_widget_show (menuitem);
857   g_signal_connect (G_OBJECT(menuitem), "activate",
858 		     G_CALLBACK(sample_set_color_cb), view);
859 
860   menuitem = gtk_menu_item_new_with_label (_("Bluescreen"));
861   g_object_set_data (G_OBJECT(menuitem), "default",
862 			    GINT_TO_POINTER(VIEW_COLOR_BLUESCREEN));
863   gtk_menu_append (GTK_MENU(subsubmenu), menuitem);
864   gtk_widget_show (menuitem);
865   g_signal_connect (G_OBJECT(menuitem), "activate",
866 		     G_CALLBACK(sample_set_color_cb), view);
867 
868   menuitem = gtk_menu_item_new(); /* Separator */
869   gtk_menu_append(GTK_MENU(submenu), menuitem);
870   gtk_widget_show(menuitem);
871 
872   create_view_menu_item (submenu, _("New View"), "<Sweep-View>/View/New View", view,
873                                                   view_new_cb, FALSE,
874 												  0, 0, s);
875 
876   /* Sample */
877   menuitem = gtk_menu_item_new_with_label(_("Sample"));
878   MENU_APPEND(m, menuitem);
879   gtk_widget_show(menuitem);
880   submenu = gtk_menu_new();
881   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
882   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
883 
884   menuitem = gtk_menu_item_new_with_label (_("Channels"));
885   gtk_menu_append (GTK_MENU(submenu), menuitem);
886   gtk_widget_show (menuitem);
887 
888   view->channelops_menuitem = menuitem;
889   view->channelops_submenu = NULL;
890   view_refresh_channelops_menu (view);
891 
892 #ifdef HAVE_LIBSAMPLERATE
893 
894   create_view_menu_item (submenu, _("Resample ..."), "<Sweep-View>/Sample/Resample ...", view,
895                                                   samplerate_dialog_new_cb, TRUE,
896 												  0, 0, view);
897 #endif
898 
899   menuitem = gtk_menu_item_new(); /* Separator */
900   gtk_menu_append(GTK_MENU(submenu), menuitem);
901   gtk_widget_show(menuitem);
902 
903   create_view_menu_item (submenu, _("Duplicate"), "<Sweep-View>/Sample/Duplicate", view,
904                                                   sample_new_copy_cb, TRUE,
905 												  GDK_d, GDK_CONTROL_MASK, s);
906 
907   /* Filters */
908   menuitem = gtk_menu_item_new_with_label(_("Process"));
909   MENU_APPEND(m, menuitem);
910   gtk_widget_show(menuitem);
911   submenu = create_proc_menu (view, accel_group);
912   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
913 
914   NOMODIFY(menuitem);
915 
916   /* Playback */
917   menuitem = gtk_menu_item_new_with_label(_("Playback"));
918   MENU_APPEND(m, menuitem);
919   gtk_widget_show(menuitem);
920   submenu = gtk_menu_new();
921   gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group);
922   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
923 
924   create_view_menu_item (submenu, _("Configure audio device ..."),
925                                    "<Sweep-View>/Playback/Configure audio device ...",
926 								   view,
927                                    device_config_cb, FALSE,
928                                    0, 0, view);
929 
930   menuitem = gtk_menu_item_new(); /* Separator */
931   gtk_menu_append(GTK_MENU(submenu), menuitem);
932   gtk_widget_show(menuitem);
933 
934   menuitem = gtk_menu_item_new_with_label(_("Transport"));
935   gtk_menu_append(GTK_MENU(submenu), menuitem);
936   gtk_widget_show(menuitem);
937   subsubmenu = gtk_menu_new();
938   gtk_menu_set_accel_group (GTK_MENU (subsubmenu), accel_group);
939   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), subsubmenu);
940 
941   NOALLOC(menuitem);
942 
943   create_view_menu_item (subsubmenu, _("Go to start of file"),
944                                                  "<Sweep-View>/Playback/Transport/Go to start of file",
945                                                   view,
946                                                   goto_start_cb, FALSE,
947 												  GDK_Home, GDK_CONTROL_MASK, view);
948 
949   create_view_menu_item (subsubmenu, _("Go to start of window"), "<Sweep-View>/Playback/Transport/Go to start of window",
950                                                   view,
951                                                   goto_start_of_view_cb, FALSE,
952 												  GDK_Home, GDK_BUTTON1_MASK, view);
953 
954   create_view_menu_item (subsubmenu, _("Skip back"), "<Sweep-View>/Playback/Transport/Skip back",
955                                                   view,
956                                                   page_back_cb, FALSE,
957 												  GDK_Page_Up, GDK_BUTTON1_MASK, view);
958 
959   create_view_menu_item (subsubmenu, _("Skip forward"), "<Sweep-View>/Playback/Transport/Skip forward",
960                                                   view,
961                                                   page_fwd_cb, FALSE,
962 												  GDK_Page_Down, GDK_BUTTON1_MASK, view);
963 
964   create_view_menu_item (subsubmenu, _("Go to end of window"), "<Sweep-View>/Playback/Transport/Go to end of window",
965                                                   view,
966                                                   goto_end_of_view_cb, FALSE,
967 												  GDK_End, GDK_BUTTON1_MASK, view);
968 
969   create_view_menu_item (subsubmenu, _("Go to end of file"), "<Sweep-View>/Playback/Transport/Go to end of file",
970                                                   view,
971                                                   goto_end_cb, FALSE,
972 												  GDK_End, GDK_CONTROL_MASK, view);
973 
974   menuitem = gtk_menu_item_new(); /* Separator */
975   gtk_menu_append(GTK_MENU(submenu), menuitem);
976   gtk_widget_show(menuitem);
977 
978   menuitem = create_view_menu_item (submenu, _("Play selection"), "<Sweep-View>/Playback/Transport/Play selection",
979                                                   view,
980                                                   play_view_sel_cb, FALSE,
981 												  GDK_space, GDK_BUTTON1_MASK, view);
982   NOALLOC(menuitem);
983 
984   menuitem = create_view_menu_item (submenu, _("Play sample"), "<Sweep-View>/Playback/Transport/Play sample",
985                                                   view,
986                                                   play_view_cb, FALSE,
987 												  GDK_space, GDK_CONTROL_MASK, view);
988   NOALLOC(menuitem);
989 
990   menuitem = gtk_menu_item_new_with_label(_("Play note"));
991   gtk_menu_append(GTK_MENU(submenu), menuitem);
992   gtk_widget_show(menuitem);
993   subsubmenu = gtk_menu_new();
994   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), subsubmenu);
995 
996   NOALLOC(menuitem);
997 
998   /*
999   ** This sets up menu items and callbacks for all the note play
1000   ** and is quite a bit neater than the old stuff.
1001   */
1002   noteplay_setup (subsubmenu, view, accel_group);
1003 
1004 
1005   menuitem = gtk_menu_item_new(); /* Separator */
1006   gtk_menu_append(GTK_MENU(submenu), menuitem);
1007   gtk_widget_show(menuitem);
1008 
1009   menuitem = gtk_check_menu_item_new_with_label(_("Toggle monitoring"));
1010   gtk_menu_append(GTK_MENU(submenu), menuitem);
1011   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem),
1012 				  view->sample->play_head->monitor);
1013   g_signal_connect (G_OBJECT(menuitem), "activate",
1014 		     G_CALLBACK(monitor_toggle_cb), view);
1015 
1016   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem),
1017                                "<Sweep-View>/Playback/Transport/Toggle monitoring");
1018 
1019   gtk_widget_show(menuitem);
1020   view->monitor_checkmenu = menuitem;
1021 
1022   menuitem = gtk_check_menu_item_new_with_label(_("Toggle looping"));
1023   gtk_menu_append(GTK_MENU(submenu), menuitem);
1024   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem),
1025 				  view->sample->play_head->looping);
1026   g_signal_connect (G_OBJECT(menuitem), "activate",
1027 		     G_CALLBACK(loop_toggle_cb), view);
1028 
1029   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem),
1030                                "<Sweep-View>/Playback/Transport/Toggle looping");
1031   gtk_widget_show(menuitem);
1032   view->loop_checkmenu = menuitem;
1033 
1034   menuitem = gtk_check_menu_item_new_with_label(_("Toggle muting"));
1035   gtk_menu_append(GTK_MENU(submenu), menuitem);
1036   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem),
1037 				  view->sample->play_head->mute);
1038   g_signal_connect (G_OBJECT(menuitem), "activate",
1039 		     G_CALLBACK(mute_toggle_cb), view);
1040   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem),
1041                                "<Sweep-View>/Playback/Transport/Toggle muting");
1042   gtk_widget_show(menuitem);
1043   view->mute_checkmenu = menuitem;
1044 
1045   menuitem = gtk_check_menu_item_new_with_label(_("Toggle reverse playback"));
1046   gtk_menu_append(GTK_MENU(submenu), menuitem);
1047   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem),
1048 				  view->sample->play_head->reverse);
1049   g_signal_connect (G_OBJECT(menuitem), "activate",
1050 		     G_CALLBACK(playrev_toggle_cb), view);
1051   gtk_widget_show(menuitem);
1052   gtk_menu_item_set_accel_path (GTK_MENU_ITEM(menuitem),
1053                                "<Sweep-View>/Playback/Transport/Toggle reverse playback");
1054   gtk_accel_map_add_entry  ("<Sweep-View>/Playback/Transport/Toggle reverse playback",
1055                              GDK_quoteleft, GDK_BUTTON1_MASK);
1056 
1057   view->playrev_checkmenu = menuitem;
1058 
1059   menuitem = gtk_menu_item_new(); /* Separator */
1060   gtk_menu_append(GTK_MENU(submenu), menuitem);
1061   gtk_widget_show(menuitem);
1062 
1063   menuitem = create_view_menu_item (submenu, _("Pause"), "<Sweep-View>/Playback/Pause", view,
1064                                                   pause_playback_cb, FALSE,
1065 												  0, 0, view);
1066   NOALLOC(menuitem);
1067 
1068   menuitem = create_view_menu_item (submenu, _("Stop"), "<Sweep-View>/Playback/Stop", view,
1069                                                   stop_playback_cb, FALSE,
1070 												  GDK_Return, GDK_BUTTON1_MASK, view);
1071   NOALLOC(menuitem);
1072 
1073   menuitem = gtk_menu_item_new_with_label (_("Help"));
1074   MENU_APPEND(m, menuitem);
1075   gtk_widget_show(menuitem);
1076   submenu = gtk_menu_new ();
1077   gtk_menu_item_set_submenu (GTK_MENU_ITEM(menuitem), submenu);
1078 
1079   menuitem = gtk_menu_item_new_with_label (_("About MP3 export..."));
1080   gtk_menu_append (GTK_MENU(submenu), menuitem);
1081   g_signal_connect (G_OBJECT(menuitem), "activate",
1082 		      G_CALLBACK(mp3_unsupported_dialog), NULL);
1083   gtk_widget_show(menuitem);
1084 
1085   menuitem = gtk_menu_item_new_with_label (_("About Sweep ..."));
1086   gtk_menu_append (GTK_MENU(submenu), menuitem);
1087   g_signal_connect (G_OBJECT(menuitem), "activate",
1088 		      G_CALLBACK(about_dialog_create), NULL);
1089   gtk_widget_show(menuitem);
1090 
1091   return accel_group;
1092 }
1093 
1094 /*
1095  * create_context_menu_sel (view)
1096  *
1097  * Creates a context menu for operations on a selection
1098  */
1099 static GtkWidget *
create_context_menu_sel(sw_view * view)1100 create_context_menu_sel (sw_view * view)
1101 {
1102   GtkWidget * menu;
1103   GtkWidget * menuitem;
1104   GtkWidget * submenu;
1105   SampleDisplay * s = SAMPLE_DISPLAY(view->display);
1106 
1107   menu = gtk_menu_new ();
1108 
1109   /* Zoom */
1110 
1111   menuitem = gtk_menu_item_new_with_label(_("Zoom to selection"));
1112   gtk_menu_append(GTK_MENU(menu), menuitem);
1113   g_signal_connect (G_OBJECT(menuitem), "activate",
1114 		     G_CALLBACK(zoom_to_sel_cb), s);
1115   gtk_widget_show(menuitem);
1116 
1117   menuitem = gtk_menu_item_new_with_label(_("Zoom normal"));
1118   gtk_menu_append(GTK_MENU(menu), menuitem);
1119   g_signal_connect (G_OBJECT(menuitem), "activate",
1120                     G_CALLBACK(zoom_norm_cb), s);
1121   gtk_widget_show(menuitem);
1122 
1123   menuitem = gtk_menu_item_new_with_label(_("Zoom all"));
1124   gtk_menu_append(GTK_MENU(menu), menuitem);
1125   g_signal_connect (G_OBJECT(menuitem), "activate",
1126 		     G_CALLBACK(zoom_all_cb), view);
1127   gtk_widget_show(menuitem);
1128 
1129   menuitem = gtk_menu_item_new(); /* Separator */
1130   gtk_menu_append(GTK_MENU(menu), menuitem);
1131   gtk_widget_show(menuitem);
1132 
1133 
1134   /* Edit */
1135 
1136   menuitem = gtk_menu_item_new_with_label(_("Edit"));
1137   gtk_menu_append (GTK_MENU(menu), menuitem);
1138   gtk_widget_show(menuitem);
1139   submenu = gtk_menu_new();
1140   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
1141 
1142   NOMODIFY(menuitem);
1143 
1144   menuitem = gtk_menu_item_new_with_label(_("Cut"));
1145   gtk_menu_append(GTK_MENU(submenu), menuitem);
1146   g_signal_connect (G_OBJECT(menuitem), "activate",
1147 		     G_CALLBACK(cut_cb), view);
1148   gtk_widget_show(menuitem);
1149 
1150   menuitem = gtk_menu_item_new_with_label(_("Copy"));
1151   gtk_menu_append(GTK_MENU(submenu), menuitem);
1152   g_signal_connect (G_OBJECT(menuitem), "activate",
1153 		     G_CALLBACK(copy_cb), view);
1154   gtk_widget_show(menuitem);
1155 
1156   menuitem = gtk_menu_item_new_with_label(_("Clear"));
1157   gtk_menu_append(GTK_MENU(submenu), menuitem);
1158   g_signal_connect (G_OBJECT(menuitem), "activate",
1159 		     G_CALLBACK(clear_cb), view);
1160   gtk_widget_show(menuitem);
1161 
1162   menuitem = gtk_menu_item_new_with_label(_("Crop"));
1163   gtk_menu_append(GTK_MENU(submenu), menuitem);
1164   g_signal_connect (G_OBJECT(menuitem), "activate",
1165 		     G_CALLBACK(crop_cb), view);
1166   gtk_widget_show(menuitem);
1167 
1168   menuitem = gtk_menu_item_new(); /* Separator */
1169   gtk_menu_append(GTK_MENU(submenu), menuitem);
1170   gtk_widget_show(menuitem);
1171 
1172   menuitem = gtk_menu_item_new_with_label(_("Paste: Insert"));
1173   gtk_menu_append(GTK_MENU(submenu), menuitem);
1174   g_signal_connect (G_OBJECT(menuitem), "activate",
1175 		     G_CALLBACK(paste_cb), view);
1176   gtk_widget_show(menuitem);
1177 
1178   menuitem = gtk_menu_item_new_with_label(_("Paste: Mix"));
1179   gtk_menu_append(GTK_MENU(submenu), menuitem);
1180   g_signal_connect (G_OBJECT(menuitem), "activate",
1181 		     G_CALLBACK(paste_mix_cb), view);
1182   gtk_widget_show(menuitem);
1183 
1184   menuitem = gtk_menu_item_new_with_label(_("Paste: Crossfade"));
1185   gtk_menu_append(GTK_MENU(submenu), menuitem);
1186   g_signal_connect (G_OBJECT(menuitem), "activate",
1187 		     G_CALLBACK(paste_xfade_cb), view);
1188   gtk_widget_show(menuitem);
1189 
1190   /* Filters */
1191 
1192   menuitem = gtk_menu_item_new_with_label(_("Process"));
1193   gtk_menu_append (GTK_MENU(menu), menuitem);
1194   gtk_widget_show(menuitem);
1195   submenu = create_proc_menu (view, NULL);
1196   gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
1197 
1198   NOMODIFY(menuitem);
1199 
1200   menuitem = gtk_menu_item_new(); /* Separator */
1201   gtk_menu_append(GTK_MENU(menu), menuitem);
1202   gtk_widget_show(menuitem);
1203 
1204   /* Select */
1205 
1206   menuitem = gtk_menu_item_new_with_label(_("Invert selection"));
1207   gtk_menu_append(GTK_MENU(menu), menuitem);
1208   g_signal_connect (G_OBJECT(menuitem), "activate",
1209 		     G_CALLBACK(select_invert_cb), s);
1210   gtk_widget_show(menuitem);
1211 
1212   NOMODIFY(menuitem);
1213 
1214   menuitem = gtk_menu_item_new_with_label(_("Select all"));
1215   gtk_menu_append(GTK_MENU(menu), menuitem);
1216   g_signal_connect (G_OBJECT(menuitem), "activate",
1217 		     G_CALLBACK(select_all_cb), s);
1218   gtk_widget_show(menuitem);
1219 
1220   NOMODIFY(menuitem);
1221 
1222   menuitem = gtk_menu_item_new_with_label(_("Select none"));
1223   gtk_menu_append(GTK_MENU(menu), menuitem);
1224   g_signal_connect (G_OBJECT(menuitem), "activate",
1225 		     G_CALLBACK(select_none_cb), s);
1226   gtk_widget_show(menuitem);
1227 
1228   NOMODIFY(menuitem);
1229 
1230   menuitem = gtk_menu_item_new(); /* Separator */
1231   gtk_menu_append(GTK_MENU(menu), menuitem);
1232   gtk_widget_show(menuitem);
1233 
1234   /* View */
1235 
1236   menuitem = gtk_menu_item_new_with_label(_("New View"));
1237   gtk_menu_append(GTK_MENU(menu), menuitem);
1238   g_signal_connect (G_OBJECT(menuitem), "activate",
1239 		     G_CALLBACK(view_new_cb), s);
1240   gtk_widget_show(menuitem);
1241 
1242 #if 0
1243   menuitem = gtk_menu_item_new(); /* Separator */
1244   gtk_menu_append(GTK_MENU(menu), menuitem);
1245   gtk_widget_show(menuitem);
1246 
1247   /* Properties */
1248 
1249   menuitem = gtk_menu_item_new_with_label(_("File properties ..."));
1250   gtk_menu_append(GTK_MENU(menu), menuitem);
1251   g_signal_connect (G_OBJECT(menuitem), "activate",
1252 		     G_CALLBACK(show_info_dialog_cb), view);
1253   gtk_widget_show(menuitem);
1254 #endif
1255 
1256   return menu;
1257 }
1258 
1259 /*
1260  * create_context_menu_point (view)
1261  *
1262  * Creates a context menu for point (cursor) operations, ie. when
1263  * no selection is active
1264  */
1265 static GtkWidget *
create_context_menu_point(sw_view * view)1266 create_context_menu_point (sw_view * view)
1267 {
1268   GtkWidget * menu;
1269   GtkWidget * menuitem;
1270   SampleDisplay * s = SAMPLE_DISPLAY(view->display);
1271 
1272   menu = gtk_menu_new ();
1273 
1274   /* Zoom */
1275 
1276   menuitem = gtk_menu_item_new_with_label(_("Zoom normal"));
1277   gtk_menu_append(GTK_MENU(menu), menuitem);
1278   g_signal_connect (G_OBJECT(menuitem), "activate",
1279                     G_CALLBACK(zoom_norm_cb), s);
1280   gtk_widget_show(menuitem);
1281 
1282   menuitem = gtk_menu_item_new_with_label(_("Zoom all"));
1283   gtk_menu_append(GTK_MENU(menu), menuitem);
1284   g_signal_connect (G_OBJECT(menuitem), "activate",
1285 		     G_CALLBACK(zoom_all_cb), view);
1286   gtk_widget_show(menuitem);
1287 
1288   menuitem = gtk_menu_item_new(); /* Separator */
1289   gtk_menu_append(GTK_MENU(menu), menuitem);
1290   gtk_widget_show(menuitem);
1291 
1292   /* Edit */
1293 
1294   menuitem = gtk_menu_item_new_with_label(_("Paste"));
1295   gtk_menu_append(GTK_MENU(menu), menuitem);
1296   g_signal_connect (G_OBJECT(menuitem), "activate",
1297 		     G_CALLBACK(paste_cb), view);
1298   gtk_widget_show(menuitem);
1299 
1300   NOMODIFY(menuitem);
1301 
1302   menuitem = gtk_menu_item_new(); /* Separator */
1303   gtk_menu_append(GTK_MENU(menu), menuitem);
1304   gtk_widget_show(menuitem);
1305 
1306   /* Select */
1307 
1308   menuitem = gtk_menu_item_new_with_label(_("Select all"));
1309   gtk_menu_append(GTK_MENU(menu), menuitem);
1310   g_signal_connect (G_OBJECT(menuitem), "activate",
1311 		     G_CALLBACK(select_all_cb), s);
1312   gtk_widget_show(menuitem);
1313 
1314   NOMODIFY(menuitem);
1315 
1316   menuitem = gtk_menu_item_new(); /* Separator */
1317   gtk_menu_append(GTK_MENU(menu), menuitem);
1318   gtk_widget_show(menuitem);
1319 
1320   /* View */
1321 
1322   menuitem = gtk_menu_item_new_with_label(_("New View"));
1323   gtk_menu_append(GTK_MENU(menu), menuitem);
1324   g_signal_connect (G_OBJECT(menuitem), "activate",
1325 		     G_CALLBACK(view_new_cb), s);
1326   gtk_widget_show(menuitem);
1327 
1328 #if 0
1329   menuitem = gtk_menu_item_new(); /* Separator */
1330   gtk_menu_append(GTK_MENU(menu), menuitem);
1331   gtk_widget_show(menuitem);
1332 
1333   /* Properties */
1334 
1335   menuitem = gtk_menu_item_new_with_label(_("File properties ..."));
1336   gtk_menu_append(GTK_MENU(menu), menuitem);
1337   g_signal_connect (G_OBJECT(menuitem), "activate",
1338 		     G_CALLBACK(show_info_dialog_cb), view);
1339   gtk_widget_show(menuitem);
1340 #endif
1341 
1342   return menu;
1343 }
1344 
1345 static gint
view_destroy_cb(GtkWidget * widget,gpointer data)1346 view_destroy_cb (GtkWidget * widget, gpointer data)
1347 {
1348   sw_view * view = (sw_view *)data;
1349 
1350   sample_display_stop_marching_ants (SAMPLE_DISPLAY(view->display));
1351 
1352   if (view->sample->op_progress_tag != -1)
1353     gtk_timeout_remove(view->sample->op_progress_tag);
1354   cancel_active_op (view->sample);
1355   sample_remove_view(view->sample, view);
1356   gtk_widget_destroy (GTK_WIDGET (view->display));
1357 
1358   return (FALSE);
1359 }
1360 
1361 static void
db_ruler_changed_cb(GtkWidget * widget,gpointer data)1362 db_ruler_changed_cb (GtkWidget * widget, gpointer data)
1363 {
1364   GtkRuler * ruler = GTK_RULER(widget);
1365   sw_view * view = (sw_view *)data;
1366 
1367   view_set_vzoom (view, ruler->lower, ruler->upper);
1368 }
1369 
1370 static void
view_refresh_db_rulers(sw_view * view)1371 view_refresh_db_rulers (sw_view * view)
1372 {
1373   int i, old_channels, new_channels;
1374   GtkWidget * vbox = view->db_rulers_vbox;
1375   GList * gl;
1376   GtkWidget * db_ruler;
1377 
1378   old_channels = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(vbox), "default"));
1379   new_channels = view->sample->sounddata->format->channels;
1380 
1381   if (old_channels == 0 || old_channels != new_channels) {
1382 
1383     for (gl = view->db_rulers; gl; gl = gl->next) {
1384 	  g_signal_handlers_disconnect_matched(GTK_OBJECT(view->window),
1385 								G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, gl->data);
1386       gtk_widget_destroy (GTK_WIDGET(gl->data));
1387     }
1388     g_list_free (view->db_rulers);
1389     view->db_rulers = NULL;
1390 
1391     g_object_set_data (G_OBJECT(vbox), "default", GINT_TO_POINTER(new_channels));
1392 
1393     for (i = 0; i < new_channels; i++) {
1394       db_ruler = db_ruler_new ();
1395       gtk_box_pack_start (GTK_BOX(vbox), db_ruler, TRUE, TRUE, 0);
1396       gtk_ruler_set_range (GTK_RULER(db_ruler), -1.0, 1.0, 0, 2.0);
1397       gtk_widget_show (db_ruler);
1398 
1399      g_signal_connect_swapped(GTK_OBJECT(view->window),
1400 				 "motion_notify_event",
1401 
1402 				 G_CALLBACK(GTK_WIDGET_GET_CLASS(db_ruler)->motion_notify_event),
1403 
1404 				 GTK_OBJECT (db_ruler));
1405 
1406 
1407       g_signal_connect (G_OBJECT(db_ruler), "changed",
1408 			  G_CALLBACK(db_ruler_changed_cb), view);
1409 
1410       view->db_rulers = g_list_append (view->db_rulers, db_ruler);
1411     }
1412   }
1413 
1414   for (gl = view->db_rulers; gl; gl = gl->next) {
1415     db_ruler = GTK_WIDGET(gl->data);
1416     gtk_ruler_set_range (GTK_RULER(db_ruler), view->vlow, view->vhigh,
1417 			 0, 2.0);
1418   }
1419 }
1420 
1421 
1422 static void
view_rate_changed_cb(GtkWidget * widget,gpointer data)1423 view_rate_changed_cb (GtkWidget * widget, gpointer data)
1424 {
1425   sw_view * v = (sw_view *)data;
1426   sw_sample * s = v->sample;
1427 
1428   s->rate = 1.0 - GTK_ADJUSTMENT(v->rate_adj)->value/1000.0;
1429 }
1430 
1431 static void
view_rate_zeroed_cb(GtkWidget * Widget,gpointer data)1432 view_rate_zeroed_cb (GtkWidget * Widget, gpointer data)
1433 {
1434   sw_view * v = (sw_view *)data;
1435   sw_sample * s = v->sample;
1436 
1437   s->rate = 1.0;
1438 
1439   gtk_adjustment_set_value (GTK_ADJUSTMENT(v->rate_adj), 0.0);
1440 }
1441 
1442 static void
view_gain_changed_cb(GtkWidget * widget,gpointer data)1443 view_gain_changed_cb (GtkWidget * widget, gpointer data)
1444 {
1445   sw_view * v = (sw_view *)data;
1446 
1447   head_set_gain (v->sample->play_head,
1448 		 GTK_ADJUSTMENT (v->gain_adj)->value / 10.0);
1449 }
1450 
1451 static void
view_set_pos_indicator_cb(GtkWidget * widget,gpointer data)1452 view_set_pos_indicator_cb (GtkWidget * widget, gpointer data)
1453 {
1454   SampleDisplay * sd = SAMPLE_DISPLAY(data);
1455   sw_view * view = sd->view;
1456 
1457 #define BUF_LEN 16
1458   char buf[BUF_LEN];
1459 
1460   if (sd->mouse_offset >= 0) {
1461     snprint_time (buf, BUF_LEN,
1462 		  frames_to_time (view->sample->sounddata->format,
1463 				  sd->mouse_offset));
1464     gtk_label_set_text (GTK_LABEL(view->pos), buf);
1465   } else {
1466     gtk_label_set_text (GTK_LABEL(view->pos), NO_TIME);
1467   }
1468 
1469 
1470 #undef BUF_LEN
1471 }
1472 
1473 static gint
menu_button_handler(GtkWidget * widget,GdkEvent * event)1474 menu_button_handler (GtkWidget * widget, GdkEvent * event)
1475 {
1476   GtkMenu * menu;
1477   GdkEventButton *event_button;
1478 
1479   g_return_val_if_fail (widget != NULL, FALSE);
1480   g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
1481   g_return_val_if_fail (event != NULL, FALSE);
1482 
1483   menu = GTK_MENU (widget);
1484 
1485   if (event->type == GDK_BUTTON_PRESS) {
1486     event_button = (GdkEventButton *) event;
1487     gtk_menu_popup (menu, NULL, NULL, NULL, NULL,
1488 		    event_button->button, event_button->time);
1489     return TRUE;
1490   }
1491 
1492   return FALSE;
1493 }
1494 
1495 #define VIEW_TOOLBAR_BUTTON SW_TOOLBAR_BUTTON
1496 #define VIEW_TOOLBAR_TOGGLE_BUTTON SW_TOOLBAR_TOGGLE_BUTTON
1497 #define VIEW_TOOLBAR_RADIO_BUTTON SW_TOOLBAR_RADIO_BUTTON
1498 
1499 #if 0
1500 typedef enum {
1501   VIEW_TOOLBAR_BUTTON,
1502   VIEW_TOOLBAR_TOGGLE_BUTTON,
1503   VIEW_TOOLBAR_RADIO_BUTTON,
1504 } view_toolbar_button_type;
1505 
1506 static GtkWidget *
1507 create_pixmap_button (GtkWidget * widget, gchar ** xpm_data,
1508 		      const gchar * tip_text, const gchar * custom_name,
1509 		      view_toolbar_button_type button_type,
1510 		      GCallback clicked,
1511 		      GCallback pressed, GCallback released,
1512 		      gpointer data)
1513 {
1514   GtkWidget * pixmap;
1515   GtkWidget * button;
1516   GtkTooltips * tooltips;
1517 
1518   switch (button_type) {
1519   case VIEW_TOOLBAR_TOGGLE_BUTTON:
1520     button = gtk_toggle_button_new ();
1521     break;
1522   case VIEW_TOOLBAR_RADIO_BUTTON:
1523     button = gtk_radio_button_new (NULL);
1524     break;
1525   case VIEW_TOOLBAR_BUTTON:
1526   default:
1527     button = gtk_button_new ();
1528     break;
1529   }
1530 
1531   if (xpm_data != NULL) {
1532     pixmap = create_widget_from_xpm (widget, xpm_data);
1533     gtk_widget_show (pixmap);
1534     gtk_container_add (GTK_CONTAINER (button), pixmap);
1535   }
1536 
1537   if (tip_text != NULL) {
1538     tooltips = gtk_tooltips_new ();
1539     gtk_tooltips_set_tip (tooltips, button, tip_text, NULL);
1540   }
1541 
1542   if (style != NULL) {
1543     gtk_widget_set_style (button, style);
1544   }
1545 
1546   if (clicked != NULL) {
1547     g_signal_connect (G_OBJECT (button), "clicked",
1548 			G_CALLBACK(clicked), data);
1549   }
1550 
1551   if (pressed != NULL) {
1552     g_signal_connect (G_OBJECT(button), "pressed",
1553 			G_CALLBACK(pressed), data);
1554   }
1555 
1556   if (released != NULL) {
1557     g_signal_connect (G_OBJECT(button), "released",
1558 			G_CALLBACK(released), data);
1559   }
1560 
1561   return button;
1562 }
1563 #endif
1564 
1565 static void
scrub_clicked_cb(GtkWidget * widget,GdkEventButton * event,gpointer data)1566 scrub_clicked_cb (GtkWidget * widget, GdkEventButton * event, gpointer data)
1567 {
1568   sw_view * view = (sw_view *)data;
1569   int width;
1570   sw_framecount_t offset;
1571 
1572   width = widget->allocation.width;
1573   offset = view->start + (view->end - view->start) * event->x / width;
1574   sample_set_playmarker (view->sample, offset, TRUE);
1575   sample_set_scrubbing (view->sample, TRUE);
1576 }
1577 
1578 static void
scrub_motion_cb(GtkWidget * widget,GdkEventMotion * event,gpointer data)1579 scrub_motion_cb (GtkWidget * widget, GdkEventMotion * event, gpointer data)
1580 {
1581   sw_view * view = (sw_view *)data;
1582   int width;
1583   sw_framecount_t offset;
1584 
1585   gdk_window_set_cursor (widget->window,
1586 			 sweep_cursors[SWEEP_CURSOR_NEEDLE]);
1587 
1588   if (event->state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) {
1589     width = widget->allocation.width;
1590     offset = view->start + (view->end - view->start) * event->x / width;
1591     sample_set_playmarker (view->sample, offset, TRUE);
1592   }
1593 }
1594 
1595 static void
scrub_released_cb(GtkWidget * widget,GdkEventButton * event,gpointer data)1596 scrub_released_cb (GtkWidget * widget, GdkEventButton * event, gpointer data)
1597 {
1598   sw_view * view = (sw_view *)data;
1599 
1600   sample_set_scrubbing (view->sample, FALSE);
1601 }
1602 
1603 static void
vzoom_clicked_cb(GtkWidget * widget,GdkEventButton * event,gpointer data)1604 vzoom_clicked_cb (GtkWidget * widget, GdkEventButton * event, gpointer data)
1605 {
1606   /*  sw_view * view = (sw_view *)data;*/
1607 }
1608 
1609 static void
vzoom_motion_cb(GtkWidget * widget,GdkEventMotion * event,gpointer data)1610 vzoom_motion_cb (GtkWidget * widget, GdkEventMotion * event, gpointer data)
1611 {
1612   /*  sw_view * view = (sw_view *)data;*/
1613 }
1614 
1615 static void
vzoom_released_cb(GtkWidget * widget,GdkEventButton * event,gpointer data)1616 vzoom_released_cb (GtkWidget * widget, GdkEventButton * event, gpointer data)
1617 {
1618   /*  sw_view * view = (sw_view *)data;*/
1619 }
1620 
1621 sw_view *
view_new(sw_sample * sample,sw_framecount_t start,sw_framecount_t end,gfloat gain)1622 view_new(sw_sample * sample, sw_framecount_t start, sw_framecount_t end,
1623 	 gfloat gain)
1624 {
1625   sw_view * view;
1626 
1627   gint screen_width, screen_height;
1628   gint win_width, win_height;
1629 
1630   GtkWidget * window;
1631   GtkWidget * main_vbox;
1632   GtkWidget * table;
1633   GtkWidget * hbox;
1634   GtkWidget * vbox;
1635   GtkWidget * handlebox;
1636   GtkWidget * separator;
1637   GtkWidget * ebox;
1638   GtkWidget * time_ruler;
1639   GtkWidget * scrollbar;
1640   GtkWidget * rate_vbox;
1641   GtkObject * rate_adj;
1642   GtkWidget * rate_vscale;
1643   GtkWidget * lcdbox;
1644   GtkWidget * imagebox;
1645   GtkObject * gain_adj;
1646   GtkWidget * tool_hbox;
1647   GtkWidget * gain_hscale;
1648   GtkWidget * menu_button;
1649   GtkWidget * button;
1650   GtkWidget * arrow;
1651   GtkWidget * pixmap;
1652   GtkWidget * progress;
1653   GtkWidget * frame;
1654   GtkWidget * label;
1655 #if 0
1656   GtkWidget * entry;
1657 #endif
1658 
1659 #if 0
1660   GtkWidget * toolbar;
1661 #endif
1662 
1663 #ifdef DEVEL_CODE
1664   GtkWidget * notebook;
1665 #endif
1666 
1667 
1668 
1669   GtkAccelGroup * accel_group;
1670 
1671   GtkTooltips * tooltips;
1672 
1673   GList * zoom_combo_items;
1674   GtkWidget * zoom_combo;
1675 
1676   gfloat step = 1.0;
1677 
1678   view = g_malloc0 (sizeof(sw_view));
1679 
1680   view->sample = sample;
1681   view->start = start;
1682   view->end = end;
1683   view->vlow = SW_AUDIO_T_MIN;
1684   view->vhigh = SW_AUDIO_T_MAX;
1685 
1686   /*  view->gain = gain;*/
1687 
1688   view->current_tool = TOOL_SELECT;
1689 
1690   view->repeater_tag = 0;
1691 
1692   view->following = TRUE;
1693 
1694   view->noready_widgets = NULL;
1695   view->nomodify_widgets = NULL;
1696   view->noalloc_widgets = NULL;
1697 
1698   view->channelops_widgets = NULL;
1699 
1700 #if 0
1701   win_width = CLAMP (sample->sounddata->nr_frames / 150,
1702 		     VIEW_MIN_WIDTH, VIEW_MAX_WIDTH);
1703   win_height =
1704     VIEW_DEFAULT_HEIGHT_PER_CHANNEL *
1705     MIN (2, sample->sounddata->format->channels);
1706 #else
1707   screen_width = gdk_screen_width ();
1708   screen_height = gdk_screen_height ();
1709 
1710   if (sample->views == NULL) {
1711     win_height = screen_height / 4;
1712   } else {
1713     win_height = screen_height / 8;
1714   }
1715   win_width = (win_height * 2 * 1618) / 1000;
1716 
1717   win_height *= MIN (2, sample->sounddata->format->channels);
1718 #endif
1719 
1720   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1721 
1722   sweep_set_window_icon (GTK_WINDOW(window));
1723 
1724   gtk_window_set_default_size (GTK_WINDOW(window), win_width, win_height);
1725   view->window = window;
1726 
1727   g_signal_connect (G_OBJECT(window), "destroy",
1728 		      G_CALLBACK(view_destroy_cb), view);
1729 
1730   main_vbox = gtk_vbox_new (FALSE, 0);
1731   gtk_container_add (GTK_CONTAINER(window), main_vbox);
1732   gtk_widget_show (main_vbox);
1733 
1734   handlebox = gtk_handle_box_new ();
1735   gtk_box_pack_start (GTK_BOX (main_vbox), handlebox, FALSE, TRUE, 0);
1736   gtk_widget_show (handlebox);
1737 
1738   view->menubar = gtk_menu_bar_new ();
1739   gtk_container_add (GTK_CONTAINER (handlebox), view->menubar);
1740   gtk_widget_show (view->menubar);
1741 
1742   /* file toolbar */
1743 
1744   handlebox = gtk_handle_box_new ();
1745   gtk_handle_box_set_shadow_type (GTK_HANDLE_BOX(handlebox), GTK_SHADOW_NONE);
1746   gtk_box_pack_start (GTK_BOX (main_vbox), handlebox, FALSE, TRUE, 0);
1747   gtk_widget_show (handlebox);
1748 
1749   /*  gtk_widget_set_style (handlebox, style_dark_grey);*/
1750 
1751   hbox = gtk_hbox_new (FALSE, 8);
1752   gtk_container_add (GTK_CONTAINER (handlebox), hbox);
1753   gtk_widget_show (hbox);
1754 
1755   gtk_widget_set_size_request (hbox, -1, 26);
1756 
1757   separator = gtk_hseparator_new ();
1758   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 2);
1759   gtk_widget_show (separator);
1760 
1761 
1762   /* File op buttons */
1763 
1764   tool_hbox = gtk_hbox_new (TRUE, 2);
1765   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
1766   gtk_widget_show (tool_hbox);
1767 
1768   button = create_pixmap_button (window, new_xpm, _("New ..."),
1769 				 NULL, VIEW_TOOLBAR_BUTTON,
1770 				 G_CALLBACK (sample_new_empty_cb), NULL, NULL, view);
1771   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1772   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1773   gtk_widget_show (button);
1774 
1775   button = create_pixmap_button (window, open_xpm, _("Open ..."),
1776 				 NULL, VIEW_TOOLBAR_BUTTON,
1777 				G_CALLBACK (sample_load_cb), NULL, NULL, window);
1778   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1779   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1780   gtk_widget_show (button);
1781 
1782   button = create_pixmap_button (window, save_xpm, _("Save"),
1783 				 NULL, VIEW_TOOLBAR_BUTTON,
1784 				 G_CALLBACK (sample_save_cb), NULL, NULL, view);
1785   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1786   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1787   gtk_widget_show (button);
1788 
1789   NOMODIFY(button);
1790 
1791   button = create_pixmap_button (window, saveas_xpm, _("Save as ..."),
1792 				 NULL, VIEW_TOOLBAR_BUTTON,
1793 				 G_CALLBACK (sample_save_as_cb), NULL, NULL, view);
1794   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1795   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1796   gtk_widget_show (button);
1797 
1798   NOMODIFY(button);
1799 
1800   separator = gtk_hseparator_new ();
1801   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 2);
1802   gtk_widget_show (separator);
1803 
1804   /* Edit buttons */
1805 
1806   tool_hbox = gtk_hbox_new (TRUE, 2);
1807   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
1808   gtk_widget_show (tool_hbox);
1809 
1810   button = create_pixmap_button (window, cut_xpm,
1811 				 _("Cut selection to clipboard"),
1812 				 NULL, VIEW_TOOLBAR_BUTTON,
1813 				 G_CALLBACK (cut_cb),
1814 				 NULL, NULL, view);
1815   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1816   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1817   gtk_widget_show (button);
1818   NOMODIFY(button);
1819 
1820   button = create_pixmap_button (window, copy_xpm,
1821 				 _("Copy selection to clipboard"),
1822 				 NULL, VIEW_TOOLBAR_BUTTON,
1823 				 G_CALLBACK (copy_cb),
1824 				 NULL, NULL, view);
1825   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1826   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1827   gtk_widget_show (button);
1828   NOMODIFY(button);
1829 
1830   button =
1831     create_pixmap_button (window, paste_xpm,
1832 			  _("Paste: insert clipboard at cursor position"),
1833 			  NULL, VIEW_TOOLBAR_BUTTON,
1834 			  G_CALLBACK (paste_cb),
1835 			  NULL, NULL, view);
1836   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1837   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1838   gtk_widget_show (button);
1839   NOMODIFY(button);
1840 
1841   button =
1842     create_pixmap_button (window, pastemix_xpm,
1843 			  _("Paste: mix clipboard in from cursor position"),
1844 			  NULL, VIEW_TOOLBAR_BUTTON,
1845 			  G_CALLBACK (paste_mix_cb),
1846 			  NULL, NULL, view);
1847   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1848   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1849   gtk_widget_show (button);
1850   NOMODIFY(button);
1851 
1852   button =
1853     create_pixmap_button (window, pastexfade_xpm,
1854 			  _("Paste: fade clipboard in from cursor position"),
1855 			  NULL, VIEW_TOOLBAR_BUTTON,
1856 			  G_CALLBACK (paste_xfade_cb),
1857 			  NULL, NULL, view);
1858   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1859   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1860   gtk_widget_show (button);
1861   NOMODIFY(button);
1862 
1863   separator = gtk_hseparator_new ();
1864   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 2);
1865   gtk_widget_show (separator);
1866 
1867   button = create_pixmap_button (window, crop_xpm,
1868 				 _("Crop"),
1869 				 NULL, VIEW_TOOLBAR_BUTTON,
1870 				 G_CALLBACK (crop_cb),
1871 				 NULL, NULL, view);
1872   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1873   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
1874   gtk_widget_show (button);
1875   NOMODIFY(button);
1876 
1877   separator = gtk_hseparator_new ();
1878   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 2);
1879   gtk_widget_show (separator);
1880 
1881   /* Undo/Redo */
1882 
1883   tool_hbox = gtk_hbox_new (TRUE, 2);
1884   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
1885   gtk_widget_show (tool_hbox);
1886 
1887   button = create_pixmap_button (window, undo_xpm, _("Undo"),
1888 				 NULL, VIEW_TOOLBAR_BUTTON,
1889 				 G_CALLBACK (undo_cb),
1890 				 NULL, NULL, view);
1891   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1892   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1893   gtk_widget_show (button);
1894   NOMODIFY(button);
1895 
1896   button = create_pixmap_button (window, redo_xpm, _("Redo"),
1897 				 NULL, VIEW_TOOLBAR_BUTTON,
1898 				 G_CALLBACK (redo_cb),
1899 				 NULL, NULL, view);
1900   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1901   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1902   gtk_widget_show (button);
1903   NOMODIFY(button);
1904 
1905   separator = gtk_hseparator_new ();
1906   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 4);
1907   gtk_widget_show (separator);
1908 
1909 
1910   /* TOOLS */
1911 
1912   ebox = gtk_event_box_new ();
1913   gtk_box_pack_start (GTK_BOX (hbox), ebox, FALSE, FALSE, 0);
1914   gtk_widget_show (ebox);
1915 
1916   gtk_widget_set_style (ebox, style_light_grey);
1917 
1918   tool_hbox = gtk_hbox_new (TRUE, 4);
1919   gtk_container_add (GTK_CONTAINER(ebox), tool_hbox);
1920   gtk_widget_show (tool_hbox);
1921 
1922   view->tool_buttons = NULL;
1923 
1924   button = create_pixmap_button (window, hand_xpm, _("Hand tool"),
1925 				 style_light_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
1926 				 G_CALLBACK (view_set_tool_cb), NULL, NULL, view);
1927   g_object_set_data (G_OBJECT(button), "default", GINT_TO_POINTER(TOOL_HAND));
1928   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, FALSE, 0);
1929   gtk_widget_show (button);
1930   view->tool_buttons = g_list_append (view->tool_buttons, button);
1931 
1932   button = create_pixmap_button (window, select_xpm, _("Selector tool"),
1933 				 style_light_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
1934 				 G_CALLBACK (view_set_tool_cb), NULL, NULL, view);
1935   g_object_set_data (G_OBJECT(button), "default", GINT_TO_POINTER(TOOL_SELECT));
1936 
1937   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, FALSE, 0);
1938   gtk_widget_show (button);
1939   view->tool_buttons = g_list_append (view->tool_buttons, button);
1940 
1941   NOMODIFY(button);
1942 
1943   button = create_pixmap_button (window, scrub_xpm,
1944 				 _("\"Scrubby\" the scrub tool"),
1945 				 style_light_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
1946 				 G_CALLBACK (view_set_tool_cb), NULL, NULL, view);
1947   g_object_set_data (G_OBJECT(button), "default", GINT_TO_POINTER(TOOL_SCRUB));
1948   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, FALSE, 0);
1949   gtk_widget_show (button);
1950   view->tool_buttons = g_list_append (view->tool_buttons, button);
1951 
1952 #ifdef DEVEL_CODE /* Pencil & Noise -- these need undos */
1953 
1954   button = create_pixmap_button (window, pencil_xpm, _("Pencil tool"),
1955 				 style_light_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
1956 				 G_CALLBACK (view_set_tool_cb), NULL, NULL, view);
1957   g_object_set_data (G_OBJECT(button), "default", GINT_TO_POINTER(TOOL_PENCIL));
1958   gtk_box_pack_start (GTK_BOX (tool_hbox), button, TRUE, TRUE, 0);
1959   gtk_widget_show (button);
1960   view->tool_buttons = g_list_append (view->tool_buttons, button);
1961 
1962   button = create_pixmap_button (window, spraycan_xpm, _("Noise tool"),
1963 				 style_light_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
1964 				 G_CALLBACK (view_set_tool_cb), NULL, NULL, view);
1965   g_object_set_data (G_OBJECT(button), "default", GINT_TO_POINTER(TOOL_NOISE));
1966   gtk_box_pack_start (GTK_BOX (tool_hbox), button, TRUE, TRUE, 0);
1967   gtk_widget_show (button);
1968   view->tool_buttons = g_list_append (view->tool_buttons, button);
1969 
1970 #endif
1971 
1972   separator = gtk_hseparator_new ();
1973   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 4);
1974   gtk_widget_show (separator);
1975 
1976 
1977   /* ZOOM */
1978 
1979   tool_hbox = gtk_hbox_new (FALSE, 2);
1980   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
1981   gtk_widget_show (tool_hbox);
1982 
1983   gtk_widget_set_style (tool_hbox, style_dark_grey);
1984 
1985 #if 0
1986   /* Zoom all */
1987   button = create_pixmap_button (window, zoom_all_xpm, _("Zoom all"),
1988 				 NULL, VIEW_TOOLBAR_BUTTON, G_CALLBACK (zoom_all_cb),
1989 				 NULL, NULL, view);
1990   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
1991   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
1992   gtk_widget_show (button);
1993 #endif
1994 
1995   /* Zoom in */
1996   button = create_pixmap_button (window, zoom_in_xpm, _("Zoom in"),
1997 				 NULL, VIEW_TOOLBAR_BUTTON, NULL,
1998 				 G_CALLBACK (zoom_in_pressed_cb), G_CALLBACK (repeater_released_cb),
1999 				 view);
2000   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
2001   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2002   gtk_widget_show (button);
2003 
2004   /* Zoom out */
2005   button = create_pixmap_button (window, zoom_out_xpm, _("Zoom out"),
2006 				 NULL, VIEW_TOOLBAR_BUTTON, NULL,
2007 				 G_CALLBACK (zoom_out_pressed_cb), G_CALLBACK (repeater_released_cb),
2008 				 view);
2009   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
2010   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2011   gtk_widget_show (button);
2012 
2013   /* Zoom combo */
2014 
2015   zoom_combo_items = NULL;
2016   zoom_combo_items = g_list_append (zoom_combo_items, "All");
2017   zoom_combo_items = g_list_append (zoom_combo_items, "01:00:00.000");
2018   zoom_combo_items = g_list_append (zoom_combo_items, "00:30:00.000");
2019   zoom_combo_items = g_list_append (zoom_combo_items, "00:05:00.000");
2020   zoom_combo_items = g_list_append (zoom_combo_items, "00:01:00.000");
2021   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:30.000");
2022   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:15.000");
2023   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:05.000");
2024   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:01.000");
2025   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:00.500");
2026   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:00.100");
2027   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:00.010");
2028   zoom_combo_items = g_list_append (zoom_combo_items, "00:00:00.001");
2029 
2030   zoom_combo = gtk_combo_new ();
2031 
2032  /* connect hack_max_combo_width_cb to the theme change signal so zoom_combo is
2033   * kept at an appropriate size regardless of font or theme changes.
2034   *
2035   * replace with gtk_entry_set_width_chars() when GTK+-2.6 is used by mainstream distro's */
2036   g_signal_connect (G_OBJECT(GTK_COMBO(zoom_combo)->entry), "style_set", G_CALLBACK(hack_max_combo_width_cb), NULL);
2037 
2038   gtk_combo_set_popdown_strings (GTK_COMBO(zoom_combo), zoom_combo_items);
2039   gtk_combo_set_value_in_list (GTK_COMBO(zoom_combo), FALSE, TRUE);
2040 
2041   /* unfortunately we can't just edit the zoom value, because the entry
2042    * reports every keystroke as a change, and not the 'enter' key. */
2043   gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO(zoom_combo)->entry), TRUE);
2044 
2045   /*gtk_widget_set_style (GTK_COMBO(zoom_combo)->button, style_dark_grey);*/
2046 
2047   g_signal_connect (G_OBJECT(GTK_COMBO(zoom_combo)->entry), "changed",
2048 		      G_CALLBACK(zoom_combo_changed_cb), view);
2049 
2050   tooltips = gtk_tooltips_new ();
2051   gtk_tooltips_set_tip (tooltips, GTK_COMBO(zoom_combo)->button,
2052 			_("Visible length"), NULL);
2053 
2054   view->zoom_combo = zoom_combo;
2055 
2056   gtk_box_pack_start (GTK_BOX (tool_hbox), view->zoom_combo, FALSE, FALSE, 0);
2057 
2058   gtk_widget_show (zoom_combo);
2059 
2060   button = create_pixmap_button (window, scroll_xpm,
2061 				 _("Autoscroll: follow playback cursor"),
2062 				 NULL, VIEW_TOOLBAR_TOGGLE_BUTTON,
2063 				 G_CALLBACK (follow_toggled_cb),
2064 				 NULL, NULL, view);
2065   gtk_button_set_relief (GTK_BUTTON(button), GTK_RELIEF_NONE);
2066   gtk_widget_set_style (button, style_light_grey);
2067 
2068   gtk_signal_handler_block_by_data (GTK_OBJECT(button), view);
2069   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
2070 				view->following);
2071   g_signal_handlers_unblock_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2072 
2073   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, TRUE, 0);
2074   gtk_widget_show (button);
2075 
2076   view->follow_toggle = button;
2077 
2078 #ifdef DEVEL_CODE
2079   button = gtk_hseparator_new ();
2080   gtk_box_pack_start (GTK_BOX(main_vbox), button, FALSE, TRUE, 0);
2081   gtk_widget_show (button);
2082 
2083   /* notebook */
2084 
2085   notebook = gtk_notebook_new ();
2086   gtk_box_pack_start (GTK_BOX(main_vbox), notebook, TRUE, TRUE, 0);
2087   gtk_widget_show (notebook);
2088 
2089   gtk_widget_set_style (notebook, style_light_grey);
2090 
2091   gtk_container_set_border_width (GTK_CONTAINER(notebook), 0);
2092   if (TRUE) {
2093     gtk_notebook_set_show_tabs (GTK_NOTEBOOK(notebook), TRUE);
2094   }
2095 #endif
2096 
2097   /* main table */
2098 
2099   table = gtk_table_new (3, 3, FALSE);
2100   gtk_table_set_col_spacing (GTK_TABLE(table), 0, 1);
2101   gtk_table_set_col_spacing (GTK_TABLE(table), 1, 2);
2102   gtk_table_set_row_spacing (GTK_TABLE(table), 0, 1);
2103   gtk_table_set_row_spacing (GTK_TABLE(table), 1, 2);
2104   gtk_container_set_border_width (GTK_CONTAINER(table), 2);
2105 #ifdef DEVEL_CODE
2106   label = gtk_label_new (g_basename(sample->pathname));
2107   gtk_notebook_append_page (GTK_NOTEBOOK(notebook), table, label);
2108 #else
2109   gtk_box_pack_start (GTK_BOX(main_vbox), table, TRUE, TRUE, 0);
2110 #endif
2111   gtk_widget_show (table);
2112 
2113   /* menu button */
2114   menu_button = gtk_button_new ();
2115   gtk_table_attach (GTK_TABLE(table), menu_button,
2116 		    0, 1, 0, 1,
2117 		    GTK_FILL, GTK_FILL,
2118 		    0, 0);
2119   gtk_widget_show (menu_button);
2120 
2121 
2122   arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2123   gtk_container_add (GTK_CONTAINER (menu_button), arrow);
2124   gtk_widget_show (arrow);
2125 
2126   /* time_ruler */
2127 
2128   ebox = gtk_event_box_new ();
2129   gtk_table_attach (GTK_TABLE(table), ebox,
2130 		    1, 2, 0, 1,
2131 		    GTK_EXPAND|GTK_FILL|GTK_SHRINK, GTK_FILL,
2132 		    0, 0);
2133   g_signal_connect (G_OBJECT(ebox), "button-press-event",
2134 		      G_CALLBACK(scrub_clicked_cb), view);
2135   g_signal_connect (G_OBJECT(ebox), "motion-notify-event",
2136 		      G_CALLBACK(scrub_motion_cb), view);
2137   g_signal_connect (G_OBJECT(ebox), "button-release-event",
2138 		      G_CALLBACK(scrub_released_cb), view);
2139   gtk_widget_show (ebox);
2140 
2141   time_ruler = time_ruler_new ();
2142   gtk_container_add (GTK_CONTAINER(ebox), time_ruler);
2143   gtk_ruler_set_range (GTK_RULER(time_ruler),
2144 		       start, end,
2145 		       start, end);
2146   time_ruler_set_format (TIME_RULER(time_ruler), sample->sounddata->format);
2147   gtk_widget_show (time_ruler);
2148   view->time_ruler = time_ruler;
2149 /* tmp GTK_<OBJECT>_GET_CLASS (object)  */
2150   g_signal_connect_swapped (GTK_OBJECT (table), "motion_notify_event",
2151                              G_CALLBACK(GTK_WIDGET_GET_CLASS(time_ruler)->motion_notify_event),
2152                              GTK_OBJECT (time_ruler));
2153 
2154   /* db_ruler */
2155 
2156   ebox = gtk_event_box_new ();
2157   gtk_table_attach (GTK_TABLE(table), ebox,
2158 		    0, 1, 1, 2,
2159 		    GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL,
2160 		    0, 0);
2161   g_signal_connect (G_OBJECT(ebox), "button-press-event",
2162 		      G_CALLBACK(vzoom_clicked_cb), view);
2163   g_signal_connect (G_OBJECT(ebox), "motion-notify-event",
2164 		      G_CALLBACK(vzoom_motion_cb), view);
2165   g_signal_connect (G_OBJECT(ebox), "button-release-event",
2166 		     G_CALLBACK(vzoom_released_cb), view);
2167   gtk_widget_show (ebox);
2168 
2169   tooltips = gtk_tooltips_new ();
2170   gtk_tooltips_set_tip (tooltips, ebox,
2171 			_("Vertical zoom [Shift + Arrow Up/Down]"), NULL);
2172 
2173   vbox = gtk_vbox_new (FALSE, 0);
2174   gtk_container_add (GTK_CONTAINER(ebox), vbox);
2175   gtk_widget_show (vbox);
2176   view->db_rulers_vbox = vbox;
2177   view->db_rulers = NULL;
2178 
2179   view_refresh_db_rulers (view);
2180 
2181   /* display */
2182   view->display = sample_display_new();
2183   gtk_table_attach (GTK_TABLE(table), view->display,
2184 		    1, 2, 1, 2,
2185 		    GTK_EXPAND|GTK_FILL|GTK_SHRINK,
2186 		    GTK_EXPAND|GTK_FILL|GTK_SHRINK,
2187 		    0, 0);
2188 
2189   sample_display_set_view(SAMPLE_DISPLAY(view->display), view);
2190 
2191   g_signal_connect (G_OBJECT(view->display), "selection-changed",
2192 		      G_CALLBACK(sd_sel_changed_cb), view);
2193   g_signal_connect (G_OBJECT(view->display), "window-changed",
2194 		      G_CALLBACK(sd_win_changed_cb), view);
2195 
2196   gtk_widget_show(view->display);
2197 
2198   /* rate adjuster */
2199 
2200   rate_vbox = gtk_vbox_new (FALSE, 0);
2201   gtk_table_attach (GTK_TABLE(table), rate_vbox,
2202 		    2, 3, 1, 2,
2203 		    GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL,
2204 		    0, 0);
2205   gtk_widget_show (rate_vbox);
2206 
2207   label = gtk_label_new ("+10%");
2208   gtk_box_pack_start (GTK_BOX(rate_vbox), label, FALSE, FALSE, 0);
2209   gtk_widget_show (label);
2210 
2211 #if 0
2212   rate_adj = gtk_adjustment_new (50.0,   /* value */
2213 				 0.0,    /* lower */
2214 				 100.0,  /* upper */
2215 				 0.001,  /* step incr */
2216 				 0.001,  /* page incr */
2217 				 0.001   /* page size */
2218 				 );
2219 #else
2220   rate_adj = gtk_adjustment_new (0.0,    /* value */
2221 				 -100.0, /* lower */
2222 				 100.0,  /* upper */
2223 				 2.5,    /* step incr */
2224 				 20.0,   /* page incr */
2225 				 0.0     /* page size */
2226 				 );
2227 #endif
2228 
2229   /*  view->rate = 1.0;*/
2230   view->rate_adj = rate_adj;
2231 
2232   rate_vscale = gtk_vscale_new (GTK_ADJUSTMENT(rate_adj));
2233   gtk_box_pack_start (GTK_BOX(rate_vbox), rate_vscale, TRUE, TRUE, 0);
2234   gtk_scale_set_draw_value (GTK_SCALE(rate_vscale), FALSE);
2235   gtk_range_set_update_policy (GTK_RANGE(rate_vscale), GTK_UPDATE_CONTINUOUS);
2236   gtk_widget_show (rate_vscale);
2237 
2238   g_signal_connect (G_OBJECT(rate_adj), "value_changed",
2239 		      G_CALLBACK(view_rate_changed_cb), view);
2240 
2241   label = gtk_label_new ("-10%");
2242   gtk_box_pack_start (GTK_BOX(rate_vbox), label, FALSE, FALSE, 0);
2243   gtk_widget_show (label);
2244 
2245   button = gtk_button_new_with_label ("0%");
2246   gtk_box_pack_start (GTK_BOX(rate_vbox), button, FALSE, FALSE, 0);
2247   gtk_widget_show (button);
2248 
2249   g_signal_connect (G_OBJECT(button), "clicked",
2250 		      G_CALLBACK(view_rate_zeroed_cb), view);
2251 
2252   /* scrollbar */
2253   step = ((gfloat)(end - start)) / 10.0;
2254   if (step < 1.0) step = 1.0;
2255 
2256   view->adj =
2257     gtk_adjustment_new((gfloat)start,            /* value */
2258 		       (gfloat)0.0,              /* start */
2259 		       (gfloat)sample->sounddata->nr_frames, /* end */
2260 		       step,                      /* step_incr */
2261 		       (gfloat)(end-start),      /* page_incr */
2262 		       (gfloat)(end-start)       /* page_size */
2263 		       );
2264 
2265   g_signal_connect (G_OBJECT(view->adj), "value-changed",
2266 		      G_CALLBACK(adj_value_changed_cb), view);
2267   g_signal_connect (G_OBJECT(view->adj), "changed",
2268 		      G_CALLBACK(adj_changed_cb), view);
2269 
2270   scrollbar = gtk_hscrollbar_new(GTK_ADJUSTMENT(view->adj));
2271   gtk_table_attach (GTK_TABLE(table), scrollbar,
2272 		    1, 2, 2, 3,
2273 		    GTK_EXPAND|GTK_FILL|GTK_SHRINK, GTK_FILL,
2274 		    0, 0);
2275   gtk_widget_show(scrollbar);
2276 
2277 
2278   /* playback toolbar */
2279 
2280   handlebox = gtk_handle_box_new ();
2281   gtk_box_pack_start (GTK_BOX (main_vbox), handlebox, FALSE, TRUE, 0);
2282   gtk_widget_show (handlebox);
2283 
2284   gtk_widget_set_style (handlebox, style_light_grey);
2285 
2286   hbox = gtk_hbox_new (FALSE, 8);
2287   gtk_container_add (GTK_CONTAINER (handlebox), hbox);
2288   gtk_widget_show (hbox);
2289 
2290   gtk_widget_set_usize (hbox, -1, 24);
2291 
2292 
2293   /* Record */
2294 
2295   tool_hbox = gtk_hbox_new (TRUE, 0);
2296   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
2297   gtk_widget_show (tool_hbox);
2298 
2299   button
2300     = create_pixmap_button (window, record_dialog_xpm,
2301 			    _("Record ..."),
2302 			    style_red_grey, VIEW_TOOLBAR_BUTTON,
2303 			    G_CALLBACK (show_rec_dialog_cb),
2304 			    NULL, NULL, view);
2305   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2306   gtk_widget_show (button);
2307 
2308   NOALLOC(button);
2309 
2310 #define PLAYPOS_LABEL
2311 #ifdef PLAYPOS_LABEL
2312   frame = gtk_frame_new (NULL);
2313   gtk_widget_set_style (frame, style_light_grey);
2314   gtk_box_pack_start (GTK_BOX(hbox), frame, TRUE, TRUE, 0);
2315   gtk_widget_show (frame);
2316 
2317   lcdbox = gtk_event_box_new ();
2318   gtk_widget_set_style (lcdbox, style_LCD);
2319   gtk_container_add (GTK_CONTAINER(frame), lcdbox);
2320   gtk_widget_show (lcdbox);
2321 
2322   tooltips = gtk_tooltips_new ();
2323   gtk_tooltips_set_tip (tooltips, lcdbox,
2324 			_("Cursor position (indicator)"), NULL);
2325 
2326   tool_hbox = gtk_hbox_new (FALSE, 0);
2327   gtk_container_add (GTK_CONTAINER(lcdbox), tool_hbox);
2328   gtk_widget_show (tool_hbox);
2329 
2330   imagebox = gtk_vbox_new (FALSE, 0);
2331   gtk_box_pack_start (GTK_BOX(tool_hbox), imagebox, FALSE, FALSE, 0);
2332   gtk_widget_show (imagebox);
2333 
2334   pixmap = create_widget_from_xpm (window, upleft_xpm);
2335   gtk_widget_show (pixmap);
2336   gtk_box_pack_start (GTK_BOX(imagebox), pixmap, FALSE, FALSE, 0);
2337 
2338   pixmap = create_widget_from_xpm (window, lowleft_xpm);
2339   gtk_widget_show (pixmap);
2340   gtk_box_pack_end (GTK_BOX(imagebox), pixmap, FALSE, FALSE, 0);
2341 
2342   label = gtk_label_new ("00:00:00.000");
2343   gtk_box_pack_start (GTK_BOX(tool_hbox), label, TRUE, TRUE, 0);
2344   gtk_widget_show (label);
2345   view->play_pos = label;
2346 
2347   imagebox = gtk_vbox_new (FALSE, 0);
2348   gtk_box_pack_start (GTK_BOX(tool_hbox), imagebox, FALSE, FALSE, 0);
2349   gtk_widget_show (imagebox);
2350 
2351   pixmap = create_widget_from_xpm (window, upright_xpm);
2352   gtk_widget_show (pixmap);
2353   gtk_box_pack_start (GTK_BOX(imagebox), pixmap, FALSE, FALSE, 0);
2354 
2355   pixmap = create_widget_from_xpm (window, lowright_xpm);
2356   gtk_widget_show (pixmap);
2357   gtk_box_pack_end (GTK_BOX(imagebox), pixmap, FALSE, FALSE, 0);
2358 
2359 #else
2360   entry = gtk_entry_new ();
2361   gtk_entry_set_text (GTK_ENTRY(entry), "00:00:00.000");
2362   gtk_entry_set_editable (GTK_ENTRY(entry), FALSE);
2363   gtk_widget_set_style (entry, style_LCD);
2364   gtk_box_pack_start (GTK_BOX(hbox), entry, TRUE, TRUE, 0);
2365   gtk_widget_show (entry);
2366   view->play_pos = entry;
2367 #endif
2368 
2369 
2370   tool_hbox = gtk_hbox_new (TRUE, 0);
2371   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
2372   gtk_widget_show (tool_hbox);
2373 
2374   /* Play reverse */
2375 
2376   button = create_pixmap_button (window, playrev_xpm,
2377 				 _("Reverse mode playback (toggle)"),
2378 				 style_green_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
2379 				 G_CALLBACK (playrev_toggled_cb), NULL, NULL, view);
2380 
2381   g_signal_handlers_block_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2382   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
2383 				view->sample->play_head->reverse);
2384   g_signal_handlers_unblock_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2385 
2386   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2387   gtk_widget_show (button);
2388 
2389   view->playrev_toggle = button;
2390 
2391 
2392   /* Loop */
2393 
2394   button = create_pixmap_button (window, loop_xpm,
2395 				 _("Loop mode playback (toggle)"),
2396 				 style_green_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
2397 				 G_CALLBACK (loop_toggled_cb), NULL, NULL, view);
2398 
2399   g_signal_handlers_block_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2400   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
2401 				view->sample->play_head->looping);
2402   g_signal_handlers_unblock_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2403 
2404   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2405   gtk_widget_show (button);
2406 
2407   view->loop_toggle = button;
2408 
2409 
2410   /* Play */
2411 
2412   tool_hbox = gtk_hbox_new (TRUE, 0);
2413   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, TRUE, TRUE, 0);
2414   gtk_widget_show (tool_hbox);
2415 
2416   button
2417     = create_pixmap_button (window, playpaus_xpm,
2418 			    /* _("Play all / Pause    [Ctrl+Space / Enter]"),*/
2419 			    _("Play all / Pause"),
2420 			    style_green_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
2421 			    G_CALLBACK (play_view_button_cb),
2422 			    NULL, NULL, view);
2423 
2424   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2425   gtk_widget_show (button);
2426 
2427   NOALLOC(button);
2428 
2429   view->play_toggle = button;
2430 
2431   /* Play selection */
2432 
2433   button
2434     = create_pixmap_button (window, playpsel_xpm,
2435 			    /*_("Play selection / Pause    [Space / Enter]"),*/
2436 			    _("Play selection / Pause"),
2437 			    style_green_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
2438 			    G_CALLBACK (play_view_sel_button_cb),
2439 			    NULL, NULL, view);
2440   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2441   gtk_widget_show (button);
2442 
2443   NOALLOC(button);
2444 
2445   view->play_sel_toggle = button;
2446 
2447   /* Stop */
2448 
2449   button
2450     = create_pixmap_button (window, stop_xpm,
2451 			    /*_("Stop playback    [Space]"),*/
2452 			    _("Stop playback"),
2453 			    style_green_grey, VIEW_TOOLBAR_BUTTON,
2454 			    G_CALLBACK (stop_playback_cb),
2455 			    NULL, NULL, view);
2456   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2457   gtk_widget_show (button);
2458 
2459   NOALLOC(button);
2460 
2461   /* Beginning */
2462 
2463   tool_hbox = gtk_hbox_new (TRUE, 0);
2464   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, FALSE, TRUE, 0);
2465   gtk_widget_show (tool_hbox);
2466 
2467   button
2468     = create_pixmap_button (window, prevtrk_xpm,
2469 			    _("Go to beginning"),
2470 			    style_green_grey, VIEW_TOOLBAR_BUTTON,
2471 			    G_CALLBACK (goto_start_cb), NULL, NULL, view);
2472   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2473   gtk_widget_show (button);
2474 
2475   NOALLOC(button);
2476 
2477   /* Rewind */
2478 
2479   button
2480     = create_pixmap_button (window, rew_xpm, _("Rewind"),
2481 			    style_green_grey, VIEW_TOOLBAR_BUTTON,
2482 			    NULL,
2483 			    G_CALLBACK (rewind_pressed_cb), G_CALLBACK (repeater_released_cb), view);
2484   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2485   gtk_widget_show (button);
2486 
2487   NOALLOC(button);
2488 
2489   /* Fast forward */
2490 
2491   button
2492     = create_pixmap_button (window, ff_xpm, _("Fast forward"),
2493 			    style_green_grey, VIEW_TOOLBAR_BUTTON,
2494 			    NULL,
2495 			    G_CALLBACK (ffwd_pressed_cb), G_CALLBACK (repeater_released_cb), view);
2496   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2497   gtk_widget_show (button);
2498 
2499   NOALLOC(button);
2500 
2501   /* End */
2502 
2503   button
2504     = create_pixmap_button (window, nexttrk_xpm,
2505 			    _("Go to the end"),
2506 			    style_green_grey, VIEW_TOOLBAR_BUTTON,
2507 			    G_CALLBACK (goto_end_cb), NULL, NULL, view);
2508   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2509   gtk_widget_show (button);
2510 
2511   NOALLOC(button);
2512 
2513   /* gain */
2514 
2515   tool_hbox = gtk_hbox_new (FALSE, 2);
2516   gtk_widget_show (tool_hbox);
2517 
2518   button = create_pixmap_button (window, mute_xpm,
2519 				 _("Muted playback (toggle)"),
2520 				 style_green_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
2521 				 G_CALLBACK (mute_toggled_cb), NULL, NULL, view);
2522 
2523   g_signal_handlers_block_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2524   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
2525 				view->sample->play_head->mute);
2526   g_signal_handlers_unblock_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2527 
2528   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2529   gtk_widget_show (button);
2530 
2531   view->mute_toggle = button;
2532 
2533   pixmap = create_widget_from_xpm (window, vol_xpm);
2534   gtk_box_pack_start (GTK_BOX (tool_hbox), pixmap, FALSE, FALSE, 0);
2535   gtk_widget_show (pixmap);
2536 
2537   tooltips = gtk_tooltips_new ();
2538   gtk_tooltips_set_tip (tooltips, pixmap,
2539 			_("Playback gain slider (volume)"), NULL);
2540 
2541   gain_adj = gtk_adjustment_new (view->sample->play_head->gain*10.0,/* value */
2542 				  0.0,   /* lower */
2543 				  10.0,  /* upper */
2544 				  0.17,  /* step incr */
2545 				  1.6,   /* page incr */
2546 				  0.0    /* page size */
2547 				  );
2548   view->gain_adj = gain_adj;
2549 
2550   gain_hscale = gtk_hscale_new (GTK_ADJUSTMENT(gain_adj));
2551   gtk_scale_set_draw_value (GTK_SCALE(gain_hscale), FALSE);
2552   gtk_range_set_update_policy (GTK_RANGE(gain_hscale), GTK_UPDATE_CONTINUOUS);
2553   gtk_widget_show (gain_hscale);
2554 
2555   tooltips = gtk_tooltips_new ();
2556   gtk_tooltips_set_tip (tooltips, gain_hscale,
2557 			_("Playback gain slider (volume)"), NULL);
2558 
2559   gtk_widget_set_style (gain_hscale, style_green_grey);
2560 
2561   g_signal_connect (G_OBJECT(gain_adj), "value_changed",
2562 		      G_CALLBACK(view_gain_changed_cb), view);
2563 
2564   gtk_box_pack_start (GTK_BOX(tool_hbox), gain_hscale, TRUE, TRUE, 0);
2565 
2566   /* Monitor */
2567 
2568   button = create_pixmap_button (window, headphones_xpm,
2569 				 _("Monitor (toggle)"),
2570 				 style_green_grey, VIEW_TOOLBAR_TOGGLE_BUTTON,
2571 				G_CALLBACK (monitor_toggled_cb), NULL, NULL, view);
2572 
2573   g_signal_handlers_block_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2574   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
2575 				view->sample->play_head->monitor);
2576   g_signal_handlers_unblock_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
2577 
2578   gtk_box_pack_start (GTK_BOX (tool_hbox), button, TRUE, TRUE, 0);
2579   gtk_widget_show (button);
2580 
2581   view->monitor_toggle = button;
2582 
2583   NOALLOC(button);
2584 
2585   /* SYNC */
2586 
2587   button = gtk_button_new_with_label (_("SYNC"));
2588   gtk_widget_set_style (button, style_green_grey);
2589   gtk_box_pack_start (GTK_BOX (tool_hbox), button, FALSE, TRUE, 0);
2590   /*gtk_widget_show (button);*/
2591 
2592   NOALLOC(button);
2593 
2594   gtk_box_pack_start (GTK_BOX (hbox), tool_hbox, TRUE, TRUE, 0);
2595 
2596   /* Status line */
2597 
2598   hbox = gtk_hbox_new (FALSE, 0);
2599 #if 0
2600   gtk_table_attach (GTK_TABLE(table), hbox,
2601 		   0, 3, 3, 4,
2602 		   GTK_FILL|GTK_SHRINK, GTK_FILL,
2603 		   0, 0);
2604 #endif
2605   gtk_box_pack_start (GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);
2606   gtk_widget_show (hbox);
2607 
2608   /* position indicator */
2609   frame = gtk_frame_new (NULL);
2610   gtk_box_pack_start (GTK_BOX(hbox), frame, FALSE, FALSE, 0);
2611   gtk_widget_show (frame);
2612 
2613   tool_hbox = gtk_hbox_new (FALSE, 2);
2614   gtk_container_add (GTK_CONTAINER(frame), tool_hbox);
2615   gtk_widget_show (tool_hbox);
2616 
2617   pixmap = create_widget_from_xpm (window, mouse_xpm);
2618   gtk_box_pack_start (GTK_BOX(tool_hbox), pixmap, FALSE, FALSE, 0);
2619   gtk_widget_show (pixmap);
2620 
2621   label = gtk_label_new (NO_TIME);
2622   gtk_box_pack_start (GTK_BOX(tool_hbox), label, FALSE, FALSE, 0);
2623 
2624  /* connect hack_max_label_width_cb to the theme change signal so label is
2625   * kept at an appropriate size regardless of font or theme changes.
2626   *
2627   * replace with gtk_label_set_width_chars() when GTK+-2.6 is used by mainstream distro's */
2628   g_signal_connect (G_OBJECT(label), "style_set", G_CALLBACK(hack_max_label_width_cb), NULL);
2629 
2630   gtk_widget_show (label);
2631   view->pos = label;
2632 
2633 
2634   /* progress bar */
2635   frame = gtk_frame_new (NULL);
2636   gtk_box_pack_start (GTK_BOX(hbox), frame, TRUE, TRUE, 0);
2637   gtk_widget_show (frame);
2638 
2639   tool_hbox = gtk_hbox_new (FALSE, 2);
2640   gtk_container_add (GTK_CONTAINER(frame), tool_hbox);
2641   gtk_widget_show (tool_hbox);
2642 
2643   progress = gtk_progress_bar_new ();
2644   gtk_box_pack_start (GTK_BOX(tool_hbox), progress, TRUE, TRUE, 0);
2645   gtk_progress_set_show_text (GTK_PROGRESS(progress), TRUE);
2646   gtk_widget_show (progress);
2647 
2648   view->progress = progress;
2649 
2650   button = gtk_button_new_with_label (_("Cancel"));
2651   gtk_box_pack_start (GTK_BOX(tool_hbox), button, FALSE, FALSE, 0);
2652   gtk_widget_show (button);
2653   g_signal_connect (G_OBJECT(button), "clicked",
2654 		      G_CALLBACK(cancel_cb), view);
2655 
2656   NOREADY(button);
2657 
2658   /* status */
2659   frame = gtk_frame_new (NULL);
2660   gtk_box_pack_start (GTK_BOX(hbox), frame, FALSE, TRUE, 0);
2661   gtk_widget_show (frame);
2662 
2663   tool_hbox = gtk_hbox_new (FALSE, 2);
2664   gtk_container_add (GTK_CONTAINER(frame), tool_hbox);
2665   gtk_widget_show (tool_hbox);
2666 
2667   label = gtk_label_new ("Sweep " VERSION);
2668   gtk_box_pack_start (GTK_BOX(tool_hbox), label, FALSE, FALSE, 0);
2669   gtk_widget_show (label);
2670   view->status = label;
2671 
2672   button = gtk_button_new ();
2673   gtk_box_pack_start (GTK_BOX(tool_hbox), button, FALSE, FALSE, 0);
2674   gtk_widget_show (button);
2675   g_signal_connect (G_OBJECT(button), "clicked",
2676 		      G_CALLBACK(show_info_dialog_cb), view);
2677 
2678   pixmap = create_widget_from_xpm (window, info_xpm);
2679   gtk_container_add (GTK_CONTAINER(button), pixmap);
2680   gtk_widget_show (pixmap);
2681 
2682   /* Had to wait until view->display was created before
2683    * setting the menus up
2684    */
2685 
2686   view->menu = gtk_menu_new ();
2687   accel_group = create_view_menu (view, view->menu);
2688   gtk_window_add_accel_group (GTK_WINDOW(view->window), accel_group);
2689 
2690   create_view_menu (view, view->menubar);
2691 
2692   view->menu_sel = create_context_menu_sel (view);
2693   view->menu_point = create_context_menu_point (view);
2694 
2695   g_signal_connect_swapped (G_OBJECT(menu_button),
2696 			     "button_press_event",
2697 			     G_CALLBACK(menu_button_handler),
2698 			     G_OBJECT(view->menu));
2699 
2700   /* Had to wait till view->display was created to set these up */
2701 
2702   g_signal_connect (G_OBJECT(view->display),
2703 		      "mouse-offset-changed",
2704 		      G_CALLBACK(view_set_pos_indicator_cb),
2705 		      view->display);
2706 
2707 #if 0
2708   g_signal_connect_swapped (G_OBJECT(view->display),
2709 			     "motion_notify_event",
2710 			     G_CALLBACK(view_set_pos_indicator_cb),
2711 			     G_OBJECT(view->display));
2712 #endif
2713 
2714   if (sample->sounddata->sels)
2715     sample_display_start_marching_ants (SAMPLE_DISPLAY(view->display));
2716 
2717   view_refresh_title(view);
2718 
2719   view_default_status(view);
2720 
2721   view_refresh_tool_buttons (view);
2722 
2723   view_refresh_edit_mode (view);
2724 
2725   gtk_widget_show(window);
2726 
2727   view_zoom_normal (view);
2728 
2729   return view;
2730 }
2731 
2732 sw_view *
view_new_all(sw_sample * sample,gfloat gain)2733 view_new_all (sw_sample * sample, gfloat gain)
2734 {
2735   return view_new(sample, 0, sample->sounddata->nr_frames, gain);
2736 }
2737 
2738 
2739 void
view_popup_context_menu(sw_view * view,guint button,guint32 activate_time)2740 view_popup_context_menu (sw_view * view, guint button, guint32 activate_time)
2741 {
2742   GtkWidget * menu;
2743 
2744   if (view->sample->sounddata->sels == NULL) {
2745     menu = view->menu_point;
2746   } else {
2747     menu = view->menu_sel;
2748   }
2749 
2750   gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL,
2751 		  button, activate_time);
2752 }
2753 
2754 /*
2755  * view_set_ends (v, start, end)
2756  *
2757  * set the endpoints shown by this view.
2758  */
2759 void
view_set_ends(sw_view * view,sw_framecount_t start,sw_framecount_t end)2760 view_set_ends (sw_view * view, sw_framecount_t start, sw_framecount_t end)
2761 {
2762   GtkAdjustment * adj = GTK_ADJUSTMENT(view->adj);
2763   GtkWidget * entry;
2764   sw_framecount_t orig_length;
2765   sw_time_t length;
2766 #define BUF_LEN 16
2767   gchar buf[BUF_LEN];
2768   gfloat step;
2769 
2770   /* Clamp view to within bounds of sample */
2771   orig_length = end - start;
2772 
2773   if(end > view->sample->sounddata->nr_frames) {
2774     end = view->sample->sounddata->nr_frames;
2775     start = end - orig_length;
2776   }
2777   if(start < 0)
2778     start = 0;
2779 
2780   /* Update duration displayed in zoom combo */
2781   length = frames_to_time (view->sample->sounddata->format, end-start);
2782   snprint_time (buf, BUF_LEN, length);
2783 
2784   entry = GTK_COMBO(view->zoom_combo)->entry;
2785 
2786   g_signal_handlers_block_matched (G_OBJECT(entry), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, view);
2787   gtk_entry_set_text (GTK_ENTRY(entry), buf);
2788   g_signal_handlers_unblock_matched (G_OBJECT(entry), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, view);
2789 
2790   /* This check used to be at at the start of this function, but by
2791    * putting it down here we ensure the zoom combo displays the correct
2792    * length, and not a string like "All". */
2793   if (start == view->start && end == view->end) return;
2794 
2795   /* Update main scrollbar */
2796   step = ((gfloat)(end - start)) / 10.0;
2797   if (step < 1.0) step = 1.0;
2798 
2799   adj->value = (gfloat)start;
2800   adj->step_increment = step;
2801   adj->page_increment = (gfloat)(end - start);
2802   adj->page_size = (gfloat)(end - start);
2803 
2804   gtk_adjustment_changed(adj);
2805 
2806   /* Update ruler */
2807   gtk_ruler_set_range (GTK_RULER(view->time_ruler),
2808 		       start, end,
2809 		       start, end);
2810 
2811   /* Update title etc. */
2812   view_refresh_title(view);
2813   view_refresh_display(view);
2814 
2815 #undef BUF_LEN
2816 }
2817 
2818 void
view_set_vzoom(sw_view * view,sw_audio_t low,sw_audio_t high)2819 view_set_vzoom (sw_view * view, sw_audio_t low, sw_audio_t high)
2820 {
2821   sw_audio_t length;
2822 
2823   length = high - low;
2824 
2825   if (length > 2.0) {
2826     low = -1.0;
2827     high = 1.0;
2828   } else if (low < -1.0) {
2829     low = -1.0;
2830     high = low + length;
2831   } else if (high > 1.0) {
2832     high = 1.0;
2833     low = high - length;
2834   }
2835 
2836   view->vlow = low;
2837   view->vhigh = high;
2838 
2839   view_refresh_db_rulers (view);
2840   view_refresh_display (view);
2841 }
2842 
2843 void
view_vzoom_in(sw_view * view,double ratio)2844 view_vzoom_in (sw_view * view, double ratio)
2845 {
2846   sw_audio_t oz, z;
2847   sw_audio_t nhigh, nlow;
2848 
2849   oz = view->vhigh - view->vlow;
2850   z = (sw_audio_t)((gdouble)oz / ratio);
2851 
2852   nlow = view->vlow + (oz - z)/2;
2853   nhigh = nlow + z;
2854 
2855   view_set_vzoom (view, nlow, nhigh);
2856 }
2857 
2858 void
view_vzoom_out(sw_view * view,double ratio)2859 view_vzoom_out (sw_view * view, double ratio)
2860 {
2861   sw_audio_t oz, z;
2862   sw_audio_t nhigh, nlow;
2863 
2864   oz = view->vhigh - view->vlow;
2865   z = (sw_audio_t)((gdouble)oz * ratio);
2866 
2867   nlow = view->vlow + (oz - z)/2;
2868   nhigh = nlow + z;
2869 
2870   view_set_vzoom (view, nlow, nhigh);
2871 }
2872 
2873 static void
view_clamp_to_offset(sw_view * view,sw_framecount_t * start,sw_framecount_t * end,sw_framecount_t offset)2874 view_clamp_to_offset (sw_view * view, sw_framecount_t * start,
2875 		      sw_framecount_t * end, sw_framecount_t offset)
2876 {
2877   sw_framecount_t length, width, nr_frames;
2878 
2879   length = *end - *start;
2880   width = SAMPLE_DISPLAY(view->display)->width;
2881   nr_frames = view->sample->sounddata->nr_frames;
2882 
2883 #ifdef SCROLL_SMOOTHLY
2884   if (!view->sample->play_head->scrubbing) {
2885 #else
2886   if (offset < *start || offset > *end) {
2887 #endif
2888       if (offset > nr_frames - length/2) {
2889 	*start = nr_frames - length;
2890 	*end = nr_frames;
2891       } else if (offset < length/2) {
2892 	*start = 0;
2893 	*end = length;
2894       } else if (length <= width * 8) {
2895 	*start = offset - length/2;
2896 	*end = *start + length;
2897       } else {
2898 #ifdef SCROLL_SMOOTHLY
2899 	*start = offset - length/2;
2900 	*end = *start + length;
2901 #else
2902 	if (view->sample->play_head->reverse) {
2903 	  *end = offset;
2904 	  *start = *end - length;
2905 	} else {
2906 	  *start = offset;
2907 	  *end = *start + length;
2908 	}
2909 #endif
2910       }
2911     }
2912 }
2913 
2914 void
2915 view_zoom_to_playmarker (sw_view * view)
2916 {
2917   sw_framecount_t start, end;
2918 
2919   g_assert (view->following);
2920 
2921   start = view->start;
2922   end = view->end;
2923 
2924   view_clamp_to_offset (view, &start, &end, view->sample->user_offset);
2925   view_set_ends (view, start, end);
2926 }
2927 
2928 void
2929 view_zoom_to_offset (sw_view * view, sw_framecount_t offset)
2930 {
2931   sw_framecount_t start, end;
2932 
2933   start = view->start;
2934   end = view->end;
2935 
2936   view_clamp_to_offset (view, &start, &end, offset);
2937 
2938   view_set_ends (view, start, end);
2939 }
2940 
2941 void
2942 view_center_on (sw_view * view, sw_framecount_t offset)
2943 {
2944   sw_framecount_t vlen2;
2945 
2946   vlen2 = (view->end - view->start) / 2;
2947 
2948   view_set_ends (view, offset - vlen2, offset + vlen2);
2949 }
2950 
2951 void
2952 view_zoom_normal (sw_view * view)
2953 {
2954   sw_framecount_t length;
2955 
2956   length = MIN (view->sample->sounddata->nr_frames,
2957 		SAMPLE_DISPLAY(view->display)->width * 1024);
2958   view_zoom_length (view, length);
2959   view_center_on (view, view->sample->user_offset);
2960 }
2961 
2962 void
2963 view_zoom_length (sw_view * view, sw_framecount_t length)
2964 {
2965   sw_framecount_t center;
2966 
2967   center = (view->end + view->start) / 2;
2968 
2969   view_set_ends (view, center - length/2, center + length/2);
2970 }
2971 
2972 void
2973 view_zoom_in (sw_view * view, double ratio)
2974 {
2975   sw_framecount_t nstart, nend, nlength, olength, offset, nr_frames;
2976   gboolean do_following;
2977   SampleDisplay * sd = SAMPLE_DISPLAY(view->display);
2978 
2979   olength = view->end - view->start;
2980   nlength = (sw_framecount_t)((double)olength / ratio);
2981 
2982   if(nlength <= DEFAULT_MIN_ZOOM) return;
2983 
2984   offset = view->sample->user_offset;
2985 
2986   /* zoom centred on the play marker if its visible, otherwise on
2987    * the middle of the view */
2988   do_following =
2989     (view->following && offset >= view->start && offset <= view->end);
2990 
2991   if (do_following) {
2992     nr_frames = view->sample->sounddata->nr_frames;
2993 
2994     if (offset >= view->start && offset < view->end) {
2995       nstart = offset - (offset - view->start) / ratio;
2996     } else {
2997       nstart = offset - nlength/2;
2998     }
2999 
3000     if (nstart > nr_frames - nlength) {
3001       nstart = nr_frames - nlength;
3002     } else if (nstart < 0) {
3003       nstart = 0;
3004     }
3005   } else {
3006     nstart = view->start + (olength - nlength)/2;
3007   }
3008 
3009   sample_display_set_cursor(sd, sweep_cursors[SWEEP_CURSOR_ZOOM_IN]);
3010 
3011   nend = nstart+nlength;
3012 
3013   /*
3014   if (view->following) {
3015     view_clamp_to_playmarker (view, &nstart, &nend);
3016   }
3017   */
3018 
3019   view_set_ends(view, nstart, nend);
3020 }
3021 
3022 void
3023 view_zoom_out (sw_view * view, double ratio)
3024 {
3025   sw_framecount_t nstart, nend, nlength, olength, offset, nr_frames;
3026   gboolean do_following;
3027   SampleDisplay * sd = SAMPLE_DISPLAY(view->display);
3028 
3029   olength = view->end - view->start;
3030   nlength = (sw_framecount_t)((double)olength * ratio);
3031 
3032   if (nlength < 0) return; /* sw_framecount_t multiplication overflow */
3033 
3034   offset = view->sample->user_offset;
3035 
3036   /* zoom centred on the play marker if it's visible, otherwise on
3037    * the middle of the view */
3038   do_following =
3039     (view->following && offset >= view->start && offset <= view->end);
3040 
3041   if (do_following) {
3042     nr_frames = view->sample->sounddata->nr_frames;
3043 
3044     if (offset >= view->start && offset < view->end) {
3045       nstart = offset - (offset - view->start) * ratio;
3046     } else {
3047       nstart = offset - nlength/2;
3048     }
3049 
3050     if (nstart > nr_frames - nlength) {
3051       nstart = nr_frames - nlength;
3052     } else if (nstart < 0) {
3053       nstart = 0;
3054     }
3055   } else {
3056     if (nlength > olength) {
3057       nstart = view->start - (nlength - olength)/2;
3058     } else {
3059       nstart = view->start + (olength - nlength)/2;
3060     }
3061   }
3062 
3063   if (nstart == view->start && (nstart+nlength) == view->end)
3064     return;
3065 
3066   sample_display_set_cursor(sd, sweep_cursors[SWEEP_CURSOR_ZOOM_OUT]);
3067 
3068   nend = nstart + nlength;
3069   view_set_ends(view, nstart, nend);
3070 }
3071 
3072 void
3073 view_zoom_to_sel (sw_view * view)
3074 {
3075   GList * gl;
3076   sw_sel * sel;
3077   gint sel_min, sel_max;
3078 
3079   if(!view->sample->sounddata->sels) return;
3080 
3081   gl = view->sample->sounddata->sels;
3082 
3083   sel = (sw_sel *)gl->data;
3084   sel_min = sel->sel_start;
3085 
3086   if (gl->next)
3087     for (gl = gl->next; gl->next; gl = gl->next);
3088 
3089   sel = (sw_sel *)gl->data;
3090   sel_max = sel->sel_end;
3091 
3092   view_set_ends(view, sel_min, sel_max);
3093 }
3094 
3095 void
3096 view_zoom_left (sw_view * view)
3097 {
3098   GtkAdjustment * adj = GTK_ADJUSTMENT(view->adj);
3099 
3100   adj->value -= adj->page_size;
3101   if(adj->value < adj->lower) {
3102     adj->value = adj->lower;
3103   }
3104 
3105   gtk_adjustment_value_changed (GTK_ADJUSTMENT(adj));
3106 }
3107 
3108 void
3109 view_zoom_right (sw_view * view)
3110 {
3111   GtkAdjustment * adj = GTK_ADJUSTMENT(view->adj);
3112 
3113   adj->value += adj->page_size;
3114   if(adj->value > adj->upper) {
3115     adj->value = adj->upper;
3116   }
3117 
3118   gtk_adjustment_value_changed (GTK_ADJUSTMENT(adj));
3119 }
3120 
3121 void
3122 view_zoom_all (sw_view * view)
3123 {
3124   sw_sample * s;
3125 
3126   s = view->sample;
3127 
3128   view_set_ends(view, 0, s->sounddata->nr_frames);
3129 }
3130 
3131 static void
3132 view_store_cb (GtkWidget * widget, gpointer data)
3133 {
3134   sw_view * view = (sw_view *)data;
3135   sw_sample * sample = view->sample;
3136   gint slot;
3137 
3138   slot = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(widget), "default"));
3139   if (slot < 0 || slot > 9) return;
3140 
3141   sample->stored_views[slot].start = view->start;
3142   sample->stored_views[slot].end = view->end;
3143 
3144   sample_set_tmp_message (sample, _("Remembered as area %d"), slot);
3145 }
3146 
3147 static void
3148 view_retrieve_cb (GtkWidget * widget, gpointer data)
3149 {
3150   sw_view * view = (sw_view *)data;
3151   sw_sample * sample = view->sample;
3152   gint slot;
3153   sw_framecount_t start, end;
3154 
3155   slot = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(widget), "default"));
3156   if (slot < 0 || slot > 9) return;
3157 
3158   start = sample->stored_views[slot].start;
3159   end =	sample->stored_views[slot].end;
3160 
3161   if (start == end) {
3162     sample_set_tmp_message (sample, _("No area remembered as %d"), slot);
3163   } else {
3164     view_set_ends (view, start, end);
3165     sample_set_tmp_message (sample, _("Zoomed to area %d"), slot);
3166   }
3167 }
3168 
3169 void
3170 view_refresh_edit_mode (sw_view * view)
3171 {
3172   GList * gl;
3173   GtkWidget * w;
3174 
3175   if (view->sample == NULL) return;
3176 
3177   switch (view->sample->edit_mode) {
3178   case SWEEP_EDIT_MODE_READY:
3179     for (gl = view->noready_widgets; gl; gl = gl->next) {
3180       w = (GtkWidget *)gl->data;
3181       gtk_widget_set_sensitive (w, FALSE);
3182     }
3183     for (gl = view->nomodify_widgets; gl; gl = gl->next) {
3184       w = (GtkWidget *)gl->data;
3185       gtk_widget_set_sensitive (w, TRUE);
3186     }
3187     for (gl = view->noalloc_widgets; gl; gl = gl->next) {
3188       w = (GtkWidget *)gl->data;
3189       gtk_widget_set_sensitive (w, TRUE);
3190     }
3191 
3192     if (view->sample->tmp_message_active) {
3193       view_set_tmp_message (view, view->sample->last_tmp_message);
3194     } else {
3195       view_set_progress_ready (view);
3196     }
3197 
3198     break;
3199   case SWEEP_EDIT_MODE_META:
3200   case SWEEP_EDIT_MODE_FILTER:
3201     for (gl = view->noready_widgets; gl; gl = gl->next) {
3202       w = (GtkWidget *)gl->data;
3203       gtk_widget_set_sensitive (w, TRUE);
3204     }
3205     for (gl = view->nomodify_widgets; gl; gl = gl->next) {
3206       w = (GtkWidget *)gl->data;
3207       gtk_widget_set_sensitive (w, FALSE);
3208     }
3209     for (gl = view->noalloc_widgets; gl; gl = gl->next) {
3210       w = (GtkWidget *)gl->data;
3211       gtk_widget_set_sensitive (w, TRUE);
3212     }
3213     break;
3214   case SWEEP_EDIT_MODE_ALLOC:
3215     for (gl = view->noready_widgets; gl; gl = gl->next) {
3216       w = (GtkWidget *)gl->data;
3217       gtk_widget_set_sensitive (w, TRUE);
3218     }
3219     for (gl = view->nomodify_widgets; gl; gl = gl->next) {
3220       w = (GtkWidget *)gl->data;
3221       gtk_widget_set_sensitive (w, FALSE);
3222     }
3223     for (gl = view->noalloc_widgets; gl; gl = gl->next) {
3224       w = (GtkWidget *)gl->data;
3225       gtk_widget_set_sensitive (w, FALSE);
3226     }
3227     break;
3228   default:
3229     g_assert_not_reached ();
3230     break;
3231   }
3232 }
3233 
3234 void
3235 view_refresh_playmode (sw_view * view)
3236 {
3237   sw_head * head = view->sample->play_head;
3238   gboolean playing, playing_sel;
3239 
3240   g_mutex_lock (head->head_mutex);
3241   playing = head->going && !head->restricted;
3242   playing_sel = head->going && head->restricted;
3243   g_mutex_unlock (head->head_mutex);
3244 
3245   g_signal_handlers_block_matched (GTK_OBJECT(view->play_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3246   gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(view->play_toggle),
3247 			       playing);
3248   g_signal_handlers_unblock_matched (GTK_OBJECT(view->play_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3249 
3250   g_signal_handlers_block_matched (GTK_OBJECT(view->play_sel_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3251   gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(view->play_sel_toggle),
3252 			       playing_sel);
3253   g_signal_handlers_unblock_matched (GTK_OBJECT(view->play_sel_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3254 
3255   /* If we're stopped, don't show the play line any more */
3256   view_refresh_display (view);
3257 
3258   view_refresh_offset_indicators (view);
3259 }
3260 
3261 void
3262 view_refresh_offset_indicators (sw_view * view)
3263 {
3264   SampleDisplay * sd = SAMPLE_DISPLAY(view->display);
3265   sw_sample * sample = view->sample;
3266   sw_framecount_t offset;
3267   static int rate_limit = 0;
3268 
3269 
3270 #define BUF_LEN 16
3271   char buf[BUF_LEN];
3272 
3273   offset = (sample->play_head->going ?
3274 	    (sw_framecount_t)sample->play_head->offset :
3275 	    sample->user_offset);
3276 
3277   snprint_time (buf, BUF_LEN,
3278 		frames_to_time (sample->sounddata->format, offset));
3279 /* cheesy rate limiter. ugly in operation. limits pango damage */
3280 if (rate_limit >= 3) {
3281 	rate_limit=0;
3282 #ifdef PLAYPOS_LABEL
3283   gtk_label_set_text (GTK_LABEL(view->play_pos), buf);
3284 #else
3285   gtk_entry_set_text (GTK_ENTRY(view->play_pos), buf);
3286 #endif
3287 
3288 }
3289 ++rate_limit;
3290 #undef BUF_LEN
3291 
3292   sample_display_refresh_play_marker (sd);
3293   sample_display_refresh_user_marker (sd);
3294 
3295   if (view->following) {
3296     view_zoom_to_offset (view, offset);
3297   }
3298 }
3299 
3300 void
3301 view_refresh_rec_offset_indicators (sw_view * view)
3302 {
3303   SampleDisplay * sd = SAMPLE_DISPLAY(view->display);
3304 
3305   sample_display_refresh_rec_marker (sd);
3306 }
3307 
3308 
3309 /* format string can include %p (current percentage) or %v (current value) */
3310 void
3311 view_set_progress_text (sw_view * view, gchar * text)
3312 {
3313   if (view == NULL) return;
3314 
3315   gtk_progress_set_format_string (GTK_PROGRESS(view->progress), text);
3316 }
3317 
3318 void
3319 view_set_progress_percent (sw_view * view, gint percent)
3320 {
3321   if (view == NULL) return;
3322 
3323   gtk_progress_set_percentage (GTK_PROGRESS(view->progress),
3324 			       (gfloat)percent/100.0);
3325 }
3326 
3327 void
3328 view_set_tmp_message (sw_view * view, gchar * message)
3329 {
3330   if (view == NULL) return;
3331 
3332   gtk_progress_set_format_string (GTK_PROGRESS(view->progress), message);
3333   gtk_progress_set_percentage (GTK_PROGRESS(view->progress), 0.0);
3334 }
3335 
3336 void
3337 view_set_progress_ready (sw_view * view)
3338 {
3339 #define BUF_LEN 64
3340   static gchar buf[BUF_LEN];
3341 
3342   if (view == NULL) return;
3343 
3344   snprintf (buf, BUF_LEN, "%s%s - %s",
3345 	    view->sample->modified ? "*" : "",
3346 	    g_basename (view->sample->pathname),
3347 	    view->sample->play_head->scrubbing ? _("Scrub!") : _("Ready"));
3348 
3349 #if 0
3350   if (view->sample->play_head->scrubbing) {
3351     snprintf (buf, BUF_LEN, "Sweep %s - %s", VERSION, _("Scrub!"));
3352   } else {
3353     snprintf (buf, BUF_LEN, "Sweep %s - %s", VERSION, _("Ready"));
3354   }
3355 #endif
3356 
3357   gtk_progress_set_format_string (GTK_PROGRESS(view->progress), buf);
3358   gtk_progress_set_percentage (GTK_PROGRESS(view->progress), 0.0);
3359 #undef BUF_LEN
3360 }
3361 
3362 void
3363 view_set_following (sw_view * view, gboolean following)
3364 {
3365   view->following = following;
3366 
3367   g_signal_handlers_block_matched (GTK_OBJECT(view->follow_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3368   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->follow_toggle),
3369 				view->following);
3370   g_signal_handlers_unblock_matched (GTK_OBJECT(view->follow_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3371 
3372   g_signal_handlers_block_matched (GTK_OBJECT(view->follow_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3373   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(view->follow_checkmenu),
3374 				  view->following);
3375   g_signal_handlers_unblock_matched (GTK_OBJECT(view->follow_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3376 
3377   if (view->following) {
3378     view_zoom_to_playmarker (view);
3379   }
3380 }
3381 
3382 static void
3383 view_close_ok_cb (GtkWidget * widget, gpointer data)
3384 {
3385   sw_view * view = (sw_view *)data;
3386 
3387   gtk_widget_destroy(view->window);
3388   g_free(view);
3389 }
3390 
3391 void
3392 view_close (sw_view * view)
3393 {
3394   sw_sample * sample = view->sample;
3395 #define BUF_LEN 256
3396   char buf[BUF_LEN];
3397 
3398   if (sample->modified && g_list_length (sample->views) == 1) {
3399     snprintf (buf, BUF_LEN, _("%s has been modified. Close anyway?"),
3400 	      g_basename (sample->pathname));
3401     question_dialog_new (sample, _("File modified"), buf,
3402 			 _("Close"), _("Don't close"),
3403 			 G_CALLBACK (view_close_ok_cb), view, NULL, NULL,
3404 			 SWEEP_EDIT_MODE_ALLOC);
3405   } else {
3406     view_close_ok_cb (NULL, view);
3407   }
3408 }
3409 
3410 void
3411 view_volume_increase (sw_view * view)
3412 {
3413   GtkAdjustment * adj = GTK_ADJUSTMENT(view->gain_adj);
3414 
3415   adj->value += 0.1;
3416   if (adj->value >= 1.0) adj->value = 1.0;
3417 
3418   gtk_adjustment_value_changed (adj);
3419 }
3420 
3421 void
3422 view_volume_decrease (sw_view * view)
3423 {
3424   GtkAdjustment * adj = GTK_ADJUSTMENT(view->gain_adj);
3425 
3426   adj->value -= 0.1;
3427   if (adj->value <= 0.0) adj->value = 0.0;
3428 
3429   gtk_adjustment_value_changed (adj);
3430 }
3431 
3432 void
3433 view_refresh_title (sw_view * view)
3434 {
3435   sw_sample * s = (sw_sample *)view->sample;
3436 
3437 #define BUF_LEN 256
3438   char buf[BUF_LEN];
3439 
3440   if (s->sounddata->nr_frames > 0) {
3441     snprintf(buf, BUF_LEN,
3442 #if 0
3443 	     "%s (%dHz %s) %0d%% - Sweep " VERSION,
3444 	     s->filename ? s->filename : _("Untitled"),
3445 	     s->sounddata->format->rate,
3446 	     s->sounddata->format->channels == 1 ? _("Mono") : _("Stereo"),
3447 #else
3448 	     "%s%s %0d%% - Sweep " VERSION,
3449 	     s->modified ? _("*") : "",
3450 	     s->pathname ? g_basename (s->pathname) : _("Untitled"),
3451 #endif
3452 	     s->progress_percent);
3453   } else {
3454     snprintf(buf, BUF_LEN,
3455 #if 0
3456 	     "%s (%dHz %s) %s - Sweep " VERSION,
3457 	     s->filename ? s->filename : _("Untitled"),
3458 	     s->sounddata->format->rate,
3459 	     s->sounddata->format->channels == 1 ? _("Mono") : _("Stereo"),
3460 #else
3461 	     "%s%s %s - Sweep " VERSION,
3462 	     s->modified ? _("*") : "",
3463 	     s->pathname ? g_basename (s->pathname) : _("Untitled"),
3464 #endif
3465 	     _("Empty"));
3466   }
3467 
3468   gtk_window_set_title (GTK_WINDOW(view->window), buf);
3469 #undef BUF_LEN
3470 }
3471 
3472 void
3473 view_default_status (sw_view * view)
3474 {
3475   sw_sample * s = (sw_sample *)view->sample;
3476   sw_sounddata * sounddata = s->sounddata;
3477 
3478 #define BYTE_BUF_LEN 16
3479   char byte_buf[BYTE_BUF_LEN];
3480 
3481 #define TIME_BUF_LEN 16
3482   char time_buf[TIME_BUF_LEN];
3483 
3484 #define CHAN_BUF_LEN 16
3485   char chan_buf[CHAN_BUF_LEN];
3486 
3487 #define BUF_LEN 256
3488   char buf [BUF_LEN];
3489 
3490   snprint_bytes (byte_buf, BYTE_BUF_LEN,
3491 		 frames_to_bytes (sounddata->format, sounddata->nr_frames));
3492 
3493   snprint_time (time_buf, TIME_BUF_LEN,
3494 		frames_to_time (sounddata->format, sounddata->nr_frames));
3495 
3496   switch (s->sounddata->format->channels) {
3497   case 1:
3498     snprintf (chan_buf, CHAN_BUF_LEN, _("Mono"));
3499     break;
3500   case 2:
3501     snprintf (chan_buf, CHAN_BUF_LEN, _("Stereo"));
3502     break;
3503   default:
3504     snprintf (chan_buf, CHAN_BUF_LEN, "%d %s", s->sounddata->format->channels,
3505 	      _("channels"));
3506     break;
3507   }
3508 
3509   snprintf (buf, BUF_LEN,
3510 	    "%dHz %s [%s]",
3511 	    s->sounddata->format->rate,
3512 	    chan_buf, time_buf);
3513 
3514   gtk_label_set_text (GTK_LABEL(view->status), buf);
3515 
3516 #undef BUF_LEN
3517 #undef BYTE_BUF_LEN
3518 #undef TIME_BUF_LEN
3519 }
3520 
3521 void
3522 view_refresh_tool_buttons (sw_view * v)
3523 {
3524   GList * gl;
3525   GtkWidget * button;
3526   sw_tool_t tool;
3527 
3528   for (gl = v->tool_buttons; gl; gl = gl->next) {
3529     button = (GtkWidget *)gl->data;
3530     tool = (sw_tool_t) g_object_get_data (G_OBJECT(button), "default");
3531 
3532     g_signal_handlers_block_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v);
3533     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button),
3534 				  (tool == v->current_tool));
3535     g_signal_handlers_unblock_matched (GTK_OBJECT(button), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v);
3536   }
3537 }
3538 
3539 void
3540 view_refresh_hruler (sw_view * v)
3541 {
3542   gtk_ruler_set_range (GTK_RULER(v->time_ruler),
3543 		       v->start, v->end,
3544 		       v->start, v->end);
3545   time_ruler_set_format (TIME_RULER(v->time_ruler),
3546 			 v->sample->sounddata->format);
3547 }
3548 
3549 void
3550 view_refresh_display (sw_view * v)
3551 {
3552   SampleDisplay * sd = SAMPLE_DISPLAY(v->display);
3553 
3554   sample_display_refresh(sd);
3555 }
3556 
3557 void
3558 view_refresh_adjustment (sw_view * v)
3559 {
3560   GtkAdjustment * adj = GTK_ADJUSTMENT(v->adj);
3561   gboolean changed = FALSE;
3562 
3563   adj->upper = (gfloat)v->sample->sounddata->nr_frames;
3564   if (adj->page_size > (gfloat)v->sample->sounddata->nr_frames) {
3565     adj->page_size = (gfloat)v->sample->sounddata->nr_frames;
3566     adj->value = 0;
3567     changed = TRUE;
3568   }
3569 
3570   if (adj->value > adj->upper - adj->page_size) {
3571     adj->value = adj->upper - adj->page_size;
3572     changed = TRUE;
3573   }
3574 
3575 #if 0
3576   if (adj->page_size > adj->upper - adj->value)
3577     adj->page_size = adj->upper - adj->value;
3578 #endif
3579 
3580 #if 0
3581   if (v->end > v->sample->sounddata->nr_frames)
3582     v->end = v->sample->sounddata->nr_frames;
3583 #endif
3584 
3585   if (adj->page_increment == 0) {
3586     adj->page_increment = (gfloat)(v->end - v->start);
3587     changed = TRUE;
3588   }
3589 
3590   if (adj->page_size == 0) {
3591     adj->page_size = (gfloat)(v->end - v->start);
3592     changed = TRUE;
3593   }
3594 
3595   if (changed)
3596     gtk_adjustment_changed (adj);
3597 }
3598 
3599 void
3600 view_refresh_looping (sw_view * view)
3601 {
3602   g_signal_handlers_block_matched (GTK_OBJECT(view->loop_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3603   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->loop_toggle),
3604 				view->sample->play_head->looping);
3605   g_signal_handlers_unblock_matched (GTK_OBJECT(view->loop_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3606 
3607   g_signal_handlers_block_matched (GTK_OBJECT(view->loop_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3608   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(view->loop_checkmenu),
3609 				  view->sample->play_head->looping);
3610   g_signal_handlers_unblock_matched (GTK_OBJECT(view->loop_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3611 }
3612 
3613 void
3614 view_refresh_playrev (sw_view * view)
3615 {
3616   g_signal_handlers_block_matched (GTK_OBJECT(view->playrev_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3617   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->playrev_toggle),
3618 				view->sample->play_head->reverse);
3619   g_signal_handlers_unblock_matched (GTK_OBJECT(view->playrev_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3620 
3621   g_signal_handlers_block_matched (GTK_OBJECT(view->playrev_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3622   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(view->playrev_checkmenu),
3623 				  view->sample->play_head->reverse);
3624   g_signal_handlers_unblock_matched (GTK_OBJECT(view->playrev_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3625 }
3626 
3627 void
3628 view_refresh_mute (sw_view * view)
3629 {
3630   g_signal_handlers_block_matched (GTK_OBJECT(view->mute_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3631   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->mute_toggle),
3632 				view->sample->play_head->mute);
3633   g_signal_handlers_unblock_matched (GTK_OBJECT(view->mute_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3634 
3635   g_signal_handlers_block_matched (GTK_OBJECT(view->mute_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3636   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(view->mute_checkmenu),
3637 				  view->sample->play_head->mute);
3638   g_signal_handlers_unblock_matched (GTK_OBJECT(view->mute_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3639 }
3640 
3641 void
3642 view_refresh_monitor (sw_view * view)
3643 {
3644   g_signal_handlers_block_matched (GTK_OBJECT(view->monitor_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3645   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->monitor_toggle),
3646 				view->sample->play_head->monitor);
3647   g_signal_handlers_unblock_matched (GTK_OBJECT(view->monitor_toggle), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3648 
3649   g_signal_handlers_block_matched (GTK_OBJECT(view->monitor_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3650   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(view->monitor_checkmenu),
3651 				  view->sample->play_head->monitor);
3652   g_signal_handlers_unblock_matched (GTK_OBJECT(view->monitor_checkmenu), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, view);
3653 }
3654 
3655 void
3656 view_fix_adjustment (sw_view * v)
3657 {
3658   GtkAdjustment * adj = GTK_ADJUSTMENT(v->adj);
3659 
3660   adj->value = (gfloat)v->start;
3661   adj->lower = (gfloat)0.0;
3662   adj->upper = (gfloat)v->sample->sounddata->nr_frames;
3663   adj->page_increment = (gfloat)(v->end - v->start);
3664   adj->page_size = (gfloat)(v->end - v->start);
3665 
3666   gtk_adjustment_changed (adj);
3667 }
3668 
3669 void
3670 view_refresh (sw_view * v)
3671 {
3672   view_refresh_adjustment (v);
3673   view_refresh_title (v);
3674   view_default_status (v);
3675 
3676   view_refresh_display (v);
3677   view_refresh_offset_indicators (v);
3678   view_refresh_tool_buttons (v);
3679   view_refresh_looping (v);
3680   view_refresh_playrev (v);
3681 
3682   view_refresh_channelops_menu (v);
3683   view_refresh_db_rulers (v);
3684 }
3685 
3686 void
3687 view_sink_last_tmp_view (void)
3688 {
3689   if (!last_tmp_view) return;
3690 
3691   sample_display_sink_tmp_sel(SAMPLE_DISPLAY(last_tmp_view->display));
3692 }
3693 
3694 void
3695 view_clear_last_tmp_view (void)
3696 {
3697   if (!last_tmp_view) return;
3698 
3699   sample_display_clear_sel(SAMPLE_DISPLAY(last_tmp_view->display));
3700 }
3701