1 /*
2  * Copyright (C) 2003 2004 2006 2011, Magnus Hjorth
3  *
4  * This file is part of mhWaveEdit.
5  *
6  * mhWaveEdit 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  * mhWaveEdit 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 mhWaveEdit; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 
22 #include <config.h>
23 #include <gdk/gdkkeysyms.h>
24 
25 #include "gotodialog.h"
26 #include "inifile.h"
27 #include "main.h"
28 #include "gettext.h"
29 
goto_dialog_apply(GotoDialog * gd)30 static gboolean goto_dialog_apply(GotoDialog *gd)
31 {
32      off_t p=0,q;
33      float f;
34      Document *d = gd->mw->doc;
35      int i, j;
36      if (d == NULL) return FALSE;
37      if (floatbox_check(gd->offset)) return TRUE;
38      for (i=0; i<5; i++)
39 	  if (gtk_toggle_button_get_active(gd->relbuttons[i]))
40 	       break;
41      switch (i) {
42      case GOTO_DIALOG_POS_AFTER_BEG_FILE:
43       p = 0;
44       break;
45      case GOTO_DIALOG_POS_AFTER_END_FILE:
46       p = d->chunk->length;
47       break;
48      case GOTO_DIALOG_POS_AFTER_CURSOR:
49       p = d->cursorpos;
50       break;
51      case GOTO_DIALOG_POS_AFTER_BEG_SEL:
52       p = (d->selstart==d->selend)?0:d->selstart;
53       break;
54      case GOTO_DIALOG_POS_AFTER_END_SEL:
55 	  p = (d->selstart==d->selend)?d->chunk->length:d->selend;
56 	  break;
57      default:
58       g_assert_not_reached();
59      }
60 
61      for (j=0; j<2; j++)
62           if (gtk_toggle_button_get_active(gd->unitbuttons[j]))
63                break;
64      f = gd->offset->val;
65      if (j == GOTO_DIALOG_UNIT_SECONDS)
66           f *= ((float)(d->chunk->format.samplerate));
67      q = p+(off_t)f;
68 
69      if(q > d->chunk->length) {
70           q = d->chunk->length;
71      } else if(q < 0) {
72           q = 0;
73      }
74 
75      document_set_cursor(d,q);
76 
77      inifile_set_gfloat("gotoOffset",gd->offset->val);
78      inifile_set_guint32("gotoRel",i);
79      inifile_set_guint32("gotoUnits",j);
80      return FALSE;
81 }
82 
goto_dialog_ok(GtkButton * button,GotoDialog * gd)83 static void goto_dialog_ok(GtkButton *button, GotoDialog *gd)
84 {
85      if (!goto_dialog_apply(gd))
86 	  gtk_widget_destroy(GTK_WIDGET(gd));
87 }
88 
goto_dialog_init(GotoDialog * gd)89 static void goto_dialog_init(GotoDialog *gd)
90 {
91      GtkWidget *a,*b,*c;
92      guint32 i;
93      GtkAccelGroup* ag;
94 
95      ag = gtk_accel_group_new();
96 
97      a = gtk_vbox_new(FALSE,0);
98      gtk_container_set_border_width(GTK_CONTAINER(a),8);
99      gtk_container_add(GTK_CONTAINER(gd),a);
100      b = gtk_hbox_new(FALSE,5);
101      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,3);
102      c = gtk_label_new(_("Place cursor "));
103      gtk_box_pack_start(GTK_BOX(b),c,FALSE,FALSE,0);
104      c = floatbox_new(inifile_get_gfloat("gotoOffset",0.0));
105      gd->offset = FLOATBOX(c);
106      gtk_box_pack_start(GTK_BOX(b),c,FALSE,FALSE,0);
107      c = gtk_radio_button_new_with_label(NULL, _("seconds"));
108      gd->unitbuttons[GOTO_DIALOG_UNIT_SECONDS] = GTK_TOGGLE_BUTTON(c);
109      gtk_box_pack_start(GTK_BOX(b),c,FALSE,FALSE,0);
110      c = gtk_radio_button_new_with_label_from_widget(
111           GTK_RADIO_BUTTON(c), _("samples"));
112      gd->unitbuttons[GOTO_DIALOG_UNIT_SAMPLES] = GTK_TOGGLE_BUTTON(c);
113      gtk_box_pack_start(GTK_BOX(b),c,FALSE,FALSE,0);
114 
115      b = gtk_radio_button_new_with_label(NULL,_("after beginning of file"));
116      gd->relbuttons[GOTO_DIALOG_POS_AFTER_BEG_FILE] = GTK_TOGGLE_BUTTON(b);
117      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
118 
119      b = gtk_radio_button_new_with_label_from_widget(
120 	  GTK_RADIO_BUTTON(b),_("after end of file"));
121      gd->relbuttons[GOTO_DIALOG_POS_AFTER_END_FILE] = GTK_TOGGLE_BUTTON(b);
122      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
123 
124      b = gtk_radio_button_new_with_label_from_widget(
125 	  GTK_RADIO_BUTTON(b),_("after current cursor position"));
126      gd->relbuttons[GOTO_DIALOG_POS_AFTER_CURSOR] = GTK_TOGGLE_BUTTON(b);
127      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
128 
129      b = gtk_radio_button_new_with_label_from_widget(
130 	  GTK_RADIO_BUTTON(b),_("after selection start"));
131      gd->relbuttons[GOTO_DIALOG_POS_AFTER_BEG_SEL] = GTK_TOGGLE_BUTTON(b);
132      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
133 
134      b = gtk_radio_button_new_with_label_from_widget(
135 	  GTK_RADIO_BUTTON(b),_("after selection end"));
136      gd->relbuttons[GOTO_DIALOG_POS_AFTER_END_SEL] = GTK_TOGGLE_BUTTON(b);
137      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
138 
139      b = gtk_label_new(_("(use a negative number to place the cursor before "
140 		       "instead of after the selected point)"));
141      gtk_label_set_justify(GTK_LABEL(b),GTK_JUSTIFY_LEFT);
142      gtk_label_set_line_wrap(GTK_LABEL(b),TRUE);
143      gtk_box_pack_start(GTK_BOX(a),b,FALSE,FALSE,0);
144      b = gtk_hbutton_box_new();
145      gtk_box_pack_end(GTK_BOX(a),b,FALSE,FALSE,0);
146      c = gtk_button_new_with_label(_("OK"));
147      gtk_signal_connect(GTK_OBJECT(c),"clicked",
148 			GTK_SIGNAL_FUNC(goto_dialog_ok),gd);
149      gtk_container_add(GTK_CONTAINER(b),c);
150      gtk_widget_add_accelerator (c, "clicked", ag, GDK_KP_Enter, 0,
151 				 (GtkAccelFlags) 0);
152      gtk_widget_add_accelerator (c, "clicked", ag, GDK_Return, 0,
153 				 (GtkAccelFlags) 0);
154      c = gtk_button_new_with_label(_("Apply"));
155      gtk_signal_connect_object(GTK_OBJECT(c),"clicked",
156 			       GTK_SIGNAL_FUNC(goto_dialog_apply),
157 			       GTK_OBJECT(gd));
158      gtk_container_add(GTK_CONTAINER(b),c);
159      c = gtk_button_new_with_label(_("Close"));
160      gtk_signal_connect_object(GTK_OBJECT(c),"clicked",
161 			       GTK_SIGNAL_FUNC(gtk_widget_destroy),
162 			       GTK_OBJECT(gd));
163      gtk_container_add(GTK_CONTAINER(b),c);
164      gtk_widget_add_accelerator (c, "clicked", ag, GDK_Escape, 0,
165 				 (GtkAccelFlags) 0);
166      b = gtk_hseparator_new();
167      gtk_box_pack_end(GTK_BOX(a),b,FALSE,FALSE,0);
168 
169      i = inifile_get_guint32("gotoRel",0);
170      if (i>4) i=0;
171      gtk_toggle_button_set_active(gd->relbuttons[i],TRUE);
172 
173      i = inifile_get_guint32("gotoUnits",0);
174      if (i>2) i=0;
175      gtk_toggle_button_set_active(gd->unitbuttons[i],TRUE);
176 
177      gtk_widget_show_all(a);
178      gtk_window_set_title(GTK_WINDOW(gd),_("Position cursor"));
179      gtk_window_add_accel_group(GTK_WINDOW (gd), ag);
180      gtk_window_set_position (GTK_WINDOW (gd), GTK_WIN_POS_CENTER);
181 }
182 
goto_dialog_class_init(GtkObjectClass * klass)183 static void goto_dialog_class_init(GtkObjectClass *klass)
184 {
185 }
186 
goto_dialog_get_type(void)187 GtkType goto_dialog_get_type(void)
188 {
189      static GtkType id = 0;
190      if (!id) {
191 	  GtkTypeInfo info = {
192 	       "GotoDialog",
193 	       sizeof(GotoDialog),
194 	       sizeof(GotoDialogClass),
195 	       (GtkClassInitFunc) goto_dialog_class_init,
196 	       (GtkObjectInitFunc) goto_dialog_init
197 	  };
198 	  id = gtk_type_unique(gtk_window_get_type(),&info);
199      }
200      return id;
201 }
202 
goto_dialog_new(Mainwindow * mw)203 GtkWidget *goto_dialog_new(Mainwindow *mw)
204 {
205      GtkWidget *w;
206      w = gtk_type_new(goto_dialog_get_type());
207      GOTO_DIALOG(w)->mw = mw;
208      return w;
209 }
210