~ubuntu-branches/ubuntu/maverick/zapping/maverick

« back to all changes in this revision

Viewing changes to src/channel_editor.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-03-08 23:19:08 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050308231908-oip7rfv6lcmo8c0e
Tags: 0.9.2-2ubuntu1
Rebuilt for Python transition (2.3 -> 2.4)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Zapping (TV viewer for the Gnome Desktop)
2
 
 * Copyright (C) 2000-2001 I�aki Garc�a Etxebarria
 
2
 * Copyright (C) 2002 I�aki Garc�a Etxebarria
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
16
16
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
17
 */
18
18
 
 
19
/* $Id: channel_editor.c,v 1.47 2005/01/19 04:16:19 mschimek Exp $ */
 
20
 
 
21
/*
 
22
  TODO:
 
23
  * input type icon
 
24
  * dnd
 
25
  * write lock channel list
 
26
  * notify other modules (ttx bookmarks, schedule etc) about changes
 
27
  * device column
 
28
  * wizard
 
29
  * channel merging e.g.
 
30
    12 FooBar +              key
 
31
       + dev1 tuner E5 fine  key
 
32
       + dev2 tuner E5 fine  key
 
33
 */
 
34
 
 
35
/* XXX gtk+ 2.3 GtkOptionMenu */
 
36
#undef GTK_DISABLE_DEPRECATED
 
37
 
19
38
#ifdef HAVE_CONFIG_H
20
 
#  include <config.h>
 
39
#  include "config.h"
21
40
#endif
22
41
 
23
42
#include <gnome.h>
24
43
 
25
 
#include "tveng.h"
26
 
#include "callbacks.h"
27
 
#include "interface.h"
28
 
#include "v4linterface.h"
 
44
#define ZCONF_DOMAIN "/zapping/internal/properties/"
29
45
#include "zconf.h"
30
 
/* Manages config values for zconf (it saves me some typing) */
31
 
#define ZCONF_DOMAIN "/zapping/internal/callbacks/"
32
46
#include "zmisc.h"
33
 
#include "plugins.h"
 
47
#include "zspinslider.h"
 
48
#include "remote.h"
 
49
#include "frequencies.h"
 
50
#include "globals.h"
34
51
#include "zvbi.h"
35
 
 
36
 
GtkWidget * ChannelWindow = NULL; /* Here is stored the channel editor
37
 
                                   widget (if any) */
38
 
 
39
 
extern tveng_rf_table * current_country; /* Currently selected contry */
40
 
extern tveng_tuned_channel * global_channel_list;
41
 
extern tveng_device_info * main_info; /* About the device we are using */
42
 
 
43
 
extern int cur_tuned_channel; /* Currently tuned channel */
44
 
 
45
 
GtkStyle *istyle; /* Insensitive CList style */
46
 
 
47
 
static void
48
 
update_edit_buttons_sensitivity         (GtkWidget      *channel_editor)
49
 
{
50
 
  GtkWidget *up = lookup_widget(channel_editor, "move_channel_up");
51
 
  GtkWidget *down = lookup_widget(channel_editor,
52
 
                                  "move_channel_down");
53
 
  GtkWidget *remove = lookup_widget(channel_editor, "remove_channel");
54
 
  GtkWidget *modify = lookup_widget(channel_editor, "modify_channel");
55
 
  GtkWidget *channel_list = lookup_widget(channel_editor, "channel_list");
56
 
  GList *ptr;
57
 
  gboolean sensitive = FALSE;
58
 
  gboolean sensitive_up = FALSE;
59
 
  gboolean sensitive_down = FALSE;
60
 
 
61
 
  ptr = GTK_CLIST(channel_list) -> row_list;
62
 
 
63
 
  while (ptr)
64
 
    {
65
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
66
 
        {
67
 
          sensitive = TRUE;
68
 
 
69
 
          ptr = g_list_first(GTK_CLIST(channel_list) -> row_list);
70
 
          sensitive_up =
71
 
            (ptr && GTK_CLIST_ROW(ptr) -> state != GTK_STATE_SELECTED);
72
 
 
73
 
          ptr = g_list_last(GTK_CLIST(channel_list) -> row_list);
74
 
          sensitive_down =
75
 
            (ptr && GTK_CLIST_ROW(ptr) -> state != GTK_STATE_SELECTED);
76
 
 
77
 
          break;
78
 
        }
79
 
 
80
 
      ptr = ptr -> next;
81
 
    }
82
 
 
83
 
  gtk_widget_set_sensitive(up, sensitive_up);
84
 
  gtk_widget_set_sensitive(down, sensitive_down);
85
 
  gtk_widget_set_sensitive(remove, sensitive);
86
 
  gtk_widget_set_sensitive(modify, sensitive);
87
 
}
88
 
 
89
 
static void
90
 
build_channel_list(GtkCList *clist, tveng_tuned_channel * list)
91
 
{
92
 
  gint i=0;
93
 
  tveng_tuned_channel *tuned_channel;
94
 
  struct tveng_enumstd *std;
95
 
  struct tveng_enum_input *input;
96
 
  gchar index[256];
97
 
  gchar alias[256];
98
 
  gchar country[256];
99
 
  gchar channel[256];
100
 
  gchar freq[256];
101
 
  gchar standard[256];
102
 
  gchar accel[256];
103
 
  gchar * buffer;
104
 
  gfloat value;
105
 
  gchar *entry[] = { index, alias, country, channel, freq, standard, accel };
106
 
 
107
 
  for (i = 0; i < sizeof(entry) / sizeof(entry[0]); i++)
108
 
    memset(entry[i], 0, 256);
109
 
 
110
 
  value = gtk_clist_get_vadjustment(clist)->value;
111
 
 
112
 
  gtk_clist_freeze(clist);
113
 
 
114
 
  gtk_clist_clear(clist);
115
 
 
116
 
  /* Setup the channel list */
117
 
  for (i = 0; (tuned_channel =
118
 
               tveng_retrieve_tuned_channel_by_index(i, list)); i++)
119
 
    {
120
 
      /* clist has no optional built-in row number? */
121
 
      /* IMHO should start at 1, but compatibility rules */
122
 
      g_snprintf(entry[0], 255, "%3u", i + 0);
123
 
      strncpy(entry[1], tuned_channel->name, 255);
124
 
 
125
 
      entry[2][0] = 0;
126
 
      entry[3][0] = 0;
127
 
      entry[4][0] = 0;
128
 
 
129
 
      input = tveng_find_input_by_hash(tuned_channel->input, main_info);
130
 
 
131
 
      if (!input || input->tuners > 0)
132
 
        {
133
 
          strncpy(entry[2], _(tuned_channel->country), 255);
134
 
          strncpy(entry[3], tuned_channel->rf_name, 255);
135
 
          g_snprintf(entry[4], 255, "%u", tuned_channel->freq);
136
 
        }
137
 
      else
138
 
        {
139
 
          strncpy(entry[3], input->name, 255);
140
 
          /* too bad there's no span-columns parameter */
141
 
        }
142
 
 
143
 
      std = tveng_find_standard_by_hash(tuned_channel->standard, main_info);
144
 
      strncpy(entry[5], std ? std->name : "", 255);
145
 
 
146
 
      entry[6][0] = 0;
147
 
 
148
 
      if ((buffer = z_key_name (tuned_channel->accel)))
149
 
        {
150
 
          strncpy (entry[6], buffer, 255);
151
 
          g_free (buffer);
152
 
        }
153
 
 
154
 
      gtk_clist_append(clist, entry);
155
 
 
156
 
      if (tuned_channel->input == 0)
157
 
        {
158
 
          gtk_clist_set_cell_style (clist, i, 2, istyle);
159
 
          gtk_clist_set_cell_style (clist, i, 3, istyle);
160
 
          gtk_clist_set_cell_style (clist, i, 4, istyle);
161
 
        }
162
 
    }
163
 
 
164
 
  gtk_clist_thaw(clist);
165
 
 
166
 
  gtk_adjustment_set_value(gtk_clist_get_vadjustment(clist), value);
167
 
 
168
 
  update_edit_buttons_sensitivity(GTK_WIDGET(clist));
169
 
}
170
 
 
171
 
static void
172
 
real_add_channel                        (GtkWidget      *some_widget,
173
 
                                         gpointer       user_data)
174
 
{
175
 
  GtkWidget * clist1 = lookup_widget(GTK_WIDGET(some_widget), "clist1");
176
 
  GtkWidget * channel_list = lookup_widget(GTK_WIDGET(some_widget),
177
 
                                           "channel_list");
178
 
  GtkWidget * channel_editor = lookup_widget(GTK_WIDGET(some_widget),
179
 
                                             "channel_editor");
180
 
  GtkWidget * channel_name = lookup_widget(GTK_WIDGET(some_widget),
181
 
                                           "channel_name");
182
 
  GtkWidget * channel_accel = lookup_widget(GTK_WIDGET(some_widget),
183
 
                                            "channel_accel");
184
 
  tveng_tuned_channel * list =
185
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
186
 
 
187
 
  GList * ptr; /* Pointer to the selected item(s) in clist1 */
188
 
  int index = 0; /* The row we are reading now */
189
 
  tveng_tuned_channel tc;
190
 
  gint selected;
191
 
  
192
 
  memset(&tc, 0, sizeof(tveng_tuned_channel));
193
 
  tc.name = gtk_entry_get_text (GTK_ENTRY(channel_name));
194
 
 
195
 
  if (current_country)
196
 
    tc.country = g_strdup(current_country->name);
197
 
  else
198
 
    tc.country = NULL;
 
52
#include "v4linterface.h"
 
53
#include "i18n.h"
 
54
#include "xawtv.h"
 
55
 
 
56
#include "channel_editor.h"
 
57
 
 
58
typedef struct station_search station_search;
 
59
 
 
60
struct station_search
 
61
{
 
62
  GtkDialog *           station_search;
 
63
  GtkLabel *            label;
 
64
  GtkProgressBar *      progressbar;
 
65
 
 
66
  guint                 timeout_handle;
 
67
 
 
68
  tv_rf_channel         ch;
 
69
  guint                 channel;
 
70
 
 
71
  guint                 found;
 
72
  guint                 iteration;
 
73
  guint                 frequ;
 
74
  gint                  strength;
 
75
  gint                  afc;
 
76
};
 
77
 
 
78
struct country {
 
79
  gchar *               table_name;
 
80
  gchar *               gui_name;
 
81
};
 
82
 
 
83
enum {
 
84
  FL_NAME,
 
85
  FL_FREQ,
 
86
  FL_NUM_COLUMNS
 
87
};
 
88
 
 
89
typedef struct channel_editor channel_editor;
 
90
 
 
91
struct channel_editor
 
92
{
 
93
  GtkDialog *           channel_editor;
 
94
 
 
95
  GtkBox *              vbox;
 
96
 
 
97
  GtkOptionMenu *       country_menu;
 
98
  GArray *              country_table;
 
99
 
 
100
  GtkButton *           channel_search;
 
101
  GtkButton *           add_all_channels;
 
102
  GtkButton *           import_xawtv;
 
103
 
 
104
  GtkTreeView *         freq_treeview;
 
105
  GtkListStore *        freq_model;
 
106
  GtkTreeSelection *    freq_selection;
 
107
 
 
108
  GtkTreeView *         channel_treeview;
 
109
  GtkListStore *        channel_model;
 
110
  GtkTreeSelection *    channel_selection;
 
111
 
 
112
  GtkWidget *           channel_up;
 
113
  GtkWidget *           channel_down;
 
114
  GtkWidget *           channel_add;
 
115
  GtkWidget *           channel_remove;
 
116
 
 
117
  GtkTable *            entry_table;
 
118
  GtkEntry *            entry_name;
 
119
  ZSpinSlider *         entry_fine_tuning;
 
120
  GtkOptionMenu *       entry_standard;
 
121
  GtkOptionMenu *       entry_input;
 
122
  GtkWidget *           entry_accel;                    /* z_key_entry */
 
123
 
 
124
  GtkTooltips *         tooltips;
 
125
 
 
126
  tveng_tuned_channel * old_channel_list;
 
127
 
 
128
  station_search *      search;
 
129
 
 
130
  gboolean              have_tuners;
 
131
};
 
132
 
 
133
#define DONT_CHANGE 0
 
134
 
 
135
#define BLOCK(object, signal, statement)                                \
 
136
  SIGNAL_HANDLER_BLOCK(ce->object,                                      \
 
137
    (gpointer) on_ ## object ## _ ## signal, statement)
 
138
 
 
139
static GtkMenu *
 
140
create_standard_menu            (channel_editor *       ce);
 
141
 
 
142
static GtkListStore *
 
143
create_freq_list_model          (const tv_rf_channel *  table);
 
144
 
 
145
static void
 
146
on_channel_selection_changed    (GtkTreeSelection *     selection,
 
147
                                 channel_editor *       ce);
 
148
 
 
149
static channel_editor *         dialog_running;
 
150
 
 
151
/*
 
152
 *  Misc helpers
 
153
 */
 
154
 
 
155
static gboolean
 
156
tunable_input                   (channel_editor *       ce,
 
157
                                 const tveng_device_info *info,
 
158
                                 const tveng_tuned_channel *tc)
 
159
{
 
160
  const tv_video_line *l;
 
161
 
 
162
  if (!ce->have_tuners)
 
163
    return FALSE;
 
164
 
 
165
  if (tc->input == DONT_CHANGE)
 
166
    return TRUE;
 
167
 
 
168
  l = tv_video_input_by_hash ((tveng_device_info *) info, tc->input);
 
169
 
 
170
  return (l && l->type == TV_VIDEO_LINE_TYPE_TUNER);
 
171
}
 
172
 
 
173
#define VALID_ITER(iter, list_store)                                    \
 
174
  ((iter) != NULL                                                       \
 
175
   && (iter)->user_data != NULL                                         \
 
176
   && ((GTK_LIST_STORE (list_store))->stamp == (iter)->stamp))
 
177
 
 
178
static inline guint
 
179
tree_model_index                (GtkTreeModel *         model,
 
180
                                 GtkTreeIter *          iter)
 
181
{
 
182
  GtkTreePath *path;
 
183
  guint row;
 
184
 
 
185
  path = gtk_tree_model_get_path (model, iter);
 
186
 
 
187
  row = gtk_tree_path_get_indices (path)[0];
 
188
 
 
189
  gtk_tree_path_free (path);
 
190
 
 
191
  return row;
 
192
}
 
193
 
 
194
static inline tveng_tuned_channel *
 
195
tree_model_tuned_channel        (GtkTreeModel *         model,
 
196
                                 GtkTreeIter *          iter)
 
197
{
 
198
  return tveng_tuned_channel_nth (global_channel_list,
 
199
                                  tree_model_index (model, iter));
 
200
}
 
201
 
 
202
/* function where are thou? */
 
203
static gboolean
 
204
tree_model_get_iter_last        (GtkTreeModel *         model,
 
205
                                 GtkTreeIter *          iter)
 
206
{
 
207
  GtkTreeIter iter2;
 
208
 
 
209
  if (!gtk_tree_model_get_iter_first (model, iter))
 
210
    return FALSE;
 
211
 
 
212
  iter2 = *iter;
 
213
 
 
214
  do *iter = iter2;
 
215
  while (gtk_tree_model_iter_next (model, &iter2));
 
216
 
 
217
  return TRUE;
 
218
}
 
219
 
 
220
static gboolean
 
221
tree_model_iter_prev            (GtkTreeModel *         model,
 
222
                                 GtkTreeIter *          iter)
 
223
{
 
224
  GtkTreePath *path;
 
225
  gboolean r;
 
226
 
 
227
  path = gtk_tree_model_get_path (model, iter);
 
228
 
 
229
  if ((r = gtk_tree_path_prev (path)))
 
230
    gtk_tree_model_get_iter (model, iter, path);
 
231
 
 
232
  gtk_tree_path_free (path);
 
233
 
 
234
  return r;
 
235
}
 
236
 
 
237
/*
 
238
 *  Channel list helpers
 
239
 */
 
240
 
 
241
static inline guint
 
242
channel_list_index              (const channel_editor * ce,
 
243
                                 GtkTreeIter *          iter)
 
244
{
 
245
  return tree_model_index (GTK_TREE_MODEL (ce->channel_model), iter);
 
246
}
 
247
 
 
248
static void
 
249
channel_list_scroll_to_cell     (const channel_editor * ce,
 
250
                                 GtkTreeIter *          iter,
 
251
                                 gfloat                 row_align)
 
252
{
 
253
  GtkTreePath *path;
 
254
 
 
255
  if ((path = gtk_tree_model_get_path (GTK_TREE_MODEL (ce->channel_model), iter)))
 
256
    {
 
257
      gtk_tree_view_scroll_to_cell (ce->channel_treeview, path, NULL,
 
258
                                    /* use_align */ TRUE,
 
259
                                    row_align, 0.0);
 
260
      gtk_tree_path_free (path);
 
261
    }
 
262
}
 
263
 
 
264
static void
 
265
channel_list_rows_changed       (channel_editor *       ce,
 
266
                                 GtkTreeIter *          first_iter,
 
267
                                 GtkTreeIter *          last_iter)
 
268
{
 
269
  GtkTreeModel *model = GTK_TREE_MODEL (ce->channel_model);
 
270
  GtkTreeIter iter;
 
271
  GtkTreePath *path, *last_path;
 
272
 
 
273
  if (!last_iter)
 
274
    last_iter = first_iter;
 
275
 
 
276
  iter = *first_iter;
 
277
 
 
278
  path = gtk_tree_model_get_path (model, first_iter);
 
279
  last_path = gtk_tree_model_get_path (model, last_iter);
 
280
 
 
281
  do
 
282
    {
 
283
      gtk_tree_model_row_changed (model, path, &iter);
 
284
 
 
285
      if (!gtk_tree_model_iter_next (model, &iter))
 
286
        break;
 
287
 
 
288
      gtk_tree_path_next (path);
 
289
    }
 
290
  while (gtk_tree_path_compare (path, last_path) <= 0);
 
291
 
 
292
  gtk_tree_path_free (last_path);
 
293
  gtk_tree_path_free (path);
 
294
}
 
295
 
 
296
static tveng_tuned_channel *
 
297
channel_list_get_tuned_channel  (const channel_editor * ce,
 
298
                                 GtkTreeIter *          iter)
 
299
{
 
300
  tveng_tuned_channel *tc;
 
301
  guint index;
 
302
 
 
303
  index = channel_list_index (ce, iter);
 
304
 
 
305
  tc = tveng_tuned_channel_nth (global_channel_list, index);
 
306
 
 
307
  g_assert (tc != NULL);
 
308
 
 
309
  return tc;
 
310
}
 
311
 
 
312
static gboolean
 
313
channel_list_get_selection      (const channel_editor * ce,
 
314
                                 GtkTreeIter *          iter_first,
 
315
                                 GtkTreeIter *          iter_last,
 
316
                                 tveng_tuned_channel ** tc_first,
 
317
                                 tveng_tuned_channel ** tc_last)
 
318
{
 
319
  GtkTreeIter iter, last;
 
320
 
 
321
  if (!z_tree_selection_iter_first (ce->channel_selection,
 
322
                                    GTK_TREE_MODEL (ce->channel_model), &iter))
 
323
    return FALSE; /* nothing selected */
 
324
 
 
325
  if (iter_first)
 
326
    *iter_first = iter;
 
327
 
 
328
  if (tc_first)
 
329
    *tc_first = channel_list_get_tuned_channel (ce, &iter);
 
330
 
 
331
  if (iter_last || tc_last)
 
332
    {
 
333
      if (!iter_last)
 
334
        iter_last = &last;
 
335
      
 
336
      do
 
337
        {
 
338
          *iter_last = iter;
 
339
          
 
340
          if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (ce->channel_model), &iter))
 
341
            break;
 
342
        }
 
343
      while (gtk_tree_selection_iter_is_selected (ce->channel_selection, &iter));
 
344
      
 
345
      if (tc_last)
 
346
        *tc_last = channel_list_get_tuned_channel (ce, iter_last);
 
347
    }
 
348
 
 
349
  return TRUE;
 
350
}
 
