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