mixer undo fix, new ffmpeg opts, docs
[goodguy/history.git] / cinelerra-5.1 / cinelerra / interfaceprefs.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 "deleteallindexes.h"
23 #include "edl.h"
24 #include "edlsession.h"
25 #include "file.h"
26 #include "filesystem.h"
27 #include "language.h"
28 #include "mwindow.h"
29 #include "preferences.h"
30 #include "preferencesthread.h"
31 #include "probeprefs.h"
32 #include "interfaceprefs.h"
33 #include "shbtnprefs.h"
34 #include "theme.h"
35
36 #if 0
37 N_("Drag all following edits")
38 N_("Drag only one edit")
39 N_("Drag source only")
40 N_("No effect")
41 #endif
42
43 #define MOVE_ALL_EDITS_TITLE N_("Drag all following edits")
44 #define MOVE_ONE_EDIT_TITLE N_("Drag only one edit")
45 #define MOVE_NO_EDITS_TITLE N_("Drag source only")
46 #define MOVE_EDITS_DISABLED_TITLE N_("No effect")
47
48 InterfacePrefs::InterfacePrefs(MWindow *mwindow, PreferencesWindow *pwindow)
49  : PreferencesDialog(mwindow, pwindow)
50 {
51         min_db = 0;
52         max_db = 0;
53         shbtn_dialog = 0;
54         file_probe_dialog = 0;
55 }
56
57 InterfacePrefs::~InterfacePrefs()
58 {
59         delete min_db;
60         delete max_db;
61         delete shbtn_dialog;
62         delete file_probe_dialog;
63 }
64
65
66 void InterfacePrefs::create_objects()
67 {
68         BC_Resources *resources = BC_WindowBase::get_resources();
69         int margin = mwindow->theme->widget_border;
70         char string[BCTEXTLEN];
71         int x0 = mwindow->theme->preferencesoptions_x;
72         int y0 = mwindow->theme->preferencesoptions_y;
73         int x = x0, y = y0;
74
75         add_subwindow(new BC_Title(x, y, _("Editing:"), LARGEFONT,
76                 resources->text_default));
77         y += 35;
78
79         int x2 = get_w()/2, y2 = y;
80         x = x2;
81         BC_Title *title;
82         add_subwindow(title = new BC_Title(x, y, _("Keyframe reticle:")));
83         y += title->get_h() + 5;
84         keyframe_reticle = new KeyframeReticle(pwindow, this, x, y,
85                 &pwindow->thread->preferences->keyframe_reticle);
86         add_subwindow(keyframe_reticle);
87         keyframe_reticle->create_objects();
88
89         y += 30;
90         add_subwindow(title = new BC_Title(x, y, _("Snapshot path:")));
91         y += title->get_h() + 5;
92         add_subwindow(snapshot_path = new SnapshotPathText(pwindow, this, x, y, get_w()-x-30));
93
94         x = x0;  y = y2;
95         add_subwindow(new BC_Title(x, y, _("Clicking on edit boundaries does what:")));
96         y += 25;
97         add_subwindow(new BC_Title(x, y, _("Button 1:")));
98
99         int x1 = x + 100;
100         ViewBehaviourText *text;
101         add_subwindow(text = new ViewBehaviourText(x1, y - 5,
102                 behavior_to_text(pwindow->thread->edl->session->edit_handle_mode[0]),
103                         pwindow,
104                         &(pwindow->thread->edl->session->edit_handle_mode[0])));
105         text->create_objects();
106         y += 30;
107         add_subwindow(new BC_Title(x, y, _("Button 2:")));
108         add_subwindow(text = new ViewBehaviourText(x1,
109                 y - 5,
110                 behavior_to_text(pwindow->thread->edl->session->edit_handle_mode[1]),
111                         pwindow,
112                         &(pwindow->thread->edl->session->edit_handle_mode[1])));
113         text->create_objects();
114         y += 30;
115         add_subwindow(new BC_Title(x, y, _("Button 3:")));
116         add_subwindow(text = new ViewBehaviourText(x1, y - 5,
117                 behavior_to_text(pwindow->thread->edl->session->edit_handle_mode[2]),
118                         pwindow,
119                         &(pwindow->thread->edl->session->edit_handle_mode[2])));
120         text->create_objects();
121         y += text->get_h() + 30;
122
123         x = x0;
124         add_subwindow(new BC_Bar(5, y,  get_w() - 10));
125         y += 5;
126         add_subwindow(new BC_Title(x, y, _("Operation:"), LARGEFONT,
127                 resources->text_default));
128         y += 35;
129
130         int y1 = y;
131         AndroidRemote *android_remote = new AndroidRemote(pwindow, x2, y);
132         add_subwindow(android_remote);
133         y += android_remote->get_h() + 10;
134         add_subwindow(title = new BC_Title(x2, y, _("Port:")));
135         int x3 = x2 + title->get_w() + margin;
136         AndroidPort *android_port = new AndroidPort(pwindow, x3, y);
137         add_subwindow(android_port);
138         y += title->get_h() + 10;
139         add_subwindow(title = new BC_Title(x2, y, _("PIN:")));
140         AndroidPIN *android_pin = new AndroidPIN(pwindow, x3, y);
141         add_subwindow(android_pin);
142         y += title->get_h() + 30;
143
144         ShBtnPrefs *shbtn_prefs = new ShBtnPrefs(pwindow, this, x2, y);
145         add_subwindow(shbtn_prefs);
146         y += shbtn_prefs->get_h() + 30;
147
148         y2 = y;
149         x = x0;  y = y1;
150         add_subwindow(file_probes = new PrefsFileProbes(pwindow, this, x, y));
151         y += 30;
152
153         PrefsTrapSigSEGV *trap_segv = new PrefsTrapSigSEGV(this, x, y);
154         add_subwindow(trap_segv);
155         x1 = x + trap_segv->get_w() + 10;
156         add_subwindow(new BC_Title(x1, y, _("(must be root)"), MEDIUMFONT, RED));
157         y += 30;
158
159         PrefsTrapSigINTR *trap_intr = new PrefsTrapSigINTR(this, x, y);
160         add_subwindow(trap_intr);
161         add_subwindow(new BC_Title(x1, y, _("(must be root)"), MEDIUMFONT, RED));
162         y += 30;
163
164         yuv420p_dvdlace = new PrefsYUV420P_DVDlace(pwindow, this, x, y);
165         add_subwindow(yuv420p_dvdlace);
166         y += 30;
167
168         if( y2 > y ) y = y2;
169         add_subwindow(title = new BC_Title(x, y + 5, _("Min DB for meter:")));
170         x += title->get_w() + 10;
171         sprintf(string, "%d", pwindow->thread->edl->session->min_meter_db);
172         add_subwindow(min_db = new MeterMinDB(pwindow, string, x, y));
173         x += min_db->get_w() + 10;
174         add_subwindow(title = new BC_Title(x, y + 5, _("Max DB:")));
175         x += title->get_w() + 10;
176         sprintf(string, "%d", pwindow->thread->edl->session->max_meter_db);
177         add_subwindow(max_db = new MeterMaxDB(pwindow, string, x, y));
178         y += 30;
179
180         StillImageUseDuration *use_stduration = new StillImageUseDuration(pwindow,
181                 pwindow->thread->edl->session->si_useduration, x2, y2);
182         add_subwindow(use_stduration);
183         int tw = 0, th = 0;
184         BC_CheckBox::calculate_extents(this, &tw, &th, 0, 0);
185         x2 += tw + 3;
186         y2 += use_stduration->get_h() + 3;
187         StillImageDuration *stduration = new StillImageDuration(pwindow, x2, y2);
188         add_subwindow(stduration);
189         x2 += stduration->get_w() + 10;
190         y2 += 3;
191         add_subwindow(new BC_Title(x2, y2, _("Seconds")));
192         y2 += 30;
193
194         x = x0;  y = y2;
195         add_subwindow(new BC_Bar(5, y,  get_w() - 10));
196         y += 5;
197
198
199         add_subwindow(new BC_Title(x, y, _("Index files:"), LARGEFONT, resources->text_default));
200         y += 30;
201
202         add_subwindow(new BC_Title(x, y + 5,
203                 _("Index files go here:"), MEDIUMFONT, resources->text_default));
204         x1 = x + 230;
205         add_subwindow(ipathtext = new IndexPathText(x1, y, pwindow,
206                 pwindow->thread->preferences->index_directory));
207         x1 +=  ipathtext->get_w();
208         add_subwindow(ipath = new BrowseButton(mwindow->theme, this, ipathtext, x1, y,
209                 pwindow->thread->preferences->index_directory,
210                 _("Index Path"), _("Select the directory for index files"), 1));
211
212         y += 30;
213         add_subwindow(new BC_Title(x, y + 5, _("Size of index file:"),
214                 MEDIUMFONT, resources->text_default));
215         sprintf(string, "%jd", pwindow->thread->preferences->index_size);
216         add_subwindow(isize = new IndexSize(x + 230, y, pwindow, string));
217         add_subwindow(new ScanCommercials(pwindow, 400,y));
218
219         y += 30;
220         add_subwindow(new BC_Title(x, y + 5, _("Number of index files to keep:"),
221                 MEDIUMFONT, resources->text_default));
222         sprintf(string, "%ld", (long)pwindow->thread->preferences->index_count);
223         add_subwindow(icount = new IndexCount(x + 230, y, pwindow, string));
224         add_subwindow(deleteall = new DeleteAllIndexes(mwindow, pwindow, 400, y));
225         y += 30;
226         add_subwindow(ffmpeg_marker_files = new IndexFFMPEGMarkerFiles(this, x, y));
227         y += 35;
228 }
229
230 const char* InterfacePrefs::behavior_to_text(int mode)
231 {
232         switch(mode) {
233                 case MOVE_ALL_EDITS: return _(MOVE_ALL_EDITS_TITLE);
234                 case MOVE_ONE_EDIT:  return _(MOVE_ONE_EDIT_TITLE);
235                 case MOVE_NO_EDITS:  return _(MOVE_NO_EDITS_TITLE);
236                 case MOVE_EDITS_DISABLED: return _(MOVE_EDITS_DISABLED_TITLE);
237                 default: return "";
238         }
239 }
240
241 IndexPathText::IndexPathText(int x, int y, PreferencesWindow *pwindow, char *text)
242  : BC_TextBox(x, y, 240, 1, text)
243 {
244         this->pwindow = pwindow;
245 }
246
247 IndexPathText::~IndexPathText() {}
248
249 int IndexPathText::handle_event()
250 {
251         strcpy(pwindow->thread->preferences->index_directory, get_text());
252         return 1;
253 }
254
255
256
257
258 IndexSize::IndexSize(int x, int y, PreferencesWindow *pwindow, char *text)
259  : BC_TextBox(x, y, 100, 1, text)
260 {
261         this->pwindow = pwindow;
262 }
263
264 int IndexSize::handle_event()
265 {
266         long result;
267
268         result = atol(get_text());
269         if(result < 64000) result = 64000;
270         //if(result < 500000) result = 500000;
271         pwindow->thread->preferences->index_size = result;
272         return 0;
273 }
274
275
276
277 IndexCount::IndexCount(int x, int y, PreferencesWindow *pwindow, char *text)
278  : BC_TextBox(x, y, 100, 1, text)
279 {
280         this->pwindow = pwindow;
281 }
282
283 int IndexCount::handle_event()
284 {
285         long result;
286
287         result = atol(get_text());
288         if(result < 1) result = 1;
289         pwindow->thread->preferences->index_count = result;
290         return 0;
291 }
292
293
294
295 IndexFFMPEGMarkerFiles::IndexFFMPEGMarkerFiles(InterfacePrefs *iface_prefs, int x, int y)
296  : BC_CheckBox(x, y,
297         iface_prefs->pwindow->thread->preferences->ffmpeg_marker_indexes,
298         _("build ffmpeg marker indexes"))
299 {
300         this->iface_prefs = iface_prefs;
301 }
302 IndexFFMPEGMarkerFiles::~IndexFFMPEGMarkerFiles()
303 {
304 }
305
306 int IndexFFMPEGMarkerFiles::handle_event()
307 {
308         iface_prefs->pwindow->thread->preferences->ffmpeg_marker_indexes = get_value();
309         return 1;
310 }
311
312
313 ViewBehaviourText::ViewBehaviourText(int x, int y, const char *text, PreferencesWindow *pwindow,
314         int *output)
315  : BC_PopupMenu(x, y, 200, text)
316 {
317         this->output = output;
318 }
319
320 ViewBehaviourText::~ViewBehaviourText()
321 {
322 }
323
324 int ViewBehaviourText::handle_event()
325 {
326         return 0;
327 }
328
329 void ViewBehaviourText::create_objects()
330 {
331         add_item(new ViewBehaviourItem(this, _(MOVE_ALL_EDITS_TITLE), MOVE_ALL_EDITS));
332         add_item(new ViewBehaviourItem(this, _(MOVE_ONE_EDIT_TITLE), MOVE_ONE_EDIT));
333         add_item(new ViewBehaviourItem(this, _(MOVE_NO_EDITS_TITLE), MOVE_NO_EDITS));
334         add_item(new ViewBehaviourItem(this, _(MOVE_EDITS_DISABLED_TITLE), MOVE_EDITS_DISABLED));
335 }
336
337
338 ViewBehaviourItem::ViewBehaviourItem(ViewBehaviourText *popup, char *text, int behaviour)
339  : BC_MenuItem(text)
340 {
341         this->popup = popup;
342         this->behaviour = behaviour;
343 }
344
345 ViewBehaviourItem::~ViewBehaviourItem()
346 {
347 }
348
349 int ViewBehaviourItem::handle_event()
350 {
351         popup->set_text(get_text());
352         *(popup->output) = behaviour;
353         return 1;
354 }
355
356
357 MeterMinDB::MeterMinDB(PreferencesWindow *pwindow, char *text, int x, int y)
358  : BC_TextBox(x, y, 50, 1, text)
359 {
360         this->pwindow = pwindow;
361 }
362
363 int MeterMinDB::handle_event()
364 {
365         pwindow->thread->redraw_meters = 1;
366         pwindow->thread->edl->session->min_meter_db = atol(get_text());
367         return 0;
368 }
369
370
371 MeterMaxDB::MeterMaxDB(PreferencesWindow *pwindow, char *text, int x, int y)
372  : BC_TextBox(x, y, 50, 1, text)
373 {
374         this->pwindow = pwindow;
375 }
376
377 int MeterMaxDB::handle_event()
378 {
379         pwindow->thread->redraw_meters = 1;
380         pwindow->thread->edl->session->max_meter_db = atol(get_text());
381         return 0;
382 }
383
384
385 ScanCommercials::ScanCommercials(PreferencesWindow *pwindow, int x, int y)
386  : BC_CheckBox(x,
387         y,
388         pwindow->thread->preferences->scan_commercials,
389         _("Scan for commercials during toc build"))
390 {
391         this->pwindow = pwindow;
392 }
393 int ScanCommercials::handle_event()
394 {
395         pwindow->thread->preferences->scan_commercials = get_value();
396         return 1;
397 }
398
399
400 AndroidRemote::AndroidRemote(PreferencesWindow *pwindow, int x, int y)
401  : BC_CheckBox(x, y,
402         pwindow->thread->preferences->android_remote,
403         _("Android Remote Control"))
404 {
405         this->pwindow = pwindow;
406 }
407 int AndroidRemote::handle_event()
408 {
409         pwindow->thread->preferences->android_remote = get_value();
410         return 1;
411 }
412
413 AndroidPIN::AndroidPIN(PreferencesWindow *pwindow, int x, int y)
414  : BC_TextBox(x, y, 240, 1, pwindow->thread->preferences->android_pin)
415 {
416         this->pwindow = pwindow;
417 }
418
419 int AndroidPIN::handle_event()
420 {
421         char *txt = pwindow->thread->preferences->android_pin;
422         int len = sizeof(pwindow->thread->preferences->android_pin);
423         strncpy(txt, get_text(), len);
424         return 1;
425 }
426
427
428 AndroidPort::AndroidPort(PreferencesWindow *pwindow, int x, int y)
429  : BC_TextBox(x, y, 72, 1, pwindow->thread->preferences->android_port)
430 {
431         this->pwindow = pwindow;
432 }
433
434 int AndroidPort::handle_event()
435 {
436         unsigned short port = atoi(get_text());
437         if( port < 1024 ) port = 1024;
438         pwindow->thread->preferences->android_port = port;
439         char str[BCSTRLEN];
440         sprintf(str,"%u",port);
441         update(str);
442         return 1;
443 }
444
445 int InterfacePrefs::start_shbtn_dialog()
446 {
447         if( !shbtn_dialog )
448                 shbtn_dialog = new ShBtnEditDialog(pwindow);
449         shbtn_dialog->start();
450         return 1;
451 }
452
453 ShBtnPrefs::ShBtnPrefs(PreferencesWindow *pwindow, InterfacePrefs *iface_prefs, int x, int y)
454  : BC_GenericButton(x, y, _("Shell Commands"))
455 {
456         this->pwindow = pwindow;
457         this->iface_prefs = iface_prefs;
458         set_tooltip(_("Main Menu Shell Commands"));
459 }
460
461 int ShBtnPrefs::handle_event()
462 {
463         return iface_prefs->start_shbtn_dialog();
464 }
465
466
467 StillImageUseDuration::StillImageUseDuration(PreferencesWindow *pwindow, int value, int x, int y)
468  : BC_CheckBox(x, y, value, _("Import images with a duration of"))
469 {
470         this->pwindow = pwindow;
471 }
472
473 int StillImageUseDuration::handle_event()
474 {
475         pwindow->thread->edl->session->si_useduration = get_value();
476         return 1;
477 }
478
479 StillImageDuration::StillImageDuration(PreferencesWindow *pwindow, int x, int y)
480  : BC_TextBox(x, y, 70, 1, pwindow->thread->edl->session->si_duration)
481 {
482         this->pwindow = pwindow;
483 }
484 int StillImageDuration::handle_event()
485 {
486         pwindow->thread->edl->session->si_duration = atof(get_text());
487         return 1;
488 }
489
490
491 HairlineItem::HairlineItem(KeyframeReticle *popup, int hairline)
492  : BC_MenuItem(popup->hairline_to_string(hairline))
493 {
494         this->popup = popup;
495         this->hairline = hairline;
496 }
497
498 HairlineItem::~HairlineItem()
499 {
500 }
501
502 int HairlineItem::handle_event()
503 {
504         popup->pwindow->thread->redraw_overlays = 1;
505         popup->set_text(get_text());
506         *(popup->output) = hairline;
507         return 1;
508 }
509
510
511 KeyframeReticle::KeyframeReticle(PreferencesWindow *pwindow,
512         InterfacePrefs *iface_prefs, int x, int y, int *output)
513  : BC_PopupMenu(x, y, 220, hairline_to_string(*output))
514 {
515         this->pwindow = pwindow;
516         this->iface_prefs = iface_prefs;
517         this->output = output;
518 }
519
520 KeyframeReticle::~KeyframeReticle()
521 {
522 }
523
524 const char *KeyframeReticle::hairline_to_string(int type)
525 {
526         switch( type ) {
527         case HAIRLINE_NEVER:    return _("Never");
528         case HAIRLINE_DRAGGING: return _("Dragging");
529         case HAIRLINE_ALWAYS:   return _("Always");
530         }
531         return _("Unknown");
532 }
533
534 void KeyframeReticle::create_objects()
535 {
536         add_item(new HairlineItem(this, HAIRLINE_NEVER));
537         add_item(new HairlineItem(this, HAIRLINE_DRAGGING));
538         add_item(new HairlineItem(this, HAIRLINE_ALWAYS));
539 }
540
541 PrefsTrapSigSEGV::PrefsTrapSigSEGV(InterfacePrefs *subwindow, int x, int y)
542  : BC_CheckBox(x, y,
543         subwindow->pwindow->thread->preferences->trap_sigsegv,
544         _("trap sigSEGV"))
545 {
546         this->subwindow = subwindow;
547 }
548 PrefsTrapSigSEGV::~PrefsTrapSigSEGV()
549 {
550 }
551 int PrefsTrapSigSEGV::handle_event()
552 {
553         subwindow->pwindow->thread->preferences->trap_sigsegv = get_value();
554         return 1;
555 }
556
557 PrefsTrapSigINTR::PrefsTrapSigINTR(InterfacePrefs *subwindow, int x, int y)
558  : BC_CheckBox(x, y,
559         subwindow->pwindow->thread->preferences->trap_sigintr,
560         _("trap sigINT"))
561 {
562         this->subwindow = subwindow;
563 }
564 PrefsTrapSigINTR::~PrefsTrapSigINTR()
565 {
566 }
567 int PrefsTrapSigINTR::handle_event()
568 {
569         subwindow->pwindow->thread->preferences->trap_sigintr = get_value();
570         return 1;
571 }
572
573
574 void InterfacePrefs::start_probe_dialog()
575 {
576         if( !file_probe_dialog )
577                 file_probe_dialog = new FileProbeDialog(pwindow);
578         file_probe_dialog->start();
579 }
580
581 PrefsFileProbes::PrefsFileProbes(PreferencesWindow *pwindow,
582                 InterfacePrefs *subwindow, int x, int y)
583  : BC_GenericButton(x, y, _("Probe Order"))
584 {
585         this->pwindow = pwindow;
586         this->subwindow = subwindow;
587         set_tooltip(_("File Open Probe Ordering"));
588 }
589
590 int PrefsFileProbes::handle_event()
591 {
592         subwindow->start_probe_dialog();
593         return 1;
594 }
595
596
597 PrefsYUV420P_DVDlace::PrefsYUV420P_DVDlace(PreferencesWindow *pwindow,
598         InterfacePrefs *subwindow, int x, int y)
599  : BC_CheckBox(x, y, pwindow->thread->preferences->dvd_yuv420p_interlace,
600         _("Use yuv420p dvd interlace format"))
601 {
602         this->pwindow = pwindow;
603         this->subwindow = subwindow;
604 }
605
606 int PrefsYUV420P_DVDlace::handle_event()
607 {
608         pwindow->thread->preferences->dvd_yuv420p_interlace = get_value();
609         return 1;
610 }
611
612
613 SnapshotPathText::SnapshotPathText(PreferencesWindow *pwindow,
614         InterfacePrefs *subwindow, int x, int y, int w)
615  : BC_TextBox(x, y, w, 1, pwindow->thread->preferences->snapshot_path)
616 {
617         this->pwindow = pwindow;
618         this->subwindow = subwindow;
619 }
620
621 SnapshotPathText::~SnapshotPathText()
622 {
623 }
624
625 int SnapshotPathText::handle_event()
626 {
627         strcpy(pwindow->thread->preferences->snapshot_path, get_text());
628         return 1;
629 }
630