351
 
 
352
static gchar *
 
353
rf_channel_string               (const tveng_tuned_channel *tc)
 
354
{
 
355
  return g_strdup_printf ("%s  %.2f MHz", tc->rf_name, tc->frequ / 1e6);
 
356
}
 
357
 
 
358
static void
 
359
channel_list_add_tuned_channel  (channel_editor *       ce,
 
360
                                 tveng_tuned_channel ** list,
 
361
                                 const tveng_tuned_channel *tc)
 
362
{
 
363
  GtkTreeModel *model = GTK_TREE_MODEL (ce->channel_model);
 
364
  GtkTreeIter iter;
 
365
  GtkTreePath *path;
 
366
  tveng_tuned_channel *tci;
 
367
  guint i;
 
368
 
199
369
  /*
200
 
    See same sequence in on_modify_channel_clicked.
201
 
  if (main_info->inputs &&
202
 
      main_info->inputs[main_info->cur_input].tuners)
203
 
  */
204
 
    {
205
 
      GtkWidget *spinslider =
206
 
        gtk_object_get_data (GTK_OBJECT (channel_editor),
207
 
                             "spinslider");
208
 
 
209
 
      tc.freq = z_spinslider_get_value (spinslider);
210
 
    }
211
 
 
212
 
  tc.accel = z_key_entry_get_key (channel_accel);
213
 
 
214
 
  selected =
215
 
    z_option_menu_get_active(lookup_widget(clist1, "attached_input"));
216
 
  if (selected && main_info->inputs)
217
 
    tc.input = main_info->inputs[selected-1].hash;
218
 
  else
219
 
    tc.input = 0;
220
 
 
221
 
  selected =
222
 
    z_option_menu_get_active(lookup_widget(clist1, "attached_standard"));
223
 
  if (selected)
224
 
    tc.standard = main_info->standards[selected-1].hash;
225
 
  else
226
 
    tc.standard = 0;
227
 
 
228
 
  ptr = GTK_CLIST(clist1) -> row_list;
229
 
 
230
 
  while (ptr)
231
 
    {
232
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
233
 
        { 
234
 
          /* Add this selected channel to the channel list */
235
 
          gtk_clist_get_text(GTK_CLIST(clist1), index, 0, &(tc.rf_name));
236
 
          break; /* found */
237
 
        }
238
 
      ptr = ptr -> next;
239
 
      index++;
240
 
    }
241
 
 
242
 
  store_control_values(&tc.num_controls, &tc.controls, main_info);
243
 
 
244
 
  list = tveng_insert_tuned_channel_sorted(&tc, list);
245
 
 
246
 
  gtk_object_set_data(GTK_OBJECT(channel_editor), "list", list);
247
 
 
248
 
  g_free(tc.controls);
249
 
  g_free(tc.country);
250
 
 
251
 
  build_channel_list(GTK_CLIST(channel_list), list);
252
 
 
253
 
  gtk_entry_set_text(GTK_ENTRY(channel_name), "");
254
 
}
255
 
 
256
 
static void
257
 
on_fine_tune_value_changed               (GtkAdjustment         *adj,
258
 
                                          tveng_device_info     *info)
259
 
{
260
 
  if (info->inputs &&
261
 
      info->inputs[info->cur_input].tuners)
262
 
    tveng_tune_input(adj->value, main_info);
263
 
}
264
 
 
265
 
static void
266
 
set_slider(uint32_t freq, GtkWidget *channel_editor,
267
 
           tveng_device_info *info)
268
 
{
269
 
  GtkWidget *spinslider =
270
 
    gtk_object_get_data (GTK_OBJECT (channel_editor), "spinslider");
271
 
  GtkAdjustment *spin_adj = z_spinslider_get_spin_adj (spinslider);
272
 
  GtkAdjustment *hscale_adj = z_spinslider_get_hscale_adj (spinslider);
273
 
 
274
 
  if (freq)
275
 
    {
276
 
      freq += 12;
277
 
      freq -= freq % 25;
278
 
 
279
 
      spin_adj -> value = freq;
280
 
      spin_adj -> lower = 5000;
281
 
      spin_adj -> upper = 900000;
282
 
      spin_adj -> step_increment = 25;
283
 
      spin_adj -> page_increment = 1e3;
284
 
      spin_adj -> page_size = 0;
285
 
 
286
 
      hscale_adj -> value = freq;
287
 
      hscale_adj -> lower = freq - 1e4;
288
 
      hscale_adj -> upper = freq + 1e4;
289
 
      hscale_adj -> step_increment = 25;
290
 
      hscale_adj -> page_increment = 1e3;
291
 
      hscale_adj -> page_size = 0;
 
370
   *  Don't add when this channel (by tuner freq) is already
 
371
   *  listed. Eventually update the station name.
 
372
   */
 
373
  for (i = 0; (tci = tveng_tuned_channel_nth (*list, i)); i++)
 
374
    {
 
375
      if (tci->input != tc->input)
 
376
        continue;
 
377
 
 
378
      if (tunable_input (ce, zapping->info, tc)
 
379
          && abs ((int)(tci->frequ - tc->frequ)) > 3000000)
 
380
        continue;
 
381
 
 
382
      gtk_tree_model_iter_nth_child (model, &iter, NULL, (gint) i);
 
383
      path = gtk_tree_model_get_path (model, &iter);
 
384
      gtk_tree_view_scroll_to_cell (ce->channel_treeview, path, NULL,
 
385
                                    /* use_align */ TRUE, 0.5, 0.0);
 
386
      gtk_tree_path_free (path);
 
387
 
 
388
      if (0 != strcmp (tci->name, tci->rf_name))
 
389
        return; /* user changed station name */
 
390
 
 
391
      if (0 == strcmp (tc->name, tci->rf_name))
 
392
        return; /* we have no station name */
 
393
      /*
 
394
      gtk_list_store_set (ce->channel_model, &iter,
 
395
                          CL_NAME, tc->name, -1);
 
396
      */
 
397
      g_free (tci->name);
 
398
      tci->name = g_strdup (tc->name);
 
399
 
 
400
      return;
 
401
    }
 
402
 
 
403
  tveng_tuned_channel_insert (list, tveng_tuned_channel_new (tc), G_MAXINT);
 
404
 
 
405
  gtk_list_store_append (ce->channel_model, &iter);
 
406
 
 
407
  channel_list_scroll_to_cell (ce, &iter, 0.5);
 
408
}
 
409
 
 
410
/*
 
411
 *  Dialog helpers
 
412
 */
 
413
 
 
414
static void
 
415
entry_fine_tuning_set           (channel_editor *       ce,
 
416
                                 const tveng_device_info *info,
 
417
                                 guint                  frequency)
 
418
{
 
419
  GtkAdjustment *spin_adj;
 
420
  GtkAdjustment *hscale_adj;
 
421
  const tv_video_line *vi;
 
422
 
 
423
  spin_adj = ce->entry_fine_tuning->spin_adj;
 
424
  hscale_adj = ce->entry_fine_tuning->hscale_adj;
 
425
 
 
426
  if (frequency > 0)
 
427
    {
 
428
      double dfreq;
 
429
 
 
430
      frequency += 500;
 
431
      frequency -= frequency % 1000;
 
432
 
 
433
      dfreq = frequency * 1e-6; /* MHz */
 
434
 
 
435
      spin_adj->value = dfreq;
 
436
      spin_adj->lower = 5;
 
437
      spin_adj->upper = 1999;
 
438
      spin_adj->step_increment = 0.05;
 
439
      spin_adj->page_increment = 1;
 
440
      spin_adj->page_size = 0;
 
441
 
 
442
      hscale_adj->value = dfreq;
 
443
      hscale_adj->lower = dfreq - 4;
 
444
      hscale_adj->upper = dfreq + 4;
 
445
      hscale_adj->step_increment = 0.05; /* XXX use tv_video_line.u.tuner.step ? */
 
446
      hscale_adj->page_increment = 1;
 
447
      hscale_adj->page_size = 0;
292
448
 
293
449
      gtk_adjustment_changed (spin_adj);
294
450
      gtk_adjustment_value_changed (spin_adj);
295
451
      gtk_adjustment_changed (hscale_adj);
296
452
      gtk_adjustment_value_changed (hscale_adj);
297
 
      z_spinslider_set_reset_value (spinslider, freq);
 
453
 
 
454
      z_spinslider_set_reset_value (ce->entry_fine_tuning, dfreq);
298
455
    }
299
456
 
300
 
  if (!freq || !info->inputs ||
301
 
      !info->inputs[info->cur_input].tuners)
 
457
  vi = tv_cur_video_input (info);
 
458
  if (0 == frequency
 
459
      || NULL == vi
 
460
      || vi->type != TV_VIDEO_LINE_TYPE_TUNER)
 
461
    gtk_widget_set_sensitive (GTK_WIDGET (ce->entry_fine_tuning), FALSE);
 
462
  else
 
463
    gtk_widget_set_sensitive (GTK_WIDGET (ce->entry_fine_tuning), TRUE);
 
464
}
 
465
 
 
466
static void
 
467
no_channel_selected             (channel_editor *       ce)
 
468
{
 
469
  gtk_widget_set_sensitive (ce->channel_up, FALSE);
 
470
  gtk_widget_set_sensitive (ce->channel_down, FALSE);
 
471
  gtk_widget_set_sensitive (ce->channel_remove, FALSE);
 
472
 
 
473
  gtk_entry_set_text (ce->entry_name, "");
 
474
  z_option_menu_set_active (GTK_WIDGET (ce->entry_standard), 0);
 
475
  z_option_menu_set_active (GTK_WIDGET (ce->entry_input), 0);
 
476
  z_key_entry_set_key (ce->entry_accel, Z_KEY_NONE);
 
477
  gtk_widget_set_sensitive (GTK_WIDGET (ce->entry_table), FALSE);  
 
478
}
 
479
 
 
480
static void
 
481
channel_buttons_set_sensitive   (channel_editor *       ce,
 
482
                                 gboolean               any_selected)
 
483
{
 
484
  GtkTreeIter iter;
 
485
 
 
486
  if (!gtk_tree_model_get_iter_first
 
487
      (GTK_TREE_MODEL (ce->channel_model), &iter))
302
488
    {
303
 
      gtk_widget_set_sensitive (spinslider, FALSE);
 
489
      no_channel_selected (ce);
304
490
      return;
305
491
    }
306
492
 
307
 
  gtk_widget_set_sensitive (spinslider, TRUE);
308
 
}
309
 
 
310
 
static void
311
 
on_input_changed                       (GtkWidget       *menu_item,
312
 
                                        gpointer        *user_data)
313
 
{
314
 
  GtkWidget * channel_editor = lookup_widget (menu_item, "channel_editor");
315
 
  gint selected = (gint) user_data;
316
 
  tveng_device_info *info = main_info;
317
 
 
318
 
  if (selected == 0) /* "don't change" */
319
 
    return;
320
 
 
321
 
  if (!info->inputs || (selected - 1) >= info->num_inputs)
322
 
    return;
323
 
 
324
 
  if (tveng_set_input (info->inputs + selected - 1, info) == -1)
325
 
    return;
326
 
 
327
 
  /* XXX zmodel_changed (z_input_model);
328
 
     destroys this menu */
329
 
 
330
 
  if (info->inputs[info->cur_input].tuners > 0)
331
 
    {
332
 
      GtkWidget *clist1 =
333
 
        lookup_widget (GTK_WIDGET (channel_editor), "clist1");
334
 
      GtkWidget *spinslider =
335
 
        gtk_object_get_data (GTK_OBJECT (channel_editor), "spinslider");
336
 
      GList *ptr;
337
 
      uint32_t freq;
338
 
 
339
 
      if (clist1)
340
 
        for (ptr = GTK_CLIST(clist1)->row_list; ptr; ptr = ptr->next)
341
 
          if (GTK_CLIST_ROW(ptr)->state == GTK_STATE_SELECTED)
342
 
            {
343
 
              freq = z_spinslider_get_value (spinslider);
344
 
              break;
345
 
            }
346
 
 
347
 
      if (clist1 && ptr && freq != 0)
348
 
        {
349
 
          /* A channel is selected which has set the slider already,
350
 
           * we keep that freq (or whatever the user entered in the
351
 
           * meantime). Happens for baseband input and "don't change"
352
 
           * channels as well, so one can switch back and forth without
353
 
           * erasing the slider setting.
354
 
           */
355
 
          set_slider (freq, channel_editor, info);
356
 
          return;
357
 
        }
358
 
      else if (tveng_get_tune(&freq, info) != -1)
359
 
        {
360
 
          set_slider (freq, channel_editor, info);
361
 
          return;
362
 
        }
363
 
      /* else: */
364
 
    }
365
 
 
366
 
  /* insensitive */
367
 
  set_slider (0, channel_editor, info);
368
 
}
369
 
 
370
 
/* Called when the current country selection has been changed */
371
 
static void
372
 
on_country_switch                      (GtkWidget       *menu_item,
373
 
                                        tveng_rf_table *country)
374
 
{
375
 
  GtkWidget * clist1 = lookup_widget(menu_item, "clist1");
376
 
 
377
 
  tveng_rf_channel * channel;
378
 
  int id=0;
379
 
 
380
 
  gchar new_entry_0[128];
381
 
  gchar new_entry_1[128];
382
 
  gchar *new_entry[] = {new_entry_0, new_entry_1}; /* Allocate room
383
 
                                                      for new entries */
384
 
  new_entry[0][127] = new_entry[1][127] = 0;
385
 
 
386
 
  /* Set the current country */
387
 
  current_country = country;
388
 
 
389
 
  gtk_clist_freeze( GTK_CLIST(clist1)); /* We are going to do a number
390
 
                                           of changes */
391
 
 
392
 
  gtk_clist_clear( GTK_CLIST(clist1));
393
 
  
394
 
  /* Get all available channels for this country */
395
 
  while ((channel = tveng_get_channel_by_id(id, country)))
396
 
    {
397
 
      g_snprintf(new_entry[0], 127, "%s", channel->name);
398
 
      g_snprintf(new_entry[1], 127, "%u", channel->freq);
399
 
      gtk_clist_append(GTK_CLIST(clist1), new_entry);
400
 
      id++;
401
 
    }
402
 
 
403
 
  gtk_clist_thaw( GTK_CLIST(clist1));
404
 
 
405
 
  /* Set the current country as the user data of the clist */
406
 
  gtk_object_set_user_data ( GTK_OBJECT(clist1), country);
407
 
}
408
 
 
409
 
static void
410
 
rebuild_inputs_and_standards (gpointer ignored, GtkWidget *widget)
411
 
{
412
 
  GtkWidget * input = lookup_widget(widget, "attached_input");
413
 
  GtkWidget * standard = lookup_widget(widget, "attached_standard");
414
 
  GtkWidget * NewMenu; /* New menu */
415
 
  GtkWidget * menu_item;
416
 
  int i;
417
 
  
418
 
  /* remove old menu */
419
 
  gtk_widget_destroy(gtk_option_menu_get_menu (GTK_OPTION_MENU (input)));
420
 
  gtk_widget_destroy(gtk_option_menu_get_menu (GTK_OPTION_MENU (standard)));
421
 
 
422
 
  NewMenu = gtk_menu_new ();
423
 
 
424
 
  menu_item = gtk_menu_item_new_with_label(_("Do not change standard"));
425
 
  gtk_widget_show (menu_item);
426
 
  gtk_menu_append(GTK_MENU (NewMenu), menu_item);
427
 
 
428
 
  for (i = 0; i < main_info->num_standards; i++)
429
 
  {
430
 
    menu_item =
431
 
      gtk_menu_item_new_with_label(main_info->standards[i].name);
432
 
    gtk_widget_show (menu_item);
433
 
    gtk_menu_append(GTK_MENU (NewMenu), menu_item);
434
 
  }
435
 
 
436
 
  if (main_info->num_standards)
437
 
    z_option_menu_set_active(standard, main_info->cur_standard+1);
438
 
  else
439
 
    z_option_menu_set_active(standard, 0);
440
 
 
441
 
  gtk_option_menu_set_menu (GTK_OPTION_MENU (standard), NewMenu);
442
 
 
443
 
  NewMenu = gtk_menu_new ();
444
 
 
445
 
  menu_item = gtk_menu_item_new_with_label(_("Do not change input"));
446
 
  gtk_widget_show (menu_item);
447
 
  gtk_menu_append(GTK_MENU (NewMenu), menu_item);
448
 
 
449
 
  for (i = 0; i < main_info->num_inputs; i++)
450
 
  {
451
 
    menu_item = gtk_menu_item_new_with_label(main_info->inputs[i].name);
452
 
    gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
453
 
                        GTK_SIGNAL_FUNC (on_input_changed),
454
 
                        (gpointer)(i + 1));
455
 
    gtk_widget_show (menu_item);
456
 
    gtk_menu_append(GTK_MENU (NewMenu), menu_item);
457
 
  }
458
 
 
459
 
  if (main_info->num_inputs)
460
 
    z_option_menu_set_active(input, main_info->cur_input+1);
461
 
  else
462
 
    z_option_menu_set_active(input, 0);
463
 
 
464
 
  gtk_option_menu_set_menu (GTK_OPTION_MENU (input), NewMenu);
465
 
}
466
 
 
467
 
static void
468
 
on_move_channel_down_clicked            (GtkWidget      *button,
469
 
                                         GtkWidget      *channel_editor)
470
 
