~ubuntu-branches/ubuntu/wily/gnome-applets/wily

« back to all changes in this revision

Viewing changes to mixer/preferences.c

  • Committer: Package Import Robot
  • Author(s): Dmitry Shachnev
  • Date: 2014-11-19 19:57:51 UTC
  • mfrom: (1.10.22)
  • Revision ID: package-import@ubuntu.com-20141119195751-gqirgm99dewik39n
Tags: 3.14.0-1~svn1
* New upstream release.
* Update (build-)dependencies for new version.
  - Require new GLib and libpanel-applet.
  - Switch from Python 2 to Python 3.
  - Drop GConf.
* Remove --enable-mixer-applet configure flag.
* Remove obsolete gnome-applets.gconf-defaults file.
* Update applet list in package description.
* Move Python modules to a private location.
* Use dh_python3.
* Use NEWS file as upstream changelog.
* Bump Standards-Version to 3.9.6, no changes needed.
* Update Homepage URL.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GNOME Volume Applet
2
 
 * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
3
 
 *
4
 
 * preferences.c: preferences screen
5
 
 *
6
 
 * This library is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU Library General Public
8
 
 * License as published by the Free Software Foundation; either
9
 
 * version 2 of the License, or (at your option) any later version.
10
 
 *
11
 
 * This library 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 GNU
14
 
 * Library General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU Library General Public
17
 
 * License along with this library; if not, write to the
18
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
 
 * Boston, MA 02111-1307, USA.
20
 
 */
21
 
 
22
 
#ifdef HAVE_CONFIG_H
23
 
#include "config.h"
24
 
#endif
25
 
 
26
 
#include <string.h>
27
 
 
28
 
#include <glib/gi18n.h>
29
 
#include <glib.h>
30
 
 
31
 
#include <gtk/gtk.h>
32
 
 
33
 
#include <gst/interfaces/mixer.h>
34
 
 
35
 
#include "applet.h"
36
 
#include "preferences.h"
37
 
#include "keys.h"
38
 
 
39
 
enum {
40
 
  COL_LABEL,
41
 
  COL_TRACK,
42
 
  NUM_COLS
43
 
};
44
 
 
45
 
static void     gnome_volume_applet_preferences_class_init      (GnomeVolumeAppletPreferencesClass *klass);
46
 
static void     gnome_volume_applet_preferences_init    (GnomeVolumeAppletPreferences *prefs);
47
 
static void     gnome_volume_applet_preferences_dispose (GObject *object);
48
 
static void     gnome_volume_applet_preferences_response (GtkDialog *dialog,
49
 
                                                          gint       response_id);
50
 
 
51
 
static void     cb_dev_selected                         (GtkComboBox *box,
52
 
                                                         gpointer    data);
53
 
 
54
 
static gboolean cb_track_select                         (GtkTreeSelection *selection,
55
 
                                                         GtkTreeModel     *model,
56
 
                                                         GtkTreePath      *path,
57
 
                                                         gboolean          path_selected,
58
 
                                                         gpointer          data);
59
 
 
60
 
static GtkDialogClass *parent_class = NULL;
61
 
 
62
 
G_DEFINE_TYPE (GnomeVolumeAppletPreferences, gnome_volume_applet_preferences, GTK_TYPE_DIALOG)
63
 
 
64
 
static void
65
 
gnome_volume_applet_preferences_class_init (GnomeVolumeAppletPreferencesClass *klass)
66
 
{
67
 
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
68
 
  GtkDialogClass *gtkdialog_class = (GtkDialogClass *) klass;
69
 
 
70
 
  parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
71
 
 
72
 
  gobject_class->dispose = gnome_volume_applet_preferences_dispose;
73
 
  gtkdialog_class->response = gnome_volume_applet_preferences_response;
74
 
}
75
 
 
76
 
static void
77
 
gnome_volume_applet_preferences_init (GnomeVolumeAppletPreferences *prefs)
78
 
