1 /*
2  * Copyright (C) 2002 2003 2004 2005 2009, 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 #include <config.h>
22 
23 
24 #include "documentlist.h"
25 
26 static GtkObjectClass *parent_class;
27 enum { CHANGED_SIGNAL, LAST_SIGNAL };
28 static guint document_list_signals[LAST_SIGNAL] = { 0 };
29 static gboolean updating = FALSE;
30 
document_list_changed(Combo * combo)31 static void document_list_changed(Combo *combo)
32 {
33      Document *d=NULL;
34      DocumentList *dl = DOCUMENT_LIST(combo);
35 
36      if (updating) return;
37      d = DOCUMENT(list_object_get(document_objects,
38 				  combo_selected_index(combo)));
39      if (d != dl->selected) {
40 	  dl->selected = d;
41 	  memcpy(&(dl->format),&(d->chunk->format),sizeof(Dataformat));
42 	  gtk_signal_emit(GTK_OBJECT(dl),
43 			  document_list_signals[CHANGED_SIGNAL]);
44      }
45 
46      if (COMBO_CLASS(parent_class)->selection_changed)
47 	  COMBO_CLASS(parent_class)->selection_changed(combo);
48 }
49 
document_list_addnotify(ListObject * lo,gpointer item,gpointer user_data)50 static void document_list_addnotify(ListObject *lo, gpointer item,
51 				      gpointer user_data)
52 {
53      Document *d = DOCUMENT(item);
54      DocumentList *dl = DOCUMENT_LIST(user_data);
55      if (dl->selected == NULL) {
56 	  dl->selected=d;
57 	  gtk_widget_set_sensitive(GTK_WIDGET(dl),TRUE);
58      }
59      document_list_setup(dl,dl->selected);
60      if (d == dl->selected) {
61 	  gtk_signal_emit(GTK_OBJECT(dl),
62 			  document_list_signals[CHANGED_SIGNAL]);
63      }
64 }
65 
document_list_remove(ListObject * lo,gpointer item,gpointer user_data)66 static void document_list_remove(ListObject *lo, gpointer item,
67 				   gpointer user_data)
68 {
69      Document *w = DOCUMENT(item);
70      DocumentList *mwl = DOCUMENT_LIST(user_data);
71      if (w == mwl->selected) {
72 	  if (list_object_get_size(document_objects) == 0) {
73 	       /* We set the selected item to NULL and dim the widget, but
74 		* no signal is sent out. */
75 	       mwl->selected = NULL;
76 	       gtk_widget_set_sensitive(GTK_WIDGET(mwl),FALSE);
77 	       return;
78 	  }
79 	  mwl->selected = DOCUMENT(list_object_get(document_objects,0));
80 	  document_list_setup(mwl,mwl->selected);
81 	  gtk_signal_emit(GTK_OBJECT(mwl),
82 			  document_list_signals[CHANGED_SIGNAL]);
83      } else
84 	  document_list_setup(mwl,mwl->selected);
85 
86 }
87 
document_list_init(GtkObject * obj)88 static void document_list_init(GtkObject *obj)
89 {
90      DocumentList *mwl = DOCUMENT_LIST(obj);
91      /* Most initialization is done in document_list_setup */
92      combo_set_max_request_width(COMBO(obj),350);
93      mwl->selected = NULL;
94      gtk_signal_connect_while_alive(GTK_OBJECT(document_objects),
95 				    "item_added",
96 				    GTK_SIGNAL_FUNC(document_list_addnotify),
97 				    obj,obj);
98      gtk_signal_connect_while_alive(GTK_OBJECT(document_objects),
99 				    "item_removed",
100 				    GTK_SIGNAL_FUNC(document_list_remove),
101 				    obj,obj);
102      gtk_signal_connect_while_alive(GTK_OBJECT(document_objects),
103 				    "item_notify",
104 				    GTK_SIGNAL_FUNC(document_list_addnotify),
105 				    obj,obj);
106 }
107 
document_list_class_init(GtkObjectClass * klass)108 static void document_list_class_init(GtkObjectClass *klass)
109 {
110      DocumentListClass *mwlc = DOCUMENT_LIST_CLASS(klass);
111      parent_class = gtk_type_class(combo_get_type());
112      mwlc->document_changed = NULL;
113      COMBO_CLASS(klass)->selection_changed = document_list_changed;
114 
115      document_list_signals[CHANGED_SIGNAL] =
116 	  gtk_signal_new( "document_changed", GTK_RUN_FIRST,
117 			  GTK_CLASS_TYPE(klass),
118 			  GTK_SIGNAL_OFFSET(DocumentListClass,
119 					    document_changed),
120 			  gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
121      gtk_object_class_add_signals(klass,document_list_signals,LAST_SIGNAL);
122 }
123 
document_list_get_type(void)124 GtkType document_list_get_type(void)
125 {
126      static GtkType id=0;
127      if (!id) {
128 	  GtkTypeInfo info = {
129 	       "DocumentList",
130 	       sizeof(DocumentList),
131 	       sizeof(DocumentListClass),
132 	       (GtkClassInitFunc)document_list_class_init,
133 	       (GtkObjectInitFunc)document_list_init
134 	  };
135 	  id = gtk_type_unique( combo_get_type(), &info );
136      }
137      return id;
138 }
139 
document_list_new(Document * chosen)140 GtkWidget *document_list_new(Document *chosen)
141 {
142      GtkWidget *widget;
143      widget = GTK_WIDGET(gtk_type_new(document_list_get_type()));
144      document_list_setup(DOCUMENT_LIST(widget),chosen);
145      return widget;
146 }
147 
148 struct setup_func_data {
149      GList *lp;
150      Document *first;
151 };
152 
document_list_setup_func(gpointer item,gpointer user_data)153 static void document_list_setup_func(gpointer item, gpointer user_data)
154 {
155      struct setup_func_data *sfdp = (struct setup_func_data *)user_data;
156      Document *w = DOCUMENT(item);
157      if (w->titlename != NULL) {
158 	  sfdp->lp = g_list_append(sfdp->lp, w->titlename);
159 	  if (sfdp->first == NULL) sfdp->first = w;
160      }
161 }
162 
document_list_setup(DocumentList * mwl,Document * chosen)163 void document_list_setup(DocumentList *mwl, Document *chosen)
164 {
165      gint i;
166      struct setup_func_data sfd;
167      updating = TRUE;
168 
169      sfd.lp = NULL;
170      sfd.first = NULL;
171      list_object_foreach(document_objects,document_list_setup_func,&sfd);
172      combo_set_items(COMBO(mwl),sfd.lp,0);
173 
174      if (chosen == NULL)
175 	  chosen = sfd.first;
176 
177      if (chosen) {
178 	  i = g_list_index(sfd.lp,chosen->titlename);
179 	  g_assert(i >= 0);
180 	  combo_set_selection(COMBO(mwl),i);
181 	  memcpy(&(mwl->format),&(chosen->chunk->format),
182 		 sizeof(Dataformat));
183 	  mwl->selected = chosen;
184      }
185      g_list_free(sfd.lp);
186      updating = FALSE;
187 }
188