{
471
 
  GtkWidget * channel_list = lookup_widget(GTK_WIDGET(button),
472
 
                                           "channel_list");
473
 
  tveng_tuned_channel * list =
474
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
475
 
  tveng_tuned_channel * tc;
476
 
  GList *ptr;
477
 
  gint pos, last_pos;
478
 
  gboolean selected[tveng_tuned_channel_num(list)];
479
 
  gboolean moved = FALSE;
480
 
 
481
 
  memset(selected, FALSE, sizeof(selected));
482
 
 
483
 
  ptr = g_list_last(GTK_CLIST(channel_list) -> row_list);
484
 
 
485
 
  /* look for first unselected entry */
486
 
  while (ptr)
487
 
    {
488
 
      if (GTK_CLIST_ROW(ptr) -> state != GTK_STATE_SELECTED)
489
 
        break;
490
 
 
491
 
      selected[g_list_position(GTK_CLIST(channel_list) -> row_list,
492
 
                               ptr)] = TRUE;
493
 
 
494
 
      ptr = ptr -> prev;
495
 
    }
496
 
 
497
 
  /* swap this and next */
498
 
  while (ptr)
499
 
    {
500
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
501
 
        {
502
 
          moved = TRUE;
503
 
          pos = g_list_position(GTK_CLIST(channel_list) -> row_list, ptr);
504
 
          g_assert(pos >= 0);
505
 
          tc = tveng_retrieve_tuned_channel_by_index(pos, list);
506
 
          tveng_tuned_channel_down(tc);
507
 
          selected[pos+1] = TRUE;
508
 
        }
509
 
 
510
 
      ptr = ptr -> prev;
511
 
    }
512
 
 
513
 
  if (!moved)
514
 
    return;
515
 
 
516
 
  /* redraw list */
517
 
  build_channel_list(GTK_CLIST(channel_list), list);
518
 
 
519
 
  /* select channels again */
520
 
  gtk_signal_handler_block_by_func(GTK_OBJECT(channel_list),
521
 
                           GTK_SIGNAL_FUNC(on_channel_list_select_row),
522
 
                           NULL);
523
 
 
524
 
  for (pos = last_pos = 0; pos < tveng_tuned_channel_num(list); pos++)
525
 
    if (selected[pos])
526
 
      {
527
 
        gtk_clist_select_row(GTK_CLIST(channel_list), pos, 0);
528
 
        if (pos > last_pos)
529
 
          last_pos = pos;
530
 
      }
531
 
 
532
 
  /* bring the row following the selection back in sight */
533
 
  if (last_pos + 1 < pos)
534
 
    last_pos++;
535
 
  if (gtk_clist_row_is_visible(GTK_CLIST(channel_list), last_pos)
536
 
      != GTK_VISIBILITY_FULL)
537
 
    gtk_clist_moveto(GTK_CLIST(channel_list), last_pos, 0, 1.0, 0.0);
538
 
 
539
 
  gtk_signal_handler_unblock_by_func(GTK_OBJECT(channel_list),
540
 
                             GTK_SIGNAL_FUNC(on_channel_list_select_row),
541
 
                             NULL);
542
 
 
543
 
  update_edit_buttons_sensitivity(GTK_WIDGET(channel_list));
544
 
}
545
 
 
546
 
static void
547
 
on_move_channel_up_clicked              (GtkWidget      *button,
548
 
                                         GtkWidget      *channel_editor)
549
 
{
550
 
  GtkWidget * channel_list = lookup_widget(GTK_WIDGET(button),
551
 
                                           "channel_list");
552
 
  tveng_tuned_channel * list =
553
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
554
 
  tveng_tuned_channel * tc;
555
 
  GList *ptr;
556
 
  gint pos, first_pos;
557
 
  gboolean selected[tveng_tuned_channel_num(list)];
558
 
  gboolean moved = FALSE;
559
 
 
560
 
  memset(selected, FALSE, sizeof(selected));
561
 
 
562
 
  ptr = g_list_first(GTK_CLIST(channel_list) -> row_list);
563
 
 
564
 
  /* look for first unselected entry */
565
 
  while (ptr)
566
 
    {
567
 
      if (GTK_CLIST_ROW(ptr) -> state != GTK_STATE_SELECTED)
568
 
        break;
569
 
 
570
 
      selected[g_list_position(GTK_CLIST(channel_list) -> row_list,
571
 
                               ptr)] = TRUE;
572
 
      ptr = ptr -> next;
573
 
    }
574
 
 
575
 
  /* swap this and next */
576
 
  while (ptr)
577
 
    {
578
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
579
 
        {
580
 
          moved = TRUE;
581
 
          pos = g_list_position(GTK_CLIST(channel_list) -> row_list, ptr);
582
 
          g_assert(pos > 0);
583
 
          tc = tveng_retrieve_tuned_channel_by_index(pos, list);
584
 
          tveng_tuned_channel_up(tc);
585
 
          selected[pos-1] = TRUE;
586
 
        }
587
 
 
588
 
      ptr = ptr -> next;
589
 
    }
590
 
 
591
 
  if (!moved)
592
 
    return;
593
 
 
594
 
  /* redraw list */
595
 
  build_channel_list(GTK_CLIST(channel_list), list);
596
 
 
597
 
  /* select channels again */
598
 
  gtk_signal_handler_block_by_func(GTK_OBJECT(channel_list),
599
 
                           GTK_SIGNAL_FUNC(on_channel_list_select_row),
600
 
                           NULL);
601
 
 
602
 
  for (pos = 0, first_pos = tveng_tuned_channel_num(list);
603
 
       pos < tveng_tuned_channel_num(list); pos++)
604
 
    if (selected[pos])
605
 
      {
606
 
        gtk_clist_select_row(GTK_CLIST(channel_list), pos, 0);
607
 
        if (pos < first_pos)
608
 
          first_pos = pos;
609
 
      }
610
 
 
611
 
  /* bring the row preceding the selection back in sight */
612
 
  if (first_pos > 0)
613
 
    first_pos--;
614
 
  if (gtk_clist_row_is_visible(GTK_CLIST(channel_list), first_pos)
615
 
      != GTK_VISIBILITY_FULL)
616
 
    gtk_clist_moveto(GTK_CLIST(channel_list), first_pos, 0, 0.0, 0.0);
617
 
 
618
 
  gtk_signal_handler_unblock_by_func(GTK_OBJECT(channel_list),
619
 
                             GTK_SIGNAL_FUNC(on_channel_list_select_row),
620
 
                             NULL);
621
 
 
622
 
  update_edit_buttons_sensitivity(GTK_WIDGET(channel_list));
623
 
}
624
 
 
625
 
static void
626
 
on_channel_list_unselect_row            (GtkCList       *channel_list,
627
 
                                         gint            row,
628
 
                                         gint            column,
629
 
                                         GdkEvent       *event,
630
 
                                         GtkWidget      *channel_editor)
631
 
{
632
 
  update_edit_buttons_sensitivity(channel_editor);
 
493
  gtk_widget_set_sensitive (ce->channel_up,
 
494
                            !gtk_tree_selection_iter_is_selected
 
495
                            (ce->channel_selection, &iter));
 
496
 
 
497
  tree_model_get_iter_last (GTK_TREE_MODEL (ce->channel_model), &iter);
 
498
 
 
499
  gtk_widget_set_sensitive (ce->channel_down,
 
500
                            !gtk_tree_selection_iter_is_selected
 
501
                            (ce->channel_selection, &iter));
 
502
 
 
503
  gtk_widget_set_sensitive (ce->channel_remove, any_selected);
 
504
}
 
505
 
 
506
/*
 
507
 *  Signals
 
508
 */
 
509
 
 
510
static void
 
511
current_rf_channel_table        (channel_editor *       ce,
 
512
                                 tv_rf_channel *        ch,
 
513
                                 const gchar **         rf_table)
 
514
{
 
515
  struct country *c;
 
516
  guint i;
 
517
 
 
518
  i = z_option_menu_get_active (GTK_WIDGET (ce->country_menu));
 
519
  c = &g_array_index (ce->country_table, struct country, i);
 
520
 
 
521
  if (rf_table)
 
522
    *rf_table = c->table_name;
 
523
 
 
524
  if (!tv_rf_channel_table_by_name (ch, c->table_name))
 
525
    g_assert_not_reached ();
 
526
}
 
527
 
 
528
static void
 
529
on_country_menu_changed         (GtkOptionMenu *        country_menu _unused_,
 
530
                                 channel_editor *       ce)
 
531
{
 
532
  tv_rf_channel ch;
 
533
  const gchar *rf_table;
 
534
 
 
535
  current_rf_channel_table (ce, &ch, &rf_table);
 
536
 
 
537
  zconf_set_string (rf_table, "/zapping/options/main/current_country");
 
538
 
 
539
  zconf_set_int (tv_rf_channel_align (&ch) ? 1 : 0,
 
540
                 "/zapping/options/main/channel_txl");
 
541
 
 
542
  ce->freq_model = create_freq_list_model (&ch);
 
543
  gtk_tree_view_set_model (ce->freq_treeview, GTK_TREE_MODEL (ce->freq_model));
 
544
}
 
545
 
 
546
static void
 
547
on_station_search_cancel_clicked (GtkButton *           cancel _unused_,
 
548
                                  channel_editor *      ce)
 
549
{
 
550
  if (ce->search)
 
551
    gtk_widget_destroy (GTK_WIDGET (ce->search->station_search));
 
552
}
 
553
 
 
554
static void
 
555
on_station_search_destroy       (GtkObject *            unused _unused_,
 
556
                                 channel_editor *       ce)
 
557
{
 
558
  if (ce->search)
 
559
    {
 
560
      gtk_timeout_remove (ce->search->timeout_handle);
 
561
 
 
562
      g_free (ce->search);
 
563
      ce->search = NULL;
 
564
    }
 
565
 
 
566
  gtk_widget_set_sensitive (GTK_WIDGET (ce->vbox), TRUE);
633
567
}
634
568
 
635
569
static gboolean
636
 
on_channel_editor_delete_event         (GtkWidget       *widget,
637
 
                                        GdkEvent        *event,
638
 
                                        gpointer         user_data)
639
 
{
640
 
  GtkWidget * related_menuitem =
641
 
    GTK_WIDGET(gtk_object_get_user_data(GTK_OBJECT(widget)));
642
 
  tveng_tuned_channel * list =
643
 
    gtk_object_get_data(GTK_OBJECT(widget), "list");
644
 
 
645
 
  tveng_clear_tuned_channel(list);
646
 
 
647
 
  gtk_signal_disconnect_by_func(GTK_OBJECT(z_input_model),
648
 
                                GTK_SIGNAL_FUNC(rebuild_inputs_and_standards),
649
 
                                ChannelWindow);
650
 
 
651
 
  zmodel_changed(z_input_model);
652
 
 
653
 
  /* Set the menuentry sensitive again */
654
 
  gtk_widget_set_sensitive(related_menuitem, TRUE);
655
 
 
656
 
  gtk_style_unref (istyle);
657
 
 
658
 
  ChannelWindow = NULL; /* No more channel window */
659
 
 
660
 
  return FALSE;
661
 
}
662
 
 
663
 
void
664
 
on_channels1_activate                  (GtkMenuItem     *menuitem,
665
 
                                        gpointer         user_data)
666
 
{
667
 
  GtkWidget * channel_editor;
668
 
  GtkWidget * country_options_menu;
669
 
 
670
 
  GtkWidget * channel_list;
671
 
 
672
 
  GtkWidget * new_menu;
673
 
  GtkWidget * menu_item = NULL;
674
 
 
675
 
  GtkWidget * move_channel_up;
676
 
  GtkWidget * move_channel_down;
677
 
 
678
 
  GtkWidget * spinslider;
679
 
  GtkAdjustment * spinslider_adj;
680
 
 
681
 
  int i = 0;
682
 
  int currently_tuned_country = 0;
683
 
 
684
 
  tveng_rf_table * tune;
685
 
  tveng_tuned_channel * tuned_channel;
686
 
  tveng_tuned_channel * list = NULL;
687
 
 
688
 
  if (ChannelWindow)
689
 
    {
690
 
      gdk_window_raise(ChannelWindow->window);
 
570
station_search_timeout          (gpointer               p)
 
571
{
 
572
  channel_editor *ce = p;
 
573
  station_search *cs = ce->search;
 
574
  tveng_tuned_channel tc;
 
575
  gchar *station_name;
 
576
 
 
577
  if (!(cs = ce->search))
 
578
    return FALSE;
 
579
 
 
580
  if (cs->iteration == 0)
 
581
    {
 
582
      gdouble progress;
 
583
 
 
584
      /* New channel */
 
585
 
 
586
      progress = cs->channel / (gdouble) tv_rf_channel_table_size (&cs->ch);
 
587
      gtk_progress_bar_set_fraction (cs->progressbar, progress);
 
588
 
 
589
      z_label_set_text_printf (cs->label,
 
590
                               _("Channel: %s   Found: %u"),
 
591
                               cs->ch.channel_name, cs->found);
 
592
 
 
593
      cs->frequ = cs->ch.frequency;
 
594
      cs->strength = 0;
 
595
 
 
596
      if (!tv_set_tuner_frequency (zapping->info, cs->frequ))
 
597
        goto next_channel;
 
598
    }
 
599
  else
 
600
    {
 
601
      gint strength, afc;
 
602
 
 
603
      /* Probe */
 
604
 
 
605
      if (!tv_get_signal_strength (zapping->info, &strength, &afc))
 
606
        goto next_channel;
 
607
 
 
608
      if (strength > 0)
 
609
        {
 
610
          cs->strength = strength;
 
611
        }
 
612
      else if (cs->iteration >= 5
 
613
               && cs->strength == 0)
 
614
        {
 
615
          goto next_channel; /* no signal after 0.5 sec */
 
616
        }
 
617
 
 
618
      if (afc && (afc != -cs->afc))
 
619
        {
 
620
          cs->afc = afc;
 
621
          cs->frequ += afc * 25000; /* should be afc*50000, but won't harm */
 
622
 
 
623
          /* error ignored */
 
624
          tv_set_tuner_frequency (zapping->info, cs->frequ);
 
625
        }
 
626
 
 
627
#ifdef HAVE_LIBZVBI
 
628
      if (cs->iteration >= 10)
 
629
        {
 
630
          if (cs->iteration == 10)
 
631
            {
 
632
              /* zvbi should store the station name if known from now */
 
633
              zvbi_name_unknown();
 
634
            }
 
635
          else
 
636
            {
 
637
              if ((station_name = zvbi_get_name ()))
 
638
                goto add_station;
 
639
 
 
640
              /* How long for XDS? */
 
641
              if (cs->iteration >= 25)
 
642
                goto add_default; /* no name after 2.5 sec */
 
643
            }
 
644
        }
 
645
#else
 
646
      if (cs->iteration >= 10)
 
647
        goto add_default; /* after 1 sec afc */
 
648
#endif
 
649
    }
 
650
 
 
651
  ++cs->iteration;
 
652
 
 
653
  return TRUE; /* continue */
 
654
 
 
655
 add_default:
 
656
  station_name = g_strdup (cs->ch.channel_name);
 
657
 
 
658
 add_station:
 
659
  CLEAR (tc);
 
660
  tc.name       = station_name;
 
661
  tc.rf_name    = (gchar *) cs->ch.channel_name;
 
662
  tc.rf_table   = (gchar *) cs->ch.table_name;
 
663
  tc.frequ      = cs->frequ;
 
664
 
 
665
  channel_list_add_tuned_channel (ce, &global_channel_list, &tc);
 
666
 
 
667
  g_free (station_name);
 
668
  cs->found++;
 
669
 
 
670
 next_channel:
 
671
  cs->channel++;
 
672
  cs->iteration = 0;
 
673
 
 
674
  if (!tv_rf_channel_next (&cs->ch))
 
675
    {
 
676
      gtk_widget_destroy (GTK_WIDGET (cs->station_search));
 
677
      return FALSE; /* remove timer */
 
678
    }
 
679
 
 
680
  return TRUE; /* continue */
 
681
}
 
682
 
 
683
static void
 
684
on_channel_search_clicked       (GtkButton *            search _unused_,
 
685
                                 channel_editor *       ce)
 
686
{
 
687
  station_search *cs;
 
688
  GtkWidget *dialog_vbox;
 
689
  GtkWidget *vbox;
 
690
  GtkWidget *dialog_action_area;
 
691
  GtkWidget *cancel;
 
692
  tv_video_line *l;
 
693
 
 
694
  if (ce->search)
 
695
    return;
 
696
 
 
697
  /* XXX we cannot search in Xv mode because there's no signal strength.
 
698
     Or is there? tveng should also tell in advance if this call will
 
699
     fail, so we can disable the option. */
 
700
  if (-1 == zmisc_switch_mode (DISPLAY_MODE_WINDOW,
 
701
                               CAPTURE_MODE_READ,
 
702
                               zapping->info))
 
703
    return;
 
704
 
 
705
  cs = g_malloc (sizeof (station_search));
 
706
  ce->search = cs;
 
707
  cs->found = 0;
 
708
 
 
709
  cs->station_search = GTK_DIALOG (gtk_dialog_new ());
 
710
  gtk_window_set_title (GTK_WINDOW (cs->station_search), _("Searching..."));
 
711
  g_signal_connect (G_OBJECT (cs->station_search), "destroy",
 
712
                    G_CALLBACK (on_station_search_destroy), ce);
 
713
 
 
714
  dialog_vbox = cs->station_search->vbox;
 
715
  gtk_widget_show (dialog_vbox);
 
716
 
 
717
  vbox = gtk_vbox_new (FALSE, 3);
 
718
  gtk_widget_show (vbox);
 
719
  gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox, TRUE, TRUE, 0);
 
720
 
 
721
  cs->label = GTK_LABEL (gtk_label_new (""));
 
722
  gtk_widget_show (GTK_WIDGET (cs->label));
 
723
  gtk_box_pack_start (GTK_BOX (vbox),
 
724
                      GTK_WIDGET (cs->label),
 
725
                      FALSE, FALSE, 0);
 
726
 
 
727
  cs->progressbar = GTK_PROGRESS_BAR (gtk_progress_bar_new ());
 
728
  gtk_widget_show (GTK_WIDGET (cs->progressbar));
 
729
  gtk_progress_bar_set_fraction (cs->progressbar, 0.0);
 
730
  gtk_box_pack_start (GTK_BOX (vbox),
 
731
                      GTK_WIDGET (cs->progressbar),
 
732
                      FALSE, FALSE, 0);
 
733
 
 
734
  dialog_action_area = cs->station_search->action_area;
 
735
  gtk_widget_show (dialog_action_area);
 
736
  gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area), GTK_BUTTONBOX_END);
 
737
 
 
738
  cancel = gtk_button_new_from_stock (GTK_STOCK_STOP);
 
739
  gtk_widget_show (cancel);
 
740
  gtk_dialog_add_action_widget (cs->station_search, cancel, 0);
 
741
  g_signal_connect (G_OBJECT (cancel), "clicked",
 
742
                    G_CALLBACK (on_station_search_cancel_clicked), ce);
 
743
 
 
744
  gtk_widget_show (GTK_WIDGET (cs->station_search));
 
745
 
 
746
  gtk_widget_set_sensitive (GTK_WIDGET (ce->vbox), FALSE);
 
747
 
 
748
  current_rf_channel_table (ce, &cs->ch, NULL);
 