{
79
 
  GtkWidget *box, *label, *view;
80
 
  GtkListStore *store;
81
 
  GtkTreeSelection *sel;
82
 
  GtkTreeViewColumn *col;
83
 
  GtkCellRenderer *render;
84
 
  GList *cells;
85
 
 
86
 
  prefs->applet = NULL;
87
 
  prefs->mixer = NULL;
88
 
 
89
 
  /* make window look cute */
90
 
  gtk_window_set_title (GTK_WINDOW (prefs), _("Volume Control Preferences"));
91
 
  gtk_container_set_border_width (GTK_CONTAINER (prefs), 5);
92
 
  gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG(prefs))), 2);
93
 
  gtk_dialog_add_buttons (GTK_DIALOG (prefs),
94
 
                          GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
95
 
                          /* help goes here (future) */
96
 
                          NULL);
97
 
 
98
 
  /* add a treeview for all the properties */
99
 
  box = gtk_vbox_new (FALSE, 6);
100
 
  gtk_container_set_border_width (GTK_CONTAINER (box), 5);
101
 
 
102
 
  label = gtk_label_new (_("Select the device and track to control."));
103
 
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
104
 
  gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
105
 
  gtk_widget_show (label);
106
 
 
107
 
  /* optionmenu */
108
 
  prefs->optionmenu = GTK_WIDGET(gtk_combo_box_text_new ());
109
 
  cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (prefs->optionmenu));
110
 
  g_object_set (G_OBJECT (cells->data), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
111
 
  g_list_free (cells);
112
 
 
113
 
  gtk_box_pack_start (GTK_BOX (box), prefs->optionmenu, FALSE, FALSE, 0);
114
 
  gtk_widget_show (prefs->optionmenu);
115
 
  g_signal_connect (prefs->optionmenu, "changed",
116
 
                    G_CALLBACK (cb_dev_selected), prefs);
117
 
 
118
 
  store = gtk_list_store_new (NUM_COLS,
119
 
                              G_TYPE_STRING, G_TYPE_POINTER);
120
 
  prefs->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
121
 
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (prefs->treeview), FALSE);
122
 
 
123
 
  /* viewport for lots of tracks */
124
 
  view = gtk_scrolled_window_new (NULL, NULL);
125
 
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
126
 
                                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
127
 
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view),
128
 
                                       GTK_SHADOW_IN);
129
 
  gtk_widget_set_size_request (view, -1, 100);
130
 
 
131
 
  gtk_container_add (GTK_CONTAINER (view), prefs->treeview);
132
 
  gtk_box_pack_start (GTK_BOX (box), view, TRUE, TRUE, 0);
133
 
 
134
 
  gtk_widget_show (prefs->treeview);
135
 
  gtk_widget_show (view);
136
 
 
137
 
  /* treeview internals */
138
 
  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview));
139
 
  gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE);
140
 
  gtk_tree_selection_set_select_function (sel, cb_track_select, prefs, NULL);
141
 
 
142
 
  render = gtk_cell_renderer_text_new ();
143
 
  col = gtk_tree_view_column_new_with_attributes ("Track name", render,
144
 
                                                  "text", COL_LABEL,
145
 
                                                  NULL);
146
 
  gtk_tree_view_column_set_clickable (col, TRUE);
147
 
  gtk_tree_view_append_column (GTK_TREE_VIEW (prefs->treeview), col);
148
 
  gtk_tree_view_set_search_column (GTK_TREE_VIEW (prefs->treeview), COL_LABEL);
149
 
 
150
 
  /* and show */
151
 
  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (prefs))), box,
152
 
                      TRUE, TRUE, 0);
153
 
  gtk_widget_show (box);
154
 
}
155
 
 
156
 
GtkWidget *
157
 
gnome_volume_applet_preferences_new (PanelApplet *applet,
158
 
                                     GList       *elements,
159
 
                                     GstMixer    *mixer,
160
 
                                     GList       *tracks)
161
 
{
162
 
  GnomeVolumeAppletPreferences *prefs;
163
 
 
164
 
  /* element */
165
 
  prefs = g_object_new (GNOME_VOLUME_APPLET_TYPE_PREFERENCES, NULL);
166
 
  prefs->applet = g_object_ref (G_OBJECT (applet));
167
 
 
168
 
  /* show devices */
169
 
  for ( ; elements != NULL; elements = elements->next) {
170
 
    gchar *name = g_object_get_data (G_OBJECT (elements->data),
171
 
                                     "gnome-volume-applet-name");
172
 
    gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (prefs->optionmenu), name);
173
 
  }
