update internationalization data
[goodguy/history.git] / cinelerra-5.0 / cinelerra / recordgui.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 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 "asset.h"
23 #include "batch.h"
24 #include "bcsignals.h"
25 #include "browsebutton.h"
26 #include "channel.h"
27 #include "channelpicker.h"
28 #include "clip.h"
29 #include "condition.h"
30 #include "bchash.h"
31 #include "edl.h"
32 #include "edlsession.h"
33 #include "file.h"
34 #include "filemov.h"
35 #include "filesystem.h"
36 #include "keys.h"
37 #include "language.h"
38 #include "loadmode.h"
39 #include "meterpanel.h"
40 #include "mutex.h"
41 #include "mwindow.h"
42 #include "mwindowgui.h"
43 #include "preferences.h"
44 #include "question.h"
45 #include "recconfirmdelete.h"
46 #include "recordgui.h"
47 #include "record.h"
48 #include "recordlabel.h"
49 #include "recordmonitor.h"
50 #include "recordtransport.h"
51 #include "recordvideo.h"
52 #include "mainsession.h"
53 #include "theme.h"
54 #include "units.h"
55 #include "videodevice.h"
56
57 #include <time.h>
58
59
60
61
62 RecordGUI::RecordGUI(MWindow *mwindow, Record *record)
63  : BC_Window(_(PROGRAM_NAME ": Recording"), 
64         mwindow->session->rwindow_x, mwindow->session->rwindow_y, 
65         mwindow->session->rwindow_w, mwindow->session->rwindow_h,
66         10, 10, 1, 0, 1)
67 {
68         this->mwindow = mwindow;
69         this->record = record;
70
71         current_operation = 0;
72         position_title = 0;
73         prev_label_title = 0;
74         frames_behind = 0;
75         frames_dropped = 0;
76         framerate = 0;
77         samples_clipped = 0;
78         cron_status = 0;
79         batch_bay = 0;
80         batch_path = 0;
81         status_thread = 0;
82         batch_start = 0;
83         batch_duration = 0;
84         record_transport = 0;
85         batch_browse = 0;
86         batch_source = 0;
87         batch_mode = 0;
88         new_batch = 0;
89         delete_batch = 0;
90         start_batches = 0;
91         stop_batches = 0;
92         activate_batch = 0;
93         label_button = 0;
94         drop_frames = 0;
95         fill_frames = 0;
96         monitor_video = 0;
97         monitor_audio = 0;
98         meter_audio = 0;
99         batch_flash = 0;
100         startover_thread = 0;
101         interrupt_thread = 0;
102         load_mode = 0;
103         flash_color = 0;
104         loop_hr = 0;
105         loop_min = 0;
106         loop_sec = 0;
107         reset = 0;
108         monitor_video_window = 0;
109         dc_offset_button = 0;
110         for( int i=0; i<MAXCHANNELS; ++i ) {
111                 dc_offset_text[i] = 0;
112                 meter[i] = 0;
113         }
114         total_dropped_frames = 0;
115         total_clipped_samples = 0;
116 }
117
118 RecordGUI::~RecordGUI()
119 {
120 TRACE("RecordGUI::~RecordGUI 1");
121         delete status_thread;
122         delete batch_source;
123         delete batch_mode;
124         delete batch_flash;
125         delete startover_thread;
126         delete interrupt_thread;
127         delete batch_start;
128         delete batch_duration;
129         delete load_mode;
130 TRACE("RecordGUI::~RecordGUI 2");
131 }
132
133
134 void RecordGUI::create_objects()
135 {
136         char string[BCTEXTLEN];
137         flash_color = RED;
138         Asset *asset = record->default_asset;
139         lock_window("RecordGUI::create_objects");
140         status_thread = new RecordStatusThread(mwindow, this);
141         status_thread->start();
142         set_icon(mwindow->theme->get_image("record_icon"));
143
144         mwindow->theme->get_recordgui_sizes(this, get_w(), get_h());
145 //printf("RecordGUI::create_objects 1\n");
146         mwindow->theme->draw_rwindow_bg(this);
147
148         int x = 10;
149         int y = 10;
150         int x1 = 0;
151         BC_Title *title;
152         int pad = max(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1), 
153                 BC_Title::calculate_h(this, "X")) + 5;
154         int button_y = 0;
155
156 // Current batch
157         add_subwindow(title = new BC_Title(x, y, _("Path:")));
158         x1 = max(title->get_w(), x1);
159         y += pad;
160         add_subwindow(title = new BC_Title(x, y, _("Start time:")));
161         x1 = max(title->get_w(), x1);
162         y += pad;
163         add_subwindow(title = new BC_Title(x, y, _("Duration time:")));
164         x1 = max(title->get_w(), x1);
165         y += pad;
166         add_subwindow(title = new BC_Title(x, y, _("Source:")));
167         x1 = max(title->get_w(), x1);
168         y += pad;
169         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
170         x1 = max(title->get_w(), x1);
171         y += pad;
172         add_subwindow(title = new BC_Title(x, y, _("Transport:")));
173         x1 = max(title->get_w(), x1);
174         y += pad;
175
176         button_y = max(y, button_y);
177
178
179
180         int x2 = 0;
181         y = 10;
182         x = x1 + 20;
183         add_subwindow(batch_path = new RecordPath(this, x, y));
184         add_subwindow(batch_browse = new BrowseButton(mwindow, 
185                 this, 
186                 batch_path, 
187                 batch_path->get_x() + batch_path->get_w(), 
188                 y,
189                 asset->path,
190                 _(PROGRAM_NAME ": Record path"),
191                 _("Select a file to record to:"),
192                 0));
193         x2 = max(x2, batch_path->get_w() + batch_browse->get_w());
194         y += pad;
195         batch_start = new RecordStart(this, x, y);
196         batch_start->create_objects();
197         x2 = max(x2, batch_start->get_w());
198         y += pad;
199         batch_duration = new RecordDuration(this, x, y);
200         batch_duration->create_objects();
201         x2 = max(x2, batch_duration->get_w());
202         y += pad;
203         batch_source = new RecordSource(this, x, y);
204         batch_source->create_objects();
205         x2 = max(x2, batch_source->get_w());
206         y += pad;
207         batch_mode = new RecordGUIModeMenu(this, x, y, 200, "");
208         batch_mode->create_objects();
209         x2 = max(x2, batch_mode->get_w());
210         y += pad;
211         record_transport = new RecordTransport(mwindow, 
212                 record, this, x, y);
213         record_transport->create_objects();
214         x2 = max(x2, record_transport->get_w());
215
216
217
218
219 // Compression settings
220         x = x2 + x1 + 30;
221         y = 10;
222         int x3 = 0;
223         pad = BC_Title::calculate_h(this, "X") + 5;
224         add_subwindow(title = new BC_Title(x, y, _("Format:")));
225         x3 = max(title->get_w(), x3);
226         y += pad;
227
228         if(asset->audio_data)
229         {
230                 add_subwindow(title = new BC_Title(x, y, _("Audio compression:")));
231                 x3 = max(title->get_w(), x3);
232                 y += pad;
233                 add_subwindow(title = new BC_Title(x, y, _("Samplerate:")));
234                 x3 = max(title->get_w(), x3);
235                 y += pad;
236                 add_subwindow(title = new BC_Title(x, y, _("Clipped samples:")));
237                 x3 = max(title->get_w(), x3);
238                 y += pad;
239         }
240
241         if(asset->video_data)
242         {
243                 add_subwindow(title = new BC_Title(x, y, _("Video compression:")));
244                 x3 = max(title->get_w(), x3);
245                 y += pad;
246                 add_subwindow(title = new BC_Title(x, y, _("Framerate:")));
247                 x3 = max(title->get_w(), x3);
248                 y += pad;
249                 add_subwindow(title = new BC_Title(x, y, _("Frames dropped:")));
250                 x3 = max(title->get_w(), x3);
251                 y += pad;
252                 add_subwindow(title = new BC_Title(x, y, _("Frames behind:")));
253                 x3 = max(title->get_w(), x3);
254                 y += pad;
255         }
256
257         add_subwindow(title = new BC_Title(x, y, _("Position:")));
258         x3 = max(title->get_w(), x3);
259         y += pad;
260         add_subwindow(title = new BC_Title(x, y, _("Prev label:")));
261         x3 = max(title->get_w(), x3);
262         y += pad;
263
264         button_y = max(y, button_y);
265         y = 10;
266         x = x3 + x2 + x1 + 40;
267
268         add_subwindow(new BC_Title(x, y, 
269                 File::formattostr(mwindow->plugindb, asset->format), 
270                 MEDIUMFONT, 
271                 mwindow->theme->recordgui_fixed_color));
272         y += pad;
273
274         if(asset->audio_data) {
275                 add_subwindow(new BC_Title(x, y, 
276                         File::bitstostr(asset->bits), 
277                         MEDIUMFONT, 
278                         mwindow->theme->recordgui_fixed_color));
279
280                 y += pad;
281                 sprintf(string, "%d", asset->sample_rate);
282                 add_subwindow(new BC_Title(x, y, 
283                         string, MEDIUMFONT, 
284                         mwindow->theme->recordgui_fixed_color));
285
286                 y += pad;
287                 add_subwindow(samples_clipped = new BC_Title(x, y, 
288                         "0", MEDIUMFONT, 
289                         mwindow->theme->recordgui_variable_color));
290                 y += pad;
291         }
292
293         if(asset->video_data) {
294                 add_subwindow(new BC_Title(x, y, 
295                         asset->format != FILE_MPEG ?
296                                 FileMOV::compressiontostr(asset->vcodec) :
297                                 _("File Capture"),
298                         MEDIUMFONT, 
299                         mwindow->theme->recordgui_fixed_color));
300         
301                 y += pad;
302                 sprintf(string, "%0.2f", asset->frame_rate);
303                 add_subwindow(framerate = new BC_Title(x, y, 
304                         string, MEDIUMFONT, 
305                         mwindow->theme->recordgui_fixed_color));
306         
307                 y += pad;
308                 add_subwindow(frames_dropped = new BC_Title(x, y, 
309                         "0", MEDIUMFONT, 
310                         mwindow->theme->recordgui_variable_color));
311                 y += pad;
312                 add_subwindow(frames_behind = new BC_Title(x, y, 
313                         "0", MEDIUMFONT, 
314                         mwindow->theme->recordgui_variable_color));
315                 y += pad;
316         }
317
318         add_subwindow(position_title = new BC_Title(x, y, 
319                 "", MEDIUMFONT, 
320                 mwindow->theme->recordgui_variable_color));
321
322         y += pad;
323         add_subwindow(prev_label_title = new BC_Title(x, y, 
324                 _("None"), MEDIUMFONT, 
325                 mwindow->theme->recordgui_variable_color));
326
327         y += pad + 10;
328         button_y = max(y, button_y);
329
330 // Buttons
331         x = 10;
332         y = button_y;
333
334         add_subwindow(title = new BC_Title(x,y, _("Batches:")));
335         int y_max = y + title->get_h();  x1 = x;
336         x += title->get_w() + 5;
337         add_subwindow(activate_batch = new RecordGUIActivateBatch(this, x, y));
338         x += activate_batch->get_w();
339         y_max = max(y_max, y + activate_batch->get_h());
340         add_subwindow(start_batches = new RecordGUIStartBatches(this, x, y));
341         y_max = max(y_max, y + start_batches->get_h());  x2 = x;
342         x += start_batches->get_w();
343         add_subwindow(new_batch = new RecordGUINewBatch(this, x, y));
344         y_max = max(y_max, y + new_batch->get_h());  x3 = x;
345         x += new_batch->get_w();  int x4 = x;
346         add_subwindow(label_button = new RecordGUILabel(this, x, y));
347         y_max = max(y_max, y + label_button->get_h());
348
349         int y1 = y_max, y2 = y1 + 5;
350         add_subwindow(title = new BC_Title(x1,y2, _("Cron:")));
351         y_max = max(y_max, y2 + title->get_h());
352         x1 += title->get_w() + 5;
353         add_subwindow(cron_status = new BC_Title(x1,y2, _("Idle"), MEDIUMFONT,
354                 mwindow->theme->recordgui_variable_color));
355         y_max = max(y_max, y2 + cron_status->get_h());
356         add_subwindow(stop_batches = new RecordGUIStopBatches(this, x2, y1));
357         y_max = max(y_max, y1 + stop_batches->get_h());
358         add_subwindow(delete_batch = new RecordGUIDeleteBatch(this, x3, y1));
359         y_max = max(y_max, y1 + delete_batch->get_h());
360         add_subwindow(clrlbls_button = new RecordGUIClearLabels(this, x4, y1));
361         y_max = max(y_max, y1 + clrlbls_button->get_h());
362
363         x = x1 = 10;
364         y = y_max + pad;
365         y1 = y + pad + 5;
366
367         fill_frames = 0;
368         monitor_video = 0;
369         monitor_audio = 0;
370         meter_audio = 0;
371         if(asset->video_data) {
372                 add_subwindow(drop_frames = new RecordGUIDropFrames(this, x, y));
373                 add_subwindow(fill_frames = new RecordGUIFillFrames(this, x, y1));
374                 x += drop_frames->get_w() + 5;  x1 = x;
375                 add_subwindow(monitor_video = new RecordGUIMonitorVideo(this, x, y));
376                 x += monitor_video->get_w() + 5;
377         }
378
379         if(asset->audio_data) {
380                 add_subwindow(monitor_audio = new RecordGUIMonitorAudio(this, x, y));
381                 x += monitor_audio->get_w() + 5;
382                 add_subwindow(meter_audio = new RecordGUIAudioMeters(this, x, y));
383                 x += meter_audio->get_w() + 5;
384         }
385
386         add_subwindow(power_off = new RecordGUIPowerOff(this, x1, y1));
387         x1 += power_off->get_w() + 10;
388         add_subwindow(commercial_check = new RecordGUICommCheck(this, x1, y1));
389
390 // Batches
391         x = 10;
392         y += 5;
393         if( fill_frames )
394                 y = y1 + fill_frames->get_h();
395         else if( monitor_audio )
396                 y += monitor_audio->get_h();
397
398         int bottom_margin = max(BC_OKButton::calculate_h(), 
399                 LoadMode::calculate_h(this, mwindow->theme)) + 5;
400
401
402         add_subwindow(batch_bay = new RecordGUIBatches(this, x, y,
403                 get_w() - 20, get_h() - y - bottom_margin - 10));
404         y += batch_bay->get_h() + 5;
405         record->record_batches.gui = batch_bay;
406         batch_bay->update_batches(-1);
407
408 // Controls
409         int loadmode_w = LoadMode::calculate_w(this, mwindow->theme, 1, 0);
410         load_mode = new LoadMode(mwindow, this, 
411                 get_w() / 2 - loadmode_w / 2, y, 
412                 &record->load_mode, 1, 0);
413         load_mode->create_objects();
414         y += load_mode->get_h() + 5;
415
416         add_subwindow(new RecordGUIOK(this));
417
418         interrupt_thread = new EndRecordThread(this);
419 //      add_subwindow(new RecordGUISave(record, this));
420         add_subwindow(new RecordGUICancel(this));
421
422         startover_thread = new RecordStartoverThread(this);
423
424         enable_batch_buttons();
425         if( batch_mode->value == RECORD_TIMED )
426                 batch_duration->enable();
427         else
428                 batch_duration->disable();
429         unlock_window();
430 }
431
432 void RecordGUI::update_batches()
433 {
434         lock_window("void RecordGUI::Update_batches");
435         batch_bay->update_batches();
436         unlock_window();
437 }
438
439
440 Batch *RecordGUI::get_current_batch()
441 {
442         return record->get_editing_batch();
443 }
444
445 Batch *RecordGUI::get_editing_batch()
446 {
447         return record->get_editing_batch();
448 }
449
450 void RecordGUI::update_batch_sources()
451 {
452 //printf("RecordGUI::update_batch_sources 1\n");
453         ChannelPicker *channel_picker =
454                 record->record_monitor->window->channel_picker;
455         if(channel_picker)
456                 batch_source->update_list(&channel_picker->channel_listitems);
457 //printf("RecordGUI::update_batch_sources 2\n");
458 }
459
460 int RecordGUI::translation_event()
461 {
462         mwindow->session->rwindow_x = get_x();
463         mwindow->session->rwindow_y = get_y();
464         return 0;
465 }
466
467
468 int RecordGUI::resize_event(int w, int h)
469 {
470 // Recompute batch list based on previous extents
471         int bottom_margin = mwindow->session->rwindow_h - 
472                 batch_bay->get_y() - 
473                 batch_bay->get_h();
474         int mode_margin = mwindow->session->rwindow_h - load_mode->get_y();
475         mwindow->session->rwindow_x = get_x();
476         mwindow->session->rwindow_y = get_y();
477         mwindow->session->rwindow_w = w;
478         mwindow->session->rwindow_h = h;
479         mwindow->theme->get_recordgui_sizes(this, w, h);
480         mwindow->theme->draw_rwindow_bg(this);
481
482         int new_h = mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y();
483         if(new_h < 10) new_h = 10;
484         batch_bay->reposition_window(batch_bay->get_x(), 
485                 batch_bay->get_y(),
486                 mwindow->session->rwindow_w - 20,
487                 mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y());
488
489         load_mode->reposition_window(mwindow->session->rwindow_w / 2 - 
490                         mwindow->theme->loadmode_w / 2,
491                 mwindow->session->rwindow_h - mode_margin);
492
493         flash();
494         return 1;
495 }
496
497 void RecordGUI::update_batch_tools()
498 {
499         lock_window("RecordGUI::update_batch_tools");
500 //printf("RecordGUI::update_batch_tools 1\n");
501         Batch *batch = get_editing_batch();
502         batch_path->update(batch->asset->path);
503
504 // File is open in editing batch
505 //      if(current_batch() == editing_batch() && record->file)
506 //              batch_path->disable();
507 //      else
508 //              batch_path->enable();
509
510         batch_start->update(&batch->start_day, &batch->start_time);
511         batch_duration->update(0, &batch->duration);
512         batch_source->update(batch->get_source_text());
513         batch_mode->update(batch->record_mode);
514         if( batch_mode->value == RECORD_TIMED )
515                 batch_duration->enable();
516         else
517                 batch_duration->disable();
518         flush();
519         unlock_window();
520 }
521
522 void RecordGUI::enable_batch_buttons()
523 {
524         lock_window("RecordGUI::enable_batch_buttons");
525         new_batch->enable();
526         delete_batch->enable();
527         start_batches->enable();
528         stop_batches->disable();
529         activate_batch->enable();
530         unlock_window();
531 }
532
533 void RecordGUI::disable_batch_buttons()
534 {
535         lock_window("RecordGUI::disable_batch_buttons");
536         new_batch->disable();
537         delete_batch->disable();
538         start_batches->disable();
539         stop_batches->enable();
540         activate_batch->disable();
541         unlock_window();
542 }
543
544 RecordGUIBatches::RecordGUIBatches(RecordGUI *gui, int x, int y, int w, int h)
545  : RecordBatchesGUI(gui->record->record_batches, x, y, w, h)
546 {
547         this->gui = gui;
548 }
549
550 // Do nothing for double clicks to protect active batch
551 int RecordGUIBatches::handle_event()
552 {
553         return 1;
554 }
555
556 int RecordGUIBatches::selection_changed()
557 {
558         RecordBatchesGUI::selection_changed();
559         gui->update_batch_tools();
560         return 1;
561 }
562
563
564 RecordGUISave::RecordGUISave(RecordGUI *gui)
565  : BC_Button(10, 
566         gui->get_h() - BC_WindowBase::get_resources()->ok_images[0]->get_h() - 10, 
567         BC_WindowBase::get_resources()->ok_images)
568 {
569         set_tooltip(_("Save the recording and quit."));
570         this->gui = gui;
571 }
572
573 int RecordGUISave::handle_event()
574 {
575         gui->set_done(0);
576         return 1;
577 }
578
579 int RecordGUISave::keypress_event()
580 {
581 //      if(get_keypress() == RETURN)
582 //      {
583 //              handle_event();
584 //              return 1;
585 //      }
586         return 0;
587 }
588
589 RecordGUICancel::RecordGUICancel(RecordGUI *gui)
590  : BC_CancelButton(gui)
591 {
592         set_tooltip(_("Quit without pasting into project."));
593         this->gui = gui;
594 }
595
596 int RecordGUICancel::handle_event()
597 {
598         gui->interrupt_thread->start(0);
599         return 1;
600 }
601
602 int RecordGUICancel::keypress_event()
603 {
604         if(get_keypress() == ESC)
605         {
606                 handle_event();
607                 return 1;
608         }
609
610         return 0;
611 }
612
613
614 RecordGUIOK::RecordGUIOK(RecordGUI *gui)
615  : BC_OKButton(gui)
616 {
617         set_tooltip(_("Quit and paste into project."));
618         this->gui = gui;
619 }
620
621 int RecordGUIOK::handle_event()
622 {
623         gui->interrupt_thread->start(1);
624         return 1;
625 }
626
627
628 RecordGUIStartOver::RecordGUIStartOver(RecordGUI *gui, int x, int y)
629  : BC_GenericButton(x, y, _("Start Over"))
630 {
631         set_tooltip(_("Rewind the current file and erase."));
632         this->gui = gui;
633 }
634 RecordGUIStartOver::~RecordGUIStartOver()
635 {
636 }
637
638 int RecordGUIStartOver::handle_event()
639 {
640         if(!gui->startover_thread->running())
641                 gui->startover_thread->start();
642         return 1;
643 }
644
645
646 RecordGUIDropFrames::RecordGUIDropFrames(RecordGUI *gui, int x, int y)
647  : BC_CheckBox(x, y, gui->record->drop_overrun_frames, _("drop overrun frames"))
648 {
649         this->set_underline(0);
650         this->gui = gui;
651         set_tooltip(_("Drop input frames when behind."));
652 }
653
654 int RecordGUIDropFrames::handle_event()
655 {
656         gui->record->drop_overrun_frames = get_value();
657         return 1;
658 }
659
660 int RecordGUIDropFrames::keypress_event()
661 {
662         if(get_keypress() == 'd') {
663                 set_value(get_value() ? 0 : 1);
664                 handle_event();
665                 return 1;
666         }
667         return 0;
668 }
669
670 RecordGUIFillFrames::RecordGUIFillFrames(RecordGUI *gui, int x, int y)
671  : BC_CheckBox(x, y, gui->record->fill_underrun_frames, _("fill underrun frames"))
672 {
673         this->set_underline(0);
674         this->gui = gui;
675         set_tooltip(_("Write extra frames when behind."));
676 }
677
678 int RecordGUIFillFrames::handle_event()
679 {
680         gui->record->fill_underrun_frames = get_value();
681         return 1;
682 }
683
684 int RecordGUIFillFrames::keypress_event()
685 {
686         if(get_keypress() == 'f') {
687                 set_value(get_value() ? 0 : 1);
688                 handle_event();
689                 return 1;
690         }
691         return 0;
692 }
693
694 RecordGUIPowerOff::RecordGUIPowerOff(RecordGUI *gui, int x, int y)
695  : BC_CheckBox(x, y, gui->record->power_off, _("poweroff when done"))
696 {
697         this->set_underline(0);
698         this->gui = gui;
699         set_tooltip(_("poweroff system when batch record done."));
700 }
701
702 int RecordGUIPowerOff::handle_event()
703 {
704         gui->record->power_off = get_value();
705         return 1;
706 }
707
708 int RecordGUIPowerOff::keypress_event()
709 {
710         if(get_keypress() == 'p') {
711                 set_value(get_value() ? 0 : 1);
712                 handle_event();
713                 return 1;
714         }
715         return 0;
716 }
717
718
719 RecordGUICommCheck::RecordGUICommCheck(RecordGUI *gui, int x, int y)
720  : BC_CheckBox(x, y, gui->record->commercial_check, _("check for ads"))
721 {
722         this->set_underline(0);
723         this->gui = gui;
724         set_tooltip(_("check for commercials."));
725 }
726
727 int RecordGUICommCheck::handle_event()
728 {
729         gui->record->update_skimming(get_value());
730         return 1;
731 }
732
733
734 int RecordGUICommCheck::keypress_event()
735 {
736         if(get_keypress() == 'c') {
737                 set_value(get_value() ? 0 : 1);
738                 gui->record->update_skimming(get_value());
739                 handle_event();
740                 return 1;
741         }
742         return 0;
743 }
744
745
746 RecordGUIMonitorVideo::RecordGUIMonitorVideo(RecordGUI *gui, int x, int y)
747  : BC_CheckBox(x, y, gui->record->monitor_video, _("Monitor video"))
748 {
749         this->set_underline(8);
750         this->gui = gui;
751 }
752
753 int RecordGUIMonitorVideo::handle_event()
754 {
755 // Video capture constitutively, just like audio, but only flash on screen if 1
756         int mode = get_value();
757         Record *record = gui->record;
758         record->set_video_monitoring(mode);
759         if(record->monitor_video) {
760                 unlock_window();
761                 BC_Window *window = record->record_monitor->window;
762                 window->lock_window("RecordGUIMonitorVideo::handle_event");
763                 window->show_window();
764                 window->raise_window();
765                 window->flush();
766                 window->unlock_window();
767                 lock_window("RecordGUIMonitorVideo::handle_event");
768                 record->video_window_open = 1;
769         }
770         return 1;
771 }
772
773
774 int RecordGUIMonitorVideo::keypress_event()
775 {
776         if(get_keypress() == 'v') {
777                 set_value(get_value() ? 0 : 1);
778                 handle_event();
779                 return 1;
780         }
781         return 0;
782 }
783
784
785
786 RecordGUIMonitorAudio::RecordGUIMonitorAudio(RecordGUI *gui, int x, int y)
787  : BC_CheckBox(x, y, gui->record->monitor_audio, _("Monitor audio"))
788 {
789         this->set_underline(8);
790         this->gui = gui;
791 }
792
793 int RecordGUIMonitorAudio::handle_event()
794 {
795         int mode = get_value();
796         Record *record = gui->record;
797         record->set_audio_monitoring(mode);
798         if(record->monitor_audio) {
799                 unlock_window();
800                 BC_Window *window = record->record_monitor->window;
801                 window->lock_window("RecordGUIMonitorAudio::handle_event");
802                 window->show_window();
803                 window->raise_window();
804                 window->flush();
805                 window->unlock_window();
806                 lock_window("RecordGUIMonitorAudio::handle_event");
807                 record->video_window_open = 1;
808         }
809         return 1;
810 }
811
812 int RecordGUIMonitorAudio::keypress_event()
813 {
814         if(get_keypress() == 'a') {
815                 set_value(get_value() ? 0 : 1);
816                 handle_event();
817                 return 1;
818         }
819         return 0;
820 }
821
822
823 RecordGUIAudioMeters::RecordGUIAudioMeters(RecordGUI *gui, int x, int y)
824  : BC_CheckBox(x, y, gui->record->metering_audio, _("Audio meters"))
825 {
826         this->set_underline(6);
827         this->gui = gui;
828 }
829
830 int RecordGUIAudioMeters::handle_event()
831 {
832         int mode = get_value();
833         Record *record = gui->record;
834         record->set_audio_metering(mode);
835         if(record->metering_audio) {
836                 unlock_window();
837                 BC_Window *window = record->record_monitor->window;
838                 window->lock_window("RecordGUIAudioMeters::handle_event");
839                 window->show_window();
840                 window->raise_window();
841                 window->flush();
842                 window->unlock_window();
843                 lock_window("RecordGUIAudioMeters::handle_event");
844                 record->video_window_open = 1;
845         }
846         return 1;
847 }
848
849 int RecordGUIAudioMeters::keypress_event()
850 {
851         if(get_keypress() == 'm') {
852                 set_value(get_value() ? 0 : 1);
853                 handle_event();
854                 return 1;
855         }
856         return 0;
857 }
858
859 RecordPath::RecordPath(RecordGUI *gui, int x, int y)
860  : RecordBatchesGUI::Path(gui->record->record_batches, x, y)
861 {
862         this->gui = gui;
863 }
864
865 int RecordPath::handle_event()
866 {
867         return RecordBatchesGUI::Path::handle_event();
868 }
869
870
871 RecordStart::RecordStart(RecordGUI *gui, int x, int y)
872  : RecordBatchesGUI::StartTime(gui, gui->record->record_batches, x, y)
873 {
874         this->gui = gui;
875 }
876
877 int RecordStart::handle_event()
878 {
879         return RecordBatchesGUI::StartTime::handle_event();
880 }
881
882 RecordDuration::RecordDuration(RecordGUI *gui, int x, int y)
883  : RecordBatchesGUI::Duration(gui, gui->record->record_batches, x, y)
884 {
885         this->gui = gui;
886 }
887
888 int RecordDuration::handle_event()
889 {
890         return RecordBatchesGUI::Duration::handle_event();
891 }
892
893
894 RecordSource::RecordSource(RecordGUI *gui, int x, int y)
895  : RecordBatchesGUI::Source(gui, gui->record->record_batches, x, y)
896 {
897         this->gui = gui;
898 }
899
900 int RecordSource::handle_event()
901 {
902         gui->record->set_batch_channel_no(get_number());
903         return RecordBatchesGUI::Source::handle_event();
904 }
905
906
907 RecordNews::RecordNews(RecordGUI *gui, int x, int y)
908  : RecordBatchesGUI::News(gui->record->record_batches, x, y)
909 {
910         this->gui = gui;
911 }
912
913 int RecordNews::handle_event()
914 {
915         return RecordBatchesGUI::News::handle_event();
916 }
917
918
919 RecordGUINewBatch::RecordGUINewBatch(RecordGUI *gui, int x, int y)
920  : RecordBatchesGUI::NewBatch(gui->record->record_batches, x, y)
921 {
922         this->gui = gui;
923         set_tooltip(_("Create new clip."));
924 }
925 int RecordGUINewBatch::handle_event()
926 {
927         gui->record->new_batch();
928         return RecordBatchesGUI::NewBatch::handle_event();
929 }
930
931
932 RecordGUIDeleteBatch::RecordGUIDeleteBatch(RecordGUI *gui, int x, int y)
933  : RecordBatchesGUI::DeleteBatch(gui->record->record_batches, x, y)
934 {
935         this->gui = gui;
936         set_tooltip(_("Delete clip."));
937 }
938
939 int RecordGUIDeleteBatch::handle_event()
940 {
941         gui->record->delete_batch();
942         return RecordBatchesGUI::DeleteBatch::handle_event();
943 }
944
945
946 RecordGUIStartBatches::RecordGUIStartBatches(RecordGUI *gui, int x, int y)
947  : RecordBatchesGUI::StartBatches(gui->record->record_batches, x, y)
948 {
949         this->gui = gui;
950         set_tooltip(_("Start batch recording\nfrom the current position."));
951 }
952
953 int RecordGUIStartBatches::handle_event()
954 {
955         Record *record = gui->record;
956         record->start_cron_thread();
957         return RecordBatchesGUI::StartBatches::handle_event();
958 }
959
960
961 RecordGUIStopBatches::RecordGUIStopBatches(RecordGUI *gui, int x, int y)
962  : RecordBatchesGUI::StopBatches(gui->record->record_batches, x, y)
963 {
964         this->gui = gui;
965 }
966
967 int RecordGUIStopBatches::handle_event()
968 {
969         Record *record = gui->record;
970         unlock_window();
971         record->stop_cron_thread(_("Stopped"));
972         lock_window();
973         return RecordBatchesGUI::StopBatches::handle_event();
974 }
975
976
977 RecordGUIActivateBatch::RecordGUIActivateBatch(RecordGUI *gui, int x, int y)
978  : RecordBatchesGUI::ActivateBatch(gui->record->record_batches, x, y)
979 {
980         this->gui = gui;
981         set_tooltip(_("Make the highlighted\nclip active."));
982 }
983 int RecordGUIActivateBatch::handle_event()
984 {
985         gui->record->activate_batch(gui->record->editing_batch());
986         gui->update_cron_status(_("Idle"));
987         return RecordBatchesGUI::ActivateBatch::handle_event();
988 }
989
990
991 RecordGUILabel::RecordGUILabel(RecordGUI *gui, int x, int y)
992  : BC_GenericButton(x, y, _("Label"))
993
994         this->gui = gui;
995         set_underline(0);
996 }
997
998
999 RecordGUILabel::~RecordGUILabel()
1000 {
1001 }
1002
1003 int RecordGUILabel::handle_event()
1004 {
1005         gui->record->toggle_label();
1006         return 1;
1007 }
1008
1009 int RecordGUILabel::keypress_event()
1010 {
1011         if(get_keypress() == 'l') {
1012                 handle_event();
1013                 return 1;
1014         }
1015         return 0;
1016 }
1017
1018
1019 RecordGUIClearLabels::RecordGUIClearLabels(RecordGUI *gui, int x, int y)
1020  : BC_GenericButton(x, y, _("ClrLbls"))
1021
1022         this->gui = gui;
1023 }
1024
1025
1026 RecordGUIClearLabels::~RecordGUIClearLabels()
1027 {
1028 }
1029
1030 int RecordGUIClearLabels::handle_event()
1031 {
1032         gui->record->clear_labels();
1033         return 1;
1034 }
1035
1036
1037 EndRecordThread::EndRecordThread(RecordGUI *gui)
1038  : Thread(1, 0, 0)
1039 {
1040         this->gui = gui;
1041         is_ok = 0;
1042 }
1043
1044 EndRecordThread::~EndRecordThread()
1045 {
1046         if(Thread::running()) {
1047                 window->lock_window("EndRecordThread::~EndRecordThread");
1048                 window->set_done(1);
1049                 window->unlock_window();
1050                 Thread::join();
1051         }
1052 }
1053
1054 void EndRecordThread::start(int is_ok)
1055 {
1056         this->is_ok = is_ok;
1057         if( gui->record->writing_file ) {
1058                 if(!running())          
1059                         Thread::start();
1060         }
1061         else {
1062                 gui->set_done(!is_ok);
1063         }
1064 }
1065
1066 void EndRecordThread::run()
1067 {
1068         window = new QuestionWindow(gui->record->mwindow);
1069         window->create_objects(_("Interrupt recording in progress?"), 0);
1070         int result = window->run_window();
1071         delete window;
1072         if(result == 2) gui->set_done(!is_ok);
1073 }
1074
1075
1076 RecordStartoverThread::RecordStartoverThread(RecordGUI *gui)
1077  : Thread(1, 0, 0)
1078 {
1079         this->gui = gui;
1080 }
1081 RecordStartoverThread::~RecordStartoverThread()
1082 {
1083         if(Thread::running()) {
1084                 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1085                 window->set_done(1);
1086                 window->unlock_window();
1087                 Thread::join();
1088         }
1089 }
1090
1091 void RecordStartoverThread::run()
1092 {
1093         Record *record = gui->record;
1094         window = new QuestionWindow(record->mwindow);
1095         window->create_objects(_("Rewind batch and overwrite?"), 0);
1096         int result = window->run_window();
1097         if(result == 2) record->start_over();
1098         delete window;
1099 }
1100
1101
1102 int RecordGUI::set_translation(int x, int y, float z)
1103 {
1104         record->video_x = x;
1105         record->video_y = y;
1106         record->video_zoom = z;
1107         return 0;
1108 }
1109
1110 void RecordGUI::reset_video()
1111 {
1112         total_dropped_frames = 0;
1113         status_thread->reset_video();
1114         update_framerate(record->default_asset->frame_rate);
1115 }
1116
1117 void RecordGUI::update_dropped_frames(long value)
1118 {
1119         status_thread->update_dropped_frames(value);
1120 }
1121
1122 void RecordGUI::update_frames_behind(long value)
1123 {
1124         status_thread->update_frames_behind(value);
1125 }
1126
1127 void RecordGUI::update_position(double value) 
1128
1129         status_thread->update_position(value);
1130 }
1131
1132 void RecordGUI::update_framerate(double value)
1133 {
1134         status_thread->update_framerate(value);
1135 }
1136
1137 void RecordGUI::update_video(int dropped, int behind)
1138 {
1139         total_dropped_frames += dropped;
1140         update_dropped_frames(total_dropped_frames);
1141         update_frames_behind(behind);
1142         status_thread->update_position(record->current_display_position());
1143 }
1144
1145 void RecordGUI::reset_audio()
1146 {
1147 //      gui->lock_window("RecordAudio::run 2");
1148 // reset meter
1149         total_clipped_samples = 0;
1150         status_thread->reset_audio();
1151         AudioDevice *adevice = record->adevice;
1152         RecordMonitorGUI *window = record->record_monitor->window;
1153         window->lock_window("RecordAudio::run 2");
1154         MeterPanel *meters = window->meters;
1155         if( meters ) {
1156                 int dmix = adevice && (adevice->get_idmix() || adevice->get_odmix());
1157                 meters->init_meters(dmix);
1158         }
1159         window->unlock_window();
1160 //      gui->unlock_window();
1161 }
1162
1163 void RecordGUI::update_clipped_samples(long value)
1164 {
1165         status_thread->update_clipped_samples(value);
1166 }
1167
1168 void RecordGUI::update_audio(int channels, double *max, int *over)
1169 {
1170 // Get clipping status
1171         int clipped = 0;
1172         for( int ch=0; ch<channels && !clipped; ++ch )
1173                 if( over[ch] ) clipped = 1;
1174         if( clipped ) {
1175                 update_clipped_samples(++total_clipped_samples);
1176         }
1177 // Update meters if monitoring
1178         if( record->metering_audio ) {
1179                 RecordMonitorGUI *window = record->record_monitor->window;
1180                 window->lock_window("RecordAudio::run 1");
1181                 MeterPanel *meters = window->meters;
1182                 int nmeters = meters->meters.total;
1183                 for( int ch=0; ch<nmeters; ++ch ) {
1184                         double vmax = ch < channels ? max[ch] : 0.;
1185                         int   vover = ch < channels ? over[ch] : 0;
1186                         meters->meters.values[ch]->update(vmax, vover);
1187                 }
1188                 window->unlock_window();
1189         }
1190 // update position, if no video
1191         if( !record->default_asset->video_data )
1192                 update_position(record->current_display_position());
1193 }
1194
1195
1196 int RecordGUI::keypress_event()
1197 {
1198         return record_transport->keypress_event();
1199 }
1200
1201 void RecordGUI::update_labels(double new_position)
1202 {
1203         RecordLabel *prev, *next;
1204
1205         for(prev = record->get_current_batch()->labels->last; 
1206                 prev; 
1207                 prev = prev->previous) {
1208                 if(prev->position <= new_position) break;
1209         }
1210
1211         for(next = record->get_current_batch()->labels->first; 
1212                 next; 
1213                 next = next->next)
1214         {
1215                 if(next->position > new_position) break;
1216         }
1217
1218         if(prev)
1219                 update_title(prev_label_title, prev->position);
1220         else
1221                 update_title(prev_label_title, -1);
1222
1223 //      if(next)
1224 //              update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1225 //      else
1226 //              update_title(next_label_title, -1);
1227 }
1228
1229
1230 int RecordGUI::update_prev_label(long new_position) 
1231
1232         update_title(prev_label_title, new_position);
1233         return 0;
1234 }
1235
1236 // int RecordGUI::update_next_label(long new_position) 
1237 // { 
1238 //      update_title(next_label_title, new_position); 
1239 // }
1240 // 
1241 int RecordGUI::update_title(BC_Title *title, double position)
1242 {
1243         static char string[256];
1244
1245         if(position >= 0) {
1246                 Units::totext(string, 
1247                                 position, 
1248                                 mwindow->edl->session->time_format, 
1249                                 record->default_asset->sample_rate, 
1250                                 record->default_asset->frame_rate, 
1251                                 mwindow->edl->session->frames_per_foot);
1252         }
1253         else {
1254                 sprintf(string, "-");
1255         }
1256         lock_window("RecordGUI::update_title");
1257         title->update(string);
1258         unlock_window();
1259         return 0;
1260 }
1261
1262
1263 void RecordGUI::update_cron_status(const char *status)
1264 {
1265         lock_window("RecordGUI::update_cron_status");
1266         cron_status->update(status);
1267         unlock_window();
1268 }
1269
1270 void RecordGUI::update_power_off(int value)
1271 {
1272         lock_window("RecordGUI::update_power_off");
1273         power_off->update(value);
1274         unlock_window();
1275 }
1276
1277
1278
1279
1280 // ===================================== GUI
1281 // ================================================== modes
1282
1283 RecordGUIModeTextBox::RecordGUIModeTextBox(RecordGUIModeMenu *mode_menu,
1284                 int x, int y, int w,const char *text)
1285  : BC_TextBox(x, y, w, 1, text)
1286 {
1287         this->mode_menu = mode_menu;
1288 }
1289
1290 RecordGUIModeTextBox::~RecordGUIModeTextBox()
1291 {
1292 }
1293
1294 int RecordGUIModeTextBox::handle_event()
1295 {
1296         return 0;
1297 }
1298
1299 RecordGUIModeListBox::RecordGUIModeListBox(RecordGUIModeMenu *mode_menu)
1300  : BC_ListBox(mode_menu->textbox->get_x() + mode_menu->textbox->get_w(),
1301                 mode_menu->textbox->get_y(), 100, 50, LISTBOX_TEXT,
1302                 &mode_menu->modes, 0, 0, 1, 0, 1)
1303 {
1304         this->mode_menu = mode_menu;
1305 }
1306
1307 RecordGUIModeListBox::~RecordGUIModeListBox()
1308 {
1309 }
1310
1311 int RecordGUIModeListBox::handle_event()
1312 {
1313         return mode_menu->handle_event();
1314 }
1315
1316 RecordGUIModeMenu::RecordGUIModeMenu(RecordGUI *record_gui,
1317                 int x, int y, int w,const char *text)
1318 {
1319         this->record_gui = record_gui;
1320         textbox = new RecordGUIModeTextBox(this,x, y, w, "");
1321         record_gui->add_subwindow(textbox);
1322         listbox = new RecordGUIModeListBox(this);
1323         record_gui->add_subwindow(listbox);
1324 }
1325
1326 RecordGUIModeMenu::~RecordGUIModeMenu()
1327 {
1328         for( int i=0; i<modes.total; ++i )
1329                 delete modes.values[i];
1330         delete listbox;
1331         delete textbox;
1332 }
1333
1334 void RecordGUIModeMenu::create_objects()
1335 {
1336         value = RECORD_UNTIMED;
1337         modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_UNTIMED)));
1338         modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_TIMED)));
1339         textbox->update(modes.values[value]->get_text());
1340 }
1341
1342 int RecordGUIModeMenu::handle_event()
1343 {
1344         value = listbox->get_selection_number(0, 0);
1345         textbox->update(modes.values[value]->get_text());
1346         textbox->handle_event();
1347         record_gui->record->set_record_mode(value);
1348         if( value == RECORD_TIMED )
1349                 record_gui->batch_duration->enable();
1350         else
1351                 record_gui->batch_duration->disable();
1352         return 0;
1353 }
1354
1355 void RecordGUIModeMenu::update(int value)
1356 {
1357         this->value = value;
1358         textbox->update(modes.values[value]->get_text());
1359 }
1360
1361 int RecordGUIModeMenu::get_w()
1362 {
1363         return textbox->get_w() + listbox->get_w();
1364 }
1365
1366 int RecordGUIModeMenu::get_h()
1367 {
1368         return MAX(textbox->get_h(), listbox->get_h());
1369 }
1370
1371
1372 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1373  : Thread(1, 0, 0)
1374 {
1375         this->mwindow = mwindow;
1376         this->gui = gui;
1377         input_lock = new Condition(0, "RecordStatusThread::input_lock");
1378         reset_video();
1379         reset_audio();
1380         done = 0;
1381 }
1382
1383 RecordStatusThread::~RecordStatusThread()
1384 {
1385         if(Thread::running())
1386         {
1387                 done = 1;
1388                 input_lock->unlock();
1389                 Thread::join();
1390         }
1391 }
1392
1393 void RecordStatusThread::reset_video()
1394 {
1395         new_dropped_frames = 0;
1396         displayed_dropped_frames = -1;
1397         new_frames_behind = 0;
1398         displayed_frames_behind = -1;
1399         new_position = 0;
1400         displayed_framerate = -1.;
1401         new_framerate = 0.;
1402 }
1403
1404 void RecordStatusThread::reset_audio()
1405 {
1406         new_clipped_samples = 0;
1407         displayed_clipped_samples = -1;
1408 }
1409
1410 void RecordStatusThread::update_frames_behind(long value)
1411 {
1412         if( value != displayed_frames_behind ) {
1413                 new_frames_behind = value;
1414                 input_lock->unlock();
1415         }
1416 }
1417
1418 void RecordStatusThread::update_dropped_frames(long value)
1419 {
1420         if( value != displayed_dropped_frames ) {
1421                 new_dropped_frames = value;
1422                 input_lock->unlock();
1423         }
1424 }
1425
1426 void RecordStatusThread::update_clipped_samples(long value)
1427 {
1428         if( value != displayed_clipped_samples ) {
1429                 new_clipped_samples = value;
1430                 input_lock->unlock();
1431         }
1432 }
1433
1434 void RecordStatusThread::update_position(double value)
1435 {
1436         this->new_position = value;
1437         input_lock->unlock();
1438 }
1439
1440 void RecordStatusThread::update_framerate(double value)
1441 {
1442         if( value != displayed_framerate ) {
1443                 new_framerate = value;
1444                 input_lock->unlock();
1445         }
1446 }
1447
1448
1449 template<class T>
1450 void RecordStatusThread::
1451 update_status_string(const char *fmt, T &new_value, T &displayed_value, BC_Title *widgit)
1452 {
1453         if( new_value >= 0 ) {
1454                 if( displayed_value != new_value ) {
1455                         displayed_value = new_value;
1456                         if( widgit ) {
1457                                 char string[64];
1458                                 sprintf(string, fmt, displayed_value);
1459                                 gui->lock_window("RecordStatusThread::run 1");
1460                                 widgit->update(string);
1461                                 gui->unlock_window();
1462                         }
1463                 }
1464                 new_value = -1;
1465         }
1466 }
1467
1468 void RecordStatusThread::run()
1469 {
1470         while(!done) {
1471                 input_lock->lock("RecordStatusThread::run");
1472                 if(done) break;
1473                 gui->record->window_lock->lock("RecordStatusThread::run");
1474                 update_status_string("%d", new_dropped_frames, displayed_dropped_frames,
1475                                         gui->frames_dropped);
1476                 update_status_string("%d", new_frames_behind, displayed_frames_behind,
1477                                         gui->frames_behind);
1478                 update_status_string("%d", new_clipped_samples, displayed_clipped_samples,
1479                                         gui->samples_clipped);
1480                 update_status_string("%0.2f", new_framerate, displayed_framerate,
1481                                         gui->framerate);
1482                 if( new_position >= 0 ) {
1483                         gui->update_title(gui->position_title, new_position);
1484                         gui->update_labels(new_position);
1485                         new_position = -1;
1486                 }
1487                 gui->record->window_lock->unlock();
1488         }
1489 }
1490
1491
1492 void RecordGUI::start_flash_batch()
1493 {
1494         if( batch_flash ) return;
1495         batch_flash = new RecordGUIFlash(this);
1496 }
1497
1498 void RecordGUI::stop_flash_batch()
1499 {
1500         if( !batch_flash ) return;
1501         delete batch_flash;
1502         batch_flash = 0;
1503 }
1504
1505 void RecordGUI::flash_batch()
1506 {
1507         lock_window("void RecordGUI::flash_batch");
1508         int cur_batch = record->current_batch();
1509         if( cur_batch >= 0 && cur_batch < batch_bay->count()) {
1510                 flash_color = flash_color == GREEN ? RED : GREEN;
1511 //printf("RecordGUI::flash_batch %x\n", flash_color);
1512                 batch_bay->set_row_color(cur_batch, flash_color);
1513                 batch_bay->update_batch_news(cur_batch);
1514         }
1515         unlock_window();
1516 }
1517
1518 RecordGUIFlash::
1519 RecordGUIFlash(RecordGUI *record_gui)
1520  : Thread(1, 0, 0)
1521 {
1522         this->record_gui = record_gui;
1523         flash_lock = new Condition(0,"RecordGUIFlash::flash_lock");
1524         done = 0;
1525         Thread::start();
1526 }
1527
1528 RecordGUIFlash::
1529 ~RecordGUIFlash()
1530 {
1531         if( Thread::running() ) {
1532                 done = 1;
1533                 flash_lock->unlock();
1534                 Thread::cancel();
1535                 Thread::join();
1536         }
1537         delete flash_lock;
1538 }
1539
1540 void RecordGUIFlash::run()
1541 {
1542         while( !done ) {
1543                 record_gui->flash_batch();
1544                 enable_cancel();
1545                 Timer::delay(500);
1546                 disable_cancel();
1547         }
1548 }
1549
1550
1551
1552 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1553  : BC_Button(230, y, mwindow->theme->calibrate_data)
1554 {
1555 }
1556
1557 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1558
1559 int RecordGUIDCOffset::handle_event()
1560 {
1561         return 1;
1562 }
1563
1564 int RecordGUIDCOffset::keypress_event() { return 0; }
1565
1566 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1567  : BC_TextBox(30, y+1, 67, 1, text, 0)
1568
1569         this->number = number; 
1570 }
1571
1572 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1573 {
1574 }
1575         
1576 int RecordGUIDCOffsetText::handle_event()
1577 {
1578         return 1;
1579 }
1580
1581 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1582  : BC_Button(400, y, mwindow->theme->over_button)
1583 { this->gui = gui; }
1584
1585 RecordGUIReset::~RecordGUIReset() 
1586 {
1587 }
1588
1589 int RecordGUIReset::handle_event()
1590 {
1591         return 1;
1592 }
1593
1594 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1595  : BC_Button(250, y, mwindow->theme->reset_data)
1596 {
1597         this->gui = gui;
1598 }
1599
1600 RecordGUIResetTranslation::~RecordGUIResetTranslation() 
1601 {
1602 }
1603
1604 int RecordGUIResetTranslation::handle_event()
1605 {
1606         gui->set_translation(0, 0, 1);
1607         return 1;
1608 }
1609
1610
1611