749
  cs->channel = 0;
 
750
  cs->iteration = 0;
 
751
 
 
752
  for (l = tv_next_video_input (zapping->info, NULL);
 
753
       l; l = tv_next_video_input (zapping->info, l))
 
754
    if (l->type == TV_VIDEO_LINE_TYPE_TUNER)
 
755
      break;
 
756
 
 
757
  g_assert (l != NULL);
 
758
 
 
759
  tv_set_video_input (zapping->info, l);
 
760
  /* XXX consider multiple tuners */
 
761
 
 
762
  cs->timeout_handle = gtk_timeout_add (100 /* ms */,
 
763
                                        station_search_timeout, ce);
 
764
}
 
765
 
 
766
static void
 
767
on_add_all_channels_clicked     (GtkButton *    add_all_channels _unused_,
 
768
                                 channel_editor *       ce)
 
769
{
 
770
  tv_rf_channel ch;
 
771
  tveng_tuned_channel tc;
 
772
  gboolean align;
 
773
 
 
774
  CLEAR (tc);
 
775
 
 
776
  current_rf_channel_table (ce, &ch, NULL);
 
777
 
 
778
  align = tv_rf_channel_align (&ch);
 
779
 
 
780
  if (align)
 
781
    {
 
782
      GtkTreeIter iter;
 
783
      gint added;
 
784
 
 
785
      added = tveng_tuned_channel_num (global_channel_list);
 
786
 
 
787
      do
 
788
        if (g_ascii_isdigit (ch.channel_name[0]))
 
789
          {
 
790
            tc.name     = (gchar *) ch.channel_name;
 
791
            tc.rf_name  = (gchar *) ch.channel_name;
 
792
            tc.rf_table = (gchar *) ch.table_name;
 
793
            tc.frequ    = ch.frequency;
 
794
 
 
795
            tveng_tuned_channel_replace (&global_channel_list,
 
796
                                         tveng_tuned_channel_new (&tc),
 
797
                                         strtoul (ch.channel_name, NULL, 0));
 
798
          }
 
799
      while (tv_rf_channel_next (&ch));
 
800
 
 
801
      added = tveng_tuned_channel_num (global_channel_list) - added;
 
802
 
 
803
      while (added-- > 0)
 
804
        gtk_list_store_append (ce->channel_model, &iter);
 
805
 
 
806
      tv_rf_channel_first (&ch);
 
807
    }
 
808
 
 
809
  do
 
810
    if (!align || !g_ascii_isdigit (ch.channel_name[0]))
 
811
      {
 
812
        tc.name         = (gchar *) ch.channel_name;
 
813
        tc.rf_name      = (gchar *) ch.channel_name;
 
814
        tc.rf_table     = (gchar *) ch.table_name;
 
815
        tc.frequ        = ch.frequency;
 
816
 
 
817
        channel_list_add_tuned_channel (ce, &global_channel_list, &tc);
 
818
      }
 
819
  while (tv_rf_channel_next (&ch));
 
820
}
 
821
 
 
822
static void
 
823
on_import_xawtv_clicked         (GtkButton *    add_all_channels _unused_,
 
824
                                 channel_editor *       ce)
 
825
{
 
826
  GtkTreeIter iter;
 
827
  guint i;
 
828
 
 
829
  /* XXX error ignored */
 
830
  xawtv_import_config (zapping->info, &global_channel_list);
 
831
 
 
832
  gtk_list_store_clear (ce->channel_model);
 
833
 
 
834
  for (i = tveng_tuned_channel_num (global_channel_list); i > 0; --i)
 
835
    gtk_list_store_append (ce->channel_model, &iter);
 
836
}
 
837
 
 
838
static void
 
839
on_freq_selection_changed       (GtkTreeSelection *     selection,
 
840
                                 channel_editor *       ce)
 
841
{
 
842
  GtkTreeIter first, last;
 
843
  GtkTreeIter freq_iter;
 
844
  tveng_tuned_channel *tc, *tc_first, *tc_last;
 
845
  tv_rf_channel ch;
 
846
  gchar *name;
 
847
  gboolean success;
 
848
 
 
849
  if (!gtk_tree_selection_get_selected (selection, NULL, &freq_iter))
 
850
    return;
 
851
 
 
852
  if (!channel_list_get_selection (ce, &first, &last, &tc_first, &tc_last))
 
853
    return;
 
854
 
 
855
  gtk_tree_model_get (GTK_TREE_MODEL (ce->freq_model), &freq_iter,
 
856
                      FL_NAME, &name, -1);
 
857
 
 
858
  current_rf_channel_table (ce, &ch, NULL);
 
859
  success = tv_rf_channel_by_name (&ch, name);
 
860
 
 
861
  g_free (name);
 
862
 
 
863
  if (!success)
 
864
    return;
 
865
 
 
866
  for (tc = tc_first;; tc = tc->next)
 
867
    {
 
868
      if (0 != strcmp (tc->rf_table, ch.table_name))
 
869
        {
 
870
          g_free (tc->rf_table);
 
871
          tc->rf_table = g_strdup (ch.table_name);
 
872
        }
 
873
 
 
874
      if (0 != strcmp (tc->rf_name, ch.channel_name))
 
875
        {
 
876
          g_free (tc->rf_name);
 
877
          tc->rf_name = g_strdup (ch.channel_name);
 
878
        }
 
879
 
 
880
      tc->frequ = ch.frequency;
 
881
 
 
882
      if (tc == tc_last)
 
883
        break;
 
884
    }
 
885
 
 
886
  if (tunable_input (ce, zapping->info, tc_first))
 
887
    {
 
888
      entry_fine_tuning_set (ce, zapping->info, ch.frequency);
 
889
      tv_set_tuner_frequency (zapping->info, ch.frequency);
 
890
    }
 
891
 
 
892
  channel_list_rows_changed (ce, &first, &last);
 
893
}
 
894
 
 
895
static void
 
896
on_channel_up_clicked           (GtkButton *            channel_up _unused_,
 
897
                                 channel_editor *       ce)
 
898
{
 
899
  GtkTreeIter dummy, first, last, first_prev;
 
900
  tveng_tuned_channel *tc;
 
901
  guint index;
 
902
 
 
903
  if (!channel_list_get_selection (ce, &first, &last, NULL, NULL))
 
904
    return;
 
905
 
 
906
  if (!tree_model_iter_prev (GTK_TREE_MODEL (ce->channel_model), &first))
 
907
    return; /* nothing above */
 
908
 
 
909
  tc = channel_list_get_tuned_channel (ce, &first);
 
910
  index = channel_list_index (ce, &last) + 1;
 
911
  tveng_tuned_channel_move (&global_channel_list, tc, index);
 
912
 
 
913
  gtk_list_store_insert_after (ce->channel_model, &dummy, &last);
 
914
  gtk_list_store_remove (ce->channel_model, &first);
 
915
 
 
916
  channel_list_get_selection (ce, &first, NULL, NULL, NULL);
 
917
  first_prev = first;
 
918
  if (!tree_model_iter_prev (GTK_TREE_MODEL (ce->channel_model), &first_prev))
 
919
    first_prev = first;
 
920
  channel_list_scroll_to_cell (ce, &first_prev, 0.01);
 
921
 
 
922
  channel_buttons_set_sensitive (ce, TRUE);
 
923
}
 
924
 
 
925
static void
 
926
on_channel_down_clicked         (GtkButton *            channel_down _unused_,
 
927
                                 channel_editor *       ce)
 
928
{
 
929
  GtkTreeIter dummy, first, last, last_next;
 
930
  tveng_tuned_channel *tc;
 
931
  guint index;
 
932
 
 
933
  if (!channel_list_get_selection (ce, &first, &last, NULL, NULL))
 
934
    return;
 
935
 
 
936
  if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (ce->channel_model), &last))
 
937
    return; /* nothing below */
 
938
 
 
939
  tc = channel_list_get_tuned_channel (ce, &last);
 
940
  index = channel_list_index (ce, &first);
 
941
  tveng_tuned_channel_move (&global_channel_list, tc, index);
 
942
 
 
943
  gtk_list_store_remove (ce->channel_model, &last);
 
944
  gtk_list_store_insert_before (ce->channel_model, &dummy, &first);
 
945
 
 
946
  channel_list_get_selection (ce, NULL, &last, NULL, NULL);
 
947
  last_next = last;
 
948
  if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (ce->channel_model), &last_next))
 
949
    last_next = last;
 
950
  channel_list_scroll_to_cell (ce, &last_next, 0.99);
 
951
 
 
952
  channel_buttons_set_sensitive (ce, TRUE);
 
953
}
 
954
 
 
955
static void
 
956
on_channel_add_clicked          (GtkButton *            channel_add _unused_,
 
957
                                 channel_editor *       ce)
 
958
{
 
959
  GtkTreeIter iter;
 
960
 
 
961
  if (channel_list_get_selection (ce, &iter, NULL, NULL, NULL))
 
962
    {
 
963
      tveng_tuned_channel_insert (&global_channel_list,
 
964
                                  tveng_tuned_channel_new (NULL),
 
965
                                  channel_list_index (ce, &iter));
 
966
      gtk_list_store_insert_before (ce->channel_model, &iter, &iter);
 
967
    }
 
968
  else
 
969
    {
 
970
      tveng_tuned_channel_insert (&global_channel_list,
 
971
                                  tveng_tuned_channel_new (NULL),
 
972
                                  G_MAXINT);
 
973
      gtk_list_store_append (ce->channel_model, &iter);
 
974
    }
 
975
 
 
976
  gtk_tree_selection_unselect_all (ce->channel_selection);
 
977
  gtk_tree_selection_select_iter (ce->channel_selection, &iter);
 
978
 
 
979
  channel_list_scroll_to_cell (ce, &iter, 0.5);
 
980
 
 
981
  channel_buttons_set_sensitive (ce, TRUE);
 
982
}
 
983
 
 
984
static void
 
985
on_channel_remove_clicked       (GtkButton *    channel_remove _unused_,
 
986
                                 channel_editor *       ce)
 
987
{
 
988
  tveng_tuned_channel *tc, *tc_next;
 
989
  GtkTreeIter iter;
 
990
 
 
991
  if (!channel_list_get_selection (ce, &iter, NULL, &tc, NULL))
 
992
    return;
 
993
 
 
994
  BLOCK (channel_selection, changed,
 
995
         while (VALID_ITER (&iter, ce->channel_model))
 
996
           {
 
997
             if (!gtk_tree_selection_iter_is_selected (ce->channel_selection, &iter))
 
998
               break;
 
999
    
 
1000
     gtk_list_store_remove (ce->channel_model, &iter);
 
1001
 
 
1002
             tc_next = tc->next;
 
1003
             tveng_tuned_channel_remove (&global_channel_list, tc);
 
1004
             tveng_tuned_channel_delete (tc);
 
1005
             tc = tc_next;
 
1006
           }
 
1007
         );
 
1008
 
 
1009
  if (VALID_ITER (&iter, ce->channel_model))
 
1010
    {
 
1011
      gtk_tree_selection_select_iter (ce->channel_selection, &iter);
 
1012
      channel_list_scroll_to_cell (ce, &iter, 0.5);
 
1013
    }
 
1014
  else
 
1015
    {
 
1016
      no_channel_selected (ce);
 
1017
    }
 
1018
}
 
1019
 
 
1020
static void
 
1021
on_entry_name_changed           (GtkEditable *          channel_name,
 
1022
                                 channel_editor *       ce)
 
1023
{
 
1024
  tveng_tuned_channel *tc, *tc_last;
 
1025
  GtkTreeIter first, last;
 
1026
  gchar *name;
 
1027
 
 
1028
  if (!channel_list_get_selection (ce, &first, &last, &tc, &tc_last))
 
1029
    return;
 
1030
 
 
1031
  name = gtk_editable_get_chars (channel_name, 0, -1);
 
1032
 
 
1033
  g_free (tc->name);
 
1034
  tc->name = name;
 
1035
 
 
1036
  while (tc != tc_last)
 
1037
    {
 
1038
      tc = tc->next;
 
1039
 
 
1040
      g_free (tc->name);
 
1041
      tc->name = g_strdup (name);
 
1042
    }
 
1043
 
 
1044
  channel_list_rows_changed (ce, &first, &last);
 
1045
}
 
1046
 
 
1047
static void
 
1048
on_entry_input_changed          (GtkOptionMenu *        entry_input,
 
1049
                                 channel_editor *       ce)
 
1050
{
 
1051
  tveng_tuned_channel *tc, *tc_last;
 
1052
  GtkTreeIter first, last;
 
1053
  guint id;
 
1054
 
 
1055
  if (!channel_list_get_selection (ce, &first, &last, &tc, &tc_last))
 
1056
    return;
 
1057
 
 
1058
  id = z_option_menu_get_active (GTK_WIDGET (entry_input));
 
1059
 
 
1060
  if (id == DONT_CHANGE)
 
1061
    {
 
1062
      tc->input = 0;
 
1063
    }
 
1064
  else
 
1065
    {
 
1066
      tv_video_line *l;
 
1067
 
 
1068
      l = tv_nth_video_input (zapping->info, id - 1);
 
1069
      tc->input = l->hash;
 
1070
      tv_set_video_input (zapping->info, l);
 
1071
    }
 
1072
 
 
1073
  for (; tc_last != tc; tc_last = tc_last->prev)
 
1074
    tc_last->input = tc->input;
 
1075
 
 
1076
  channel_list_rows_changed (ce, &first, &last);
 
1077
}
 
1078
 
 
1079
static void
 
1080
on_entry_fine_tuning_value_changed (GtkAdjustment *     spin_adj,
 
1081
                                    channel_editor *    ce)
 
1082
{
 
1083
  tveng_tuned_channel *tc, *tc_last;
 
1084
  GtkTreeIter first, last;
 
1085
 
 
1086
  if (!channel_list_get_selection (ce, &first, &last, &tc, &tc_last))
 
1087
    return;
 
1088
 
 
1089
  tc->frequ = (guint)(spin_adj->value * 1000000);
 
1090
 
 
1091
  tv_set_tuner_frequency (zapping->info, tc->frequ);
 
1092
 
 
1093
  for (; tc_last != tc; tc_last = tc_last->prev)
 
1094
    {
 
1095
      if (0 != strcmp (tc->rf_name, tc_last->rf_name))
 
1096
        {
 
1097
          g_free (tc_last->rf_name);
 
1098
          tc_last->rf_name = g_strdup (tc->rf_name);
 
1099
        }
 
1100
 
 
1101
      tc_last->frequ = tc->frequ;
 
1102
    }
 
1103
 
 
1104
  channel_list_rows_changed (ce, &first, &last);
 
1105
}
 
1106
 
 
1107
static void
 
1108
on_entry_standard_changed       (GtkOptionMenu *        entry_standard,
 
1109
                                 channel_editor *       ce)
 
1110
{
 
1111
  tveng_tuned_channel *tc, *tc_last;
 
1112
  GtkTreeIter first, last;
 
1113
  guint id;
 
1114
 
 
1115
  if (!channel_list_get_selection (ce, &first, &last, &tc, &tc_last))
 
1116
    return;
 
1117
 
 
1118
  id = z_option_menu_get_active (GTK_WIDGET (entry_standard));
 
1119
 
 
1120
  if (id == DONT_CHANGE)
 
1121
    {
 
1122
      tc->standard = 0;
 
1123
    }
 
1124
  else
 
1125
    {
 
1126
      tv_video_standard *s;
 
1127
 
 
1128
      s = tv_nth_video_standard (zapping->info, id - 1);
 
1129
      tc->standard = s->hash;
 
1130
      tv_set_video_standard (zapping->info, s);
 
1131
    }
 
1132
 
 
1133
  for (; tc_last != tc; tc_last = tc_last->prev)
 
1134
    tc_last->standard = tc->standard;
 
1135
 
 
1136
  channel_list_rows_changed (ce, &first, &last);
 
1137
}
 
1138
 
 
1139
static void
 
1140
on_entry_accel_changed          (GtkEditable *          editable _unused_,
 
1141
                                 channel_editor *       ce)
 
1142
{
 
1143
  tveng_tuned_channel *tc, *tc_last;
 
1144
  GtkTreeIter first, last;
 
1145
  z_key key;
 
1146
 
 
1147
  if (!channel_list_get_selection (ce, &first, &last, &tc, &tc_last))
 
1148
    return;
 
1149
 
 
1150
  key = z_key_entry_get_key (ce->entry_accel);
 
1151
 
 
1152
  for (;;)
 
1153
    {
 
1154
      tc->accel = key;
 
1155
      if (tc == tc_last)
 
1156
        break;
 
1157
      tc = tc->next;
 
1158
    }
 
1159
 
 
1160
  channel_list_rows_changed (ce, &first, &last);
 
1161
}
 
1162
 
 
1163
static void
 
1164
on_channel_selection_changed    (GtkTreeSelection *     selection _unused_,
 
1165
                                 channel_editor *       ce)
 