174
 
 
175
 
  gnome_volume_applet_preferences_change (prefs, mixer, tracks);
176
 
  return GTK_WIDGET (prefs);
177
 
}
178
 
 
179
 
static void
180
 
gnome_volume_applet_preferences_dispose (GObject *object)
181
 
{
182
 
  GnomeVolumeAppletPreferences *prefs = GNOME_VOLUME_APPLET_PREFERENCES (object);
183
 
 
184
 
  if (prefs->applet) {
185
 
    g_object_unref (G_OBJECT (prefs->applet));
186
 
    prefs->applet = NULL;
187
 
  }
188
 
 
189
 
  if (prefs->mixer) {
190
 
    gst_object_unref (GST_OBJECT (prefs->mixer));
191
 
    prefs->mixer = NULL;
192
 
  }
193
 
 
194
 
  G_OBJECT_CLASS (parent_class)->dispose (object);
195
 
}
196
 
 
197
 
static void
198
 
gnome_volume_applet_preferences_response (GtkDialog *dialog,
199
 
                                          gint       response_id)
200
 
{
201
 
  switch (response_id) {
202
 
    case GTK_RESPONSE_CLOSE:
203
 
      gtk_widget_destroy (GTK_WIDGET (dialog));
204
 
      break;
205
 
 
206
 
    default:
207
 
      break;
208
 
  }
209
 
 
210
 
  if (((GtkDialogClass *) parent_class)->response)
211
 
    ((GtkDialogClass *) parent_class)->response (dialog, response_id);
212
 
}
213
 
 
214
 
/*
215
 
 * Change the element. Basically recreates this object internally.
216
 
 */
217
 
 
218
 
void
219
 
gnome_volume_applet_preferences_change (GnomeVolumeAppletPreferences *prefs,
220
 
                                        GstMixer *mixer,
221
 
                                        GList *tracks)
222
 
{
223
 
  GtkTreeIter iter;
224
 
  GtkTreeSelection *sel;
225
 
  GtkListStore *store;
226
 
  GtkTreeModel *model;
227
 
  const GList *item;
228
 
  gchar *label;
229
 
  gboolean change = (mixer != prefs->mixer), res;
230
 
  GList *tree_iter;
231
 
 
232
 
  /* because the old list of tracks is cleaned out when the application removes
233
 
   * all the tracks, we need to keep a backup of the list before clearing it */
234
 
  GList *old_selected_tracks = g_list_copy (tracks);
235
 
 
236
 
  prefs->track_lock = TRUE;
237
 
  if (change) {
238
 
    /* remove old */
239
 
    model = gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->treeview));
240
 
    store = GTK_LIST_STORE (model);
241
 
 
242
 
    while (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
243
 
      gtk_list_store_remove (store, &iter);
244
 
    }
245
 
 
246
 
    /* take/put reference */
247
 
    gst_object_replace ((GstObject **) &prefs->mixer, GST_OBJECT (mixer));
248
 
 
249
 
    /* select active element */
250
 
    model = gtk_combo_box_get_model (GTK_COMBO_BOX (prefs->optionmenu));
251
 
    for (res = gtk_tree_model_get_iter_first (model, &iter); res; res = gtk_tree_model_iter_next (model, &iter)) {
252
 
      gtk_tree_model_get (model, &iter, COL_LABEL, &label, -1);
253
 
      if (!strcmp (label, g_object_get_data (G_OBJECT (mixer), "gnome-volume-applet-name"))) {
254
 
        gtk_combo_box_set_active_iter (GTK_COMBO_BOX (prefs->optionmenu), &iter);
255
 
      }
256
 
      
257
 
      g_free (label);
258
 
    }
259
 
 
260
 
    /* now over to the tracks */
261
 
    model = gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->treeview));
262
 
    store = GTK_LIST_STORE (model);
263
 
    sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview));
264
 
 
265
 
    /* add all tracks */
