root/sweep/trunk/src/view.c

Revision 701, 108.3 kB (checked in by erikd, 2 years ago)

Replace deprecated gtk_timeout_add/remove functions with their replacements.

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