1166
{
 
1167
  GtkTreeIter iter;
 
1168
  tveng_tuned_channel *tc;
 
1169
 
 
1170
  if (!channel_list_get_selection (ce, &iter, NULL, &tc, NULL))
 
1171
    {
 
1172
      no_channel_selected (ce);
691
1173
      return;
692
1174
    }
693
1175
 
694
 
  channel_editor = build_widget("channel_editor", NULL);
695
 
  country_options_menu = lookup_widget(channel_editor,
696
 
                                       "country_options_menu");
697
 
 
698
 
  move_channel_up = lookup_widget(channel_editor, "move_channel_up");
699
 
  move_channel_down = lookup_widget(channel_editor, "move_channel_down");
700
 
 
701
 
  channel_list = lookup_widget(channel_editor, "channel_list");
702
 
  new_menu = gtk_menu_new();
703
 
 
704
 
  /* Let's setup the window */
705
 
  gtk_widget_destroy(gtk_option_menu_get_menu (GTK_OPTION_MENU
706
 
                                               (country_options_menu)));
707
 
 
708
 
  while ((tune = tveng_get_country_tune_by_id(i)))
709
 
    {
 
1176
  z_switch_channel (tc, zapping->info);
 
1177
 
 
1178
  BLOCK (entry_name, changed,
 
1179
         gtk_entry_set_text (ce->entry_name, tc->name));
 
1180
 
 
1181
  BLOCK (entry_input, changed,
 
1182
         {
 
1183
           const tv_video_line *l;
 
1184
           guint index;
 
1185
 
 
1186
           l = NULL;
 
1187
           index = 0;
 
1188
 
 
1189
           if (tc->input != DONT_CHANGE)
 
1190
             for (l = tv_next_video_input (zapping->info, NULL);
 
1191
                  l; l = tv_next_video_input (zapping->info, l), ++index)
 
1192
               if (l->hash == tc->input)
 
1193
                 break;
 
1194
 
 
1195
           if (l)
 
1196
             z_option_menu_set_active (GTK_WIDGET (ce->entry_input), index + 1);
 
1197
         }
 
1198
  );
 
1199
 
 
1200
  SIGNAL_HANDLER_BLOCK (ce->entry_fine_tuning->spin_adj,
 
1201
                        (gpointer) on_entry_fine_tuning_value_changed,
 
1202
                        entry_fine_tuning_set (ce, zapping->info, tc->frequ));
 
1203
 
 
1204
  BLOCK (entry_standard, changed,
 
1205
         {
 
1206
           const tv_video_standard *s;
 
1207
           guint index;
 
1208
 
 
1209
           /* Standards depend on current input */
 
1210
           gtk_widget_destroy (gtk_option_menu_get_menu (ce->entry_standard));
 
1211
           gtk_option_menu_set_menu (ce->entry_standard,
 
1212
                                     GTK_WIDGET (create_standard_menu (ce)));
 
1213
 
 
1214
           s = NULL;
 
1215
           index = 0;
 
1216
 
 
1217
           if (tc->standard != DONT_CHANGE)
 
1218
             for (s = tv_next_video_standard (zapping->info, NULL);
 
1219
                  s; s = tv_next_video_standard (zapping->info, s), ++index)
 
1220
               if (s->hash == tc->standard)
 
1221
                 break;
 
1222
 
 
1223
           if (s)
 
1224
             z_option_menu_set_active (GTK_WIDGET (ce->entry_standard), index + 1);
 
1225
         }
 
1226
  );
 
1227
 
 
1228
  SIGNAL_HANDLER_BLOCK (z_key_entry_entry (ce->entry_accel),
 
1229
                        (gpointer) on_entry_accel_changed,
 
1230
                        z_key_entry_set_key (ce->entry_accel, tc->accel));
 
1231
 
 
1232
  gtk_widget_set_sensitive (GTK_WIDGET (ce->entry_table), TRUE);
 
1233
 
 
1234
  channel_buttons_set_sensitive (ce, TRUE);
 
1235
}
 
1236
 
 
1237
static void
 
1238
on_ok_clicked                   (GtkButton *            ok _unused_,
 
1239
                                 channel_editor *       ce)
 
1240
{
 
1241
  tveng_tuned_channel_list_delete (&ce->old_channel_list);
 
1242
 
 
1243
  gtk_widget_destroy (GTK_WIDGET (ce->channel_editor));
 
1244
}
 
1245
 
 
1246
static void
 
1247
on_help_clicked                 (GtkButton *            button _unused_,
 
1248
                                 channel_editor *       ce)
 
1249
{
 
1250
  z_help_display (GTK_WINDOW (ce->channel_editor),
 
1251
                  "zapping", "zapping-channel-editor");
 
1252
}
 
1253
 
 
1254
static void
 
1255
on_cancel_clicked               (GtkButton *            cancel _unused_,
 
1256
                                 channel_editor *       ce)
 
1257
{
 
1258
  gtk_widget_destroy (GTK_WIDGET (ce->channel_editor));
 
1259
}
 
1260
 
 
1261
static void
 
1262
on_channel_editor_destroy       (GtkObject *            unused _unused_,
 
1263
                                 channel_editor *       ce)
 
1264
{
 
1265
  if (ce->search)
 
1266
    gtk_widget_destroy (GTK_WIDGET (ce->search->station_search));
 
1267
 
 
1268
  if (ce->old_channel_list)
 
1269
    {
 
1270
      tveng_tuned_channel_list_delete (&global_channel_list);
 
1271
      global_channel_list = ce->old_channel_list;
 
1272
      ce->old_channel_list = NULL;
 
1273
    }
 
1274
 
 
1275
  {
 
1276
    struct country *c;
 
1277
 
 
1278
    for (c = &g_array_index (ce->country_table, struct country, 0); c->table_name; c++)
 
1279
      {
 
1280
        g_free (c->table_name);
 
1281
        g_free (c->gui_name);
 
1282
      }
 
1283
 
 
1284
    g_array_free (ce->country_table, /* elements */ FALSE);
 
1285
  }
 
1286
 
 
1287
  g_free (ce);
 
1288
 
 
1289
  /* Update menus. XXX should rebuild automatically when
 
1290
     opened after any change. */
 
1291
  zmodel_changed (z_input_model);
 
1292
 
 
1293
  dialog_running = NULL;
 
1294
}
 
1295
 
 
1296
/*
 
1297
 * channel_list GtkTreeCellDataFuncs
 
1298
 */
 
1299
 
 
1300
static void
 
1301
set_func_index                  (GtkTreeViewColumn *    column _unused_,
 
1302
                                 GtkCellRenderer *      cell,
 
1303
                                 GtkTreeModel *         model,
 
1304
                                 GtkTreeIter *          iter,
 
1305
                                 gpointer               data _unused_)
 
1306
{
 
1307
  tveng_tuned_channel *tc = tree_model_tuned_channel (model, iter);
 
1308
  gchar buf[32];
 
1309
 
 
1310
  g_snprintf (buf, sizeof (buf) - 1, "%u", tc->index);
 
1311
 
 
1312
  g_object_set (GTK_CELL_RENDERER (cell), "text", buf, NULL);
 
1313
}
 
1314
 
 
1315
static void
 
1316
set_func_name                   (GtkTreeViewColumn *    column _unused_,
 
1317
                                 GtkCellRenderer *      cell,
 
1318
                                 GtkTreeModel *         model,
 
1319
                                 GtkTreeIter *          iter,
 
1320
                                 gpointer               data _unused_)
 
1321
{
 
1322
  tveng_tuned_channel *tc = tree_model_tuned_channel (model, iter);
 
1323
 
 
1324
  g_object_set (GTK_CELL_RENDERER (cell), "text", tc->name, NULL);
 
1325
}
 
1326
 
 
1327
static void
 
1328
set_func_input                  (GtkTreeViewColumn *    column _unused_,
 
1329
                                 GtkCellRenderer *      cell,
 
1330
                                 GtkTreeModel *         model,
 
1331
                                 GtkTreeIter *          iter,
 
1332
                                 gpointer               data _unused_)
 
1333
{
 
1334
  tveng_tuned_channel *tc = tree_model_tuned_channel (model, iter);
 
1335
  const tv_video_line *l;
 
1336
  const gchar *input_name = NULL;
 
1337
 
 
1338
  if (tc->input != DONT_CHANGE)
 
1339
    if ((l = tv_video_input_by_hash (zapping->info, (guint) tc->input)))
 
1340
      input_name = l->label;
 
1341
 
 
1342
  g_object_set (GTK_CELL_RENDERER (cell), "text", input_name, NULL);
 
1343
}
 
1344
 
 
1345
static void
 
1346
set_func_channel                (GtkTreeViewColumn *    column _unused_,
 
1347
                                 GtkCellRenderer *      cell,
 
1348
                                 GtkTreeModel *         model,
 
1349
                                 GtkTreeIter *          iter,
 
1350
                                 gpointer               data)
 
1351
{
 
1352
  channel_editor *ce = data;
 
1353
  tveng_tuned_channel *tc = tree_model_tuned_channel (model, iter);
 
1354
 
 
1355
  if (tunable_input (ce, zapping->info, tc)
 
1356
      && tc->frequ != 0)
 
1357
    {
 
1358
      gchar *rf_name;
 
1359
 
 
1360
      rf_name = rf_channel_string (tc);
 
1361
      g_object_set (GTK_CELL_RENDERER (cell), "text", rf_name, NULL);
 
1362
      g_free (rf_name);
 
1363
    }
 
1364
  else
 
1365
    {
 
1366
      g_object_set (GTK_CELL_RENDERER (cell), "text", NULL, NULL);
 
1367
    }
 
1368
}
 
1369
 
 
1370
static void
 
1371
set_func_standard               (GtkTreeViewColumn *    column _unused_,
 
1372
                                 GtkCellRenderer *      cell,
 
1373
                                 GtkTreeModel *         model,
 
1374
                                 GtkTreeIter *          iter,
 
1375
                                 gpointer               data _unused_)
 
1376
{
 
1377
  tveng_tuned_channel *tc = tree_model_tuned_channel (model, iter);
 
1378
  const tv_video_standard *s;
 
1379
  const gchar *standard_name = NULL;
 
1380
 
 
1381
  if (tc->standard != DONT_CHANGE)
 
1382
    if ((s = tv_video_standard_by_hash (zapping->info, (guint) tc->standard)))
 
1383
      standard_name = s->label;
 
1384
 
 
1385
  g_object_set (GTK_CELL_RENDERER (cell), "text", standard_name, NULL);
 
1386
}
 
1387
 
 
1388
static void
 
1389
set_func_key                    (GtkTreeViewColumn *    column _unused_,
 
1390
                                 GtkCellRenderer *      cell,
 
1391
                                 GtkTreeModel *         model,
 
1392
                                 GtkTreeIter *          iter,
 
1393
                                 gpointer               data _unused_)
 
1394
{
 
1395
  tveng_tuned_channel *tc = tree_model_tuned_channel (model, iter);
 
1396
  gchar *key_name;
 
1397
 
 
1398
  key_name = z_key_name (tc->accel);
 
1399
 
 
1400
  g_object_set (GTK_CELL_RENDERER (cell), "text", key_name, NULL);
 
1401
 
 
1402
  g_free (key_name);
 
1403
}
 
1404
 
 
1405
#define LABEL(name, x, y)                                               \
 
1406
  label = gtk_label_new (_(name));                                      \
 
1407
  gtk_widget_show (label);                                              \
 
1408
  gtk_table_attach (ce->entry_table, label, x, x + 1, y, y + 1,         \
 
1409
                    (GtkAttachOptions) (GTK_FILL),                      \
 
1410
                    (GtkAttachOptions) (0), 0, 0);                      \
 
1411
  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);                  \
 
1412
  gtk_misc_set_padding (GTK_MISC (label), 3, 0);
 
1413
 
 
1414
#define BUTTON(name, stock, sensitive)                                  \
 
1415
  ce->name = gtk_button_new_from_stock (stock);                         \
 
1416
  gtk_widget_show (ce->name);                                           \
 
1417
  gtk_widget_set_sensitive (ce->name, sensitive);                       \
 
1418
  gtk_box_pack_start (GTK_BOX (vbox), ce->name, FALSE, FALSE, 0);       \
 
1419
  CONNECT (name, clicked);
 
1420
 
 
1421
#define CONNECT(object, signal)                                         \
 
1422
  g_signal_connect (G_OBJECT (ce->object), #signal,                     \
 
1423
                    G_CALLBACK (on_ ## object ## _ ## signal), ce)
 
1424
 
 
1425
static gint
 
1426
country_compare                 (struct country *       c1,
 
1427
                                 struct country *       c2)
 
1428
{
 
1429
  return g_utf8_collate (c1->gui_name, c2->gui_name);
 
1430
}
 
1431
 
 
1432
static GtkWidget *
 
1433
create_country_menu             (channel_editor *       ce)
 
1434
{
 
1435
  GtkWidget *country_menu;
 
1436
  GtkWidget *menu;
 
1437
  tv_rf_channel ch;
 
1438
  const gchar *table_name;
 
1439
  const gchar *country_code;
 
1440
  gchar buf[4];
 
1441
  gint hist, i;
 
1442
  struct country *c;
 
1443
 
 
1444
  country_menu = gtk_option_menu_new ();
 
1445
  gtk_widget_show (country_menu);
 
1446
  gtk_tooltips_set_tip (ce->tooltips, country_menu,
 
1447
                        _("Select the frequency table "
 
1448
                          "used in your country"), NULL);
 
1449
 
 
1450
  menu = gtk_menu_new ();
 
1451
  gtk_option_menu_set_menu (GTK_OPTION_MENU (country_menu), menu);
 
1452
 
 
1453
  tv_rf_channel_first_table (&ch);
 
1454
 
 
1455
  ce->country_table = g_array_new (/* zero_term */ TRUE,
 
1456
                                   /* clear */ FALSE,
 
1457
                                   sizeof (struct country));
 
1458
  do {
 
1459
    do {
 
1460
      const char *country_name;
 
1461
 
 
1462
      if ((country_name = iso3166_to_country_name (ch.country_code)))
 
1463
        {
 
1464
          struct country c;
 
1465
 
 
1466
          c.table_name = g_strconcat (ch.country_code, "@", ch.table_name, NULL);
 
1467
 
 
1468
          if (ch.domain)
 
1469
            c.gui_name = g_strdup_printf ("%s (%s)", country_name, ch.domain);
 
1470
          else
 
1471
            c.gui_name = g_strdup (country_name);
 
1472
 
 
1473
          g_array_append_val (ce->country_table, c);
 
1474
        }
 
1475
    } while (tv_rf_channel_next_country (&ch));
 
1476
  } while (tv_rf_channel_next_table (&ch));
 
1477
 
 
1478
  g_array_sort (ce->country_table, (GCompareFunc) country_compare);
 
1479
 
 
1480
  /*
 
1481
   *  Default country, table or both
 
1482
   *  from e.g. "", "FR", "FR@ccir", "ccir", "Europe" (old current_country)
 
1483
   */
 
1484
  table_name = zconf_get_string (NULL, "/zapping/options/main/current_country");
 
1485
  country_code = locale_country ();
 
1486
 
 
1487
  if (table_name
 
1488
      && g_ascii_isalpha (table_name[0])
 
1489
      && g_ascii_isalpha (table_name[1])
 
1490
      && '@' == table_name[2])
 
1491
    {
 
1492
      buf[0] = table_name[0];
 
1493
      buf[1] = table_name[1];
 
1494
      buf[2] = 0;
 
1495
      country_code = buf;
 
1496
      table_name += 3;
 
1497
    }
 
1498
 
 
1499
  if (table_name
 
1500
      && 0 == table_name[0])
 
1501
    table_name = NULL;
 
1502
 
 
1503
  hist = -1;
 
1504
  i = 0;
 
1505
 
 
1506
  for (c = &g_array_index (ce->country_table, struct country, 0);
 
1507
       c->table_name; c++)
 
1508
    {
 
1509
      GtkWidget *item;
 
1510
 
 
1511
      item = gtk_menu_item_new_with_label (c->gui_name);
 
1512
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
1513
      gtk_widget_show (item);
 
1514
 
 
1515
      if (hist < 0)
 
1516
        if (!table_name || 0 == strcmp (c->table_name + 3, table_name))
 
1517
          if (!country_code || 0 == strncmp (c->table_name, country_code, 2))
 
1518
            hist = i;
710
1519
      i++;
711
 
      if (tune == current_country)
712
 
        currently_tuned_country = i-1;
713
 
      menu_item = gtk_menu_item_new_with_label(_(tune->name));
714
 
      gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
715
 
                         GTK_SIGNAL_FUNC(on_country_switch),
716
 
                         tune);
717
 
      gtk_widget_show(menu_item);
718
 
      gtk_menu_append( GTK_MENU(new_menu), menu_item);
719
 
    }
720
 
 
721
 
  /* select the first item if there's no current country */
722
 
  if (current_country == NULL)
723
 
    currently_tuned_country = 0;
724
 
 
725
 
  gtk_widget_show(new_menu);
726
 
 
727
 
  gtk_option_menu_set_menu( GTK_OPTION_MENU(country_options_menu),
728
 
                            new_menu);
729
 
 
730
 
  gtk_option_menu_set_history ( GTK_OPTION_MENU(country_options_menu),
731
 
                                currently_tuned_country);
732
 
 
733
 
  i = 0;
734
 
 
735
 
  while ((tuned_channel =
736
 
          tveng_retrieve_tuned_channel_by_index(i++, global_channel_list)))
737
 
    list = tveng_append_tuned_channel(tuned_channel, list);
738
 
 
739
 
  istyle = gtk_style_copy (channel_editor->style);
740
 
 
741
 
  /* Cough. */
742
 
  istyle->fg[GTK_STATE_NORMAL] =
743
 
    istyle->fg[GTK_STATE_INSENSITIVE];
744
 
 
745
 
  build_channel_list(GTK_CLIST(channel_list), list);
746
 
  
747
 
  /* Change contry to the currently tuned one */
748
 
  if (menu_item)
749
 
    on_country_switch(menu_item, 
750
 
                      tveng_get_country_tune_by_id (currently_tuned_country));
751
 
 
752
 
  /* Save the disabled menuitem */
753
 
  gtk_object_set_user_data(GTK_OBJECT(channel_editor), menuitem);
754
 
  gtk_object_set_data(GTK_OBJECT(channel_editor), "list", list);
755
 
 
756
 
  gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE);
757
 
 
758
 
  /* Add fine tuning widget */
759
 
  spinslider_adj = GTK_ADJUSTMENT
760
 
    (gtk_adjustment_new (0, 0, 0, 0, 0, 0));
761
 
  spinslider = z_spinslider_new (spinslider_adj, NULL, "kHz", 0);
762
 
  gtk_widget_set_sensitive (spinslider, FALSE);
763
 
  gtk_widget_show (spinslider);
764
 
  gtk_table_attach_defaults(GTK_TABLE(lookup_widget(channel_editor,
765
 
                                                    "table72")),
766
 
                            spinslider, 1, 2, 2, 3);
767
 
  gtk_object_set_data (GTK_OBJECT (channel_editor),
768
 
                       "spinslider", spinslider);
769
 
 
770
 
  rebuild_inputs_and_standards(NULL, channel_editor);
771
 
  gtk_signal_connect(GTK_OBJECT(z_input_model), "changed",
772
 
                     GTK_SIGNAL_FUNC(rebuild_inputs_and_standards),
773
 
                     channel_editor);
774
 
 
775
 
  gtk_signal_connect(GTK_OBJECT(move_channel_up), "clicked",
776
 
                     GTK_SIGNAL_FUNC(on_move_channel_up_clicked),
777
 
                     channel_editor);
778
 
  gtk_signal_connect(GTK_OBJECT(move_channel_down), "clicked",
779
 
                     GTK_SIGNAL_FUNC(on_move_channel_down_clicked),
780
 
                     channel_editor);
781
 
  gtk_signal_connect(GTK_OBJECT(channel_list), "unselect-row",
782
 
                     GTK_SIGNAL_FUNC(on_channel_list_unselect_row),
783
 
                     channel_editor);
784
 
  gtk_signal_connect(GTK_OBJECT(channel_editor), "delete-event",
785
 
                     GTK_SIGNAL_FUNC(on_channel_editor_delete_event),
786
 
                     channel_editor);
787
 
  gtk_signal_connect(GTK_OBJECT(spinslider_adj), "value-changed",
788
 
                     GTK_SIGNAL_FUNC(on_fine_tune_value_changed),
789
 
                     main_info);
790
 
 
791
 
  update_edit_buttons_sensitivity(channel_editor);
792
 
 
793
 
  gtk_widget_show(channel_editor);
794
 
 
795
 
  ChannelWindow = channel_editor; /* Set this, we are present */
796
 
}
797
 
 
798
 
/**
799
 
 * This is called when we are done processing the channels, to update
800
 
 *  the GUI
801
 
 */
802
 
void
803
 