266
 
    for (item = gst_mixer_list_tracks (mixer); item; item = item->next) {
267
 
      GstMixerTrack *track = item->data;
268
 
 
269
 
      if (track->num_channels <= 0)
270
 
        continue;
271
 
      
272
 
      gtk_list_store_append (store, &iter);
273
 
      gtk_list_store_set (store, &iter,
274
 
                          COL_LABEL, track->label,
275
 
                          COL_TRACK, track,
276
 
                          -1);
277
 
      
278
 
      /* select active tracks */
279
 
      for (tree_iter = g_list_first (old_selected_tracks); tree_iter; tree_iter = tree_iter->next) {
280
 
        GstMixerTrack *test_against = tree_iter->data;
281
 
        if (!strcmp (test_against->label, track->label))
282
 
          gtk_tree_selection_select_iter (sel, &iter);
283
 
      }
284
 
    }
285
 
  } else {
286
 
    model = gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->treeview));
287
 
    sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview));
288
 
    gtk_tree_selection_unselect_all (sel);
289
 
 
290
 
    for (res = gtk_tree_model_get_iter_first (model, &iter); res == TRUE; res = gtk_tree_model_iter_next (model, &iter)) {
291
 
      gtk_tree_model_get (model, &iter, COL_LABEL, &label, -1);
292
 
 
293
 
      /* select active tracks */
294
 
      for (tree_iter = g_list_first (old_selected_tracks); tree_iter; tree_iter = tree_iter->next) {
295
 
        GstMixerTrack *track = tree_iter->data;
296
 
        if (!strcmp (track->label, label))
297
 
          gtk_tree_selection_select_iter (sel, &iter);
298
 
      }
299
 
 
300
 
      g_free (label);
301
 
    }
302
 
  }
303
 
  prefs->track_lock = FALSE;
304
 
  g_list_free (old_selected_tracks);
305
 
}
306
 
 
307
 
/*
308
 
 * Select callback (menu/tree).
309
 
 */
310
 
 
311
 
static void
312
 
cb_dev_selected (GtkComboBox *box,
313
 
                 gpointer    data)
314
 
{
315
 
  GnomeVolumeAppletPreferences *prefs = data;
316
 
  /* GnomeVolumeApplet *applet = (GnomeVolumeApplet *) prefs->applet; */
317
 
  GtkTreeIter iter;
318
 
 
319
 
  if (gtk_combo_box_get_active_iter (box, &iter)) {
320
 
    gchar *label;
321
 
    GConfValue *value;
322
 
 
323
 
    gtk_tree_model_get (gtk_combo_box_get_model (box),
324
 
                        &iter, COL_LABEL, &label, -1);
325
 
 
326
 
    /* write to gconf */
327
 
    value = gconf_value_new (GCONF_VALUE_STRING);
328
 
    gconf_value_set_string (value, label);
329
 
    panel_applet_gconf_set_value (PANEL_APPLET (prefs->applet),
330
 
                      GNOME_VOLUME_APPLET_KEY_ACTIVE_ELEMENT,
331
 
                      value, NULL);
332
 
    g_free (label);
333
 
    gconf_value_free (value);
334
 
  }
335
 
}
336
 
 
337
 
/* get the percent volume from a track */
338
 
 
339
 
static int 
340
 
gnome_volume_applet_get_volume (GstMixer *mixer, GstMixerTrack *track)
341
 
{
342
 
  int *volumes, main_volume, range;
343
 
 
344
 
  if (track->num_channels == 0)
345
 
    return 0;
346
 
 
347
 
  volumes = g_new (gint, track->num_channels);
348
 
  gst_mixer_get_volume (mixer, track, volumes);
349
 
  main_volume = volumes[0];
350
 
  g_free (volumes);
351
 
 
352
 
  range = track->max_volume - track->min_volume;
353
 
  if (range == 0)
354
 
    return 0;
355
 
 
356
 
  return 100 * (main_volume - track->min_volume) / range;
357
 
}
358
 
 
359
 
static gboolean
360
 
