add grouping, default proxy vcodec h264.mp4, default titlebar alpha=1, green bar bug
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / channeledit.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2011 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "batch.h"
23 #include "bcprogressbox.h"
24 #include "bcsignals.h"
25 #include "channel.h"
26 #include "channeldb.h"
27 #include "channeledit.h"
28 #include "channelpicker.h"
29 #include "chantables.h"
30 #include "clip.h"
31 #include "condition.h"
32 #include "language.h"
33 #include "mainsession.h"
34 #include "mwindow.h"
35 #include "picture.h"
36 #include "theme.h"
37 #include "videodevice.h"
38 #include <ctype.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #define MSG_NO_PIC_CONTROLS _("Device has no picture controls.")
43 //#define MSG_NO_INP_SELECTION _("Device has no input selection.")
44
45 ChannelEditThread::ChannelEditThread(ChannelPicker *channel_picker,
46         ChannelDB *channeldb)
47  : Thread()
48 {
49         this->channel_picker = channel_picker;
50         this->channeldb = channeldb;
51         in_progress = 0;
52         this->window = 0;
53         new_channels = new ChannelDB;
54         completion = new Condition(1, "ChannelEditThread::completion");
55         scan_thread = 0;
56 }
57 ChannelEditThread::~ChannelEditThread()
58 {
59         close_threads();
60         delete scan_thread;
61         delete new_channels;
62         delete completion;
63 }
64
65 void ChannelEditThread::run()
66 {
67         if(in_progress)
68         {
69                 if(window)
70                 {
71                         window->lock_window("ChannelEditThread::run");
72                         window->raise_window(1);
73                         window->unlock_window();
74                 }
75                 return;
76         }
77         in_progress = 1;
78         completion->lock("ChannelEditThread::run");
79
80 // Copy master channel list to temporary.
81         new_channels->copy_from(channel_picker->channeldb);
82         Channel *channel = channel_picker->get_current_channel();
83         current_channel = channel_picker->channeldb->number_of(channel);
84 //printf("ChannelEditThread::run 1 %d\n", current_channel);
85
86 // Run the channel list window using the temporary list.
87         window = new ChannelEditWindow(this, channel_picker);
88         window->create_objects();
89         int result = window->run_window();
90         delete window;  window = 0;
91
92         if(!result) {
93 // Copy new channels to master list
94                 channel_picker->channeldb->clear();
95
96                 channel_picker->channeldb->copy_from(new_channels);
97                 channel_picker->update_channel_list();
98
99         }
100
101         channel_picker->handle_channel_edit(result);
102
103         completion->unlock();
104         in_progress = 0;
105
106 }
107
108 void ChannelEditThread::close_threads()
109 {
110         if(in_progress && window)
111         {
112                 window->set_done(1);
113                 completion->lock("ChannelEditThread::close_threads");
114                 completion->unlock();
115         }
116 }
117
118 char *ChannelEditThread::value_to_freqtable(int value)
119 {
120         switch(value)
121         {
122                 case NTSC_DVB: return _("NTSC_DVB");
123                 case CATV_DVB: return _("CATV_DVB");
124                 case NTSC_BCAST: return _("NTSC_BCAST");
125                 case NTSC_CABLE: return _("NTSC_CABLE");
126                 case NTSC_HRC: return _("NTSC_HRC");
127                 case NTSC_BCAST_JP: return _("NTSC_BCAST_JP");
128                 case NTSC_CABLE_JP: return _("NTSC_CABLE_JP");
129                 case PAL_AUSTRALIA: return _("PAL_AUSTRALIA");
130                 case PAL_EUROPE: return _("PAL_EUROPE");
131                 case PAL_E_EUROPE: return _("PAL_E_EUROPE");
132                 case PAL_ITALY: return _("PAL_ITALY");
133                 case PAL_IRELAND: return _("PAL_IRELAND");
134                 case PAL_NEWZEALAND: return _("PAL_NEWZEALAND");
135         }
136         return _("ERROR");
137 }
138
139 char* ChannelEditThread::value_to_norm(int value)
140 {
141         switch(value)
142         {
143                 case NTSC: return _("NTSC");
144                 case PAL: return _("PAL");
145                 case SECAM: return _("SECAM");
146         }
147         return _("ERROR");
148 }
149
150 char* ChannelEditThread::value_to_input(int value)
151 {
152         ArrayList<Channel*> *inputs = channel_picker->get_video_inputs();
153         return value >= inputs->total ? _("None") :
154                 inputs->values[value]->device_name;
155 }
156
157
158
159
160
161
162
163 ChannelEditWindow::ChannelEditWindow(ChannelEditThread *thread,
164         ChannelPicker *channel_picker)
165  : BC_Window(_(PROGRAM_NAME ": Channels"),
166         channel_picker->mwindow->session->channels_x,
167         channel_picker->mwindow->session->channels_y,
168         375, 400, 375, 400, 0, 0, 1)
169 {
170         this->thread = thread;
171         this->channel_picker = channel_picker;
172         this->edit_thread = 0;
173         this->picture_thread = 0;
174         this->scan_confirm_thread = 0;
175 }
176
177 ChannelEditWindow::~ChannelEditWindow()
178 {
179         if( thread->scan_thread )
180                 thread->scan_thread->stop();
181         channel_list.remove_all_objects();
182         delete edit_thread;
183         delete picture_thread;
184         delete scan_confirm_thread;
185 }
186
187 void ChannelEditWindow::create_objects()
188 {
189         lock_window("ChannelEditWindow::create_objects");
190         int x = 10, y = 10;
191
192 // Create channel list
193         for(int i = 0; i < thread->new_channels->size(); i++)
194         {
195                 channel_list.append(new BC_ListBoxItem(thread->new_channels->get(i)->title));
196         }
197
198         add_subwindow(list_box = new ChannelEditList(this, x, y));
199         x += 200;
200         if(channel_picker->use_select())
201         {
202                 add_subwindow(new ChannelEditSelect(this, x, y));
203                 y += 30;
204         }
205         add_subwindow(new ChannelEditAdd(this, x, y));
206         y += 30;
207         add_subwindow(new ChannelEdit(this, x, y));
208         y += 30;
209         add_subwindow(new ChannelEditMoveUp(this, x, y));
210         y += 30;
211         add_subwindow(new ChannelEditMoveDown(this, x, y));
212         y += 30;
213         add_subwindow(new ChannelEditSort(this, x, y));
214         y += 30;
215
216         Channel *channel_usage = channel_picker->get_channel_usage();
217         if(channel_usage && channel_usage->has_scanning)
218         {
219                 add_subwindow(new ChannelEditScan(this, x, y));
220                 y += 30;
221         }
222         add_subwindow(new ChannelEditDel(this, x, y));
223         y += 30;
224         add_subwindow(new ChannelEditPicture(this, x, y));
225         y += 100;
226         x = 10;
227         add_subwindow(new BC_OKButton(this));
228         x += 150;
229         add_subwindow(new BC_CancelButton(this));
230
231
232         edit_thread = new ChannelEditEditThread(this, channel_picker);
233         picture_thread = new ChannelEditPictureThread(channel_picker);
234         show_window();
235         unlock_window();
236 }
237
238 int ChannelEditWindow::close_event()
239 {
240         if( thread->scan_thread )
241                 thread->scan_thread->stop();
242         return BC_WindowBase::close_event();
243 }
244
245 int ChannelEditWindow::translation_event()
246 {
247         channel_picker->mwindow->session->channels_x = get_x();
248         channel_picker->mwindow->session->channels_y = get_y();
249         return 0;
250 }
251
252
253 int ChannelEditWindow::add_channel()
254 {
255         Channel *new_channel;
256         Channel *prev_channel = 0;
257
258 // Create new channel
259         new_channel = new Channel;
260
261 // Reuse parameters from previous channel
262         if(thread->new_channels->size())
263         {
264                 prev_channel = thread->new_channels->get(
265                                 thread->new_channels->size() - 1);
266                 new_channel->copy_settings(prev_channel);
267         }
268         else
269 // Use default channel parameters
270         if(channel_picker->get_master_channel())
271         {
272                 new_channel->copy_settings(channel_picker->get_master_channel());
273         }
274
275 // Copy device usage.  Need the same thing for playback.
276         if(channel_picker->get_master_channel())
277         {
278                 new_channel->copy_usage(channel_picker->get_master_channel());
279         }
280
281 // Add to channel table
282         channel_list.append(new BC_ListBoxItem(new_channel->title));
283         thread->new_channels->append(new_channel);
284         update_list();
285
286 // Start common routing
287         edit_thread->edit_channel(new_channel, 0);
288         return 0;
289 }
290
291 void ChannelEditWindow::update_list()
292 {
293 // Create channel list
294         channel_list.remove_all_objects();
295         for(int i = 0; i < thread->new_channels->size(); i++)
296         {
297                 channel_list.append(
298                         new BC_ListBoxItem(
299                                 thread->new_channels->get(i)->title));
300         }
301
302         list_box->update(&channel_list, 0, 0, 1, list_box->get_yposition());
303 }
304
305 void ChannelEditWindow::update_list(Channel *channel)
306 {
307         int i;
308         for(i = 0; i < thread->new_channels->size(); i++)
309                 if(thread->new_channels->get(i) == channel) break;
310
311         if(i < thread->new_channels->size())
312         {
313                 channel_list.values[i]->set_text(channel->title);
314         }
315
316         update_list();
317 }
318
319
320 void ChannelEditWindow::edit_channel()
321 {
322         if(list_box->get_selection_number(0, 0) > -1)
323         {
324                 thread->current_channel = list_box->get_selection_number(0, 0);
325                 edit_thread->edit_channel(
326                         thread->new_channels->get(
327                                 list_box->get_selection_number(0, 0)),
328                         1);
329         }
330 }
331
332 void ChannelEditWindow::edit_picture()
333 {
334         picture_thread->edit_picture();
335 }
336
337 void ChannelEditWindow::scan_confirm()
338 {
339         channel_picker->load_scan_defaults(&thread->scan_params);
340         if(!scan_confirm_thread) scan_confirm_thread = new ConfirmScanThread(this);
341         unlock_window();
342         scan_confirm_thread->start();
343         lock_window("ChannelEditWindow::scan_confirm");
344 }
345
346 void ChannelEditWindow::scan()
347 {
348         thread->new_channels->clear();
349         update_list();
350
351         if( !thread->scan_thread )
352                 thread->scan_thread = new ScanThread(thread);
353         thread->scan_thread->start();
354 }
355
356
357 void ChannelEditWindow::get_chan_num(Channel *channel, int &chan, int &stream)
358 {
359         const char *cp = channel->title;
360         int chn = 0, str = 0;
361         while( isdigit(*cp) ) chn = 10*chn + (*cp++ -'0');
362         if( chn != 0 && *cp != 0 ) {
363                 if( *cp++ == '.' )
364                         while( isdigit(*cp) ) str = 10*str + (*cp++ -'0');
365                 if( !str ) chn = 0;
366         }
367         chan = chn;  stream = str;
368 }
369
370 void ChannelEditWindow::sort()
371 {
372         int done = 0;
373         while(!done) {
374                 done = 1;
375                 for(int i = 0; i < thread->new_channels->size() - 1; i++) {
376                         Channel *channel1 = thread->new_channels->get(i);
377                         Channel *channel2 = thread->new_channels->get(i + 1);
378                         int ch1, st1;  get_chan_num(channel1, ch1, st1);
379                         int ch2, st2;  get_chan_num(channel2, ch2, st2);
380                         if( (ch1 > 0 && ch2 > 0) ?
381                              (ch1 > ch2 || (ch1 == ch2 && (st1 > st2 || (st1 == st2 &&
382                                 strcasecmp(channel2->title, channel1->title) < 0)))) :
383                              strcasecmp(channel2->title, channel1->title) < 0) {
384                                 thread->new_channels->set(i, channel2);
385                                 thread->new_channels->set(i + 1, channel1);
386                                 done = 0;
387                         }
388                 }
389         }
390         update_list();
391 }
392
393
394 void ChannelEditWindow::delete_channel(int number)
395 {
396         delete thread->new_channels->get(number);
397         channel_list.remove_number(number);
398         thread->new_channels->remove_number(number);
399         update_list();
400 }
401
402 void ChannelEditWindow::delete_channel(Channel *channel)
403 {
404         int i;
405         for(i = 0; i < thread->new_channels->size(); i++)
406         {
407                 if(thread->new_channels->get(i) == channel)
408                 {
409                         break;
410                 }
411         }
412         if(i < thread->new_channels->size()) delete_channel(i);
413 }
414
415 int ChannelEditWindow::move_channel_up()
416 {
417         if(list_box->get_selection_number(0, 0) > -1)
418         {
419                 int number2 = list_box->get_selection_number(0, 0);
420                 int number1 = number2 - 1;
421                 Channel *temp;
422                 BC_ListBoxItem *temp_text;
423
424                 if(number1 < 0) number1 = thread->new_channels->size() - 1;
425
426                 temp = thread->new_channels->get(number1);
427                 thread->new_channels->set(number1, thread->new_channels->get(number2));
428                 thread->new_channels->set(number2, temp);
429
430                 temp_text = channel_list.values[number1];
431                 channel_list.values[number1] = channel_list.values[number2];
432                 channel_list.values[number2] = temp_text;
433                 list_box->update(&channel_list,
434                         0,
435                         0,
436                         1,
437                         list_box->get_xposition(),
438                         list_box->get_yposition(),
439                         number1,
440                         1);
441         }
442         return 0;
443 }
444
445 int ChannelEditWindow::move_channel_down()
446 {
447         if(list_box->get_selection_number(0, 0) > -1)
448         {
449                 int number2 = list_box->get_selection_number(0, 0);
450                 int number1 = number2 + 1;
451                 Channel *temp;
452                 BC_ListBoxItem *temp_text;
453
454                 if(number1 > thread->new_channels->size() - 1) number1 = 0;
455
456                 temp = thread->new_channels->get(number1);
457                 thread->new_channels->set(number1, thread->new_channels->get(number2));
458                 thread->new_channels->set(number2, temp);
459                 temp_text = channel_list.values[number1];
460                 channel_list.values[number1] = channel_list.values[number2];
461                 channel_list.values[number2] = temp_text;
462                 list_box->update(&channel_list,
463                         0,
464                         0,
465                         1,
466                         list_box->get_xposition(),
467                         list_box->get_yposition(),
468                         number1,
469                         1);
470         }
471         return 0;
472 }
473
474 int ChannelEditWindow::change_channel_from_list(int channel_number)
475 {
476         if(channel_number > -1 && channel_number < thread->new_channels->size())
477         {
478                 thread->current_channel = channel_number;
479                 channel_picker->set_channel(thread->new_channels->get(channel_number));
480         }
481         return 0;
482 }
483
484 ChannelEditSelect::ChannelEditSelect(ChannelEditWindow *window, int x, int y)
485  : BC_GenericButton(x, y, _("Select"))
486 {
487         this->window = window;
488 }
489 ChannelEditSelect::~ChannelEditSelect()
490 {
491 }
492 int ChannelEditSelect::handle_event()
493 {
494         window->change_channel_from_list(
495                 window->list_box->get_selection_number(0, 0));
496         return 1;
497 }
498
499 ChannelEditAdd::ChannelEditAdd(ChannelEditWindow *window, int x, int y)
500  : BC_GenericButton(x, y, _("Add..."))
501 {
502         this->window = window;
503 }
504 ChannelEditAdd::~ChannelEditAdd()
505 {
506 }
507 int ChannelEditAdd::handle_event()
508 {
509         window->add_channel();
510         return 1;
511 }
512
513 ChannelEditList::ChannelEditList(ChannelEditWindow *window, int x, int y)
514  : BC_ListBox(x,
515                         y,
516                         185,
517                         window->get_h() - BC_OKButton::calculate_h() - y - 10,
518                         LISTBOX_TEXT,
519                         &(window->channel_list))
520 {
521         this->window = window;
522 }
523 ChannelEditList::~ChannelEditList()
524 {
525 }
526 int ChannelEditList::handle_event()
527 {
528         window->edit_channel();
529         return 1;
530 }
531
532 ChannelEditMoveUp::ChannelEditMoveUp(ChannelEditWindow *window, int x, int y)
533  : BC_GenericButton(x, y, _("Move up"))
534 {
535         this->window = window;
536 }
537 ChannelEditMoveUp::~ChannelEditMoveUp()
538 {
539 }
540 int ChannelEditMoveUp::handle_event()
541 {
542         lock_window("ChannelEditMoveUp::handle_event");
543         window->move_channel_up();
544         unlock_window();
545         return 1;
546 }
547
548 ChannelEditMoveDown::ChannelEditMoveDown(ChannelEditWindow *window, int x, int y)
549  : BC_GenericButton(x, y, _("Move down"))
550 {
551         this->window = window;
552 }
553 ChannelEditMoveDown::~ChannelEditMoveDown()
554 {
555 }
556 int ChannelEditMoveDown::handle_event()
557 {
558         lock_window("ChannelEditMoveDown::handle_event");
559         window->move_channel_down();
560         unlock_window();
561         return 1;
562 }
563
564 ChannelEditSort::ChannelEditSort(ChannelEditWindow *window, int x, int y)
565  : BC_GenericButton(x, y, _("Sort"))
566 {
567         this->window = window;
568 }
569 int ChannelEditSort::handle_event()
570 {
571         lock_window("ChannelEditSort::handle_event");
572         window->sort();
573         unlock_window();
574         return 1;
575 }
576
577 ChannelEditScan::ChannelEditScan(ChannelEditWindow *window, int x, int y)
578  : BC_GenericButton(x, y, _("Scan"))
579 {
580         this->window = window;
581 }
582 int ChannelEditScan::handle_event()
583 {
584         window->scan_confirm();
585         return 1;
586 }
587
588 ChannelEditDel::ChannelEditDel(ChannelEditWindow *window, int x, int y)
589  : BC_GenericButton(x, y, _("Delete"))
590 {
591         this->window = window;
592 }
593 ChannelEditDel::~ChannelEditDel()
594 {
595 }
596 int ChannelEditDel::handle_event()
597 {
598         if(window->list_box->get_selection_number(0, 0) > -1)
599                 window->delete_channel(window->list_box->get_selection_number(0, 0));
600         return 1;
601 }
602
603 ChannelEdit::ChannelEdit(ChannelEditWindow *window, int x, int y)
604  : BC_GenericButton(x, y, _("Edit..."))
605 {
606         this->window = window;
607 }
608 ChannelEdit::~ChannelEdit()
609 {
610 }
611 int ChannelEdit::handle_event()
612 {
613         window->edit_channel();
614         return 1;
615 }
616
617 ChannelEditPicture::ChannelEditPicture(ChannelEditWindow *window, int x, int y)
618  : BC_GenericButton(x, y, _("Picture..."))
619 {
620         this->window = window;
621 }
622 ChannelEditPicture::~ChannelEditPicture()
623 {
624 }
625 int ChannelEditPicture::handle_event()
626 {
627         window->edit_picture();
628         return 1;
629 }
630
631
632 // ========================= confirm overwrite by channel scanning
633
634 ConfirmScan::ConfirmScan(ChannelEditWindow *gui, int x, int y)
635  : BC_Window(_(PROGRAM_NAME ": Scan confirm"),
636         x, y, 350, BC_OKButton::calculate_h() + 130,
637         0, 0, 0, 0, 1)
638 {
639         this->gui = gui;
640 }
641
642 void ConfirmScan::create_objects()
643 {
644         lock_window("ConfirmScan::create_objects");
645         int x = 10, y = 10;
646         int y2 = 0, x2 = 0;
647         BC_Title *title;
648         add_subwindow(title = new BC_Title(x, y, _("Set parameters for channel scanning.")));
649         y += title->get_h() + 10;
650         y2 = y;
651
652         add_subwindow(title = new BC_Title(x, y, _("Frequency table:")));
653         x2 = title->get_w();
654         y += BC_PopupMenu::calculate_h();
655         add_subwindow(title = new BC_Title(x, y, _("Norm:")));
656         x2 = MAX(x2, title->get_w());
657         y += BC_PopupMenu::calculate_h();
658         add_subwindow(title = new BC_Title(x, y, _("Input:")));
659         x2 = MAX(x2, title->get_w());
660         y += BC_PopupMenu::calculate_h();
661         x2 += x + 5;
662
663         y = y2;
664         x = x2;
665         ChannelEditEditFreqtable *table;
666         add_subwindow(table = new ChannelEditEditFreqtable(x,
667                 y,
668                 0,
669                 gui->thread));
670         table->add_items();
671         y += table->get_h() + 10;
672
673         ChannelEditEditNorm *norm;
674         add_subwindow(norm = new ChannelEditEditNorm(x,
675                 y,
676                 0,
677                 gui->thread));
678         norm->add_items();
679         y += norm->get_h() + 10;
680
681         ChannelEditEditInput *input;
682         add_subwindow(input = new ChannelEditEditInput(x,
683                 y,
684                 0,
685                 gui->thread));
686         input->add_items();
687
688
689         add_subwindow(new BC_OKButton(this));
690         add_subwindow(new BC_CancelButton(this));
691         show_window();
692         unlock_window();
693 }
694
695 ConfirmScanThread::ConfirmScanThread(ChannelEditWindow *gui)
696  : BC_DialogThread()
697 {
698         this->gui = gui;
699 }
700
701 void ConfirmScanThread::handle_done_event(int result)
702 {
703         gui->channel_picker->save_scan_defaults(&gui->thread->scan_params);
704         if(!result)
705         {
706                 get_gui()->hide_window();
707                 gui->lock_window("ConfirmScanThread::handle_done_event");
708                 gui->scan();
709                 gui->unlock_window();
710         }
711 }
712
713 ConfirmScanThread::~ConfirmScanThread()
714 {
715         close_window();
716 }
717
718 BC_Window* ConfirmScanThread::new_gui()
719 {
720         int x = gui->get_abs_cursor_x(1);
721         int y = gui->get_abs_cursor_y(1);
722         ConfirmScan *result = new ConfirmScan(gui, x, y);
723         result->create_objects();
724         return result;
725 }
726
727
728
729
730
731
732 ScanThread::ScanThread(ChannelEditThread *edit)
733  : Thread(1, 0, 0)
734 {
735         this->edit = edit;
736         interrupt = 1;
737         progress = 0;
738 }
739
740 ScanThread::~ScanThread()
741 {
742         stop();
743 }
744
745 void ScanThread::stop()
746 {
747 // Cancel previous job
748         interrupt = 1;
749         Thread::join();
750         if( progress ) {
751                 progress->stop_progress();
752                 delete progress;  progress = 0;
753         }
754 }
755
756 void ScanThread::start()
757 {
758         stop();
759         interrupt = 0;
760
761         progress = new BC_ProgressBox(
762                 edit->channel_picker->parent_window->get_abs_cursor_x(1),
763                 edit->channel_picker->parent_window->get_abs_cursor_y(1),
764                 _("Scanning"),
765                 chanlists[edit->scan_params.freqtable].count);
766         progress->start();
767
768         Thread::start();
769 }
770
771 void ScanThread::run()
772 {
773         for(int i = 0; i < chanlists[edit->scan_params.freqtable].count &&
774                         !interrupt && !progress->is_cancelled(); i++) {
775                 edit->scan_params.entry = i;
776                 char string[BCTEXTLEN];
777                 sprintf(edit->scan_params.title, "%s",
778                         chanlists[edit->scan_params.freqtable].list[i].name);
779                 sprintf(string, _("Scanning %s"), edit->scan_params.title);
780                 progress->update_title(string, 1);
781                 progress->update(i, 1);
782                 edit->channel_picker->set_channel(&edit->scan_params);
783                 sleep(1); // has_signal should do whatever it takes
784                 if( interrupt ) break;
785                 int got_signal = edit->channel_picker->has_signal();
786                 if( interrupt ) break;
787                 if(!got_signal) continue;
788                 if(edit->channel_picker->get_channel_usage()->has_subchan) {
789                         ArrayList<Channel*> channels;
790                         edit->channel_picker->create_channeldb(&channels);
791                         if( channels.total ) {
792                                 edit->window->lock_window("ScanThread::run");
793                                 for( int i=0; i<channels.total; ++i ) {
794                                         Channel *new_channel = channels.values[i];
795                                         new_channel->copy_usage(&edit->scan_params);
796                                         edit->new_channels->append(new_channel);
797                                 }
798                                 edit->window->update_list();
799                                 edit->window->unlock_window();
800                                 continue;
801                         }
802                 }
803                 Channel *new_channel = new Channel;
804                 new_channel->copy_usage(&edit->scan_params);
805                 new_channel->copy_settings(&edit->scan_params);
806                 edit->window->lock_window("ScanThread::run");
807                 edit->new_channels->append(new_channel);
808                 edit->window->update_list();
809                 edit->window->unlock_window();
810         }
811         edit->window->set_done(interrupt || progress->is_cancelled() ? 1 : 0);
812 }
813
814
815
816
817
818
819
820 // ================================= Edit a single channel
821
822
823
824 ChannelEditEditThread::ChannelEditEditThread(ChannelEditWindow *window,
825         ChannelPicker *channel_picker)
826  : Thread()
827 {
828         this->window = window;
829         this->channel_picker = channel_picker;
830         in_progress = 0;
831         edit_window = 0;
832         editing = 0;
833         completion = new Condition(1, "ChannelEditEditThread::completion");
834 }
835
836 ChannelEditEditThread::~ChannelEditEditThread()
837 {
838         close_threads();
839         delete completion;
840 }
841
842 void ChannelEditEditThread::close_threads()
843 {
844         if(edit_window)
845         {
846                 edit_window->set_done(1);
847                 completion->lock("ChannelEditEditThread::close_threads");
848                 completion->unlock();
849         }
850 }
851
852 int ChannelEditEditThread::edit_channel(Channel *channel, int editing)
853 {
854         if(in_progress)
855         {
856                 edit_window->lock_window("ChannelEditEditThread::edit_channel");
857                 edit_window->raise_window(1);
858                 edit_window->unlock_window();
859                 return 1;
860         }
861         in_progress = 1;
862
863 // Copy the channel to edit into a temporary
864         completion->lock("ChannelEditEditThread::edit_channel");
865         this->editing = editing;
866         this->output_channel = channel;
867         new_channel.copy_settings(output_channel);
868         new_channel.copy_usage(output_channel);
869
870         if(editing && new_channel.title[0])
871                 user_title = 1;
872         else
873                 user_title = 0;
874         set_synchronous(0);
875         Thread::start();
876         return 0;
877 }
878
879
880 void ChannelEditEditThread::set_device()
881 {
882         channel_picker->set_channel(&new_channel);
883 }
884
885 void ChannelEditEditThread::change_source(const char *source_name)
886 {
887         for(int i = 0; i < chanlists[new_channel.freqtable].count; i++)
888         {
889                 if(!strcasecmp(chanlists[new_channel.freqtable].list[i].name, source_name))
890                 {
891                         new_channel.entry = i;
892                         i = chanlists[new_channel.freqtable].count;
893                         set_device();
894                 }
895         }
896         if(!user_title)
897         {
898                 strcpy(new_channel.title, source_name);
899                 if(edit_window->title_text)
900                 {
901                         edit_window->title_text->update(source_name);
902                 }
903         }
904 }
905
906 void ChannelEditEditThread::source_up()
907 {
908         new_channel.entry++;
909         if(new_channel.entry > chanlists[new_channel.freqtable].count - 1) new_channel.entry = 0;
910         source_text->update(chanlists[new_channel.freqtable].list[new_channel.entry].name);
911         set_device();
912 }
913
914 void ChannelEditEditThread::source_down()
915 {
916         new_channel.entry--;
917         if(new_channel.entry < 0) new_channel.entry = chanlists[new_channel.freqtable].count - 1;
918         source_text->update(chanlists[new_channel.freqtable].list[new_channel.entry].name);
919         set_device();
920 }
921
922 void ChannelEditEditThread::set_input(int value)
923 {
924         new_channel.input = value;
925         set_device();
926 }
927
928 void ChannelEditEditThread::set_norm(int value)
929 {
930         new_channel.norm = value;
931         set_device();
932 }
933
934 void ChannelEditEditThread::set_freqtable(int value)
935 {
936         new_channel.freqtable = value;
937         if(new_channel.entry > chanlists[new_channel.freqtable].count - 1) new_channel.entry = 0;
938         source_text->update(chanlists[new_channel.freqtable].list[new_channel.entry].name);
939         set_device();
940 }
941
942 void ChannelEditEditThread::run()
943 {
944         ChannelEditEditWindow edit_window(this, window, channel_picker);
945         edit_window.create_objects(&new_channel);
946         this->edit_window = &edit_window;
947         int result = edit_window.run_window();
948         this->edit_window = 0;
949
950 // Done editing channel.  Keep channel.
951         if(!result)
952         {
953                 output_channel->copy_settings(&new_channel);
954                 window->lock_window();
955                 window->update_list(output_channel);
956                 window->unlock_window();
957         }
958         else
959         {
960 // Discard channel.
961                 if(!editing)
962                 {
963                         window->lock_window();
964                         window->delete_channel(output_channel);
965                         window->unlock_window();
966                 }
967         }
968         editing = 0;
969         completion->unlock();
970         in_progress = 0;
971 }
972
973 ChannelEditEditWindow::ChannelEditEditWindow(ChannelEditEditThread *thread,
974         ChannelEditWindow *window,
975         ChannelPicker *channel_picker)
976  : BC_Window(_(PROGRAM_NAME ": Edit Channel"),
977         channel_picker->parent_window->get_abs_cursor_x(1),
978         channel_picker->parent_window->get_abs_cursor_y(1),
979         390, 300, 390, 300, 0, 0, 1)
980 {
981         this->channel_picker = channel_picker;
982         this->window = window;
983         this->thread = thread;
984 }
985 ChannelEditEditWindow::~ChannelEditEditWindow()
986 {
987 }
988
989 void ChannelEditEditWindow::create_objects(Channel *channel)
990 {
991         lock_window("ChannelEditEditWindow::create_objects");
992         this->new_channel = channel;
993         Channel *channel_usage = channel_picker->get_channel_usage();
994         title_text = 0;
995
996         int x = 10, y = 10;
997 //      if(!channel_usage ||
998 //              (!channel_usage->use_frequency &&
999 //              !channel_usage->use_fine &&
1000 //              !channel_usage->use_norm &&
1001 //              !channel_usage->use_input))
1002 //      {
1003 //              add_subwindow(new BC_Title(x, y, MSG_NO_INP_SELECTION));
1004 //              y += 30;
1005 //      }
1006 //      else
1007 //      {
1008                 add_subwindow(new BC_Title(x, y, _("Title:")));
1009                 add_subwindow(title_text = new ChannelEditEditTitle(x, y + 20, thread));
1010                 y += 50;
1011 //      }
1012
1013         if(channel_usage && channel_usage->use_frequency)
1014         {
1015                 add_subwindow(new BC_Title(x, y, _("Channel:")));
1016                 y += 20;
1017                 add_subwindow(thread->source_text = new ChannelEditEditSource(x, y, thread));
1018                 add_subwindow(new ChannelEditEditSourceTumbler(x + 160, y, thread));
1019                 y += 40;
1020
1021                 add_subwindow(new BC_Title(x, y, _("Frequency table:")));
1022                 ChannelEditEditFreqtable *table;
1023                 add_subwindow(table = new ChannelEditEditFreqtable(x + 130,
1024                         y,
1025                         thread,
1026                         window->thread));
1027                 table->add_items();
1028                 y += 30;
1029         }
1030
1031         if(channel_usage && channel_usage->use_fine)
1032         {
1033                 add_subwindow(new BC_Title(x, y, _("Fine:")));
1034                 add_subwindow(new ChannelEditEditFine(x + 130, y, thread));
1035                 y += 30;
1036         }
1037
1038         if(channel_usage && channel_usage->use_norm)
1039         {
1040                 add_subwindow(new BC_Title(x, y, _("Norm:")));
1041                 ChannelEditEditNorm *norm;
1042                 add_subwindow(norm = new ChannelEditEditNorm(x + 130,
1043                         y,
1044                         thread,
1045                         window->thread));
1046                 norm->add_items();
1047                 y += 30;
1048         }
1049
1050         if( (channel_usage && channel_usage->use_input) ||
1051                 !channel_usage)
1052         {
1053                 add_subwindow(new BC_Title(x, y, _("Input:")));
1054                 ChannelEditEditInput *input;
1055                 add_subwindow(input = new ChannelEditEditInput(x + 130,
1056                         y,
1057                         thread,
1058                         window->thread));
1059                 input->add_items();
1060                 y += 30;
1061         }
1062
1063         add_subwindow(new BC_OKButton(this));
1064         x += 200;
1065         add_subwindow(new BC_CancelButton(this));
1066         show_window();
1067         unlock_window();
1068 }
1069
1070 ChannelEditEditTitle::ChannelEditEditTitle(int x,
1071         int y,
1072         ChannelEditEditThread *thread)
1073  : BC_TextBox(x, y, 150, 1, thread->new_channel.title)
1074 {
1075         this->thread = thread;
1076 }
1077 ChannelEditEditTitle::~ChannelEditEditTitle()
1078 {
1079 }
1080 int ChannelEditEditTitle::handle_event()
1081 {
1082         if(strlen(get_text()) < 1024)
1083         {
1084                 strcpy(thread->new_channel.title, get_text());
1085         }
1086         thread->user_title = get_text()[0] ? 1 : 0;
1087         return 1;
1088 }
1089
1090
1091 ChannelEditEditSource::ChannelEditEditSource(int x, int y, ChannelEditEditThread *thread)
1092  : BC_TextBox(x, y, 150, 1, chanlists[thread->new_channel.freqtable].list[thread->new_channel.entry].name)
1093 {
1094         this->thread = thread;
1095 }
1096
1097 ChannelEditEditSource::~ChannelEditEditSource()
1098 {
1099 }
1100 int ChannelEditEditSource::handle_event()
1101 {
1102         thread->change_source(get_text());
1103         return 1;
1104 }
1105
1106
1107 ChannelEditEditSourceTumbler::ChannelEditEditSourceTumbler(int x, int y, ChannelEditEditThread *thread)
1108  : BC_Tumbler(x, y)
1109 {
1110         this->thread = thread;
1111 }
1112 ChannelEditEditSourceTumbler::~ChannelEditEditSourceTumbler()
1113 {
1114 }
1115 int ChannelEditEditSourceTumbler::handle_up_event()
1116 {
1117         thread->source_up();
1118         return 1;
1119 }
1120 int ChannelEditEditSourceTumbler::handle_down_event()
1121 {
1122         thread->source_down();
1123         return 1;
1124 }
1125
1126 ChannelEditEditInput::ChannelEditEditInput(int x,
1127         int y,
1128         ChannelEditEditThread *thread,
1129         ChannelEditThread *edit)
1130  : BC_PopupMenu(x,
1131         y,
1132         150,
1133         edit->value_to_input(thread ? thread->new_channel.input : edit->scan_params.input))
1134 {
1135         this->thread = thread;
1136         this->edit = edit;
1137 }
1138 ChannelEditEditInput::~ChannelEditEditInput()
1139 {
1140 }
1141 void ChannelEditEditInput::add_items()
1142 {
1143         ArrayList<Channel*> *inputs;
1144         inputs = edit->channel_picker->get_video_inputs();
1145
1146         if(inputs)
1147         {
1148                 for(int i = 0; i < inputs->total; i++)
1149                 {
1150                         add_item(new ChannelEditEditInputItem(thread,
1151                                 edit,
1152                                 inputs->values[i]->device_name,
1153                                 i));
1154                 }
1155         }
1156 }
1157 int ChannelEditEditInput::handle_event()
1158 {
1159         return 0;
1160 }
1161
1162 ChannelEditEditInputItem::ChannelEditEditInputItem(ChannelEditEditThread *thread,
1163         ChannelEditThread *edit,
1164         char *text,
1165         int value)
1166  : BC_MenuItem(text)
1167 {
1168         this->thread = thread;
1169         this->edit = edit;
1170         this->value = value;
1171 }
1172 ChannelEditEditInputItem::~ChannelEditEditInputItem()
1173 {
1174 }
1175 int ChannelEditEditInputItem::handle_event()
1176 {
1177         get_popup_menu()->set_text(get_text());
1178         if(thread && !thread->user_title)
1179         {
1180                 strcpy(thread->new_channel.title, get_text());
1181                 if(thread->edit_window->title_text)
1182                 {
1183                         thread->edit_window->title_text->update(get_text());
1184                 }
1185         }
1186         if(thread)
1187                 thread->set_input(value);
1188         else
1189                 edit->scan_params.input = value;
1190         return 1;
1191 }
1192
1193 ChannelEditEditNorm::ChannelEditEditNorm(int x,
1194         int y,
1195         ChannelEditEditThread *thread,
1196         ChannelEditThread *edit)
1197  : BC_PopupMenu(x,
1198         y,
1199         100,
1200         edit->value_to_norm(thread ? thread->new_channel.norm : edit->scan_params.norm))
1201 {
1202         this->thread = thread;
1203         this->edit = edit;
1204 }
1205 ChannelEditEditNorm::~ChannelEditEditNorm()
1206 {
1207 }
1208 void ChannelEditEditNorm::add_items()
1209 {
1210         add_item(new ChannelEditEditNormItem(thread,
1211                 edit,
1212                 edit->value_to_norm(NTSC), NTSC));
1213         add_item(new ChannelEditEditNormItem(thread,
1214                 edit,
1215                 edit->value_to_norm(PAL), PAL));
1216         add_item(new ChannelEditEditNormItem(thread,
1217                 edit,
1218                 edit->value_to_norm(SECAM), SECAM));
1219 }
1220
1221
1222 ChannelEditEditNormItem::ChannelEditEditNormItem(ChannelEditEditThread *thread,
1223         ChannelEditThread *edit,
1224         char *text,
1225         int value)
1226  : BC_MenuItem(text)
1227 {
1228         this->value = value;
1229         this->edit = edit;
1230         this->thread = thread;
1231 }
1232 ChannelEditEditNormItem::~ChannelEditEditNormItem()
1233 {
1234 }
1235 int ChannelEditEditNormItem::handle_event()
1236 {
1237         get_popup_menu()->set_text(get_text());
1238         if(thread)
1239                 thread->set_norm(value);
1240         else
1241                 edit->scan_params.norm = value;
1242         return 1;
1243 }
1244
1245
1246 ChannelEditEditFreqtable::ChannelEditEditFreqtable(int x,
1247         int y,
1248         ChannelEditEditThread *thread,
1249         ChannelEditThread *edit)
1250  : BC_PopupMenu(x,
1251         y,
1252         150,
1253         edit->value_to_freqtable(thread ? thread->new_channel.freqtable : edit->scan_params.freqtable))
1254 {
1255         this->thread = thread;
1256         this->edit = edit;
1257 }
1258 ChannelEditEditFreqtable::~ChannelEditEditFreqtable()
1259 {
1260 }
1261 void ChannelEditEditFreqtable::add_items()
1262 {
1263         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(NTSC_DVB), NTSC_DVB));
1264         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(CATV_DVB), CATV_DVB));
1265         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(NTSC_BCAST), NTSC_BCAST));
1266         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(NTSC_CABLE), NTSC_CABLE));
1267         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(NTSC_HRC), NTSC_HRC));
1268         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(NTSC_BCAST_JP), NTSC_BCAST_JP));
1269         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(NTSC_CABLE_JP), NTSC_CABLE_JP));
1270         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(PAL_AUSTRALIA), PAL_AUSTRALIA));
1271         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(PAL_EUROPE), PAL_EUROPE));
1272         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(PAL_E_EUROPE), PAL_E_EUROPE));
1273         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(PAL_ITALY), PAL_ITALY));
1274         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(PAL_IRELAND), PAL_IRELAND));
1275         add_item(new ChannelEditEditFreqItem(thread, edit, edit->value_to_freqtable(PAL_NEWZEALAND), PAL_NEWZEALAND));
1276 }
1277
1278 ChannelEditEditFreqItem::ChannelEditEditFreqItem(ChannelEditEditThread *thread,
1279         ChannelEditThread *edit,
1280         char *text, int value)
1281  : BC_MenuItem(text)
1282 {
1283         this->value = value;
1284         this->edit = edit;
1285         this->thread = thread;
1286 }
1287 ChannelEditEditFreqItem::~ChannelEditEditFreqItem()
1288 {
1289 }
1290 int ChannelEditEditFreqItem::handle_event()
1291 {
1292         get_popup_menu()->set_text(get_text());
1293         if(thread)
1294                 thread->set_freqtable(value);
1295         else
1296                 edit->scan_params.freqtable = value;
1297         return 1;
1298 }
1299
1300
1301
1302 ChannelEditEditFine::ChannelEditEditFine(int x,
1303         int y,
1304         ChannelEditEditThread *thread)
1305  : BC_ISlider(x,
1306                 y,
1307                 0,
1308                 240,
1309                 240,
1310                 -100,
1311                 100,
1312                 thread->new_channel.fine_tune)
1313 {
1314         this->thread = thread;
1315 }
1316 ChannelEditEditFine::~ChannelEditEditFine()
1317 {
1318 }
1319 int ChannelEditEditFine::handle_event()
1320 {
1321         return 1;
1322 }
1323 int ChannelEditEditFine::button_release_event()
1324 {
1325         if(BC_Slider::button_release_event())
1326         {
1327                 thread->new_channel.fine_tune = get_value();
1328                 thread->set_device();
1329                 return 1;
1330         }
1331         return 0;
1332 }
1333
1334
1335 // ========================== picture quality
1336
1337 ChannelEditPictureThread::ChannelEditPictureThread(
1338         ChannelPicker *channel_picker)
1339  : BC_DialogThread()
1340 {
1341         this->channel_picker = channel_picker;
1342 }
1343 ChannelEditPictureThread::~ChannelEditPictureThread()
1344 {
1345 }
1346
1347 void ChannelEditPictureThread::handle_done_event(int result)
1348 {
1349         if(channel_picker->get_picture_usage())
1350                 channel_picker->get_picture_usage()->save_defaults();
1351 }
1352
1353 BC_Window* ChannelEditPictureThread::new_gui()
1354 {
1355         ChannelEditPictureWindow *edit_window = new ChannelEditPictureWindow(this,
1356                 channel_picker);
1357         edit_window->create_objects();
1358         return edit_window;
1359 }
1360
1361 void ChannelEditPictureThread::edit_picture()
1362 {
1363         start();
1364 }
1365
1366
1367 ChannelEditPictureWindow::ChannelEditPictureWindow(ChannelEditPictureThread *thread,
1368         ChannelPicker *channel_picker)
1369  : BC_Window(_(PROGRAM_NAME ": Picture"),
1370         channel_picker->mwindow->session->picture_x,
1371         channel_picker->mwindow->session->picture_y,
1372         calculate_w(channel_picker), calculate_h(channel_picker),
1373         calculate_w(channel_picker), calculate_h(channel_picker))
1374 {
1375         this->thread = thread;
1376         this->channel_picker = channel_picker;
1377 }
1378 ChannelEditPictureWindow::~ChannelEditPictureWindow()
1379 {
1380 }
1381
1382 int ChannelEditPictureWindow::calculate_h(ChannelPicker *channel_picker)
1383 {
1384         PictureConfig *picture_usage = channel_picker->get_picture_usage();
1385         int pad = BC_Pot::calculate_h();
1386         int text_h = channel_picker->parent_window->get_text_height(MEDIUMFONT);
1387         int result = 20 + text_h + 5 + BC_OKButton::calculate_h();
1388
1389 // Only used for Video4Linux 1
1390         if( !picture_usage || (
1391              !picture_usage->use_brightness &&
1392              !picture_usage->use_contrast &&
1393              !picture_usage->use_color &&
1394              !picture_usage->use_hue &&
1395              !picture_usage->use_whiteness &&
1396              !channel_picker->get_controls() ) ) {
1397                 result += BC_Title::calculate_h(channel_picker->parent_window,
1398                         MSG_NO_PIC_CONTROLS);
1399         }
1400         else
1401         {
1402                 if(picture_usage->use_brightness)
1403                         result += pad;
1404                 if(picture_usage->use_contrast)
1405                         result += pad;
1406                 if(picture_usage->use_color)
1407                         result += pad;
1408                 if(picture_usage->use_hue)
1409                         result += pad;
1410                 if(picture_usage->use_whiteness)
1411                         result += pad;
1412         }
1413
1414         result += channel_picker->get_controls() * pad;
1415         return result;
1416 }
1417
1418 int ChannelEditPictureWindow::calculate_w(ChannelPicker *channel_picker)
1419 {
1420         PictureConfig *picture_usage = channel_picker->get_picture_usage();
1421         int widget_border = ((Theme*)channel_picker->get_theme())->widget_border;
1422         int pad = BC_Pot::calculate_w() + 4 * widget_border;
1423         int result = 0;
1424
1425 // Only used for Video4Linux 1
1426         if(!picture_usage ||
1427                 (!picture_usage->use_brightness &&
1428                 !picture_usage->use_contrast &&
1429                 !picture_usage->use_color &&
1430                 !picture_usage->use_hue &&
1431                 !picture_usage->use_whiteness &&
1432                 !channel_picker->get_controls()))
1433         {
1434                 result = BC_Title::calculate_w(channel_picker->parent_window,
1435                         MSG_NO_PIC_CONTROLS) + 20;
1436         }
1437
1438 // Only used for Video4Linux 1
1439         if(picture_usage)
1440         {
1441                 if(picture_usage->use_brightness)
1442                 {
1443                         int new_w = BC_Title::calculate_w(channel_picker->parent_window, _("Brightness:")) + pad;
1444                         result = MAX(result, new_w);
1445                 }
1446                 if(picture_usage->use_contrast)
1447                 {
1448                         int new_w = BC_Title::calculate_w(channel_picker->parent_window, _("Contrast:")) + pad;
1449                         result = MAX(result, new_w);
1450                 }
1451                 if(picture_usage->use_color)
1452                 {
1453                         int new_w = BC_Title::calculate_w(channel_picker->parent_window, _("Color:")) + pad;
1454                         result = MAX(result, new_w);
1455                 }
1456                 if(picture_usage->use_hue)
1457                 {
1458                         int new_w = BC_Title::calculate_w(channel_picker->parent_window, _("Hue:")) + pad;
1459                         result = MAX(result, new_w);
1460                 }
1461                 if(picture_usage->use_whiteness)
1462                 {
1463                         int new_w = BC_Title::calculate_w(channel_picker->parent_window, _("Whiteness:")) + pad;
1464                         result = MAX(result, new_w);
1465                 }
1466         }
1467
1468         for(int i = 0; i < channel_picker->get_controls(); i++)
1469         {
1470                 int new_w = BC_Title::calculate_w(channel_picker->parent_window,
1471                                 channel_picker->get_control(i)->name) +
1472                         pad;
1473                 result = MAX(result, new_w);
1474         }
1475
1476         return result;
1477 }
1478
1479
1480 void ChannelEditPictureWindow::create_objects()
1481 {
1482         lock_window("ChannelEditPictureWindow::create_objects");
1483         int x = 10, y = 10;
1484         int widget_border = ((Theme*)channel_picker->get_theme())->widget_border;
1485         int x1 = get_w() - BC_Pot::calculate_w() * 2 - widget_border * 2;
1486         int x2 = get_w() - BC_Pot::calculate_w() - widget_border;
1487         int pad = BC_Pot::calculate_h();
1488
1489 #define SWAP_X x1 ^= x2; x2 ^= x1; x1 ^= x2;
1490
1491         PictureConfig *picture_usage = channel_picker->get_picture_usage();
1492
1493 // Only used for Video4Linux 1
1494         if(!picture_usage ||
1495                 (!picture_usage->use_brightness &&
1496                 !picture_usage->use_contrast &&
1497                 !picture_usage->use_color &&
1498                 !picture_usage->use_hue &&
1499                 !picture_usage->use_whiteness &&
1500                 !channel_picker->get_controls()))
1501         {
1502                 add_subwindow(new BC_Title(x, y, MSG_NO_PIC_CONTROLS));
1503                 y += 50;
1504         }
1505
1506 // Only used for Video4Linux 1
1507         if(picture_usage && picture_usage->use_brightness)
1508         {
1509                 add_subwindow(new BC_Title(x, y + 10, _("Brightness:")));
1510                 add_subwindow(new ChannelEditBright(x1, y, channel_picker, channel_picker->get_brightness()));
1511                 y += pad;
1512                 SWAP_X
1513
1514         }
1515
1516         if(picture_usage && picture_usage->use_contrast)
1517         {
1518                 add_subwindow(new BC_Title(x, y + 10, _("Contrast:")));
1519                 add_subwindow(new ChannelEditContrast(x1, y, channel_picker, channel_picker->get_contrast()));
1520                 y += pad;
1521                 SWAP_X
1522         }
1523
1524         if(picture_usage && picture_usage->use_color)
1525         {
1526                 add_subwindow(new BC_Title(x, y + 10, _("Color:")));
1527                 add_subwindow(new ChannelEditColor(x1, y, channel_picker, channel_picker->get_color()));
1528                 y += pad;
1529                 SWAP_X
1530         }
1531
1532         if(picture_usage && picture_usage->use_hue)
1533         {
1534                 add_subwindow(new BC_Title(x, y + 10, _("Hue:")));
1535                 add_subwindow(new ChannelEditHue(x1, y, channel_picker, channel_picker->get_hue()));
1536                 y += pad;
1537                 SWAP_X
1538         }
1539
1540         if(picture_usage && picture_usage->use_whiteness)
1541         {
1542                 add_subwindow(new BC_Title(x, y + 10, _("Whiteness:")));
1543                 add_subwindow(new ChannelEditWhiteness(x1, y, channel_picker, channel_picker->get_whiteness()));
1544                 y += pad;
1545                 SWAP_X
1546         }
1547
1548         for(int i = 0; i < channel_picker->get_controls(); i++)
1549         {
1550                 BC_Title *title;
1551                 add_subwindow(title = new BC_Title(x,
1552                         y + 10,
1553                         _(channel_picker->get_control(i)->name)));
1554
1555                 int x3 = x1;
1556                 if(x3 < title->get_x() + title->get_w() + widget_border)
1557                         x3 = title->get_x() + title->get_w() + widget_border;
1558
1559                 add_subwindow(new ChannelEditCommon(x3,
1560                         y,
1561                         channel_picker,
1562                         channel_picker->get_control(i)));
1563                 y += pad;
1564                 SWAP_X
1565         }
1566
1567
1568         y += pad;
1569         add_subwindow(new BC_OKButton(this));
1570         show_window();
1571         unlock_window();
1572 }
1573
1574 int ChannelEditPictureWindow::translation_event()
1575 {
1576         channel_picker->mwindow->session->picture_x = get_x();
1577         channel_picker->mwindow->session->picture_y = get_y();
1578         return 0;
1579 }
1580
1581
1582
1583 ChannelEditBright::ChannelEditBright(int x, int y, ChannelPicker *channel_picker, int value)
1584  : BC_IPot(x,
1585                 y,
1586                 value,
1587                 -100,
1588                 100)
1589 {
1590         this->channel_picker = channel_picker;
1591 }
1592 ChannelEditBright::~ChannelEditBright() {}
1593 int ChannelEditBright::handle_event()
1594 {
1595         return 1;
1596 }
1597 int ChannelEditBright::button_release_event()
1598 {
1599         if(BC_Pot::button_release_event())
1600         {
1601                 channel_picker->set_brightness(get_value());
1602                 return 1;
1603         }
1604         return 0;
1605 }
1606
1607 ChannelEditContrast::ChannelEditContrast(int x, int y, ChannelPicker *channel_picker, int value)
1608  : BC_IPot(x,
1609                 y,
1610                 value,
1611                 -100,
1612                 100)
1613 {
1614         this->channel_picker = channel_picker;
1615 }
1616 ChannelEditContrast::~ChannelEditContrast() {}
1617 int ChannelEditContrast::handle_event()
1618 {
1619         return 1;
1620 }
1621 int ChannelEditContrast::button_release_event()
1622 {
1623         if(BC_Pot::button_release_event())
1624         {
1625                 channel_picker->set_contrast(get_value());
1626                 return 1;
1627         }
1628         return 0;
1629 }
1630
1631
1632 ChannelEditColor::ChannelEditColor(int x, int y, ChannelPicker *channel_picker, int value)
1633  : BC_IPot(x,
1634                 y,
1635                 value,
1636                 -100,
1637                 100)
1638 {
1639         this->channel_picker = channel_picker;
1640 }
1641 ChannelEditColor::~ChannelEditColor() {}
1642 int ChannelEditColor::handle_event()
1643 {
1644         return 1;
1645 }
1646 int ChannelEditColor::button_release_event()
1647 {
1648         if(BC_Pot::button_release_event())
1649         {
1650                 channel_picker->set_color(get_value());
1651                 return 1;
1652         }
1653         return 0;
1654 }
1655
1656 ChannelEditHue::ChannelEditHue(int x, int y, ChannelPicker *channel_picker, int value)
1657  : BC_IPot(x,
1658                 y,
1659                 value,
1660                 -100,
1661                 100)
1662 {
1663         this->channel_picker = channel_picker;
1664 }
1665 ChannelEditHue::~ChannelEditHue() {}
1666 int ChannelEditHue::handle_event()
1667 {
1668         return 1;
1669 }
1670 int ChannelEditHue::button_release_event()
1671 {
1672         if(BC_Pot::button_release_event())
1673         {
1674                 channel_picker->set_hue(get_value());
1675                 return 1;
1676         }
1677         return 0;
1678 }
1679
1680 ChannelEditWhiteness::ChannelEditWhiteness(int x, int y, ChannelPicker *channel_picker, int value)
1681  : BC_IPot(x,
1682                 y,
1683                 value,
1684                 -100,
1685                 100)
1686 {
1687         this->channel_picker = channel_picker;
1688 }
1689 ChannelEditWhiteness::~ChannelEditWhiteness()
1690 {
1691 }
1692 int ChannelEditWhiteness::handle_event()
1693 {
1694         return 1;
1695 }
1696 int ChannelEditWhiteness::button_release_event()
1697 {
1698         if(BC_Pot::button_release_event())
1699         {
1700                 channel_picker->set_whiteness(get_value());
1701                 return 1;
1702         }
1703         return 0;
1704 }
1705
1706
1707
1708 ChannelEditCommon::ChannelEditCommon(int x,
1709         int y,
1710         ChannelPicker *channel_picker,
1711         PictureItem *item)
1712  : BC_IPot(x,
1713                 y,
1714                 item->value,
1715                 item->min,
1716                 item->max)
1717 {
1718         this->channel_picker = channel_picker;
1719         this->device_id = item->device_id;
1720 }
1721
1722 ChannelEditCommon::~ChannelEditCommon()
1723 {
1724 }
1725
1726 int ChannelEditCommon::handle_event()
1727 {
1728         return 1;
1729 }
1730
1731 int ChannelEditCommon::button_release_event()
1732 {
1733         if(BC_Pot::button_release_event())
1734         {
1735                 channel_picker->set_picture(device_id, get_value());
1736                 return 1;
1737         }
1738         return 0;
1739 }
1740
1741 int ChannelEditCommon::keypress_event()
1742 {
1743         if(BC_Pot::keypress_event())
1744         {
1745                 channel_picker->set_picture(device_id, get_value());
1746                 return 1;
1747         }
1748         return 0;
1749 }
1750
1751
1752
1753
1754