on_channels_done_clicked               (GtkButton       *button,
804
 
                                        gpointer         user_data)
805
 
{
806
 
  GtkWidget * channel_editor = lookup_widget(GTK_WIDGET (button),
807
 
                                             "channel_editor"); /* The
808
 
                                             channel editor window */
809
 
  GtkWidget * menu_item; /* The menu item asocciated with this entry */
810
 
  tveng_tuned_channel * list =
811
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
812
 
 
813
 
  int index; /* The row we are reading now */
814
 
 
815
 
  tveng_tuned_channel * tc;
816
 
 
817
 
  /* Clear tuned channel list */
818
 
  global_channel_list =
819
 
    tveng_clear_tuned_channel(global_channel_list);
820
 
 
821
 
  index = 0;
822
 
 
823
 
  while ((tc = tveng_retrieve_tuned_channel_by_index(index++, list)))
824
 
    global_channel_list =
825
 
      tveng_append_tuned_channel(tc, global_channel_list);
826
 
 
827
 
  /* We are done, acknowledge the update in the model  */
828
 
  menu_item =
829
 
    GTK_WIDGET(gtk_object_get_user_data(GTK_OBJECT(channel_editor)));
830
 
 
831
 
  gtk_signal_disconnect_by_func(GTK_OBJECT(z_input_model),
832
 
                                GTK_SIGNAL_FUNC(rebuild_inputs_and_standards),
833
 
                                ChannelWindow);
834
 
  zmodel_changed(z_input_model);
835
 
 
836
 
  gtk_widget_set_sensitive(menu_item, TRUE);
837
 
 
838
 
  tveng_clear_tuned_channel(list);
839
 
 
840
 
  gtk_widget_destroy(channel_editor);
841
 
 
842
 
  ChannelWindow = NULL;
843
 
}
844
 
 
845
 
void
846
 
on_add_channel_clicked                 (GtkButton       *button,
847
 
                                        gpointer         user_data)
848
 
{
849
 
  GtkWidget *channel_name = lookup_widget(GTK_WIDGET(button),
850
 
                                          "channel_name");
851
 
  GtkWidget *clist1 = lookup_widget(GTK_WIDGET(button), "clist1");
852
 
  gchar *buf =
853
 
    gtk_entry_get_text(GTK_ENTRY(channel_name));
854
 
  GList *ptr;
855
 
  gchar *buf2;
856
 
  gint index;
857
 
 
858
 
  if (!buf || !*buf)
859
 
    {
860
 
      ptr = GTK_CLIST(clist1) -> row_list;
861
 
      index = 0;
862
 
      while (ptr)
863
 
        {
864
 
          if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
865
 
            { 
866
 
              /* Add this selected channel to the channel list */
867
 
              gtk_clist_get_text(GTK_CLIST(clist1), index, 0,
868
 
                                 &(buf2));
869
 
              break; /* found */
870
 
            }
871
 
          ptr = ptr -> next;
872
 
          index++;
873
 
        }
874
 
 
875
 
      if (!ptr)
876
 
        buf2 = "";
877
 
 
878
 
      buf = Prompt(lookup_widget(GTK_WIDGET(button),
879
 
                                 "channel_editor"),
880
 
                   _("Add Channel"), _("New channel name:"), buf2);
881
 
      
882
 
      if (buf)
883
 
        {
884
 
          gtk_entry_set_text(GTK_ENTRY(channel_name), buf);
885
 
          g_free(buf);
886
 
        }
887
 
      else
888
 
        return; /* cancelled */
889
 
    }
890
 
 
891
 
  real_add_channel(channel_name, user_data);
892
 
}
893
 
 
894
 
void
895
 
on_add_all_channels_clicked            (GtkButton       *button,
896
 
                                        gpointer         user_data)
897
 
{
898
 
  GtkWidget * channel_list = lookup_widget(GTK_WIDGET(button),
899
 
                                           "channel_list");
900
 
  GtkWidget * channel_editor = lookup_widget(GTK_WIDGET(button),
901
 
                                             "channel_editor");
902
 
  tveng_tuned_channel * list =
903
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
904
 
  tveng_tuned_channel tc;
905
 
  tveng_rf_channel *chan;
906
 
  int i = 0;
907
 
 
908
 
  while ((chan = tveng_get_channel_by_id(i++, current_country)))
909
 
    {
910
 
      memset(&tc, 0, sizeof(tveng_tuned_channel));
911
 
      tc.rf_name = tc.name = g_strdup(chan->name);
912
 
      tc.country = g_strdup(current_country->name);
913
 
      tc.freq = chan->freq;
914
 
      store_control_values(&tc.num_controls, &tc.controls, main_info);
915
 
      list = tveng_insert_tuned_channel_sorted(&tc, list);
916
 
      g_free(tc.controls);
917
 
      g_free(tc.name);
918
 
      g_free(tc.country);
919
 
    }
920
 
 
921
 
  gtk_object_set_data(GTK_OBJECT(channel_editor), "list", list);
922
 
 
923
 
  build_channel_list(GTK_CLIST(channel_list), list);
924
 
}
925
 
 
926
 
void
927
 
on_modify_channel_clicked              (GtkButton       *button,
928
 
                                        gpointer         user_data)
929
 
{
930
 
  GtkWidget * clist1 = lookup_widget(GTK_WIDGET(button), "clist1");
931
 
  GtkWidget * channel_list = lookup_widget(GTK_WIDGET(button),
932
 
                                           "channel_list");
933
 
  GtkWidget * channel_editor = lookup_widget(GTK_WIDGET(button),
934
 
                                             "channel_editor");
935
 
  tveng_tuned_channel * list =
936
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
937
 
  GtkWidget * channel_name = lookup_widget(GTK_WIDGET(button),
938
 
                                           "channel_name");
939
 
  GtkWidget * channel_accel = lookup_widget(GTK_WIDGET(button),
940
 
                                            "channel_accel");
941
 
  GList * ptr; /* Pointer to the selected item(s) in clist1 */
942
 
  int index=0; /* The row we are reading now */
943
 
  tveng_tuned_channel tc, *p;
944
 
  gint selected;
945
 
  gboolean selected_rows[tveng_tuned_channel_num(list)];
946
 
 
947
 
  memset(selected_rows, 0, sizeof(selected_rows));
948
 
 
949
 
  tc.name = gtk_entry_get_text (GTK_ENTRY(channel_name));
950
 
 
951
 
  if (current_country)
952
 
    tc.country = g_strdup(current_country->name);
953
 
  else
954
 
    tc.country = NULL;
955
 
 
956
 
  tc.accel = z_key_entry_get_key (channel_accel);
957
 
 
 
1520
    }
 
1521
 
 
1522
  if (hist < 0)
 
1523
    hist = 0; /* any */
 
1524
  else if (!table_name)
 
1525
    zconf_set_string (g_array_index (ce->country_table, struct country, hist).table_name,
 
1526
                      "/zapping/options/main/current_country");
 
1527
 
 
1528
  gtk_option_menu_set_history (GTK_OPTION_MENU (country_menu), (guint) hist);
 
1529
 
 
1530
  return country_menu;
 
1531
}
 
1532
 
 
1533
static GtkListStore *
 
1534
create_freq_list_model          (const tv_rf_channel *  table)
 
1535
{
 
1536
  GtkListStore *model;
 
1537
  tv_rf_channel ch;
 
1538
 
 
1539
  model = gtk_list_store_new (FL_NUM_COLUMNS,
 
1540
                              G_TYPE_STRING,    /* name */
 
1541
                              G_TYPE_STRING);   /* freq */
 
1542
  ch = *table;
 
1543
 
 
1544
  do
 
1545
    {
 
1546
      gchar freq[256];
 
1547
      GtkTreeIter iter;
 
1548
 
 
1549
      g_snprintf (freq, sizeof (freq) - 1, "%.2f", ch.frequency / 1e6);
 
1550
 
 
1551
      gtk_list_store_append (model, &iter);
 
1552
      gtk_list_store_set (model, &iter,
 
1553
                          FL_NAME, ch.channel_name,
 
1554
                          FL_FREQ, freq, -1);
 
1555
    }
 
1556
  while (tv_rf_channel_next (&ch));
 
1557
 
 
1558
  return model;
 
1559
}
 
1560
 
 
1561
static GtkWidget *
 
1562
create_freq_treeview            (channel_editor *       ce)
 
1563
{
 
1564
  GtkWidget *scrolledwindow;
 
1565
  GtkCellRenderer *renderer;
 
1566
  GtkTreeViewColumn *column;
 
1567
  tv_rf_channel ch;
 
1568
 
 
1569
  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 
1570
  gtk_widget_show (scrolledwindow);
 
1571
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
 
1572
                                  GTK_POLICY_NEVER,
 
1573
                                  GTK_POLICY_AUTOMATIC);
 
1574
 
 
1575
  ce->freq_treeview = GTK_TREE_VIEW (gtk_tree_view_new ());
 
1576
  gtk_widget_show (GTK_WIDGET (ce->freq_treeview));
 
1577
  gtk_container_add (GTK_CONTAINER (scrolledwindow), GTK_WIDGET (ce->freq_treeview));
 
1578
  gtk_tree_view_set_rules_hint (ce->freq_treeview, TRUE);
 
1579
 
 
1580
  ce->freq_selection = gtk_tree_view_get_selection (ce->freq_treeview);
 
1581
  gtk_tree_selection_set_mode (ce->freq_selection, GTK_SELECTION_SINGLE);
 
1582
  CONNECT (freq_selection, changed);
 
1583
 
 
1584
  current_rf_channel_table (ce, &ch, NULL);
 
1585
  ce->freq_model = create_freq_list_model (&ch);
 
1586
  gtk_tree_view_set_model (ce->freq_treeview, GTK_TREE_MODEL (ce->freq_model));
 
1587
 
 
1588
  renderer = gtk_cell_renderer_text_new ();
 
1589
  /* TRANSLATORS: RF channel name in frequency table. */
 
1590
  column = gtk_tree_view_column_new_with_attributes
 
1591
    (_("Ch. Name"), renderer, "text", FL_NAME, NULL);
 
1592
  gtk_tree_view_append_column (ce->freq_treeview, column);  
 
1593
          
 
1594
  renderer = gtk_cell_renderer_text_new ();
 
1595
  column = gtk_tree_view_column_new_with_attributes
 
1596
    (_("Freq (MHz)"), renderer, "text", FL_FREQ, NULL);
 
1597
  gtk_tree_view_append_column (ce->freq_treeview, column);  
 
1598
 
 
1599
  return scrolledwindow;
 
1600
}
 
1601
 
 
1602
static GtkListStore *
 
1603
create_channel_list_model       (const tveng_tuned_channel *list _unused_)
 
1604
{
 
1605
  GtkListStore *model;
 
1606
  GtkTreeIter iter;
 
1607
  guint i;
 
1608
 
 
1609
  model = gtk_list_store_new (1, G_TYPE_UINT);
 
1610
 
 
1611
  for (i = tveng_tuned_channel_num (global_channel_list); i; i--)
 
1612
    gtk_list_store_append (model, &iter);
 
1613
 
 
1614
  return model;
 
1615
}
 
1616
 
 
1617
static GtkWidget *
 
1618
create_channel_treeview         (channel_editor *       ce)
 
1619
{
 
1620
  GtkWidget *scrolledwindow;
 
1621
 
 
1622
  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 
1623
  gtk_widget_show (scrolledwindow);
 
1624
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
 
1625
                                  GTK_POLICY_NEVER,
 
1626
                                  GTK_POLICY_AUTOMATIC);
 
1627
 
 
1628
  ce->channel_treeview = GTK_TREE_VIEW (gtk_tree_view_new ());
 
1629
  gtk_widget_show (GTK_WIDGET (ce->channel_treeview));
 
1630
  gtk_container_add (GTK_CONTAINER (scrolledwindow),
 
1631
                     GTK_WIDGET (ce->channel_treeview));
 
1632
  gtk_tree_view_set_rules_hint (ce->channel_treeview, TRUE);
958
1633
  /*
959
 
    When this is a baseband input, tc.freq will be random.
960
 
    You'll get it when switching back to tuner, so it's
961
 
    even better to store the spinslider value (default 0)
962
 
    instead of initializing to zero or some.
963
 
  if (main_info->inputs &&
964
 
      main_info->inputs[main_info->cur_input].tuners)
 
1634
  gtk_tree_view_set_search_column (ce->channel_treeview, CL_NAME);
965
1635
  */
966
 
    {
967
 
      GtkWidget *spinslider =
968
 
        gtk_object_get_data (GTK_OBJECT (channel_editor),
969
 
                             "spinslider");
970
 
 
971
 
      tc.freq = z_spinslider_get_value (spinslider);
972
 
    }
973
 
 
974
 
  selected =
975
 
    z_option_menu_get_active(lookup_widget(clist1, "attached_input"));
976
 
  if (selected && main_info->inputs)
977
 
    tc.input = main_info->inputs[selected-1].hash;
978
 
  else
979
 
    tc.input = 0;
980
 
 
981
 
  selected =
982
 
    z_option_menu_get_active(lookup_widget(clist1, "attached_standard"));
983
 
  if (selected)
984
 
    tc.standard = main_info->standards[selected-1].hash;
985
 
  else
986
 
    tc.standard = 0;
987
 
 
988
 
  ptr = GTK_CLIST(clist1) -> row_list;
989
 
 
990
 
  /* Again, using a GUI element as a data storage struct is a
991
 
     HORRIBLE(tm) thing, but other things would be overcomplicated */
992
 
  while (ptr)
993
 
    {
994
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
995
 
        { 
996
 
          gtk_clist_get_text(GTK_CLIST(clist1), index, 0,
997
 
                             &(tc.rf_name));
998
 
          break;
999
 
        }
1000
 
      index ++;
1001
 
      ptr = ptr -> next;
1002
 
    }
1003
 
 
1004
 
  if (!ptr)
1005
 
    return;
1006
 
 
1007
 
  store_control_values(&tc.num_controls, &tc.controls, main_info);
1008
 
 
1009
 
  index = 0;
1010
 
 
1011
 
  ptr = GTK_CLIST(channel_list) -> row_list;
1012
 
 
1013
 
  while (ptr)
1014
 
    {
1015
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
1016
 
        {
1017
 
          if ((p = tveng_retrieve_tuned_channel_by_index(index,
1018
 
                                                         list)))
1019
 
            tveng_copy_tuned_channel(p, &tc);
1020
 
          selected_rows[index] = TRUE;
1021
 
        }
1022
 
 
1023
 
      ptr = ptr -> next;
1024
 
      index++;
1025
 
    }
1026
 
 
1027
 
  g_free(tc.controls);
1028
 
  g_free(tc.country);
1029
 
 
1030
 
  build_channel_list(GTK_CLIST(channel_list), list);
1031
 
 
1032
 
  /* select channels again */
1033
 
  gtk_signal_handler_block_by_func(GTK_OBJECT(channel_list),
1034
 
                           GTK_SIGNAL_FUNC(on_channel_list_select_row),
1035
 
                           NULL);
1036
 
 
1037
 
  for (index=0; index<tveng_tuned_channel_num(list); index++)
1038
 
    if (selected_rows[index])
1039
 
      gtk_clist_select_row(GTK_CLIST(channel_list), index, 0);
1040
 
  gtk_signal_handler_unblock_by_func(GTK_OBJECT(channel_list),
1041
 
                             GTK_SIGNAL_FUNC(on_channel_list_select_row),
1042
 
                             NULL);
1043
 
 
1044
 
  update_edit_buttons_sensitivity(GTK_WIDGET(channel_list));
1045
 
}
1046
 
 
1047
 
void
1048
 
on_remove_channel_clicked              (GtkButton       *button,
1049
 
                                        gpointer         user_data)
1050
 
{
1051
 
  GtkWidget * channel_list = lookup_widget(GTK_WIDGET(button),
1052
 
                                           "channel_list");
1053
 
  GtkWidget * channel_editor = lookup_widget(GTK_WIDGET(button),
1054
 
                                             "channel_editor");
1055
 
  tveng_tuned_channel * list =
1056
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
1057
 
 
1058
 
  GList * ptr; /* Pointer to the selected item(s) in clist1 */
1059
 
  int index; /* The row we are reading now */
1060
 
  int deleted = 0;
1061
 
 
1062
 
  index = 0;
1063
 
 
1064
 
  ptr = GTK_CLIST(channel_list) -> row_list;
1065
 
 
1066
 
  while (ptr)
1067
 
    {
1068
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
1069
 
        {
1070
 
          /* Add this selected channel to the channel list */
1071
 
          list = tveng_remove_tuned_channel(NULL, index-deleted, list);
1072
 
          deleted++;
1073
 
        }
1074
 
 
1075
 
      ptr = ptr -> next;
1076
 
      index++;
1077
 
    }
1078
 
 
1079
 
  gtk_object_set_data(GTK_OBJECT(channel_editor), "list", list);
1080
 
 
1081
 
  build_channel_list(GTK_CLIST(channel_list), list);
1082
 
}
1083
 
 
1084
 
void
1085
 
on_clist1_select_row                   (GtkWidget       *clist,
1086
 
                                        gint             row,
1087
 
                                        gint             column,
1088
 
                                        GdkEvent        *event,
1089
 
                                        gpointer         user_data)
1090
 
{
1091
 
  tveng_rf_table *country = (tveng_rf_table *)
1092
 
    gtk_object_get_user_data( GTK_OBJECT(clist));
1093
 
  tveng_rf_channel * selected_channel =
1094
 
    tveng_get_channel_by_id (row, country);
1095
 
 
1096
 
  if ((!selected_channel) || (!country) || (!main_info->inputs))
1097
 
    {
1098
 
      /* If we reach this it means that we are trying to select a item
1099
 
       in the channel list but it hasn't been filled yet (it is filled
1100
 
       by a callback) */
1101
 
      return;
1102
 
    }
1103
 
 
1104
 
  if (!main_info->inputs[main_info->cur_input].tuners)
1105
 
    return;
1106
 
 
1107
 
  if (-1 == tveng_tune_input(selected_channel->freq, main_info))
1108
 
    g_warning("Cannot tune input at %d: %s", selected_channel->freq,
1109
 
              main_info->error);
1110
 
  else
1111
 
    set_slider(selected_channel->freq,
1112
 
               lookup_widget(clist, "channel_editor"), main_info);
1113
 
}
1114
 
 
1115
 
void
1116
 
on_cancel_channels_clicked             (GtkButton       *button,
1117
 
                                        gpointer         user_data)
1118
 