cb_track_select (GtkTreeSelection *selection,
361
 
                 GtkTreeModel     *model,
362
 
                 GtkTreePath      *path,
363
 
                 gboolean          path_selected,
364
 
                 gpointer          data)
365
 
{
366
 
  GnomeVolumeAppletPreferences *prefs = data;
367
 
  GtkTreeIter iter;
368
 
  gchar *label;
369
 
  GConfValue *value;
370
 
  GtkTreeSelection *sel;
371
 
  GString *gconf_string;
372
 
  GstMixerTrack *selected_track; /* the track just selected */
373
 
  GnomeVolumeApplet *applet = (GnomeVolumeApplet*) prefs->applet; /* required to update the track settings */
374
 
  int volume_percent;
375
 
 
376
 
  if (prefs->track_lock)
377
 
    return TRUE;
378
 
 
379
 
  gconf_string = g_string_new ("");
380
 
 
381
 
  /* get value */
382
 
  gtk_tree_model_get_iter (model, &iter, path);
383
 
  gtk_tree_model_get (model, &iter, COL_LABEL, &label, COL_TRACK, &selected_track, -1);
384
 
  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->treeview));
385
 
 
386
 
  /* clear the list of selected tracks */
387
 
  if (applet->tracks) {
388
 
    g_list_free (applet->tracks);
389
 
    applet->tracks = NULL;
390
 
  }
391
 
 
392
 
  if (gtk_tree_selection_count_selected_rows (sel) > 0) {
393
 
    GList *lst;
394
 
 
395
 
    /* add the ones already selected */
396
 
    for (lst = gtk_tree_selection_get_selected_rows (sel, &model); lst != NULL; lst = lst->next) {
397
 
      GstMixerTrack *curr = NULL;
398
 
      gchar *it_label;
399
 
 
400
 
      gtk_tree_model_get_iter (model, &iter, lst->data);
401
 
      gtk_tree_model_get (model, &iter, COL_LABEL, &it_label, COL_TRACK, &curr, -1);
402
 
 
403
 
      /* grab the main volume (they will all be the same, so it doesn't matter 
404
 
       * which one we get) */
405
 
      volume_percent = gnome_volume_applet_get_volume (prefs->mixer, curr);
406
 
 
407
 
      if (strcmp (it_label, label)) {
408
 
        applet->tracks = g_list_append (applet->tracks, curr);
409
 
 
410
 
        if (!path_selected) {
411
 
          g_string_append_printf (gconf_string, "%s:", curr->label);
412
 
        } else {
413
 
          gconf_string = g_string_append (gconf_string, curr->label);
414
 
        }
415
 
      }
416
 
    }
417
 
    g_list_foreach (lst, (GFunc)gtk_tree_path_free, NULL);
418
 
    g_list_free (lst);
419
 
  }
420
 
 
421
 
  /* add the one just selected and adjust its volume if it's not the only one
422
 
   * selected */
423
 
  if (!path_selected) {
424
 
    GstMixerTrack *curr;
425
 
 
426
 
    gtk_tree_model_get_iter (model, &iter, path);
427
 
    gtk_tree_model_get (model, &iter, COL_TRACK, &curr, -1);
428
 
    gconf_string = g_string_append (gconf_string, curr->label);
429
 
 
430
 
    applet->tracks = g_list_append (applet->tracks, curr);
431
 
 
432
 
    /* unify the volume of this track with the others already added */
433
 
    if (g_list_length (applet->tracks) > 1) {
434
 
      gnome_volume_applet_adjust_volume (prefs->mixer, curr, volume_percent);
435
 
    }
436
 
  }
437
 
 
438
 
  /* write to gconf */
439
 
  value = gconf_value_new (GCONF_VALUE_STRING);
440
 
  gconf_value_set_string (value, gconf_string->str);
441
 
  panel_applet_gconf_set_value (PANEL_APPLET (prefs->applet),
442
 
                                GNOME_VOLUME_APPLET_KEY_ACTIVE_TRACK,
443
 
                                value, NULL);
444
 
  g_free (label);
445
 
  g_string_free (gconf_string, TRUE);
446
 
  gconf_value_free (value);
447
 
  
448
 
  return TRUE;
449
 
}