r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / cinelerra / channeledit.C
blobd49c475de4b65d8f27ad281798517719fa440a84
1 #include "batch.h"
2 #include "channel.h"
3 #include "channeldb.h"
4 #include "channeledit.h"
5 #include "channelpicker.h"
6 #include "chantables.h"
7 #include "condition.h"
8 #include "language.h"
9 #include "mwindow.h"
10 #include "mwindowgui.h"
11 #include "picture.h"
12 #include "record.h"
13 #include "recordgui.h"
14 #include "theme.h"
15 #include "videodevice.h"
17 #include <string.h>
19 ChannelEditThread::ChannelEditThread(MWindow *mwindow, 
20         ChannelPicker *channel_picker,
21         ChannelDB *channeldb,
22         Record *record)
23  : Thread()
25         this->channel_picker = channel_picker;
26         this->mwindow = mwindow;
27         this->channeldb = channeldb;
28         this->record = record;
29         in_progress = 0;
30         this->window = 0;
31         new_channels = new ChannelDB;
32         completion = new Condition(1, "ChannelEditThread::completion");
34 ChannelEditThread::~ChannelEditThread()
36         delete new_channels;
37         delete completion;
40 void ChannelEditThread::run()
42         int i;
44         if(in_progress) 
45         {
46                 if(window)
47                 {
48                         window->lock_window("ChannelEditThread::run");
49                         window->raise_window(1);
50                         window->unlock_window();
51                 }
52                 return;
53         }
54         in_progress = 1;
55         completion->lock("ChannelEditThread::run");
57 // Copy master channel list to temporary.
58         new_channels->copy_from(channel_picker->channeldb);
59         current_channel = channel_picker->get_current_channel_number();
60 //printf("ChannelEditThread::run 1 %d\n", current_channel);
62 // Run the channel list window using the temporary list.
63         ChannelEditWindow window(mwindow, this, channel_picker);
64         window.create_objects();
65         this->window = &window;
66         int result = window.run_window();
67         this->window = 0;
69         if(!result)
70         {
71 // Copy new channels to master list
72                 channel_picker->channeldb->clear();
73                 
74                 channel_picker->channeldb->copy_from(new_channels);
75                 channel_picker->update_channel_list();
77                 if(record)
78                 {
79                         record->record_gui->lock_window("ChannelEditThread::run");
80                         record->record_gui->update_batch_sources();
82 //printf("ChannelEditThread::run 10 %d\n", current_channel);
83                         record->set_channel(current_channel);
84                         record->record_gui->unlock_window();
85                         record->save_defaults();
86                         record->channeldb->save(record->get_channeldb_prefix());
87                 }
88                 mwindow->save_defaults();
89         }
90         else
91         {
92 // Rejected.
93                 if(record)
94                 {
95                         record->set_channel(record->get_editing_batch()->channel);
96                 }
97         }
99         window.edit_thread->close_threads();
100         window.picture_thread->close_threads();
102         completion->unlock();
103         in_progress = 0;
107 int ChannelEditThread::close_threads()
109         if(in_progress && window)
110         {
111                 window->edit_thread->close_threads();
112                 window->picture_thread->close_threads();
113                 window->set_done(1);
114                 completion->lock("ChannelEditThread::close_threads");
115                 completion->unlock();
116         }
120 ChannelEditWindow::ChannelEditWindow(MWindow *mwindow, 
121         ChannelEditThread *thread, 
122         ChannelPicker *channel_picker)
123  : BC_Window(PROGRAM_NAME ": Channels", 
124         mwindow->gui->get_abs_cursor_x(1) - 330, 
125         mwindow->gui->get_abs_cursor_y(1), 
126         330, 
127         330, 
128         330, 
129         330,
130         0,
131         0,
132         1)
134         this->thread = thread;
135         this->channel_picker = channel_picker;
136         this->mwindow = mwindow;
138 ChannelEditWindow::~ChannelEditWindow()
140         int i;
141         for(i = 0; i < channel_list.total; i++)
142         {
143                 delete channel_list.values[i];
144         }
145         channel_list.remove_all();
146         delete edit_thread;
147         delete picture_thread;
150 int ChannelEditWindow::create_objects()
152         int x = 10, y = 10, i;
153         char string[1024];
155 // Create channel list
156         for(i = 0; i < thread->new_channels->size(); i++)
157         {
158                 channel_list.append(new BC_ListBoxItem(thread->new_channels->get(i)->title));
159         }
161         add_subwindow(list_box = new ChannelEditList(mwindow, this, x, y));
162         x += 200;
163         if(thread->record)
164         {
165                 add_subwindow(new ChannelEditSelect(mwindow, this, x, y));
166                 y += 30;
167         }
168         add_subwindow(new ChannelEditAdd(mwindow, this, x, y));
169         y += 30;
170         add_subwindow(new ChannelEdit(mwindow, this, x, y));
171         y += 30;
172         add_subwindow(new ChannelEditMoveUp(mwindow, this, x, y));
173         y += 30;
174         add_subwindow(new ChannelEditMoveDown(mwindow, this, x, y));
175         y += 30;
176         add_subwindow(new ChannelEditDel(mwindow, this, x, y));
177         y += 30;
178         add_subwindow(new ChannelEditPicture(mwindow, this, x, y));
179         y += 100;
180         x = 10;
181         add_subwindow(new BC_OKButton(this));
182         x += 150;
183         add_subwindow(new BC_CancelButton(this));
186         edit_thread = new ChannelEditEditThread(this, 
187                 channel_picker, 
188                 thread->record);
189         picture_thread = new ChannelEditPictureThread(channel_picker, this);
190         show_window();
191         return 0;
194 int ChannelEditWindow::close_event()
196         set_done(0);
199 int ChannelEditWindow::add_channel()
201         Channel *new_channel;
202         Channel *prev_channel = 0;
204 // Create new channel
205         new_channel = new Channel;
207 // Reuse parameters from previous channel
208         if(thread->new_channels->size()) 
209         {
210                 prev_channel = thread->new_channels->get(
211                                 thread->new_channels->size() - 1);
212                 new_channel->copy_settings(prev_channel);
213         }
214         else
215 // Use default channel parameters
216         if(thread->record)
217         {
218                 new_channel->copy_settings(thread->record->master_channel);
219         }
221 // Copy device usage.  Need the same thing for playback.
222         if(thread->record)
223         {
224                 new_channel->copy_usage(thread->record->master_channel);
225         }
227 // Add to channel table
228         channel_list.append(new BC_ListBoxItem(new_channel->title));
229         thread->new_channels->append(new_channel);
230         update_list();
232 // Start common routing
233         edit_thread->edit_channel(new_channel, 0);
234         return 0;
237 int ChannelEditWindow::update_list()
239         list_box->update(&channel_list, 0, 0, 1, list_box->get_yposition());
242 int ChannelEditWindow::update_list(Channel *channel)
244         int i;
245         for(i = 0; i < thread->new_channels->size(); i++)
246                 if(thread->new_channels->get(i) == channel) break;
248         if(i < thread->new_channels->size())
249         {
250                 channel_list.values[i]->set_text(channel->title);
251         }
253         update_list();
257 int ChannelEditWindow::edit_channel()
259         if(list_box->get_selection_number(0, 0) > -1)
260         {
261                 thread->current_channel = list_box->get_selection_number(0, 0);
262                 edit_thread->edit_channel(
263                         thread->new_channels->get(
264                                 list_box->get_selection_number(0, 0)), 
265                         1);
266         }
269 int ChannelEditWindow::edit_picture()
271         picture_thread->edit_picture();
274 int ChannelEditWindow::delete_channel(int number)
276         delete thread->new_channels->get(number);
277         channel_list.remove_number(number);
278         thread->new_channels->remove_number(number);
279         update_list();
282 int ChannelEditWindow::delete_channel(Channel *channel)
284         int i;
285         for(i = 0; i < thread->new_channels->size(); i++)
286         {
287                 if(thread->new_channels->get(i) == channel)
288                 {
289                         break;
290                 }
291         }
292         if(i < thread->new_channels->size()) delete_channel(i);
293         return 0;
296 int ChannelEditWindow::move_channel_up()
298         if(list_box->get_selection_number(0, 0) > -1)
299         {
300                 int number2 = list_box->get_selection_number(0, 0);
301                 int number1 = number2 - 1;
302                 Channel *temp;
303                 BC_ListBoxItem *temp_text;
305                 if(number1 < 0) number1 = thread->new_channels->size() - 1;
307                 temp = thread->new_channels->get(number1);
308                 thread->new_channels->set(number1, thread->new_channels->get(number2));
309                 thread->new_channels->set(number2, temp);
311                 temp_text = channel_list.values[number1];
312                 channel_list.values[number1] = channel_list.values[number2];
313                 channel_list.values[number2] = temp_text;
314                 list_box->update(&channel_list, 
315                         0, 
316                         0, 
317                         1, 
318                         list_box->get_xposition(), 
319                         list_box->get_yposition(), 
320                         number1,
321                         1);
322         }
323         return 0;
326 int ChannelEditWindow::move_channel_down()
328         if(list_box->get_selection_number(0, 0) > -1)
329         {
330                 int number2 = list_box->get_selection_number(0, 0);
331                 int number1 = number2 + 1;
332                 Channel *temp;
333                 BC_ListBoxItem *temp_text;
335                 if(number1 > thread->new_channels->size() - 1) number1 = 0;
337                 temp = thread->new_channels->get(number1);
338                 thread->new_channels->set(number1, thread->new_channels->get(number2));
339                 thread->new_channels->set(number2, temp);
340                 temp_text = channel_list.values[number1];
341                 channel_list.values[number1] = channel_list.values[number2];
342                 channel_list.values[number2] = temp_text;
343                 list_box->update(&channel_list, 
344                         0, 
345                         0, 
346                         1, 
347                         list_box->get_xposition(), 
348                         list_box->get_yposition(), 
349                         number1,
350                         1);
351         }
352         return 0;
355 int ChannelEditWindow::change_channel_from_list(int channel_number)
357         Channel *channel;
358         if(channel_number > -1 && channel_number < thread->new_channels->size())
359         {
360                 thread->current_channel = channel_number;
361                 channel_picker->set_channel(thread->new_channels->get(channel_number));
362         }
365 ChannelEditSelect::ChannelEditSelect(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
366  : BC_GenericButton(x, y, _("Select"))
368         this->window = window;
370 ChannelEditSelect::~ChannelEditSelect()
373 int ChannelEditSelect::handle_event()
375         window->change_channel_from_list(
376                 window->list_box->get_selection_number(0, 0));
379 ChannelEditAdd::ChannelEditAdd(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
380  : BC_GenericButton(x, y, _("Add..."))
382         this->window = window;
384 ChannelEditAdd::~ChannelEditAdd()
387 int ChannelEditAdd::handle_event()
389         window->add_channel();
392 ChannelEditList::ChannelEditList(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
393  : BC_ListBox(x, 
394                         y, 
395                         185, 
396                         250, 
397                         LISTBOX_TEXT, 
398                         &(window->channel_list))
400         this->window = window;
402 ChannelEditList::~ChannelEditList()
405 int ChannelEditList::handle_event()
407         window->edit_channel();
410 ChannelEditMoveUp::ChannelEditMoveUp(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
411  : BC_GenericButton(x, y, _("Move up"))
413         this->window = window;
415 ChannelEditMoveUp::~ChannelEditMoveUp()
418 int ChannelEditMoveUp::handle_event()
420         lock_window("ChannelEditMoveUp::handle_event");
421         window->move_channel_up();
422         unlock_window();
425 ChannelEditMoveDown::ChannelEditMoveDown(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
426  : BC_GenericButton(x, y, _("Move down"))
428         this->window = window;
430 ChannelEditMoveDown::~ChannelEditMoveDown()
433 int ChannelEditMoveDown::handle_event()
435         lock_window("ChannelEditMoveDown::handle_event");
436         window->move_channel_down();
437         unlock_window();
440 ChannelEditDel::ChannelEditDel(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
441  : BC_GenericButton(x, y, _("Delete"))
443         this->window = window;
445 ChannelEditDel::~ChannelEditDel()
448 int ChannelEditDel::handle_event()
450         if(window->list_box->get_selection_number(0, 0) > -1) window->delete_channel(window->list_box->get_selection_number(0, 0));
453 ChannelEdit::ChannelEdit(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
454  : BC_GenericButton(x, y, _("Edit..."))
456         this->window = window;
458 ChannelEdit::~ChannelEdit()
461 int ChannelEdit::handle_event()
463         window->edit_channel();
466 ChannelEditPicture::ChannelEditPicture(MWindow *mwindow, ChannelEditWindow *window, int x, int y)
467  : BC_GenericButton(x, y, _("Picture..."))
469         this->window = window;
471 ChannelEditPicture::~ChannelEditPicture()
474 int ChannelEditPicture::handle_event()
476         window->edit_picture();
481 // ================================= Edit a single channel
485 ChannelEditEditThread::ChannelEditEditThread(ChannelEditWindow *window, 
486         ChannelPicker *channel_picker,
487         Record *record)
488  : Thread()
490         this->window = window;
491         this->channel_picker = channel_picker;
492         this->record = record;
493         in_progress = 0;
494         edit_window = 0;
495         editing = 0;
496         completion = new Condition(1, "ChannelEditEditThread::completion");
499 ChannelEditEditThread::~ChannelEditEditThread()
501         delete completion;
504 int ChannelEditEditThread::close_threads()
506         if(edit_window)
507         {
508                 edit_window->set_done(1);
509                 completion->lock("ChannelEditEditThread::close_threads");
510                 completion->unlock();
511         }
514 int ChannelEditEditThread::edit_channel(Channel *channel, int editing)
516         if(in_progress) 
517         {
518                 edit_window->lock_window("ChannelEditEditThread::edit_channel");
519                 edit_window->raise_window(1);
520                 edit_window->unlock_window();
521                 return 1;
522         }
523         in_progress = 1;
525 // Copy the channel to edit into a temporary
526         completion->lock("ChannelEditEditThread::edit_channel");
527         this->editing = editing;
528         this->output_channel = channel;
529         new_channel.copy_settings(output_channel);
530         new_channel.copy_usage(output_channel);
532         if(editing && new_channel.title[0])
533                 user_title = 1;
534         else
535                 user_title = 0;
536         set_synchronous(0);
537         Thread::start();
540 char *ChannelEditEditThread::value_to_freqtable(int value)
542         switch(value)
543         {
544                 case NTSC_BCAST:
545                         return _("NTSC_BCAST");
546                         break;
547                 case NTSC_CABLE:
548                         return _("NTSC_CABLE");
549                         break;
550                 case NTSC_HRC:
551                         return _("NTSC_HRC");
552                         break;
553                 case NTSC_BCAST_JP:
554                         return _("NTSC_BCAST_JP");
555                         break;
556                 case NTSC_CABLE_JP:
557                         return _("NTSC_CABLE_JP");
558                         break;
559                 case PAL_AUSTRALIA:
560                         return _("PAL_AUSTRALIA");
561                         break;
562                 case PAL_EUROPE:
563                         return _("PAL_EUROPE");
564                         break;
565                 case PAL_E_EUROPE:
566                         return _("PAL_E_EUROPE");
567                         break;
568                 case PAL_ITALY:
569                         return _("PAL_ITALY");
570                         break;
571                 case PAL_IRELAND:
572                         return _("PAL_IRELAND");
573                         break;
574                 case PAL_NEWZEALAND:
575                         return _("PAL_NEWZEALAND");
576                         break;
577         }
580 char* ChannelEditEditThread::value_to_norm(int value)
582         switch(value)
583         {
584                 case NTSC:
585                         return _("NTSC");
586                         break;
587                 case PAL:
588                         return _("PAL");
589                         break;
590                 case SECAM:
591                         return _("SECAM");
592                         break;
593         }
596 char* ChannelEditEditThread::value_to_input(int value)
598         if(channel_picker->get_video_inputs()->total > value)
599                 return channel_picker->get_video_inputs()->values[value]->device_name;
600         else
601                 return _("None");
604 void ChannelEditEditThread::set_device()
606         channel_picker->set_channel(&new_channel);
609 int ChannelEditEditThread::change_source(char *source_name)
611         int i, result;
612         for(i = 0; i < chanlists[new_channel.freqtable].count; i++)
613         {
614                 if(!strcasecmp(chanlists[new_channel.freqtable].list[i].name, source_name))
615                 {
616                         new_channel.entry = i;
617                         i = chanlists[new_channel.freqtable].count;
618                         set_device();
619                 }
620         }
621         if(!user_title)
622         {
623                 strcpy(new_channel.title, source_name);
624                 if(edit_window->title_text)
625                 {
626                         edit_window->title_text->update(source_name);
627                 }
628         }
631 int ChannelEditEditThread::source_up()
633         new_channel.entry++;
634         if(new_channel.entry > chanlists[new_channel.freqtable].count - 1) new_channel.entry = 0;
635         source_text->update(chanlists[new_channel.freqtable].list[new_channel.entry].name);
636         set_device();
639 int ChannelEditEditThread::source_down()
641         new_channel.entry--;
642         if(new_channel.entry < 0) new_channel.entry = chanlists[new_channel.freqtable].count - 1;
643         source_text->update(chanlists[new_channel.freqtable].list[new_channel.entry].name);
644         set_device();
647 int ChannelEditEditThread::set_input(int value)
649         new_channel.input = value;
650         set_device();
653 int ChannelEditEditThread::set_norm(int value)
655         new_channel.norm = value;
656         set_device();
659 int ChannelEditEditThread::set_freqtable(int value)
661         new_channel.freqtable = value;
662         if(new_channel.entry > chanlists[new_channel.freqtable].count - 1) new_channel.entry = 0;
663         source_text->update(chanlists[new_channel.freqtable].list[new_channel.entry].name);
664         set_device();
667 void ChannelEditEditThread::run()
669         ChannelEditEditWindow edit_window(this, window, channel_picker);
670         edit_window.create_objects(&new_channel);
671         this->edit_window = &edit_window;
672         int result = edit_window.run_window();
673         this->edit_window = 0;
675 // Done editing channel.  Keep channel.
676         if(!result)
677         {
678                 output_channel->copy_settings(&new_channel);
679                 window->lock_window();
680                 window->update_list(output_channel);
681                 window->unlock_window();
682         }
683         else
684         {
685 // Discard channel.
686                 if(!editing)
687                 {
688                         window->lock_window();
689                         window->delete_channel(output_channel);
690                         window->unlock_window();
691                 }
692         }
693         editing = 0;
694         completion->unlock();
695         in_progress = 0;
698 ChannelEditEditWindow::ChannelEditEditWindow(ChannelEditEditThread *thread, 
699         ChannelEditWindow *window,
700         ChannelPicker *channel_picker)
701  : BC_Window(PROGRAM_NAME ": Edit Channel", 
702         channel_picker->mwindow->gui->get_abs_cursor_x(1), 
703         channel_picker->mwindow->gui->get_abs_cursor_y(1), 
704         390, 
705         270, 
706         390, 
707         270,
708         0,
709         0,
710         1)
712         this->channel_picker = channel_picker;
713         this->window = window;
714         this->thread = thread;
716 ChannelEditEditWindow::~ChannelEditEditWindow()
719 int ChannelEditEditWindow::create_objects(Channel *channel)
721         this->new_channel = channel;
722         Channel *channel_usage = channel_picker->get_channel_usage();
723         title_text = 0;
725         int x = 10, y = 10;
726         if(!channel_usage ||
727                 (!channel_usage->use_frequency && 
728                 !channel_usage->use_fine && 
729                 !channel_usage->use_norm && 
730                 !channel_usage->use_input))
731         {
732                 add_subwindow(new BC_Title(x, y, "Device has no input selection."));
733                 y += 30;
734         }
735         else
736         {
737                 add_subwindow(new BC_Title(x, y, _("Title:")));
738                 add_subwindow(title_text = new ChannelEditEditTitle(x, y + 20, thread));
739                 y += 50;
740         }
742         if(channel_usage->use_frequency)
743         {
744                 add_subwindow(new BC_Title(x, y, _("Channel:")));
745                 y += 20;
746                 add_subwindow(thread->source_text = new ChannelEditEditSource(x, y, thread));
747                 add_subwindow(new ChannelEditEditSourceTumbler(x + 160, y, thread));
748                 y += 40;
750                 add_subwindow(new BC_Title(x, y, _("Frequency table:")));
751                 ChannelEditEditFreqtable *table;
752                 add_subwindow(table = new ChannelEditEditFreqtable(x + 130, y, thread));
753                 table->add_items();
754                 y += 30;
755         }
757         if(channel_usage->use_fine)
758         {
759                 add_subwindow(new BC_Title(x, y, _("Fine:")));
760                 add_subwindow(new ChannelEditEditFine(x + 130, y, thread));
761                 y += 30;
762         }
764         if(channel_usage->use_norm)
765         {
766                 add_subwindow(new BC_Title(x, y, _("Norm:")));
767                 ChannelEditEditNorm *norm;
768                 add_subwindow(norm = new ChannelEditEditNorm(x + 130, y, thread));
769                 norm->add_items();
770                 y += 30;
771         }
773         if(channel_usage->use_input)
774         {
775                 add_subwindow(new BC_Title(x, y, _("Input:")));
776                 ChannelEditEditInput *input;
777                 add_subwindow(input = new ChannelEditEditInput(x + 130, y, thread, thread->record));
778                 input->add_items();
779                 y += 30;
780         }
782         add_subwindow(new BC_OKButton(x, y));
783         x += 200;
784         add_subwindow(new BC_CancelButton(x, y));
785         show_window();
786         return 0;
789 ChannelEditEditTitle::ChannelEditEditTitle(int x, 
790         int y, 
791         ChannelEditEditThread *thread)
792  : BC_TextBox(x, y, 150, 1, thread->new_channel.title)
794         this->thread = thread;
796 ChannelEditEditTitle::~ChannelEditEditTitle()
799 int ChannelEditEditTitle::handle_event()
801         if(strlen(get_text()) < 1024)
802         {
803                 strcpy(thread->new_channel.title, get_text());
804         }
805         if(get_text()[0]) 
806                 thread->user_title = 1;
807         else
808                 thread->user_title = 0;
809         return 1;
813 ChannelEditEditSource::ChannelEditEditSource(int x, int y, ChannelEditEditThread *thread)
814  : BC_TextBox(x, y, 150, 1, chanlists[thread->new_channel.freqtable].list[thread->new_channel.entry].name)
816         this->thread = thread;
819 ChannelEditEditSource::~ChannelEditEditSource()
822 int ChannelEditEditSource::handle_event()
824         thread->change_source(get_text());
828 ChannelEditEditSourceTumbler::ChannelEditEditSourceTumbler(int x, int y, ChannelEditEditThread *thread)
829  : BC_Tumbler(x, y)
831         this->thread = thread;
833 ChannelEditEditSourceTumbler::~ChannelEditEditSourceTumbler()
836 int ChannelEditEditSourceTumbler::handle_up_event()
838         thread->source_up();
840 int ChannelEditEditSourceTumbler::handle_down_event()
842         thread->source_down();
845 ChannelEditEditInput::ChannelEditEditInput(int x, int y, ChannelEditEditThread *thread, Record *record)
846  : BC_PopupMenu(x, y, 150, thread->value_to_input(thread->new_channel.input))
848         this->thread = thread;
849         this->record = record;
851 ChannelEditEditInput::~ChannelEditEditInput()
854 int ChannelEditEditInput::add_items()
856         ArrayList<Channel*> *inputs;
857         inputs = thread->channel_picker->get_video_inputs();
858         
859         if(inputs)
860                 for(int i = 0; i < inputs->total; i++)
861                 {
862                         add_item(new ChannelEditEditInputItem(thread, inputs->values[i]->device_name, i));
863                 }
865 int ChannelEditEditInput::handle_event()
867         return 0;
870 ChannelEditEditInputItem::ChannelEditEditInputItem(ChannelEditEditThread *thread, char *text, int value)
871  : BC_MenuItem(text)
873         this->thread = thread;
874         this->value = value;
876 ChannelEditEditInputItem::~ChannelEditEditInputItem()
879 int ChannelEditEditInputItem::handle_event()
881         get_popup_menu()->set_text(get_text());
882         if(!thread->user_title)
883         {
884                 strcpy(thread->new_channel.title, get_text());
885                 if(thread->edit_window->title_text)
886                 {
887                         thread->edit_window->title_text->update(get_text());
888                 }
889         }
890         thread->set_input(value);
893 ChannelEditEditNorm::ChannelEditEditNorm(int x, int y, ChannelEditEditThread *thread)
894  : BC_PopupMenu(x, y, 100, thread->value_to_norm(thread->new_channel.norm))
896         this->thread = thread;
898 ChannelEditEditNorm::~ChannelEditEditNorm()
901 int ChannelEditEditNorm::add_items()
903         add_item(new ChannelEditEditNormItem(thread, thread->value_to_norm(NTSC), NTSC));
904         add_item(new ChannelEditEditNormItem(thread, thread->value_to_norm(PAL), PAL));
905         add_item(new ChannelEditEditNormItem(thread, thread->value_to_norm(SECAM), SECAM));
906         return 0;
910 ChannelEditEditNormItem::ChannelEditEditNormItem(ChannelEditEditThread *thread, char *text, int value)
911  : BC_MenuItem(text)
913         this->value = value;
914         this->thread = thread;
916 ChannelEditEditNormItem::~ChannelEditEditNormItem()
919 int ChannelEditEditNormItem::handle_event()
921         get_popup_menu()->set_text(get_text());
922         thread->set_norm(value);
926 ChannelEditEditFreqtable::ChannelEditEditFreqtable(int x, int y, ChannelEditEditThread *thread)
927  : BC_PopupMenu(x, y, 150, thread->value_to_freqtable(thread->new_channel.freqtable))
929         this->thread = thread;
931 ChannelEditEditFreqtable::~ChannelEditEditFreqtable()
934 int ChannelEditEditFreqtable::add_items()
936         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(NTSC_BCAST), NTSC_BCAST));
937         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(NTSC_CABLE), NTSC_CABLE));
938         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(NTSC_HRC), NTSC_HRC));
939         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(NTSC_BCAST_JP), NTSC_BCAST_JP));
940         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(NTSC_CABLE_JP), NTSC_CABLE_JP));
941         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(PAL_AUSTRALIA), PAL_AUSTRALIA));
942         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(PAL_EUROPE), PAL_EUROPE));
943         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(PAL_E_EUROPE), PAL_E_EUROPE));
944         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(PAL_ITALY), PAL_ITALY));
945         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(PAL_IRELAND), PAL_IRELAND));
946         add_item(new ChannelEditEditFreqItem(thread, thread->value_to_freqtable(PAL_NEWZEALAND), PAL_NEWZEALAND));
947         return 0;
950 ChannelEditEditFreqItem::ChannelEditEditFreqItem(ChannelEditEditThread *thread, char *text, int value)
951  : BC_MenuItem(text)
953         this->value = value;
954         this->thread = thread;
956 ChannelEditEditFreqItem::~ChannelEditEditFreqItem()
959 int ChannelEditEditFreqItem::handle_event()
961         get_popup_menu()->set_text(get_text());
962         thread->set_freqtable(value);
967 ChannelEditEditFine::ChannelEditEditFine(int x, int y, ChannelEditEditThread *thread)
968  : BC_ISlider(x, 
969                 y, 
970                 0, 
971                 240, 
972                 240, 
973                 -100, 
974                 100, 
975                 thread->new_channel.fine_tune)
977         this->thread = thread;
979 ChannelEditEditFine::~ChannelEditEditFine()
982 int ChannelEditEditFine::handle_event()
984         thread->new_channel.fine_tune = get_value();
985         thread->set_device();
989 // ========================== picture quality
991 ChannelEditPictureThread::ChannelEditPictureThread(ChannelPicker *channel_picker, ChannelEditWindow *window)
992  : Thread()
994         this->channel_picker = channel_picker;
995         this->window = window;
996         in_progress = 0;
997         edit_window = 0;
998         completion = new Condition(1, "ChannelEditPictureThread::completion");
1000 ChannelEditPictureThread::~ChannelEditPictureThread()
1002         delete completion;
1005 int ChannelEditPictureThread::edit_picture()
1007         if(in_progress) 
1008         {
1009                 edit_window->lock_window("ChannelEditPictureThread::edit_picture");
1010                 edit_window->raise_window(1);
1011                 edit_window->unlock_window();
1012                 return 1;
1013         }
1014         in_progress = 1;
1015         completion->lock("ChannelEditPictureThread::edit_picture");
1016         set_synchronous(0);
1017         Thread::start();
1020 void ChannelEditPictureThread::run()
1022         ChannelEditPictureWindow edit_window(this, channel_picker);
1023         edit_window.create_objects();
1024         this->edit_window = &edit_window;
1025         int result = edit_window.run_window();
1026         this->edit_window = 0;
1027         completion->unlock();
1028         in_progress = 0;
1031 int ChannelEditPictureThread::close_threads()
1033         if(edit_window)
1034         {
1035                 edit_window->set_done(1);
1036                 completion->lock("ChannelEditPictureThread::close_threads");
1037                 completion->unlock();
1038         }
1042 ChannelEditPictureWindow::ChannelEditPictureWindow(ChannelEditPictureThread *thread, ChannelPicker *channel_picker)
1043  : BC_Window(PROGRAM_NAME ": Picture", 
1044         channel_picker->mwindow->gui->get_abs_cursor_x(1) - 200, 
1045         channel_picker->mwindow->gui->get_abs_cursor_y(1) - 220, 
1046         200, 
1047         250, 
1048         200, 
1049         250)
1051         this->thread = thread;
1052         this->channel_picker = channel_picker;
1054 ChannelEditPictureWindow::~ChannelEditPictureWindow()
1057 int ChannelEditPictureWindow::create_objects()
1059         int x = 10, y = 10;
1060         int x1 = 110, x2 = 145;
1061 #define SWAP_X x1 ^= x2; x2 ^= x1; x1 ^= x2;
1063         Picture *picture_usage = channel_picker->get_picture_usage();
1065         if(!picture_usage ||
1066                 (!picture_usage->use_brightness &&
1067                 !picture_usage->use_contrast &&
1068                 !picture_usage->use_color &&
1069                 !picture_usage->use_hue &&
1070                 !picture_usage->use_whiteness &&
1071                 !channel_picker->get_controls()))
1072         {
1073                 add_subwindow(new BC_Title(x, y, "Device has no picture controls."));
1074                 y += 50;
1075         }
1077         if(picture_usage->use_brightness)
1078         {
1079                 add_subwindow(new BC_Title(x, y + 10, _("Brightness:")));
1080                 add_subwindow(new ChannelEditBright(x1, y, channel_picker, channel_picker->get_brightness()));
1081                 y += 30;
1082                 SWAP_X
1083                 
1084         }
1086         if(picture_usage->use_contrast)
1087         {
1088                 add_subwindow(new BC_Title(x, y + 10, _("Contrast:")));
1089                 add_subwindow(new ChannelEditContrast(x1, y, channel_picker, channel_picker->get_contrast()));
1090                 y += 30;
1091                 SWAP_X
1092         }
1094         if(picture_usage->use_color)
1095         {
1096                 add_subwindow(new BC_Title(x, y + 10, _("Color:")));
1097                 add_subwindow(new ChannelEditColor(x1, y, channel_picker, channel_picker->get_color()));
1098                 y += 30;
1099                 SWAP_X
1100         }
1102         if(picture_usage->use_hue)
1103         {
1104                 add_subwindow(new BC_Title(x, y + 10, _("Hue:")));
1105                 add_subwindow(new ChannelEditHue(x1, y, channel_picker, channel_picker->get_hue()));
1106                 y += 30;
1107                 SWAP_X
1108         }
1110         if(picture_usage->use_whiteness)
1111         {
1112                 add_subwindow(new BC_Title(x, y + 10, _("Whiteness:")));
1113                 add_subwindow(new ChannelEditWhiteness(x1, y, channel_picker, channel_picker->get_whiteness()));
1114                 y += 30;
1115                 SWAP_X
1116         }
1118         for(int i = 0; i < channel_picker->get_controls(); i++)
1119         {
1120                 add_subwindow(new BC_Title(x, 
1121                         y + 10, 
1122                         _(channel_picker->get_control(i)->name)));
1123                 add_subwindow(new ChannelEditCommon(x1, 
1124                         y, 
1125                         channel_picker,
1126                         channel_picker->get_control(i)));
1127                 y += 30;
1128                 SWAP_X
1129         }
1132         y += 20;
1133         add_subwindow(new BC_OKButton(x + 70, y));
1134         return 0;
1139 ChannelEditBright::ChannelEditBright(int x, int y, ChannelPicker *channel_picker, int value)
1140  : BC_IPot(x, 
1141                 y, 
1142                 value, 
1143                 -100, 
1144                 100)
1146         this->channel_picker = channel_picker;
1148 ChannelEditBright::~ChannelEditBright() {}
1149 int ChannelEditBright::handle_event()
1151         return 1;
1153 int ChannelEditBright::button_release_event()
1155         if(BC_Pot::button_release_event())
1156         {
1157                 channel_picker->set_brightness(get_value());
1158                 return 1;
1159         }
1160         return 0;
1163 ChannelEditContrast::ChannelEditContrast(int x, int y, ChannelPicker *channel_picker, int value)
1164  : BC_IPot(x, 
1165                 y, 
1166                 value, 
1167                 -100, 
1168                 100)
1170         this->channel_picker = channel_picker;
1172 ChannelEditContrast::~ChannelEditContrast() {}
1173 int ChannelEditContrast::handle_event()
1175         return 1;
1177 int ChannelEditContrast::button_release_event()
1179         if(BC_Pot::button_release_event())
1180         {
1181                 channel_picker->set_contrast(get_value());
1182                 return 1;
1183         }
1184         return 0;
1188 ChannelEditColor::ChannelEditColor(int x, int y, ChannelPicker *channel_picker, int value)
1189  : BC_IPot(x, 
1190                 y, 
1191                 value, 
1192                 -100, 
1193                 100)
1195         this->channel_picker = channel_picker;
1197 ChannelEditColor::~ChannelEditColor() {}
1198 int ChannelEditColor::handle_event()
1200         return 1;
1202 int ChannelEditColor::button_release_event()
1204         if(BC_Pot::button_release_event())
1205         {
1206                 channel_picker->set_color(get_value());
1207                 return 1;
1208         }
1209         return 0;
1212 ChannelEditHue::ChannelEditHue(int x, int y, ChannelPicker *channel_picker, int value)
1213  : BC_IPot(x, 
1214                 y, 
1215                 value, 
1216                 -100, 
1217                 100)
1219         this->channel_picker = channel_picker;
1221 ChannelEditHue::~ChannelEditHue() {}
1222 int ChannelEditHue::handle_event()
1224         return 1;
1226 int ChannelEditHue::button_release_event()
1228         if(BC_Pot::button_release_event())
1229         {
1230                 channel_picker->set_hue(get_value());
1231                 return 1;
1232         }
1233         return 0;
1236 ChannelEditWhiteness::ChannelEditWhiteness(int x, int y, ChannelPicker *channel_picker, int value)
1237  : BC_IPot(x, 
1238                 y, 
1239                 value, 
1240                 -100, 
1241                 100)
1243         this->channel_picker = channel_picker;
1245 ChannelEditWhiteness::~ChannelEditWhiteness() 
1248 int ChannelEditWhiteness::handle_event()
1250         return 1;
1252 int ChannelEditWhiteness::button_release_event()
1254         if(BC_Pot::button_release_event())
1255         {
1256                 channel_picker->set_whiteness(get_value());
1257                 return 1;
1258         }
1259         return 0;
1264 ChannelEditCommon::ChannelEditCommon(int x, 
1265         int y, 
1266         ChannelPicker *channel_picker,
1267         PictureItem *item)
1268  : BC_IPot(x, 
1269                 y, 
1270                 item->value, 
1271                 item->min, 
1272                 item->max)
1274         this->channel_picker = channel_picker;
1275         this->device_id = item->device_id;
1278 ChannelEditCommon::~ChannelEditCommon() 
1282 int ChannelEditCommon::handle_event()
1284         return 1;
1287 int ChannelEditCommon::button_release_event()
1289         if(BC_Pot::button_release_event())
1290         {
1291                 channel_picker->set_picture(device_id, get_value());
1292                 return 1;
1293         }
1294         return 0;