{
1119
 
  GtkWidget * channel_editor = lookup_widget(GTK_WIDGET (button),
1120
 
                                             "channel_editor"); /* The
1121
 
                                             channel editor window */
1122
 
  GtkWidget * menu_item; /* The menu item asocciated with this entry */
1123
 
 
1124
 
  tveng_tuned_channel * list =
1125
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
1126
 
 
1127
 
  /* We are done, acknowledge the update in the channel list */
1128
 
  menu_item =
1129
 
    GTK_WIDGET(gtk_object_get_user_data(GTK_OBJECT(channel_editor)));
1130
 
 
1131
 
  tveng_clear_tuned_channel(list);
1132
 
 
1133
 
  gtk_signal_disconnect_by_func(GTK_OBJECT(z_input_model),
1134
 
                                GTK_SIGNAL_FUNC(rebuild_inputs_and_standards),
1135
 
                                ChannelWindow);
1136
 
 
1137
 
  zmodel_changed(z_input_model);
1138
 
 
1139
 
  gtk_widget_set_sensitive(menu_item, TRUE);
1140
 
 
1141
 
  gtk_widget_destroy(channel_editor);
1142
 
 
1143
 
  ChannelWindow = NULL;
1144
 
}
1145
 
 
1146
 
void
1147
 
on_channel_name_activate               (GtkWidget       *editable,
1148
 
                                        gpointer         user_data)
1149
 
{
1150
 
  GtkWidget     *channel_list =
1151
 
    lookup_widget(editable, "channel_list");
1152
 
  GList *ptr = GTK_CLIST(channel_list) -> row_list;
1153
 
  gint n_select = 0;
1154
 
 
1155
 
  while (ptr)
1156
 
    {
1157
 
      if (GTK_CLIST_ROW(ptr) -> state == GTK_STATE_SELECTED)
1158
 
        n_select ++;
1159
 
 
1160
 
      ptr = ptr -> next;
1161
 
    }
1162
 
 
1163
 
  if (n_select != 1)
1164
 
    real_add_channel(editable, user_data);
1165
 
  else
1166
 
    on_modify_channel_clicked(GTK_BUTTON(lookup_widget(editable,
1167
 
                                "modify_channel")), user_data);
1168
 
}
1169
 
 
1170
 
void
1171
 
on_help_channels_clicked               (GtkButton       *button,
1172
 
                                        gpointer         user_data)
1173
 
{
1174
 
  GnomeHelpMenuEntry help_ref = { NULL,
1175
 
                                  "channel_editor.html" };
1176
 
  enum tveng_capture_mode cur_mode;
1177
 
 
1178
 
  cur_mode = tveng_stop_everything(main_info);
1179
 
 
1180
 
  help_ref.name = gnome_app_id;
1181
 
  gnome_help_display (NULL, &help_ref);
1182
 
 
1183
 
  if (z_restart_everything(cur_mode, main_info) == -1)
1184
 
    ShowBox(main_info->error, GNOME_MESSAGE_BOX_ERROR);
1185
 
}
1186
 
 
1187
 
static gint control_timeout_id = -1;
1188
 
 
1189
 
static gint
1190
 
control_timeout                         (gpointer       data)
1191
 
{
1192
 
  control_timeout_id = -1;
1193
 
  return FALSE;
1194
 
}
1195
 
 
1196
 
void
1197
 
on_channel_list_select_row             (GtkCList        *clist,
1198
 
                                        gint             row,
1199
 
                                        gint             column,
1200
 
                                        GdkEvent        *event,
1201
 
                                        gpointer         user_data)
1202
 
{
1203
 
  tveng_rf_table * country;
1204
 
  tveng_rf_channel * channel;
1205
 
  int country_id;
1206
 
  int channel_id;
1207
 
  GtkWidget * country_options_menu = lookup_widget(GTK_WIDGET (clist),
1208
 
                                                   "country_options_menu");
1209
 
  GtkWidget * clist1 = lookup_widget(GTK_WIDGET(clist), "clist1");
1210
 
  GtkWidget * channel_name = lookup_widget(GTK_WIDGET(clist),
1211
 
                                           "channel_name");
1212
 
  GtkWidget * channel_editor =
1213
 
    lookup_widget(GTK_WIDGET(clist), "channel_editor");
1214
 
  tveng_tuned_channel * list =
1215
 
    gtk_object_get_data(GTK_OBJECT(channel_editor), "list");
1216
 
  GtkWidget * channel_accel = lookup_widget(GTK_WIDGET(clist),
1217
 
                                            "channel_accel");
1218
 
  GtkWidget * widget;
1219
 
  struct tveng_enumstd *std;
1220
 
  struct tveng_enum_input *input;
1221
 
 
1222
 
  if (control_timeout_id != -1)
1223
 
    {
1224
 
      /* This code only triggers when many channels have been selected
1225
 
       in a short amount of time, avoid switching to all of them
1226
 
       pointlessly */
1227
 
      gtk_timeout_remove(control_timeout_id);
1228
 
      control_timeout_id =
1229
 
        gtk_timeout_add(50, (GtkFunction)control_timeout, NULL);
1230
 
      return;
1231
 
    }
1232
 
 
1233
 
  list = tveng_retrieve_tuned_channel_by_index(row, list);
1234
 
 
1235
 
  g_assert(list != NULL);
1236
 
 
1237
 
  country = tveng_get_country_tune_by_name (list->country);
1238
 
 
1239
 
  /* If we could understand the country, select it */
1240
 
  if (country)
1241
 
    {
1242
 
      country_id = tveng_get_id_of_country_tune (country);
1243
 
      if (country_id < 0)
1244
 
        {
1245
 
          g_warning("Returned country tune id is invalid");
1246
 
          return;
1247
 
        }
1248
 
 
1249
 
      channel = tveng_get_channel_by_name (list->rf_name, country);
1250
 
      if (!channel)
1251
 
        {
1252
 
          g_warning("Channel %s cannot be found in current country: %s", 
1253
 
                    list->rf_name, country->name);
1254
 
          return;
1255
 
        }
1256
 
 
1257
 
      channel_id = tveng_get_id_of_channel (channel, country);
1258
 
      if (channel_id < 0)
1259
 
        {
1260
 
          g_warning ("Returned channel id (%d) is not valid",
1261
 
                     channel_id);
1262
 
          return;
1263
 
        }
1264
 
 
1265
 
      gtk_option_menu_set_history ( GTK_OPTION_MENU(country_options_menu),
1266
 
                                    country_id);
1267
 
      on_country_switch (clist1, country);
1268
 
 
1269
 
      gtk_clist_select_row(GTK_CLIST (clist1), channel_id, 0);
1270
 
      /* make the row visible */
1271
 
      gtk_clist_moveto(GTK_CLIST(clist1), channel_id, 0,
1272
 
                       0.5, 0);
1273
 
    }
1274
 
 
1275
 
  gtk_entry_set_text(GTK_ENTRY(channel_name), list->name);
1276
 
 
1277
 
  z_key_entry_set_key (channel_accel, list->accel);
1278
 
 
1279
 
  /* Tune to this channel's freq */
1280
 
  z_switch_channel(list, main_info);
1281
 
 
1282
 
  if (main_info->inputs &&
1283
 
      main_info->inputs[main_info->cur_input].tuners)
1284
 
    {
1285
 
      set_slider(list->freq, channel_editor, main_info);
1286
 
    }
1287
 
  else if (list->input == 0)
1288
 
    {
1289
 
      /* Problematic. This is a "don't change input" and
1290
 
       * despite displaying a RF the user can't change it
1291
 
       * because we're not switched to a tuner, and we can't
1292
 
       * switch to a tuner either. (Which one? Making this
1293
 
       * silently a "tuner input channel"? The whole "don't
1294
 
       * change" channel idea is kind of odd.)
1295
 
       *
1296
 
       * Anyway we set the slider to this freq for
1297
 
       * on_input_changed while keeping it disabled. Same
1298
 
       * below, see on_modify_channel_clicked and real_add_channel.
1299
 
       */
1300
 
      set_slider(list->freq, channel_editor, main_info);
1301
 
    }
1302
 
  else /* decidedly baseband input */
1303
 
    {
1304
 
      set_slider(list->freq, channel_editor, main_info);
1305
 
    }
1306
 
 
1307
 
  widget = lookup_widget(channel_accel, "attached_standard");
1308
 
  if (list->standard)
1309
 
    {
1310
 
      std = tveng_find_standard_by_hash(list->standard, main_info);
1311
 
      if (std)
1312
 
        z_option_menu_set_active(widget, std->index+1);
1313
 
      else
1314
 
        z_option_menu_set_active(widget, 0);
1315
 
    }
1316
 
  else
1317
 
    z_option_menu_set_active(widget, 0);
1318
 
 
1319
 
  widget = lookup_widget(channel_accel, "attached_input");
1320
 
 
1321
 
  if (list->input)
1322
 
    {
1323
 
      input = tveng_find_input_by_hash(list->input, main_info);
1324
 
      if (input)
1325
 
        z_option_menu_set_active(widget, input->index+1);
1326
 
      else
1327
 
        z_option_menu_set_active(widget, 0);
1328
 
    }
1329
 
  else
1330
 
    z_option_menu_set_active(widget, 0);
1331
 
 
1332
 
  update_edit_buttons_sensitivity(channel_editor);
1333
 
 
1334
 
  /* block this call a bit longer */
1335
 
  control_timeout_id =
1336
 
    gtk_timeout_add(50, (GtkFunction)control_timeout, NULL);
1337
 
}
1338
 
 
1339
 
/*
1340
 
  Called when a key is pressed in the channel list. Should call remove
1341
 
  if the pressed key is Del
1342
 
*/
1343
 
gboolean
1344
 
on_channel_list_key_press_event        (GtkWidget       *widget,
1345
 
                                        GdkEventKey     *event,
1346
 
                                        gpointer         user_data)
1347
 
{
1348
 
  GtkWidget * remove_channel = lookup_widget(widget, "remove_channel");
1349
 
  if ((event->keyval == GDK_Delete) || (event->keyval == GDK_KP_Delete))
1350
 
    {
1351
 
      if (remove_channel)
1352
 
        on_remove_channel_clicked(GTK_BUTTON(remove_channel), NULL);
1353
 
      return TRUE; /* Processed */
1354
 
    }
1355
 
 
1356
 
  return FALSE;
1357
 
}
1358
 
 
1359
 
static
1360
 
gint do_search (GtkWidget * searching)
1361
 
{
1362
 
  GtkWidget * progress = lookup_widget(searching, "progressbar1");
1363
 
  GtkWidget * label80 = lookup_widget(searching, "label80");
1364
 
  gint scanning_channel =
1365
 
    GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(searching),
1366
 
                                        "scanning_channel"));
1367
 
  GtkWidget * channel_list =
1368
 
    gtk_object_get_user_data(GTK_OBJECT(searching));
1369
 
  GtkWidget * clist1 =
1370
 
    lookup_widget(channel_list, "clist1");
1371
 
  gint strength, afc;
1372
 
  gchar * tuned_name=NULL;
1373
 
  tveng_rf_channel * channel;
1374
 
 
1375
 
  if (scanning_channel >= 0)
1376
 
    {
1377
 
      channel = tveng_get_channel_by_id(scanning_channel,
1378
 
                                        current_country);
1379
 
      g_assert(channel != NULL);
1380
 
 
1381
 
      if ((-1 != tveng_get_signal_strength(&strength, &afc, main_info)) &&
1382
 
          (strength > 0))
1383
 
        {
1384
 
          GtkWidget * channel_name =
1385
 
            lookup_widget(channel_list, "channel_name");
1386
 
          guint32 last_freq = channel->freq, last_afc = afc;
1387
 
 
1388
 
#ifdef HAVE_LIBZVBI
1389
 
          /* zvbi should store the station name if known from now */
1390
 
          zvbi_name_unknown();
1391
 
#endif
1392
 
 
1393
 
          /* wait afc code, receive some VBI data to get the station,
1394
 
             etc. XXX should wake up earlier when the data is ready */
1395
 
          usleep(3e5);
1396
 
 
1397
 
          /* Fine search (untested) */
1398
 
          while (afc && (afc != -last_afc))
 
1636
  ce->channel_selection = gtk_tree_view_get_selection (ce->channel_treeview);
 
1637
  gtk_tree_selection_set_mode (ce->channel_selection, GTK_SELECTION_MULTIPLE);
 
1638
  CONNECT (channel_selection, changed);
 
1639
 
 
1640
  ce->channel_model = create_channel_list_model (global_channel_list); /* XXX */
 
1641
  gtk_tree_view_set_model (ce->channel_treeview,
 
1642
                           GTK_TREE_MODEL (ce->channel_model));
 
1643
 
 
1644
  gtk_tree_view_insert_column_with_data_func
 
1645
    (ce->channel_treeview, -1 /* append */, "",
 
1646
     gtk_cell_renderer_text_new (), set_func_index, ce, NULL);
 
1647
 
 
1648
  gtk_tree_view_insert_column_with_data_func
 
1649
    (ce->channel_treeview, -1 /* append */, _("Channel name"),
 
1650
     gtk_cell_renderer_text_new (), set_func_name, ce, NULL);
 
1651
 
 
1652
  gtk_tree_view_insert_column_with_data_func
 
1653
    (ce->channel_treeview, -1 /* append */, _("Video input"),
 
1654
     gtk_cell_renderer_text_new (), set_func_input, ce, NULL);
 
1655
 
 
1656
  gtk_tree_view_insert_column_with_data_func
 
1657
    (ce->channel_treeview, -1 /* append */, _("RF Channel"),
 
1658
     gtk_cell_renderer_text_new (), set_func_channel, ce, NULL);
 
1659
 
 
1660
  gtk_tree_view_insert_column_with_data_func
 
1661
    (ce->channel_treeview, -1 /* append */, _("Video standard"),
 
1662
     gtk_cell_renderer_text_new (), set_func_standard, ce, NULL);
 
1663
  
 
1664
  gtk_tree_view_insert_column_with_data_func
 
1665
    (ce->channel_treeview, -1 /* append */, _("Accelerator"),
 
1666
     gtk_cell_renderer_text_new (), set_func_key, ce, NULL);
 
1667
  
 
1668
  return scrolledwindow;
 
1669
}
 
1670
 
 
1671
static GtkMenu *
 
1672
create_input_menu               (channel_editor *       ce _unused_)
 
1673
{
 
1674
  GtkMenu *menu;
 
1675
  GtkWidget *menu_item;
 
1676
  const tv_video_line *l;
 
1677
 
 
1678
  menu = GTK_MENU (gtk_menu_new ());
 
1679
 
 
1680
  menu_item = gtk_menu_item_new_with_label (_("Do not change input"));
 
1681
  gtk_widget_show (menu_item);
 
1682
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 
1683
 
 
1684
  for (l = tv_next_video_input (zapping->info, NULL);
 
1685
       l; l = tv_next_video_input (zapping->info, l))
 
1686
    {
 
1687
      menu_item = gtk_menu_item_new_with_label (l->label);
 
1688
      gtk_widget_show (menu_item);
 
1689
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 
1690
    }
 
1691
 
 
1692
  return menu;
 
1693
}
 
1694
 
 
1695
static GtkMenu *
 
1696
create_standard_menu            (channel_editor *       ce _unused_)
 
1697
{
 
1698
  GtkMenu *menu;
 
1699
  GtkWidget *menu_item;
 
1700
  const tv_video_standard *s;
 
1701
 
 
1702
  menu = GTK_MENU (gtk_menu_new ());
 
1703
 
 
1704
  menu_item = gtk_menu_item_new_with_label (_("Do not change standard"));
 
1705
  gtk_widget_show (menu_item);
 
1706
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 
1707
 
 
1708
  for (s = tv_next_video_standard (zapping->info, NULL);
 
1709
       s; s = tv_next_video_standard (zapping->info, s))
 
1710
    {
 
1711
      menu_item = gtk_menu_item_new_with_label (s->label);
 
1712
      gtk_widget_show (menu_item);
 
1713
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 
1714
    }
 
1715
 
 
1716
  return menu;
 
1717
}
 
1718
 
 
1719
static GtkWidget *
 
1720
create_channel_editor           (void)
 
1721
{
 
1722
  struct channel_editor *ce;
 
1723
  const tv_video_line *l;
 
1724
 
 
1725
  ce = g_malloc (sizeof (*ce));
 
1726
 
 
1727
  ce->old_channel_list = tveng_tuned_channel_list_new (global_channel_list);
 
1728
 
 
1729
  ce->search = NULL;
 
1730
 
 
1731
  for (l = tv_next_video_input (zapping->info, NULL);
 
1732
       l; l = tv_next_video_input (zapping->info, l))
 
1733
    if (l->type == TV_VIDEO_LINE_TYPE_TUNER)
 
1734
      break;
 
1735
 
 
1736
  ce->have_tuners = (l != NULL);
 
1737
 
 
1738
  /* Build dialog */
 
1739
 
 
1740
  ce->tooltips = gtk_tooltips_new ();
 
1741
 
 
1742
  ce->channel_editor = GTK_DIALOG (gtk_dialog_new ());
 
1743
  gtk_window_set_title (GTK_WINDOW (ce->channel_editor), _("Channel editor"));
 
1744
  CONNECT (channel_editor, destroy);
 
1745
 
 
1746
  {
 
1747
    GtkWidget *dialog_vbox;
 
1748
 
 
1749
    dialog_vbox = GTK_DIALOG (ce->channel_editor)->vbox;
 
1750
    gtk_widget_show (dialog_vbox);
 
1751
 
 
1752
    ce->vbox = GTK_BOX (gtk_vbox_new (FALSE, 3));
 
1753
    gtk_widget_show (GTK_WIDGET (ce->vbox));
 
1754
    gtk_box_pack_start (GTK_BOX (dialog_vbox),
 
1755
                        GTK_WIDGET (ce->vbox), TRUE, TRUE, 0);
 
1756
 
 
1757
    {
 
1758
      GtkWidget *vpaned;
 
1759
 
 
1760
      vpaned = gtk_vpaned_new ();
 
1761
      gtk_widget_show (vpaned);
 
1762
      gtk_box_pack_start (ce->vbox, vpaned, TRUE, TRUE, 0);
 
1763
 
 
1764
      {
 
1765
        GtkWidget *frame;
 
1766
 
 
1767
        frame = gtk_frame_new (_("Region"));
 
1768
        gtk_widget_show (frame);
 
1769
        gtk_container_add (GTK_CONTAINER (vpaned), frame);
 
1770
        gtk_container_set_border_width (GTK_CONTAINER (frame), 3);
 
1771
        gtk_widget_set_sensitive (frame, ce->have_tuners);
 
1772
 
 
1773
        {
 
1774
          GtkWidget *hbox;
 
1775
          GtkWidget *scrolledwindow;
 
1776
          
 
1777
          hbox = gtk_hbox_new (FALSE, 0);
 
1778
          gtk_widget_show (hbox);
 
1779
          gtk_container_add (GTK_CONTAINER (frame), hbox);
 
1780
        
 
1781
          {
 
1782
            GtkWidget *vbox;
 
1783
#if 0
 
1784
            GtkWidget *label;
 
1785
#endif      
 
1786
            vbox = gtk_vbox_new (FALSE, 3);
 
1787
            gtk_widget_show (vbox);
 
1788
            gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
 
1789
            
 
1790
            ce->country_menu = GTK_OPTION_MENU (create_country_menu (ce));
 
1791
            gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ce->country_menu),
 
1792
                                FALSE, FALSE, 0);
 
1793
            CONNECT (country_menu, changed);
 
1794
            
1399
1795
            {
1400
 
              /* Should be afc*50, but won't harm */
1401
 
              if (-1 == tveng_tune_input(last_freq + afc*25, main_info))
1402
 
                break;
1403
 
              usleep(2e5);
1404
 
              if (-1 == tveng_get_signal_strength(&strength, &afc,
1405
 
                                                  main_info) ||
1406
 
                  !strength)
1407
 
                break;
1408
 
              last_freq += afc*25;
 
1796
              GtkWidget *hbox;
 
1797
              
 
1798
              hbox = gtk_vbox_new (TRUE, 3);
 
1799
              gtk_widget_show (hbox);
 
1800
              gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
1801
              
 
1802
              ce->channel_search = GTK_BUTTON (gtk_button_new_with_mnemonic
 
1803
                                               (_("Automatic station _search")));
 
1804
              gtk_widget_show (GTK_WIDGET (ce->channel_search));
 
1805
              gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (ce->channel_search),
 
1806
                                  TRUE, TRUE, 0);
 
1807
              CONNECT (channel_search, clicked);
 
1808
              gtk_tooltips_set_tip (ce->tooltips, GTK_WIDGET (ce->channel_search),
 
1809
                                    _("Select a suitable frequency table, then "
 
1810
                                      "click here to search through all channels "
 
1811
                                      "in the table and add the received stations "
 
1812
                                      "to the channel list."), NULL);
 
1813
              
 
1814
              ce->add_all_channels = GTK_BUTTON (gtk_button_new_with_mnemonic
 
1815
                                                 (_("Add all _channels")));
 
1816
              gtk_widget_show (GTK_WIDGET (ce->add_all_channels));
 
1817
              gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (ce->add_all_channels),
 
1818
                                  TRUE, TRUE, 0);
 
1819
              CONNECT (add_all_channels, clicked);
 
1820
              gtk_tooltips_set_tip (ce->tooltips,
 
1821
                                    GTK_WIDGET (ce->add_all_channels),
 
1822
                                    _("Add all channels in the frequency "
 
1823
                                      "table to the channel list."), NULL);
 
1824
 
 
1825
              ce->import_xawtv = GTK_BUTTON (gtk_button_new_with_mnemonic
 
1826
                                             (_("_Import XawTV configuration")));
 
1827
              gtk_widget_show (GTK_WIDGET (ce->import_xawtv));
 
1828
              gtk_widget_set_sensitive (GTK_WIDGET (ce->import_xawtv),
 
1829
                                        xawtv_config_present ());
 
1830
              gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (ce->import_xawtv),
 
1831
                                  TRUE, TRUE, 0);
 
1832
              CONNECT (import_xawtv, clicked);
1409
1833
            }
1410
1834
 
1411
 
#ifdef HAVE_LIBZVBI
1412
 
          if (zconf_get_boolean(NULL, "/zapping/options/vbi/use_vbi"))
1413
 
            tuned_name = zvbi_get_name();
 
1835
#if 0
 
1836
            label = gtk_label_new (("When your country is not listed or "
 
1837
                                     "misrepresented please send an e-mail,\n"
 
1838
                                     "if possible including the correct "
 
1839
                                     "frequency table, to zapping-misc@lists.sf.net."));
 
1840
            gtk_widget_show (label);
 
1841
            gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
1414
1842
#endif
1415
 
          if ((!zconf_get_boolean(NULL, "/zapping/options/vbi/use_vbi"))
1416
 
              || (!tuned_name))
1417
 
            tuned_name = g_strdup(channel->name);
1418
 
 
1419
 
          gtk_entry_set_text(GTK_ENTRY(channel_name), tuned_name);
1420
 
          g_free(tuned_name);
1421
 
 
1422
 
          real_add_channel(channel_name, NULL);
1423
 
        }
1424
 
    }
1425
 
 
1426
 
  scanning_channel++;
1427
 
 
1428
 
  /* Check if we have reached the end */
1429
 
  if (current_country->channel_count <= scanning_channel)
1430
 
    {
1431
 
      gtk_widget_destroy(searching);
1432
 
      return FALSE;
1433
 
    }
1434
 
 
1435
 
  gtk_progress_set_percentage(GTK_PROGRESS(progress),
1436
 
     ((gfloat)scanning_channel)/current_country->channel_count);
1437
 
 
1438
 
  channel = tveng_get_channel_by_id(scanning_channel,
1439
 
                                    current_country);
1440
 
  g_assert(channel != NULL);
1441
 
  gtk_label_set_text(GTK_LABEL(label80), channel->name);
1442
 
 
1443
 
  gtk_clist_select_row(GTK_CLIST (clist1), scanning_channel, 0);
1444
 
 
1445
 
  /* make the row visible */
1446
 
  gtk_clist_moveto(GTK_CLIST(clist1), scanning_channel, 0,
1447
 
                   0.5, 0);
1448
 
 
1449
 
  /* Tune to this channel's freq */
1450
 
  if (-1 == tveng_tune_input (channel->freq, main_info))
1451
 
    g_warning("While tuning: %s", main_info -> error);
1452
 
 
1453
 
  gtk_object_set_data(GTK_OBJECT(searching), "scanning_channel",
1454
 
                      GINT_TO_POINTER(scanning_channel));
1455
 
 
1456
 
  /* The timeout has to be big enough to let the tuner estabilize */
1457
 
  gtk_object_set_data(GTK_OBJECT(searching), "timeout",
1458
 
                      GINT_TO_POINTER((gtk_timeout_add(150,
1459
 
                            (GtkFunction)do_search, searching))));
1460
 
 
1461
 
  return FALSE;
1462
 
  /*
1463
 
    rationale: returning TRUE might look like it does the same thing as
1464
 
    above, but it doesn't. We want 150ms from now, not from when this
1465
 
    callback was called. This is because some vbi functions here might
1466
 
    take some time to complete.
1467
 
  */
1468
 
}
1469
 
 
1470
 
void
1471
 
on_channel_search_clicked              (GtkButton       *button,
1472
 
                                        gpointer         user_data)
1473
 
{
1474
 
  GtkWidget * channel_editor =
1475
 
    lookup_widget(GTK_WIDGET(button), "channel_editor");
1476
 
  GtkWidget * channel_list =
1477
 
    lookup_widget(channel_editor, "channel_list");
1478
 
  GtkWidget * searching;
1479
 
  GtkWidget * progress;
1480
 
  gint timeout;
1481
 
 
1482
 
  /* Make a prove to see whether it's possible to get the signal
1483
 
     strength */
1484
 
  if (-1 == tveng_get_signal_strength(NULL, NULL, main_info))
1485
 
    {
1486
 
      /* Channel auto-searching won't work with XVideo */
1487
 
      if (main_info->current_controller == TVENG_CONTROLLER_XV)
1488
 
        ShowBox(_("Channel autosearching won't work with XVideo.\n"
1489
 
                  "Please switch to another controller by starting\n"
1490
 
                  "Capture mode (\"View/Go Capturing\" menu "
1491
 
                  "entry).\nReported error:\n%s"),
1492
 
                GNOME_MESSAGE_BOX_WARNING, main_info->error);
1493
 
      else
1494
 
        ShowBox(_("Your current V4L/V4L2 driver cannot do "
1495
 
                  "channel autosearching, sorry"),
1496
 
                GNOME_MESSAGE_BOX_INFO);
1497
 
      return;
1498
 
    }
1499
 
 
1500
 
  searching = build_widget("searching", NULL);
1501
 
  progress = lookup_widget(searching, "progressbar1");
1502
 
 
1503
 
  gtk_progress_set_percentage(GTK_PROGRESS(progress), 0.0);
1504
 
 
1505
 
  /* The timeout has to be big enough to let the tuner estabilize */
1506
 
  timeout = gtk_timeout_add(150, (GtkFunction)do_search, searching);
1507
 
 
1508
 
  gtk_object_set_user_data(GTK_OBJECT(searching), channel_list);
1509
 
  gtk_object_set_data(GTK_OBJECT(searching), "timeout",
1510
 
                      GINT_TO_POINTER(timeout));
1511
 
  gtk_object_set_data(GTK_OBJECT(searching), "scanning_channel",
1512
 
                      GINT_TO_POINTER(-1));
1513
 
 
1514
 
  gtk_widget_show(searching);
1515
 
}
1516
 
 
1517
 
void
1518
 
on_cancel_search_clicked               (GtkButton       *button,
1519
 
                                        gpointer         user_data)
1520
 
{
1521
 
  GtkWidget * searching =
1522
 
    lookup_widget(GTK_WIDGET(button), "searching");
1523
 
  gint timeout =
1524
 
    GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(searching), "timeout"));
1525
 
 
1526
 
  gtk_timeout_remove(timeout);
1527
 
 
1528
 
  gtk_widget_destroy(searching);
1529
 
}
1530
 
 
1531
 
gboolean
1532
 
on_searching_delete_event              (GtkWidget       *widget,
1533
 
                                        GdkEvent        *event,
1534
 
                                        gpointer         user_data)
1535
 
{
1536
 
  gint timeout =
1537
 
    GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "timeout"));
1538
 
 
1539
 
  gtk_timeout_remove(timeout);
1540
 
 
1541
 
  return FALSE;
 
1843
          }
 
1844
          
 
1845
          scrolledwindow = create_freq_treeview (ce);
 
1846
          gtk_box_pack_start (GTK_BOX (hbox), scrolledwindow, TRUE, TRUE, 0);
 
1847
        }
 
1848
      }
 
1849
      
 
1850
      {
 
1851
        GtkWidget *frame;
 
1852
        
 
1853
        frame = gtk_frame_new (_("Channel List"));
 
1854
        gtk_widget_show (frame);
 
1855
        gtk_container_add (GTK_CONTAINER (vpaned), frame);
 
1856
        gtk_container_set_border_width (GTK_CONTAINER (frame), 3);
 
1857
        
 
1858
        {
 
1859
          GtkWidget *hbox;
 
1860
          GtkWidget *scrolledwindow;
 
1861
          
 
1862
          hbox = gtk_hbox_new (FALSE, 3);
 
1863
          gtk_widget_show (hbox);
 
1864
          gtk_container_add (GTK_CONTAINER (frame), hbox);
 
1865
          
 
1866
          scrolledwindow = create_channel_treeview (ce);
 
1867
          gtk_box_pack_start (GTK_BOX (hbox), scrolledwindow, TRUE, TRUE, 0);
 
1868
          
 
1869
          {
 
1870
            GtkWidget *vbox;
 
1871
            
 
1872
            vbox = gtk_vbox_new (FALSE, 3);
 
1873
            gtk_widget_show (vbox);
 
1874
            gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
 
1875
            
 
1876
            BUTTON (channel_up,   GTK_STOCK_GO_UP,   FALSE);
 
1877
            BUTTON (channel_down,         GTK_STOCK_GO_DOWN, FALSE);
 
1878
            BUTTON (channel_add,          GTK_STOCK_ADD,     TRUE);
 
1879
            BUTTON (channel_remove, GTK_STOCK_REMOVE,  FALSE);
 
1880
          }
 
1881
        }
 
1882
      }
 
1883
    }
 
1884
 
 
1885
    {
 
1886
      GtkWidget *frame;
 
1887
 
 
1888
      frame = gtk_frame_new (_("Edit channel"));
 
1889
      gtk_widget_show (frame);
 
1890
      gtk_box_pack_start (ce->vbox, frame, FALSE, FALSE, 0);
 
1891
      gtk_container_set_border_width (GTK_CONTAINER (frame), 3);
 
1892
 
 
1893
      {
 
1894
        GtkWidget *label;
 
1895
        GtkWidget *menu;
 
1896
        GtkAdjustment *adj;
 
1897
          
 
1898
        ce->entry_table = GTK_TABLE (gtk_table_new (5, 2, FALSE));
 
1899
        gtk_widget_show (GTK_WIDGET (ce->entry_table));
 
1900
        gtk_widget_set_sensitive (GTK_WIDGET (ce->entry_table), FALSE);
 
1901
        gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (ce->entry_table));
 
1902
        gtk_table_set_row_spacings (ce->entry_table, 3);
 
1903
        gtk_table_set_col_spacings (ce->entry_table, 3);
 
1904
 
 
1905
        LABEL (_("Name:"), 0, 0);
 
1906
  
 
1907
        ce->entry_name = GTK_ENTRY (gtk_entry_new ());
 
1908
        gtk_widget_show (GTK_WIDGET (ce->entry_name));
 
1909
        CONNECT (entry_name, changed);
 
1910
        gtk_table_attach (ce->entry_table, GTK_WIDGET (ce->entry_name), 1, 2, 0, 1,
 
1911
                          (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
 
1912
                          (GtkAttachOptions)(0), 0, 0);
 
1913
 
 
1914
        LABEL (_("Video input:"), 0, 1);
 
1915
 
 
1916
        ce->entry_input = GTK_OPTION_MENU (gtk_option_menu_new ());
 
1917
        gtk_widget_show (GTK_WIDGET (ce->entry_input));
 
1918
        CONNECT (entry_input, changed);
 
1919
        gtk_table_attach (ce->entry_table, GTK_WIDGET (ce->entry_input), 1, 2, 1, 2,
 
1920
                          (GtkAttachOptions)(GTK_FILL),
 
1921
                          (GtkAttachOptions)(0), 0, 0);
 
1922
        gtk_option_menu_set_menu (ce->entry_input,
 
1923
                                  GTK_WIDGET (create_input_menu (ce)));
 
1924
 
 
1925
        LABEL (_("Fine tuning:"), 0, 2);
 
1926
 
 
1927
        adj = GTK_ADJUSTMENT
 
1928
          (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
 
1929
 
 
1930
        ce->entry_fine_tuning =
 
1931
          Z_SPINSLIDER (z_spinslider_new (adj, NULL, _("MHz"), 0.0, 2));
 
1932
        gtk_widget_show (GTK_WIDGET (ce->entry_fine_tuning));
 
1933
        gtk_widget_set_sensitive (GTK_WIDGET (ce->entry_fine_tuning), FALSE);
 
1934
        gtk_table_attach (ce->entry_table,
 
1935
                          GTK_WIDGET (ce->entry_fine_tuning),
 
1936
                          1, 2, 2, 3,
 
1937
                          (GtkAttachOptions)(GTK_FILL),
 
1938
                          (GtkAttachOptions)(GTK_FILL), 0, 0);
 
1939
        g_signal_connect (G_OBJECT (adj), "value-changed",
 
1940
                          G_CALLBACK (on_entry_fine_tuning_value_changed), ce);
 
1941
 
 
1942
        LABEL (_("Video standard:"), 0, 3);
 
1943
 
 
1944
        ce->entry_standard = GTK_OPTION_MENU (gtk_option_menu_new ());
 
1945
        gtk_widget_show (GTK_WIDGET (ce->entry_standard));
 
1946
        CONNECT (entry_standard, changed);
 
1947
        gtk_table_attach (ce->entry_table, GTK_WIDGET (ce->entry_standard), 1, 2, 3, 4,
 
1948
                          (GtkAttachOptions)(GTK_FILL),
 
1949
                          (GtkAttachOptions)(0), 0, 0);
 
1950
        menu = gtk_menu_new ();
 
1951
        gtk_option_menu_set_menu (ce->entry_standard, menu);
 
1952
 
 
1953
        LABEL (_("Accelerator:"), 0, 4);
 
1954
 
 
1955
        ce->entry_accel = z_key_entry_new ();
 
1956
        gtk_widget_show (ce->entry_accel);
 
1957
        gtk_table_attach (ce->entry_table, ce->entry_accel, 1, 2, 4, 5,
 
1958
                          (GtkAttachOptions)(GTK_FILL),
 
1959
                          (GtkAttachOptions)(GTK_FILL), 0, 0);
 
1960
        g_signal_connect (G_OBJECT (z_key_entry_entry (ce->entry_accel)),
 
1961
                          "changed", G_CALLBACK (on_entry_accel_changed), ce);
 
1962
      }
 
1963
    }
 
1964
  }
 
1965
 
 
1966
  {
 
1967
    GtkWidget *dialog_action_area;
 
1968
 
 
1969
    dialog_action_area = GTK_DIALOG (ce->channel_editor)->action_area;
 
1970
    gtk_widget_show (dialog_action_area);
 
1971
    gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area), GTK_BUTTONBOX_END);
 
1972
 
 
1973
    {
 
1974
      GtkWidget *hbox;
 
1975
      GtkWidget *ok;
 
1976
      GtkWidget *cancel;
 
1977
  
 
1978
      hbox = gtk_hbox_new (TRUE, 15);
 
1979
      gtk_widget_show (hbox);
 
1980
      gtk_container_add (GTK_CONTAINER (dialog_action_area), hbox);
 
1981
      
 
1982
      cancel = gtk_button_new_from_stock (GTK_STOCK_HELP);
 
1983
      gtk_widget_show (cancel);
 
1984
      gtk_box_pack_start (GTK_BOX (hbox), cancel, FALSE, TRUE, 0);
 
1985
      g_signal_connect (G_OBJECT (cancel), "clicked",
 
1986
                        G_CALLBACK (on_help_clicked), ce);
 
1987
 
 
1988
      cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
 
1989
      gtk_widget_show (cancel);
 
1990
      gtk_box_pack_start (GTK_BOX (hbox), cancel, FALSE, TRUE, 0);
 
1991
      g_signal_connect (G_OBJECT (cancel), "clicked",
 
1992
                        G_CALLBACK (on_cancel_clicked), ce);
 
1993
 
 
1994
      ok = gtk_button_new_from_stock (GTK_STOCK_OK);
 
1995
      gtk_widget_show (ok);
 
1996
      gtk_box_pack_start (GTK_BOX (hbox), ok, FALSE, TRUE, 0);
 
1997
      g_signal_connect (G_OBJECT (ok), "clicked",
 
1998
                        G_CALLBACK (on_ok_clicked), ce);
 
1999
    }
 
2000
  }
 
2001
 
 
2002
  return GTK_WIDGET (ce->channel_editor);
 
2003
}
 
2004
 
 
2005
static PyObject *
 
2006
py_channel_editor               (PyObject *             self _unused_,
 
2007
                                 PyObject *             args _unused_)
 
2008
{
 
2009
  if (!dialog_running)
 
2010
    gtk_widget_show (create_channel_editor ());
 
2011
  else
 
2012
    gtk_window_present (GTK_WINDOW (dialog_running->channel_editor));
 
2013
 
 
2014
  py_return_true;
 
2015
}
 
2016
 
 
2017
void
 
2018
startup_channel_editor          (void)
 
2019
{
 
2020
  cmd_register ("channel_editor", py_channel_editor, METH_VARARGS,
 
2021
                ("Channel editor"), "zapping.channel_editor()");
 
2022
}
 
2023
 
 
2024
void
 
2025
shutdown_channel_editor         (void)
 
2026
{
1542
2027
}