1 // interface.c
2 // LiVES
3 // (c) G. Finch 2003 - 2020 <salsaman+lives@gmail.com>
4 // Released under the GNU GPL 3 or later
5 // see file ../COPYING for licensing details
6
7 #include "main.h"
8 #include "callbacks.h"
9 #include "interface.h"
10 #include "paramwindow.h"
11 #include "merge.h"
12 #include "resample.h"
13 #include "startup.h"
14 #include "omc-learn.h" // for OSC_NOTIFY mapping
15
16 // functions called in multitrack.c
17 extern void multitrack_preview_clicked(LiVESButton *, livespointer user_data);
18 extern void mt_change_disp_tracks_ok(LiVESButton *, livespointer user_data);
19
20 static void dsu_fill_details(LiVESWidget *widget, livespointer data);
21 static void qslider_changed(LiVESWidget *slid, livespointer data);
22
add_suffix_check(LiVESBox * box,const char * ext)23 void add_suffix_check(LiVESBox *box, const char *ext) {
24 char *ltext;
25
26 LiVESWidget *checkbutton;
27
28 if (!ext) ltext = (_("Let LiVES set the _file extension"));
29 else ltext = lives_strdup_printf(_("Let LiVES set the _file extension (.%s)"), ext);
30 checkbutton = lives_standard_check_button_new(ltext, mainw->fx1_bool, box, NULL);
31 lives_free(ltext);
32 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
33 LIVES_GUI_CALLBACK(on_boolean_toggled), &mainw->fx1_bool);
34 }
35
36
add_deinterlace_checkbox(LiVESBox * for_deint)37 static LiVESWidget *add_deinterlace_checkbox(LiVESBox *for_deint) {
38 char *tmp, *tmp2;
39 LiVESWidget *hbox = lives_hbox_new(FALSE, 0);
40 LiVESWidget *checkbutton = lives_standard_check_button_new((tmp = (_("Apply _Deinterlace"))), mainw->open_deint,
41 LIVES_BOX(hbox),
42 (tmp2 = (_("If this is set, frames will be deinterlaced as they are imported."))));
43 lives_free(tmp); lives_free(tmp2);
44
45 if (LIVES_IS_HBOX(for_deint)) {
46 LiVESWidget *filler;
47 lives_box_pack_top(for_deint, hbox, FALSE, FALSE, widget_opts.packing_width);
48 filler = add_fill_to_box(LIVES_BOX(for_deint));
49 if (filler) lives_box_reorder_child(for_deint, filler, 1);
50 } else lives_box_pack_start(for_deint, hbox, FALSE, FALSE, widget_opts.packing_height);
51
52 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
53 LIVES_GUI_CALLBACK(on_boolean_toggled), &mainw->open_deint);
54
55 lives_widget_show_all(LIVES_WIDGET(for_deint));
56
57 return hbox;
58 }
59
60
pv_sel_changed(LiVESFileChooser * chooser,livespointer user_data)61 static void pv_sel_changed(LiVESFileChooser *chooser, livespointer user_data) {
62 LiVESSList *slist;
63 LiVESWidget *pbutton = (LiVESWidget *)user_data;
64 if (!LIVES_IS_FILE_CHOOSER(chooser)) return;
65 slist = lives_file_chooser_get_filenames(chooser);
66 end_fs_preview();
67
68 if (!slist || !slist->data || lives_slist_length(slist) > 1 ||
69 !(lives_file_test((char *)lives_slist_nth_data(slist, 0), LIVES_FILE_TEST_IS_REGULAR))) {
70 lives_widget_set_sensitive(pbutton, FALSE);
71 } else lives_widget_set_sensitive(pbutton, TRUE);
72
73 lives_slist_free_all(&slist);
74 }
75
76
show_playbar_labels(int clipno)77 void show_playbar_labels(int clipno) {
78 lives_clip_t *sfile = mainw->files[clipno];
79 char *tmp, *tmpch;
80 char *str_video = (_("Video")), *str_opening;
81 boolean hhr, hvb, hla, hra;
82
83 lives_label_set_text(LIVES_LABEL(mainw->vidbar), str_video);
84 tmp = get_achannel_name(2, 0);
85 lives_label_set_text(LIVES_LABEL(mainw->laudbar), tmp);
86 lives_free(tmp);
87 tmp = get_achannel_name(2, 1);
88 lives_label_set_text(LIVES_LABEL(mainw->raudbar), tmp);
89 lives_free(tmp);
90
91 tmp = (_("(No video)"));
92
93 if (palette->style & STYLE_1) {
94 hhr = hvb = hra = TRUE;
95 hla = FALSE;
96 } else {
97 hhr = hvb = hla = hra = FALSE;
98 }
99
100 if (!IS_VALID_CLIP(clipno)) {
101 lives_label_set_text(LIVES_LABEL(mainw->vidbar), tmp);
102 lives_free(tmp);
103
104 lives_free(str_video);
105 hhr = hvb = hla = hra = TRUE;
106 goto showhide;
107 }
108
109 str_opening = (_("[opening...]"));
110
111 if (CLIP_HAS_VIDEO(clipno)) {
112 if (sfile->opening_loc || (sfile->frames == 123456789 && sfile->opening)) {
113 lives_free(tmp);
114 tmp = lives_strdup_printf(_("%s %s"), str_video, str_opening);
115 } else {
116 if (sfile->fps > 0.) {
117 sfile->video_time = sfile->frames / sfile->fps;
118 }
119 if (sfile->video_time > 0.) {
120 lives_free(tmp);
121 tmp = lives_strdup_printf(_("%s [%.2f sec]"), str_video, sfile->video_time);
122 } else {
123 if (sfile->video_time <= 0. && sfile->frames > 0) {
124 lives_free(tmp);
125 tmp = (_("(Undefined)"));
126 }
127 }
128 }
129 lives_label_set_text(LIVES_LABEL(mainw->vidbar), tmp);
130 lives_free(tmp);
131
132 hhr = hvb = FALSE;
133 }
134
135 lives_free(str_video);
136
137 if (!CLIP_HAS_AUDIO(clipno)) {
138 tmp = (_("(No audio)"));
139 } else {
140 hhr = FALSE;
141
142 tmpch = get_achannel_name(sfile->achans, 0);
143 if (sfile->opening_audio) {
144 tmp = lives_strdup_printf(_("%s %s"), tmpch, str_opening);
145 } else {
146 tmp = lives_strdup_printf(_("%s [%.2f sec]"), tmpch, sfile->laudio_time);
147 }
148 lives_free(tmpch);
149 }
150
151 lives_label_set_text(LIVES_LABEL(mainw->laudbar), tmp);
152 lives_free(tmp);
153
154 if (sfile->achans > 1) {
155 tmpch = get_achannel_name(sfile->achans, 1);
156 if (sfile->opening_audio) {
157 tmp = lives_strdup_printf(_("%s %s"), tmpch, str_opening);
158 } else {
159 tmp = lives_strdup_printf(_("%s [%.2f sec]"), tmpch, sfile->raudio_time);
160 }
161 lives_free(tmpch);
162 lives_label_set_text(LIVES_LABEL(mainw->raudbar), tmp);
163 lives_free(tmp);
164 hra = FALSE;
165 }
166
167 lives_free(str_opening);
168
169 showhide:
170 if (!hhr && !lives_widget_is_visible(mainw->hruler)) lives_widget_show(mainw->hruler);
171 else if (hhr && lives_widget_is_visible(mainw->hruler)) lives_widget_hide(mainw->hruler);
172 if (!hvb && !lives_widget_is_visible(mainw->vidbar)) lives_widget_show(mainw->vidbar);
173 else if (hvb && lives_widget_is_visible(mainw->vidbar)) lives_widget_hide(mainw->vidbar);
174 if (!hla && !lives_widget_is_visible(mainw->laudbar)) lives_widget_show(mainw->laudbar);
175 else if (hla && lives_widget_is_visible(mainw->laudbar)) lives_widget_hide(mainw->laudbar);
176 if (!hra && !lives_widget_is_visible(mainw->raudbar)) lives_widget_show(mainw->raudbar);
177 else if (hra && lives_widget_is_visible(mainw->raudbar)) lives_widget_hide(mainw->raudbar);
178 }
179
180
clear_tbar_bgs(int posx,int posy,int width,int height,int which)181 void clear_tbar_bgs(int posx, int posy, int width, int height, int which) {
182 // empirically we need to draw wider
183 posx -= OVERDRAW_MARGIN;
184 if (width > 0) width += OVERDRAW_MARGIN;
185
186 if (posx < 0) posx = 0;
187 if (posy < 0) posy = 0;
188
189 if (which == 0 || which == 2) {
190 if (mainw->laudio_drawable) {
191 clear_widget_bg_area(mainw->laudio_draw, mainw->laudio_drawable, posx, posy, width, height);
192 }
193 }
194
195 if (which == 0 || which == 3) {
196 if (mainw->raudio_drawable) {
197 clear_widget_bg_area(mainw->raudio_draw, mainw->raudio_drawable, posx, posy, width, height);
198 }
199 }
200
201 if (which == 0 || which == 1) {
202 clear_widget_bg_area(mainw->video_draw, mainw->video_drawable, posx, posy, width, height);
203 }
204 }
205
206
lives_ce_update_timeline(int frame,double x)207 double lives_ce_update_timeline(int frame, double x) {
208 // update clip editor timeline
209 // sets real_pointer_time and pointer_time
210 // if frame == 0 then x must be a time value
211
212 // returns the pointer time (quantised to frame)
213
214 static int last_current_file = -1;
215
216 if (!prefs->show_gui) return 0.;
217
218 if (lives_widget_get_allocation_width(mainw->vidbar) <= 0) {
219 return 0.;
220 }
221
222 if (!CURRENT_CLIP_IS_VALID) {
223 if (!prefs->hide_framebar) {
224 lives_entry_set_text(LIVES_ENTRY(mainw->framecounter), "");
225 lives_widget_queue_draw_if_visible(mainw->framecounter);
226 }
227 clear_tbar_bgs(0, 0, 0, 0, 0);
228 show_playbar_labels(-1);
229 return -1.;
230 }
231
232 if (x < 0.) x = 0.;
233
234 if (frame == 0) frame = calc_frame_from_time4(mainw->current_file, x);
235
236 x = calc_time_from_frame(mainw->current_file, frame);
237 if (x > CLIP_TOTAL_TIME(mainw->current_file)) x = CLIP_TOTAL_TIME(mainw->current_file);
238 cfile->real_pointer_time = x;
239
240 if (cfile->frames > 0 && frame > cfile->frames) frame = cfile->frames;
241 x = calc_time_from_frame(mainw->current_file, frame);
242 cfile->pointer_time = x;
243
244 cfile->frameno = cfile->last_frameno = frame;
245 if (cfile->achans) {
246 cfile->aseek_pos = (off64_t)((double)(cfile->real_pointer_time * cfile->arate) * cfile->achans *
247 (cfile->asampsize / 8));
248 if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
249 }
250
251 #ifndef ENABLE_GIW_3
252 lives_ruler_set_value(LIVES_RULER(mainw->hruler), x);
253 lives_widget_queue_draw_if_visible(mainw->hruler);
254 #endif
255
256 if (prefs->show_gui && !prefs->hide_framebar && cfile->frames > 0) {
257 char *framecount;
258 if (cfile->frames > 0) framecount = lives_strdup_printf("%9d / %d", frame, cfile->frames);
259 else framecount = lives_strdup_printf("%9d", frame);
260 lives_entry_set_text(LIVES_ENTRY(mainw->framecounter), framecount);
261 lives_freep((void **)&framecount);
262 //lives_widget_queue_draw_if_visible(mainw->framecounter);
263 }
264
265 if (!LIVES_IS_PLAYING && mainw->play_window && cfile->is_loaded && !mainw->multitrack) {
266 if (mainw->prv_link == PRV_PTR && mainw->preview_frame != frame) {
267 if (cfile->frames > 0) {
268 cfile->frameno = frame;
269 load_preview_image(FALSE);
270 }
271 }
272 }
273
274 if (mainw->is_ready && !LIVES_IS_PLAYING && !prefs->hide_framebar && mainw->current_file != last_current_file) {
275 lives_signal_handler_block(mainw->spinbutton_pb_fps, mainw->pb_fps_func);
276 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), cfile->pb_fps);
277 lives_signal_handler_unblock(mainw->spinbutton_pb_fps, mainw->pb_fps_func);
278 }
279
280 show_playbar_labels(mainw->current_file);
281 redraw_timeline(mainw->current_file);
282
283 last_current_file = mainw->current_file;
284 return cfile->pointer_time;
285 }
286
287
update_timer_bars(int posx,int posy,int width,int height,int which)288 void update_timer_bars(int posx, int posy, int width, int height, int which) {
289 // update the on-screen timer bars,
290 // and if we are not playing,
291 // get play times for video, audio channels, and total (longest) time
292
293 // refresh = reread audio waveforms
294
295 // which 0 = all, 1 = vidbar, 2 = laudbar, 3 = raudbar
296
297 lives_painter_t *cr = NULL;
298 char *filename;
299
300 double allocwidth;
301 double atime;
302
303 double y = 0., scalex;
304
305 int start;
306 int offset_left = 0;
307 int offset_right = 0;
308 int offset_end;
309 int lpos = -9999, pos;
310
311 int current_file = mainw->current_file;
312 int xwidth, zwidth;
313 int afd = -1;
314 int bar_height;
315
316 register int i;
317
318 if (CURRENT_CLIP_IS_VALID && cfile->cb_src != -1) mainw->current_file = cfile->cb_src;
319
320 if (!CURRENT_CLIP_IS_VALID || mainw->foreign || mainw->multitrack || mainw->recoverable_layout) {
321 mainw->current_file = current_file;
322 return;
323 }
324
325 if (!LIVES_IS_PLAYING) {
326 get_total_time(cfile);
327 }
328
329 if (!mainw->is_ready || !prefs->show_gui) {
330 mainw->current_file = current_file;
331 return;
332 }
333
334 // draw timer bars
335 // first the background
336 clear_tbar_bgs(posx, posy, width, height, which);
337
338 // empirically we need to draw wider
339 posx -= OVERDRAW_MARGIN;
340 if (width > 0) width += OVERDRAW_MARGIN;
341 if (posx < 0) posx = 0;
342 if (posy < 0) posy = 0;
343
344 if (cfile->frames > 0 && mainw->video_drawable && (which == 0 || which == 1)) {
345 bar_height = CE_VIDBAR_HEIGHT;
346 allocwidth = lives_widget_get_allocation_width(mainw->video_draw);
347 scalex = (double)allocwidth / CURRENT_CLIP_TOTAL_TIME;
348
349 offset_left = ROUND_I((double)(cfile->start - 1.) / cfile->fps * scalex);
350 offset_right = ROUND_I((double)(cfile->end) / cfile->fps * scalex);
351
352 cr = lives_painter_create_from_surface(mainw->video_drawable);
353 xwidth = UTIL_CLAMP(width, allocwidth);
354
355 if (offset_left > posx) {
356 // unselected
357 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_unsel);
358 lives_painter_rectangle(cr, posx, 0,
359 NORMAL_CLAMP(offset_left - posx, xwidth),
360 bar_height);
361 lives_painter_fill(cr);
362 }
363
364 if (offset_right > posx) {
365 if (offset_left < posx) offset_left = posx;
366 if (offset_right > posx + xwidth) offset_right = posx + xwidth;
367 // selected
368 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_sel);
369 lives_painter_rectangle(cr, offset_left, 0, offset_right - offset_left,
370 bar_height);
371 lives_painter_fill(cr);
372 }
373
374 if (offset_right < posx + xwidth) {
375 if (posx > offset_right) offset_right = posx;
376 zwidth = ROUND_I(cfile->video_time * scalex) - offset_right;
377 if (posx < offset_right) xwidth -= offset_right - posx;
378 zwidth = NORMAL_CLAMP(zwidth, xwidth);
379 // unselected
380 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_unsel);
381 lives_painter_rectangle(cr, offset_right, 0, zwidth, bar_height);
382 lives_painter_fill(cr);
383 }
384 lives_painter_destroy(cr);
385 }
386
387 bar_height = CE_AUDBAR_HEIGHT / 2.;
388
389 if (cfile->achans > 0 && mainw->laudio_drawable && (which == 0 || which == 2)) {
390 allocwidth = lives_widget_get_allocation_width(mainw->laudio_draw);
391 scalex = (double)allocwidth / CURRENT_CLIP_TOTAL_TIME;
392 offset_left = ROUND_I((double)(cfile->start - 1.) / cfile->fps * scalex);
393 offset_right = ROUND_I((double)(cfile->end) / cfile->fps * scalex);
394 offset_end = ROUND_I(cfile->laudio_time * scalex);
395
396 if (!cfile->audio_waveform) {
397 cfile->audio_waveform = (float **)lives_calloc(cfile->achans, sizeof(float *));
398 cfile->aw_sizes = (size_t *)lives_calloc(cfile->achans, sizeof(size_t));
399 }
400
401 start = offset_end;
402 if (!cfile->audio_waveform[0]) {
403 // re-read the audio
404 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mainw->laudio_draw), "drawn", LIVES_INT_TO_POINTER(0)); // force redrawing
405 cfile->audio_waveform[0] = (float *)lives_calloc((int)offset_end, sizeof(float));
406 start = cfile->aw_sizes[0] = 0;
407 } else if (cfile->aw_sizes[0] != offset_end) {
408 start = 0;
409 cfile->audio_waveform[0] = (float *)lives_realloc(cfile->audio_waveform[0], (int)offset_end * sizeof(float));
410 }
411
412 if (cfile->audio_waveform[0]) {
413 if (start != offset_end) {
414 cfile->aw_sizes[0] = offset_end;
415 filename = lives_get_audio_file_name(mainw->current_file);
416 afd = lives_open_buffered_rdonly(filename);
417 lives_free(filename);
418
419 for (i = start; i < offset_end; i++) {
420 if (afd == -1) {
421 THREADVAR(read_failed) = -2;
422 return;
423 }
424 atime = (double)i / scalex;
425 cfile->audio_waveform[0][i] = cfile->vol
426 * get_float_audio_val_at_time(mainw->current_file, afd, atime, 0, cfile->achans) * 2.;
427 }
428 lives_close_buffered(afd);
429 }
430
431 cr = lives_painter_create_from_surface(mainw->laudio_drawable);
432 offset_right = NORMAL_CLAMP(offset_right, cfile->laudio_time * scalex);
433 xwidth = UTIL_CLAMP(width, allocwidth);
434 if (offset_end > posx + xwidth) offset_end = posx + xwidth;
435 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_unsel);
436 lpos = -9999;
437 lives_painter_move_to(cr, posx, bar_height);
438 for (i = posx; i < offset_left && i < offset_end; i++) {
439 pos = ROUND_I((double)(i * cfile->fps / scalex) / cfile->fps * scalex);
440 if (pos != lpos) {
441 lpos = pos;
442 y = bar_height * (1. - cfile->audio_waveform[0][pos] / 2.);
443 }
444
445 lives_painter_line_to(cr, i, bar_height);
446 lives_painter_line_to(cr, i, y);
447 lives_painter_line_to(cr, i, bar_height);
448 }
449 lives_painter_close_path(cr);
450 lives_painter_stroke(cr);
451
452 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_sel);
453 lpos = -9999;
454
455 lives_painter_move_to(cr, i, bar_height);
456 for (; i < offset_right && i < offset_end; i++) {
457 pos = ROUND_I((double)(i * cfile->fps / scalex) / cfile->fps * scalex);
458 if (pos != lpos) {
459 lpos = pos;
460 y = bar_height * (1. - cfile->audio_waveform[0][pos] / 2.);
461 }
462
463 lives_painter_line_to(cr, i, bar_height);
464 lives_painter_line_to(cr, i, y);
465 lives_painter_line_to(cr, i, bar_height);
466 }
467 lives_painter_close_path(cr);
468 lives_painter_stroke(cr);
469
470 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_unsel);
471 lpos = -9999;
472 lives_painter_move_to(cr, offset_right, bar_height);
473 for (; i < offset_end; i++) {
474 pos = ROUND_I((double)(i * cfile->fps / scalex) / cfile->fps * scalex);
475 if (pos != lpos) {
476 lpos = pos;
477 y = bar_height * (1. - cfile->audio_waveform[0][pos] / 2.);
478 }
479
480 lives_painter_line_to(cr, i, bar_height);
481 lives_painter_line_to(cr, i, y);
482 lives_painter_line_to(cr, i, bar_height);
483 }
484 lives_painter_close_path(cr);
485 lives_painter_stroke(cr);
486 lives_painter_destroy(cr);
487 }
488 }
489
490 if (cfile->achans > 1 && mainw->raudio_drawable && (which == 0 || which == 3)) {
491 allocwidth = lives_widget_get_allocation_width(mainw->raudio_draw);
492 scalex = (double)allocwidth / CURRENT_CLIP_TOTAL_TIME;
493 offset_left = ROUND_I((double)(cfile->start - 1.) / cfile->fps * scalex);
494 offset_right = ROUND_I((double)(cfile->end) / cfile->fps * scalex);
495 offset_end = ROUND_I(cfile->raudio_time * scalex);
496
497 start = offset_end;
498 if (!cfile->audio_waveform[1]) {
499 // re-read the audio and force a redraw
500 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mainw->raudio_draw), "drawn", LIVES_INT_TO_POINTER(0));
501 cfile->audio_waveform[1] = (float *)lives_calloc((int)offset_end, sizeof(float));
502 start = cfile->aw_sizes[1] = 0;
503 } else if (cfile->aw_sizes[1] != offset_end) {
504 start = 0;
505 cfile->audio_waveform[1] = (float *)lives_realloc(cfile->audio_waveform[1], (int)offset_end * sizeof(float));
506 }
507 cfile->aw_sizes[1] = offset_end;
508
509 if (cfile->audio_waveform[1]) {
510 if (start != offset_end) {
511 cfile->aw_sizes[1] = offset_end;
512 filename = lives_get_audio_file_name(mainw->current_file);
513 afd = lives_open_buffered_rdonly(filename);
514 lives_free(filename);
515 for (i = start; i < offset_end; i++) {
516 if (afd == -1) {
517 THREADVAR(read_failed) = -2;
518 return;
519 }
520 atime = (double)i / scalex;
521 cfile->audio_waveform[1][i] = cfile->vol
522 * get_float_audio_val_at_time(mainw->current_file, afd, atime, 1, cfile->achans) * 2.;
523 }
524 lives_close_buffered(afd);
525 afd = -1;
526 }
527
528 offset_right = NORMAL_CLAMP(offset_right, cfile->raudio_time * scalex);
529 xwidth = UTIL_CLAMP(width, allocwidth);
530
531 cr = lives_painter_create_from_surface(mainw->raudio_drawable);
532 if (offset_end > posx + xwidth) offset_end = posx + xwidth;
533 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_unsel);
534 lpos = -9999;
535 lives_painter_move_to(cr, posx, bar_height);
536 for (i = posx; i < offset_left && i < offset_end; i++) {
537 pos = ROUND_I((double)(i * cfile->fps / scalex) / cfile->fps * scalex);
538 if (pos != lpos) {
539 lpos = pos;
540 y = bar_height * (1. - cfile->audio_waveform[1][pos] / 2.);
541 }
542
543 lives_painter_line_to(cr, i, bar_height);
544 lives_painter_line_to(cr, i, y);
545 lives_painter_line_to(cr, i, bar_height);
546 }
547 lives_painter_close_path(cr);
548 lives_painter_stroke(cr);
549
550 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_sel);
551 lpos = -9999;
552
553 lives_painter_move_to(cr, i, bar_height);
554 for (; i < offset_right && i < offset_end; i++) {
555 pos = ROUND_I((double)(i * cfile->fps / scalex) / cfile->fps * scalex);
556 if (pos != lpos) {
557 lpos = pos;
558 y = bar_height * (1. - cfile->audio_waveform[1][pos] / 2.);
559 }
560
561 lives_painter_line_to(cr, i, bar_height);
562 lives_painter_line_to(cr, i, y);
563 lives_painter_line_to(cr, i, bar_height);
564 }
565 lives_painter_close_path(cr);
566 lives_painter_stroke(cr);
567
568 lives_painter_set_source_rgb_from_lives_rgba(cr, &palette->ce_unsel);
569 lpos = -9999;
570 lives_painter_move_to(cr, offset_right, bar_height);
571 for (; i < offset_end; i++) {
572 pos = ROUND_I((double)(i * cfile->fps / scalex) / cfile->fps * scalex);
573 if (pos != lpos) {
574 lpos = pos;
575 y = bar_height * (1. - cfile->audio_waveform[1][pos] / 2.);
576 }
577
578 lives_painter_line_to(cr, i, bar_height);
579 lives_painter_line_to(cr, i, y);
580 lives_painter_line_to(cr, i, bar_height);
581 }
582 lives_painter_close_path(cr);
583 lives_painter_stroke(cr);
584 lives_painter_destroy(cr);
585 }
586 }
587
588 if (which == 0) {
589 // playback cursors
590 if (CURRENT_CLIP_TOTAL_TIME > 0.) {
591 // set the range of the timeline
592 if (!cfile->opening_loc && which == 0) {
593 if (!lives_widget_is_visible(mainw->hruler)) {
594 lives_widget_show(mainw->hruler);
595 }
596 }
597
598 if (!lives_widget_is_visible(mainw->video_draw)) {
599 lives_widget_show(mainw->hruler);
600 lives_widget_show(mainw->video_draw);
601 lives_widget_show(mainw->laudio_draw);
602 lives_widget_show(mainw->raudio_draw);
603 }
604
605 #ifdef ENABLE_GIW
606 giw_timeline_set_max_size(GIW_TIMELINE(mainw->hruler), CURRENT_CLIP_TOTAL_TIME);
607 #endif
608 lives_ruler_set_upper(LIVES_RULER(mainw->hruler), CURRENT_CLIP_TOTAL_TIME);
609 lives_widget_queue_draw(mainw->hruler);
610 }
611 show_playbar_labels(mainw->current_file);
612 }
613 //lives_widget_queue_draw_if_visible(mainw->hruler);
614
615
616 mainw->current_file = current_file;
617 if (which == 0 || which == 1) lives_widget_queue_draw_if_visible(mainw->video_draw);
618 if (which == 0 || which == 2) lives_widget_queue_draw_if_visible(mainw->laudio_draw);
619 if (which == 0 || which == 3) lives_widget_queue_draw_if_visible(mainw->raudio_draw);
620 }
621
622
redraw_timer_bars(double oldx,double newx,int which)623 void redraw_timer_bars(double oldx, double newx, int which) {
624 // redraw region from cache
625 // oldx and newx are in seconds
626 double scalex;
627 int allocwidth;
628
629 if (oldx == newx) return;
630 if (CURRENT_CLIP_TOTAL_TIME == 0.) return;
631
632 allocwidth = lives_widget_get_allocation_width(mainw->video_draw);
633
634 if (allocwidth == 0) return;
635
636 scalex = allocwidth / CURRENT_CLIP_TOTAL_TIME;
637
638 if (newx > oldx) {
639 update_timer_bars(ROUND_I(oldx * scalex - .5), 0, ROUND_I((newx - oldx) * scalex + .5), 0, which);
640 } else {
641 update_timer_bars(ROUND_I(newx * scalex - .5), 0, ROUND_I((oldx - newx) * scalex + .5), 0, which);
642 }
643 }
644
645
on_fsp_click(LiVESWidget * widget,LiVESXEventButton * event,livespointer user_data)646 static boolean on_fsp_click(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data) {
647 lives_button_clicked(LIVES_BUTTON(user_data));
648 return FALSE;
649 }
650
651
widget_add_preview(LiVESWidget * widget,LiVESBox * for_preview,LiVESBox * for_button,LiVESBox * for_deint,int preview_type)652 void widget_add_preview(LiVESWidget *widget, LiVESBox *for_preview, LiVESBox *for_button, LiVESBox *for_deint,
653 int preview_type) {
654 LiVESWidget *preview_button = NULL;
655
656 if (preview_type == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || preview_type == LIVES_PREVIEW_TYPE_RANGE ||
657 preview_type == LIVES_PREVIEW_TYPE_IMAGE_ONLY) {
658 mainw->fs_playframe = lives_standard_frame_new(_("Preview"), 0.5, FALSE);
659 mainw->fs_playalign = lives_alignment_new(0.5, 0.5, 1., 1.);
660
661 mainw->fs_playimg = lives_drawing_area_new();
662 lives_widget_set_no_show_all(mainw->fs_playimg, TRUE);
663 lives_widget_set_app_paintable(mainw->fs_playimg, TRUE);
664
665 mainw->fs_playarea = lives_event_box_new();
666
667 lives_widget_nullify_with(widget, (void **)&mainw->fs_playframe);
668 lives_widget_nullify_with(widget, (void **)&mainw->fs_playarea);
669 lives_widget_nullify_with(widget, (void **)&mainw->fs_playalign);
670 lives_widget_nullify_with(widget, (void **)&mainw->fs_playimg);
671
672 lives_widget_set_events(mainw->fs_playframe, LIVES_BUTTON_PRESS_MASK);
673
674 lives_widget_apply_theme(mainw->fs_playframe, LIVES_WIDGET_STATE_NORMAL);
675 lives_widget_apply_theme(mainw->fs_playalign, LIVES_WIDGET_STATE_NORMAL);
676 lives_widget_set_fg_color(mainw->fs_playalign, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
677
678 lives_widget_apply_theme(mainw->fs_playarea, LIVES_WIDGET_STATE_NORMAL);
679
680 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mainw->fs_playarea), "pixbuf", NULL);
681
682 lives_container_set_border_width(LIVES_CONTAINER(mainw->fs_playframe), 0);
683
684 lives_box_pack_start(for_preview, mainw->fs_playframe, FALSE, TRUE, 0);
685
686 if (preview_type != LIVES_PREVIEW_TYPE_RANGE) {
687 lives_widget_set_size_request(mainw->fs_playframe,
688 ((int)(DEF_FRAME_HSIZE_UNSCALED * (widget_opts.scale < 1.
689 ? widget_opts.scale : 1.)) >> 2) << 1,
690 ((int)(DEF_FRAME_VSIZE_UNSCALED * (widget_opts.scale < 1.
691 ? widget_opts.scale : 1.)) >> 2) << 1);
692 } else {
693 lives_widget_set_vexpand(mainw->fs_playframe, TRUE);
694 }
695 lives_container_add(LIVES_CONTAINER(mainw->fs_playframe), mainw->fs_playalign);
696 lives_container_add(LIVES_CONTAINER(mainw->fs_playalign), mainw->fs_playarea);
697 lives_container_add(LIVES_CONTAINER(mainw->fs_playarea), mainw->fs_playimg);
698 } else mainw->fs_playframe = mainw->fs_playalign = mainw->fs_playarea = mainw->fs_playimg = NULL; // AUDIO_ONLY
699
700 if (preview_type == LIVES_PREVIEW_TYPE_VIDEO_AUDIO) {
701 preview_button =
702 lives_standard_button_new_with_label(_("Click here to _Preview the Selected Video, "
703 "Image or Audio File"),
704 DEF_BUTTON_WIDTH * 4, DEF_BUTTON_HEIGHT);
705 } else if (preview_type == LIVES_PREVIEW_TYPE_AUDIO_ONLY) {
706 preview_button = lives_standard_button_new_with_label(_("Click here to _Preview the Selected "
707 "Audio File"), DEF_BUTTON_WIDTH * 4, DEF_BUTTON_HEIGHT);
708 } else if (preview_type == LIVES_PREVIEW_TYPE_RANGE) {
709 widget_opts.expand = LIVES_EXPAND_NONE;
710 preview_button = lives_standard_button_new_with_label(_("\nClick here to _Preview the Selection\n"),
711 DEF_BUTTON_WIDTH * 4, DEF_BUTTON_HEIGHT);
712 lives_widget_set_hexpand(mainw->fs_playframe, TRUE);
713 lives_widget_set_vexpand(mainw->fs_playframe, TRUE);
714 lives_widget_set_halign(preview_button, LIVES_ALIGN_CENTER);
715 widget_opts.expand = LIVES_EXPAND_DEFAULT;
716 } else {
717 preview_button = lives_standard_button_new_with_label(_("Click here to _Preview the file"),
718 DEF_BUTTON_WIDTH * 4, DEF_BUTTON_HEIGHT);
719 }
720
721 if (preview_type == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || preview_type == LIVES_PREVIEW_TYPE_RANGE ||
722 preview_type == LIVES_PREVIEW_TYPE_IMAGE_ONLY) {
723 lives_box_pack_start(for_button, preview_button, FALSE, FALSE, widget_opts.packing_width);
724 lives_signal_connect(LIVES_GUI_OBJECT(mainw->fs_playframe), LIVES_WIDGET_BUTTON_PRESS_EVENT,
725 LIVES_GUI_CALLBACK(on_fsp_click), preview_button);
726 }
727
728 if (preview_type == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || preview_type == LIVES_PREVIEW_TYPE_RANGE) {
729 add_deinterlace_checkbox(for_deint);
730 }
731
732 lives_signal_sync_connect(LIVES_GUI_OBJECT(preview_button), LIVES_WIDGET_CLICKED_SIGNAL,
733 LIVES_GUI_CALLBACK(on_fs_preview_clicked), LIVES_INT_TO_POINTER(preview_type));
734
735 if (LIVES_IS_FILE_CHOOSER(widget) && preview_type != LIVES_PREVIEW_TYPE_RANGE) {
736 lives_widget_set_sensitive(preview_button, FALSE);
737
738 lives_signal_sync_connect(LIVES_GUI_OBJECT(widget), LIVES_WIDGET_SELECTION_CHANGED_SIGNAL,
739 LIVES_GUI_CALLBACK(pv_sel_changed), (livespointer)preview_button);
740 }
741 }
742
743
on_dth_cancel_clicked(LiVESButton * button,livespointer user_data)744 static void on_dth_cancel_clicked(LiVESButton *button, livespointer user_data) {
745 if (LIVES_POINTER_TO_INT(user_data) == 1) mainw->cancelled = CANCEL_KEEP;
746 else mainw->cancelled = CANCEL_USER;
747 }
748
749
750 static ticks_t last_t;
751
create_threaded_dialog(char * text,boolean has_cancel,boolean * td_had_focus)752 xprocess *create_threaded_dialog(char *text, boolean has_cancel, boolean *td_had_focus) {
753 LiVESWidget *dialog_vbox;
754 LiVESWidget *vbox;
755 LiVESWidget *hbox;
756 xprocess *procw;
757 char tmp_label[256];
758
759 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
760
761 last_t = lives_get_current_ticks();
762
763 procw = (xprocess *)(lives_calloc(sizeof(xprocess), 1));
764
765 procw->processing = lives_standard_dialog_new(_("Processing..."), FALSE, -1, -1);
766
767 lives_window_set_decorated(LIVES_WINDOW(procw->processing), FALSE);
768
769 lives_window_add_accel_group(LIVES_WINDOW(procw->processing), accel_group);
770
771 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(procw->processing));
772
773 vbox = lives_vbox_new(FALSE, 0);
774 lives_box_pack_start(LIVES_BOX(dialog_vbox), vbox, TRUE, TRUE, 0);
775
776 lives_snprintf(tmp_label, 256, "%s...\n", text);
777 widget_opts.justify = LIVES_JUSTIFY_CENTER;
778 widget_opts.mnemonic_label = FALSE;
779 procw->label = lives_standard_label_new(tmp_label);
780 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
781 widget_opts.mnemonic_label = TRUE;
782 lives_box_pack_start(LIVES_BOX(vbox), procw->label, FALSE, TRUE, 0);
783
784 procw->progressbar = lives_standard_progress_bar_new();
785
786 lives_progress_bar_set_pulse_step(LIVES_PROGRESS_BAR(procw->progressbar), .01);
787 lives_box_pack_start(LIVES_BOX(vbox), procw->progressbar, FALSE, FALSE, 0);
788
789 if (widget_opts.apply_theme && (palette->style & STYLE_1)) {
790 lives_widget_set_fg_color(procw->progressbar, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
791 }
792
793 widget_opts.justify = LIVES_JUSTIFY_CENTER;
794 procw->label2 = lives_standard_label_new(_("\nPlease Wait"));
795 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
796 lives_box_pack_start(LIVES_BOX(vbox), procw->label2, FALSE, FALSE, 0);
797
798 widget_opts.justify = LIVES_JUSTIFY_CENTER;
799 #ifdef PROGBAR_IS_ENTRY
800 procw->label3 = procw->progressbar;
801 #else
802 procw->label3 = lives_standard_label_new("");
803 lives_box_pack_start(LIVES_BOX(vbox), procw->label3, FALSE, FALSE, 0);
804 #endif
805 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
806 widget_opts.expand = LIVES_EXPAND_EXTRA;
807 hbox = lives_hbox_new(FALSE, widget_opts.filler_len * 8);
808 add_fill_to_box(LIVES_BOX(hbox));
809 add_fill_to_box(LIVES_BOX(hbox));
810 widget_opts.expand = LIVES_EXPAND_DEFAULT;
811 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, 0);
812
813 if (has_cancel) {
814 if (CURRENT_CLIP_IS_VALID && mainw->cancel_type == CANCEL_SOFT) {
815 LiVESWidget *enoughbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing), NULL, _("_Enough"),
816 LIVES_RESPONSE_CANCEL);
817 lives_widget_set_can_default(enoughbutton, TRUE);
818
819 lives_signal_sync_connect(LIVES_GUI_OBJECT(enoughbutton), LIVES_WIDGET_CLICKED_SIGNAL,
820 LIVES_GUI_CALLBACK(on_dth_cancel_clicked), LIVES_INT_TO_POINTER(1));
821
822 lives_widget_add_accelerator(enoughbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
823 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
824 lives_button_uncenter(enoughbutton, DLG_BUTTON_WIDTH);
825 } else {
826 procw->cancel_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing), LIVES_STOCK_CANCEL, NULL,
827 LIVES_RESPONSE_CANCEL);
828 lives_widget_set_can_default(procw->cancel_button, TRUE);
829
830 lives_widget_add_accelerator(procw->cancel_button, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
831 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
832
833 lives_signal_sync_connect(LIVES_GUI_OBJECT(procw->cancel_button), LIVES_WIDGET_CLICKED_SIGNAL,
834 LIVES_GUI_CALLBACK(on_dth_cancel_clicked), LIVES_INT_TO_POINTER(0));
835 lives_button_uncenter(procw->cancel_button, DLG_BUTTON_WIDTH);
836 }
837 }
838
839 if (lives_has_toplevel_focus(LIVES_MAIN_WINDOW_WIDGET)) {
840 *td_had_focus = TRUE;
841 } else *td_had_focus = FALSE;
842
843 lives_widget_show_all(procw->processing);
844
845 lives_set_cursor_style(LIVES_CURSOR_BUSY, procw->processing);
846 lives_set_cursor_style(LIVES_CURSOR_BUSY, NULL);
847
848 procw->is_ready = TRUE;
849 return procw;
850 }
851
852
create_processing(const char * text)853 xprocess *create_processing(const char *text) {
854 LiVESWidget *dialog_vbox;
855 LiVESWidget *hbox;
856 LiVESWidget *vbox2;
857 LiVESWidget *vbox3;
858
859 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
860
861 xprocess *procw = (xprocess *)(lives_malloc(sizeof(xprocess)));
862
863 char tmp_label[256];
864 boolean markup = widget_opts.use_markup;
865
866 widget_opts.use_markup = FALSE;
867
868 procw->frac_done = -1.;
869
870 procw->processing = lives_standard_dialog_new(_("Processing..."), FALSE, -1, -1);
871
872 lives_window_set_decorated(LIVES_WINDOW(procw->processing), FALSE);
873
874 if (prefs->gui_monitor != 0) {
875 lives_window_set_monitor(LIVES_WINDOW(procw->processing), widget_opts.monitor);
876 }
877
878 lives_window_add_accel_group(LIVES_WINDOW(procw->processing), accel_group);
879
880 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(procw->processing));
881
882 vbox2 = lives_vbox_new(FALSE, 0);
883 lives_box_pack_start(LIVES_BOX(dialog_vbox), vbox2, TRUE, TRUE, 0);
884
885 vbox3 = lives_vbox_new(FALSE, 0);
886 lives_box_pack_start(LIVES_BOX(vbox2), vbox3, TRUE, TRUE, 0);
887
888 widget_opts.use_markup = markup;
889 lives_snprintf(tmp_label, 256, "%s...\n", text);
890 widget_opts.use_markup = FALSE;
891 widget_opts.justify = LIVES_JUSTIFY_CENTER;
892 widget_opts.mnemonic_label = FALSE;
893 procw->label = lives_standard_label_new(tmp_label);
894 widget_opts.mnemonic_label = TRUE;
895 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
896
897 lives_box_pack_start(LIVES_BOX(vbox3), procw->label, TRUE, TRUE, 0);
898
899 procw->progressbar = lives_standard_progress_bar_new();
900
901 lives_box_pack_start(LIVES_BOX(vbox3), procw->progressbar, FALSE, FALSE, 0);
902 if (palette->style & STYLE_1) {
903 lives_widget_set_fg_color(procw->progressbar, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
904 }
905
906 widget_opts.justify = LIVES_JUSTIFY_CENTER;
907 if (mainw->internal_messaging && mainw->rte != 0 && !mainw->transrend_proc) {
908 procw->label2 = lives_standard_label_new(_("\n\nPlease Wait\n\nRemember to switch off effects (ctrl-0) afterwards !"));
909 } else procw->label2 = lives_standard_label_new(_("\nPlease Wait"));
910 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
911
912 lives_box_pack_start(LIVES_BOX(vbox3), procw->label2, FALSE, FALSE, 0);
913
914 widget_opts.justify = LIVES_JUSTIFY_CENTER;
915 #ifdef PROGBAR_IS_ENTRY
916 procw->label3 = procw->progressbar;
917 #else
918 procw->label3 = lives_standard_label_new("");
919 lives_box_pack_start(LIVES_BOX(vbox3), procw->label3, FALSE, FALSE, 0);
920 #endif
921 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
922
923 widget_opts.expand = LIVES_EXPAND_EXTRA;
924 hbox = lives_hbox_new(FALSE, widget_opts.filler_len * 8);
925 add_fill_to_box(LIVES_BOX(hbox));
926 add_fill_to_box(LIVES_BOX(hbox));
927 widget_opts.expand = LIVES_EXPAND_DEFAULT;
928
929 lives_box_pack_start(LIVES_BOX(vbox3), hbox, FALSE, FALSE, 0);
930
931 if (mainw->iochan) {
932 // add "show details" arrow
933 int woat = widget_opts.apply_theme;
934 widget_opts.apply_theme = 0;
935 widget_opts.expand = LIVES_EXPAND_EXTRA;
936 procw->scrolledwindow = lives_standard_scrolled_window_new(ENC_DETAILS_WIN_H, ENC_DETAILS_WIN_V,
937 LIVES_WIDGET(mainw->optextview));
938 widget_opts.expand = LIVES_EXPAND_DEFAULT;
939 widget_opts.apply_theme = woat;
940 lives_standard_expander_new(_("Show Details"), LIVES_BOX(vbox3), procw->scrolledwindow);
941 }
942
943 procw->stop_button = procw->preview_button = procw->pause_button = NULL;
944
945 if (CURRENT_CLIP_IS_VALID) {
946 if (cfile->opening_loc
947 #ifdef ENABLE_JACK
948 || mainw->jackd_read
949 #endif
950 #ifdef HAVE_PULSE_AUDIO
951 || mainw->pulsed_read
952 #endif
953 ) {
954 // the "enough" button for opening
955 procw->stop_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing), NULL, _("_Enough"),
956 LIVES_RESPONSE_ACCEPT); // used only for open location and for audio recording
957 lives_widget_set_can_default(procw->stop_button, TRUE);
958 }
959
960 if (cfile->nokeep) procw->pause_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing),
961 NULL, _("Paus_e"), LIVES_RESPONSE_ACCEPT);
962 else procw->pause_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing), NULL, _("Pause/_Enough"),
963 LIVES_RESPONSE_ACCEPT);
964 lives_widget_set_can_default(procw->pause_button, TRUE);
965
966 procw->preview_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing), NULL, _("_Preview"),
967 LIVES_RESPONSE_SHOW_DETAILS);
968 lives_widget_set_can_default(procw->preview_button, TRUE);
969 }
970
971 procw->cancel_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(procw->processing), LIVES_STOCK_CANCEL, NULL,
972 LIVES_RESPONSE_CANCEL);
973
974 lives_widget_set_can_default(procw->cancel_button, TRUE);
975 lives_button_grab_default_special(procw->cancel_button);
976
977 lives_widget_add_accelerator(procw->cancel_button, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
978 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
979
980 if (procw->stop_button)
981 lives_signal_sync_connect(LIVES_GUI_OBJECT(procw->stop_button), LIVES_WIDGET_CLICKED_SIGNAL,
982 LIVES_GUI_CALLBACK(on_stop_clicked), NULL);
983
984 lives_signal_sync_connect(LIVES_GUI_OBJECT(procw->pause_button), LIVES_WIDGET_CLICKED_SIGNAL,
985 LIVES_GUI_CALLBACK(on_effects_paused), NULL);
986
987 if (mainw->multitrack && mainw->multitrack->is_rendering) {
988 lives_signal_sync_connect(LIVES_GUI_OBJECT(procw->preview_button), LIVES_WIDGET_CLICKED_SIGNAL,
989 LIVES_GUI_CALLBACK(multitrack_preview_clicked), mainw->multitrack);
990 } else {
991 lives_signal_sync_connect(LIVES_GUI_OBJECT(procw->preview_button), LIVES_WIDGET_CLICKED_SIGNAL,
992 LIVES_GUI_CALLBACK(on_preview_clicked), NULL);
993 }
994
995 lives_signal_sync_connect(LIVES_GUI_OBJECT(procw->cancel_button), LIVES_WIDGET_CLICKED_SIGNAL,
996 LIVES_GUI_CALLBACK(on_cancel_keep_button_clicked), NULL);
997
998 if (mainw->show_procd) lives_widget_show_all(procw->processing);
999 if (procw->preview_button) lives_widget_hide(procw->preview_button);
1000 if (procw->pause_button) lives_widget_hide(procw->pause_button);
1001
1002 if (procw->stop_button) lives_widget_hide(procw->stop_button);
1003
1004 return procw;
1005 }
1006
1007
vid_text_view_new(void)1008 static LiVESWidget *vid_text_view_new(void) {
1009 LiVESWidget *textview;
1010 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1011 textview = lives_standard_text_view_new(NULL, NULL);
1012 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1013 lives_widget_set_size_request(textview, TB_WIDTH, TB_HEIGHT_VID);
1014 if (palette->style & STYLE_3) {
1015 lives_widget_set_bg_color(textview, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1016 }
1017 if (mainw->multitrack) {
1018 lives_text_view_set_top_margin(LIVES_TEXT_VIEW(textview), 2);
1019 lives_text_view_set_bottom_margin(LIVES_TEXT_VIEW(textview), 20);
1020 lives_widget_set_valign(textview, LIVES_ALIGN_FILL);
1021 } else {
1022 lives_text_view_set_bottom_margin(LIVES_TEXT_VIEW(textview), TB_HEIGHT_VID >> 2);
1023 lives_text_view_set_top_margin(LIVES_TEXT_VIEW(textview), TB_HEIGHT_VID >> 2);
1024 }
1025 return textview;
1026 }
1027
1028
aud_text_view_new(void)1029 static LiVESWidget *aud_text_view_new(void) {
1030 LiVESWidget *textview;
1031 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1032 textview = lives_standard_text_view_new(NULL, NULL);
1033 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1034 lives_widget_set_size_request(textview, TB_WIDTH, TB_HEIGHT_AUD);
1035 if (palette->style & STYLE_3) {
1036 lives_widget_set_bg_color(textview, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1037 }
1038 if (mainw->multitrack) {
1039 lives_text_view_set_bottom_margin(LIVES_TEXT_VIEW(textview), 20);
1040 } else {
1041 lives_text_view_set_bottom_margin(LIVES_TEXT_VIEW(textview), TB_HEIGHT_AUD >> 2);
1042 lives_text_view_set_top_margin(LIVES_TEXT_VIEW(textview), TB_HEIGHT_AUD >> 2);
1043 }
1044 return textview;
1045 }
1046
1047
create_clip_info_window(int audio_channels,boolean is_mt)1048 lives_clipinfo_t *create_clip_info_window(int audio_channels, boolean is_mt) {
1049 LiVESWidget *dialog_vbox;
1050 LiVESWidget *table;
1051 LiVESWidget *label;
1052 LiVESWidget *vidframe;
1053 LiVESWidget *laudframe;
1054 LiVESWidget *raudframe;
1055 LiVESWidget *okbutton;
1056 LiVESWidget *vbox;
1057 LiVESWidget *hbox;
1058 LiVESWidget *layout;
1059
1060 LiVESAccelGroup *accel_group;
1061
1062 lives_clipinfo_t *filew = (lives_clipinfo_t *)(lives_malloc(sizeof(lives_clipinfo_t)));
1063
1064 char *title;
1065 char *tmp;
1066
1067 int offset = 0;
1068
1069 if (!is_mt)
1070 title = get_menu_name(cfile, TRUE);
1071 else {
1072 offset = 2;
1073 title = (_("Multitrack Details"));
1074 }
1075
1076 filew->dialog = lives_standard_dialog_new(title, FALSE, -1, -1);
1077 lives_free(title);
1078
1079 lives_signal_handlers_disconnect_by_func(filew->dialog, LIVES_GUI_CALLBACK(return_true), NULL);
1080
1081 accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
1082 lives_window_add_accel_group(LIVES_WINDOW(filew->dialog), accel_group);
1083
1084 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(filew->dialog));
1085 lives_container_set_border_width(LIVES_CONTAINER(dialog_vbox), 2);
1086
1087 if (cfile->frames > 0 || is_mt) {
1088 vidframe = lives_standard_frame_new(_("Video"), 0., FALSE);
1089
1090 lives_box_pack_start(LIVES_BOX(dialog_vbox), vidframe, TRUE, TRUE, 0);
1091
1092 vbox = lives_vbox_new(FALSE, 0);
1093 lives_container_add(LIVES_CONTAINER(vidframe), vbox);
1094 lives_container_set_border_width(LIVES_CONTAINER(vbox), widget_opts.border_width);
1095
1096 layout = lives_layout_new(LIVES_BOX(vbox));
1097
1098 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("Format"), TRUE);
1099 if (palette->style & STYLE_3) {
1100 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1101 }
1102
1103 filew->textview_type = vid_text_view_new();
1104 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1105 lives_layout_pack(LIVES_HBOX(hbox), filew->textview_type);
1106 lives_widget_set_valign(filew->textview_type, LIVES_ALIGN_FILL);
1107
1108 widget_opts.expand |= LIVES_EXPAND_EXTRA_WIDTH;
1109 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1110 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1111
1112 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("FPS"), TRUE);
1113 if (palette->style & STYLE_3) {
1114 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1115 }
1116
1117 filew->textview_fps = vid_text_view_new();
1118 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1119 lives_layout_pack(LIVES_HBOX(hbox), filew->textview_fps);
1120
1121 lives_layout_add_row(LIVES_LAYOUT(layout));
1122
1123 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("Frame Size"), TRUE);
1124 if (palette->style & STYLE_3) {
1125 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1126 }
1127
1128 filew->textview_size = vid_text_view_new();
1129 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1130 lives_layout_pack(LIVES_HBOX(hbox), filew->textview_size);
1131
1132 widget_opts.expand |= LIVES_EXPAND_EXTRA_WIDTH;
1133 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1134 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1135
1136 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("Frames"), TRUE);
1137 if (palette->style & STYLE_3) {
1138 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1139 }
1140
1141 filew->textview_frames = vid_text_view_new();
1142 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1143 lives_layout_pack(LIVES_HBOX(hbox), filew->textview_frames);
1144 lives_widget_set_valign(filew->textview_frames, LIVES_ALIGN_FILL);
1145
1146 lives_layout_add_row(LIVES_LAYOUT(layout));
1147
1148 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("File Size"), TRUE);
1149 if (palette->style & STYLE_3) {
1150 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1151 }
1152
1153 filew->textview_fsize = vid_text_view_new();
1154 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1155 lives_layout_pack(LIVES_HBOX(hbox), filew->textview_fsize);
1156
1157 widget_opts.expand |= LIVES_EXPAND_EXTRA_WIDTH;
1158 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1159 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1160
1161 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("Total Time"), TRUE);
1162 if (palette->style & STYLE_3) {
1163 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1164 }
1165
1166 filew->textview_vtime = vid_text_view_new();
1167 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1168 lives_layout_pack(LIVES_HBOX(hbox), filew->textview_vtime);
1169 if (mainw->multitrack) lives_text_view_set_top_margin(LIVES_TEXT_VIEW(filew->textview_vtime), 10);
1170 }
1171
1172 if (audio_channels > 0) {
1173 if (audio_channels > 1) tmp = get_achannel_name(2, 0);
1174 else tmp = (_("Audio"));
1175
1176 laudframe = lives_standard_frame_new(tmp, 0., FALSE);
1177 lives_free(tmp);
1178
1179 lives_box_pack_start(LIVES_BOX(dialog_vbox), laudframe, TRUE, TRUE, 0);
1180
1181 table = lives_table_new(1, 4, TRUE);
1182
1183 lives_table_set_col_spacings(LIVES_TABLE(table), widget_opts.packing_width * 4);
1184 lives_table_set_row_spacings(LIVES_TABLE(table), widget_opts.packing_height);
1185 lives_container_set_border_width(LIVES_CONTAINER(table), widget_opts.border_width);
1186
1187 lives_container_add(LIVES_CONTAINER(laudframe), table);
1188
1189 label = lives_standard_label_new(_("Rate/size"));
1190 if (palette->style & STYLE_3) {
1191 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1192 }
1193 lives_label_set_hpadding(LIVES_LABEL(label), 4);
1194 lives_table_attach(LIVES_TABLE(table), label, 0 + offset, 1 + offset, 0, 1,
1195 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1196
1197 filew->textview_lrate = aud_text_view_new();
1198 lives_table_attach(LIVES_TABLE(table), filew->textview_lrate, 1 + offset, 2 + offset, 0, 1,
1199 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1200 lives_widget_set_valign(filew->textview_lrate, LIVES_ALIGN_FILL);
1201
1202 if (!is_mt) {
1203 label = lives_standard_label_new(_("Total time"));
1204 if (palette->style & STYLE_3) {
1205 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1206 }
1207 lives_table_attach(LIVES_TABLE(table), label, 2, 3, 0, 1,
1208 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1209
1210 filew->textview_ltime = aud_text_view_new();
1211 lives_table_attach(LIVES_TABLE(table), filew->textview_ltime, 3, 4, 0, 1,
1212 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1213 }
1214 }
1215
1216 if (audio_channels > 1) {
1217 tmp = get_achannel_name(2, 1);
1218 raudframe = lives_standard_frame_new(tmp, 0., FALSE);
1219 lives_free(tmp);
1220
1221 lives_box_pack_start(LIVES_BOX(dialog_vbox), raudframe, TRUE, TRUE, 0);
1222
1223 table = lives_table_new(1, 4, TRUE);
1224
1225 lives_table_set_col_spacings(LIVES_TABLE(table), widget_opts.packing_width * 4);
1226 lives_table_set_row_spacings(LIVES_TABLE(table), widget_opts.packing_height);
1227 lives_container_set_border_width(LIVES_CONTAINER(table), widget_opts.border_width);
1228
1229 lives_container_add(LIVES_CONTAINER(raudframe), table);
1230
1231
1232 label = lives_standard_label_new(_("Rate/size"));
1233 if (palette->style & STYLE_3) {
1234 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1235 }
1236 lives_label_set_hpadding(LIVES_LABEL(label), 4);
1237 lives_table_attach(LIVES_TABLE(table), label, 0 + offset, 1 + offset, 0, 1,
1238 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1239
1240 filew->textview_rrate = aud_text_view_new();
1241 lives_table_attach(LIVES_TABLE(table), filew->textview_rrate, 1 + offset, 2 + offset, 0, 1,
1242 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1243 lives_widget_set_valign(filew->textview_rrate, LIVES_ALIGN_FILL);
1244
1245 if (!is_mt) {
1246 label = lives_standard_label_new(_("Total time"));
1247 if (palette->style & STYLE_3) {
1248 lives_widget_set_bg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
1249 }
1250 lives_label_set_hpadding(LIVES_LABEL(label), 4);
1251 lives_table_attach(LIVES_TABLE(table), label, 2, 3, 0, 1,
1252 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1253
1254 filew->textview_rtime = aud_text_view_new();
1255 lives_table_attach(LIVES_TABLE(table), filew->textview_rtime, 3, 4, 0, 1,
1256 (LiVESAttachOptions)(0), (LiVESAttachOptions)(0), 0, 0);
1257 }
1258 }
1259
1260 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(filew->dialog), LIVES_STOCK_CLOSE, _("_Close Window"),
1261 LIVES_RESPONSE_OK);
1262 lives_button_grab_default_special(okbutton);
1263
1264 lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
1265 LIVES_GUI_CALLBACK(lives_general_button_clicked), filew);
1266
1267 accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
1268 lives_window_add_accel_group(LIVES_WINDOW(filew->dialog), accel_group);
1269
1270 lives_widget_add_accelerator(okbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
1271 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
1272
1273 lives_widget_show_all(filew->dialog);
1274
1275 return filew;
1276 }
1277
1278
on_resizecb_toggled(LiVESToggleButton * t,livespointer user_data)1279 static void on_resizecb_toggled(LiVESToggleButton *t, livespointer user_data) {
1280 LiVESWidget *cb = (LiVESWidget *)user_data;
1281
1282 if (!lives_toggle_button_get_active(t)) {
1283 lives_widget_set_sensitive(cb, FALSE);
1284 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(cb), FALSE);
1285 } else {
1286 lives_widget_set_sensitive(cb, TRUE);
1287 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(cb), prefs->enc_letterbox);
1288 }
1289 }
1290
1291
create_encoder_prep_dialog(const char * text1,const char * text2,boolean opt_resize)1292 LiVESWidget *create_encoder_prep_dialog(const char *text1, const char *text2, boolean opt_resize) {
1293 LiVESWidget *dialog;
1294 LiVESWidget *dialog_vbox;
1295 LiVESWidget *okbutton;
1296 LiVESWidget *checkbutton = NULL;
1297 LiVESWidget *checkbutton2;
1298 LiVESWidget *label;
1299 LiVESWidget *hbox;
1300
1301 char *labeltext, *tmp, *tmp2;
1302
1303 dialog = create_question_dialog(_("Encoding Options"), text1);
1304 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
1305
1306 if (opt_resize) {
1307 if (text2) labeltext = (_("<------------- (Check the box to re_size as suggested)"));
1308 else labeltext = (_("<------------- (Check the box to use the _size recommendation)"));
1309
1310 hbox = lives_hbox_new(FALSE, 0);
1311 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_width);
1312
1313 checkbutton = lives_standard_check_button_new(labeltext, FALSE, LIVES_BOX(hbox), NULL);
1314
1315 lives_free(labeltext);
1316
1317 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
1318 LIVES_GUI_CALLBACK(on_boolean_toggled),
1319 &mainw->fx1_bool);
1320 } else if (!text2) mainw->fx1_bool = TRUE;
1321
1322 if (text2 && (mainw->fx1_bool || opt_resize)) {
1323 hbox = lives_hbox_new(FALSE, 0);
1324 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
1325
1326 checkbutton2 = lives_standard_check_button_new
1327 ((tmp = (_("Use _letterboxing to maintain aspect ratio (optional)"))), FALSE, LIVES_BOX(hbox),
1328 (tmp2 = (H_("Draw black rectangles either above or to the sides of the image, "
1329 "to prevent it from stretching."))));
1330
1331 lives_free(tmp); lives_free(tmp2);
1332
1333 if (opt_resize) {
1334 lives_widget_set_sensitive(checkbutton2, FALSE);
1335 } else lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(checkbutton2), prefs->enc_letterbox);
1336
1337 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton2), LIVES_WIDGET_TOGGLED_SIGNAL,
1338 LIVES_GUI_CALLBACK(on_boolean_toggled), &prefs->enc_letterbox);
1339
1340 if (opt_resize)
1341 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
1342 LIVES_GUI_CALLBACK(on_resizecb_toggled), checkbutton2);
1343 }
1344
1345 if (text2) {
1346 label = lives_standard_label_new(text2);
1347 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, TRUE, TRUE, 0);
1348 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
1349 LIVES_RESPONSE_CANCEL);
1350 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
1351 LIVES_RESPONSE_OK);
1352 } else {
1353 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
1354 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), NULL, _("Keep _my settings"),
1355 LIVES_RESPONSE_CANCEL);
1356 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), NULL, _("Use _recommended settings"),
1357 LIVES_RESPONSE_OK);
1358 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1359 }
1360
1361 lives_button_grab_default_special(okbutton);
1362
1363 lives_widget_show_all(dialog);
1364 return dialog;
1365 }
1366
1367
scrolled_textview(const char * text,LiVESTextBuffer * textbuffer,int window_width,LiVESWidget ** ptextview)1368 LiVESWidget *scrolled_textview(const char *text, LiVESTextBuffer *textbuffer, int window_width,
1369 LiVESWidget **ptextview) {
1370 LiVESWidget *scrolledwindow = NULL;
1371 LiVESWidget *textview = lives_standard_text_view_new(text, textbuffer);
1372 if (textview) {
1373 int woex = widget_opts.expand;
1374 int height = RFX_WINSIZE_V;
1375 if (!LIVES_SHOULD_EXPAND_HEIGHT) height >>= 1;
1376 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
1377 scrolledwindow = lives_standard_scrolled_window_new(window_width, height, textview);
1378 widget_opts.expand = woex;
1379 lives_container_set_border_width(LIVES_CONTAINER(scrolledwindow), widget_opts.border_width);
1380 if (palette->style & STYLE_1) {
1381 lives_widget_set_bg_color(lives_bin_get_child(LIVES_BIN(scrolledwindow)),
1382 LIVES_WIDGET_STATE_NORMAL, &palette->info_base);
1383 }
1384 }
1385 if (ptextview) *ptextview = textview;
1386 return scrolledwindow;
1387 }
1388
1389
create_text_window(const char * title,const char * text,LiVESTextBuffer * textbuffer,boolean add_buttons)1390 text_window *create_text_window(const char *title, const char *text, LiVESTextBuffer *textbuffer,
1391 boolean add_buttons) {
1392 // general text window
1393 LiVESWidget *dialog_vbox;
1394 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
1395
1396 int woat;
1397 int window_width = RFX_WINSIZE_H;
1398
1399 textwindow = (text_window *)lives_malloc(sizeof(text_window));
1400
1401 if (LIVES_SHOULD_EXPAND_EXTRA_WIDTH) window_width
1402 = RFX_WINSIZE_H * 1.5 * widget_opts.scale;
1403
1404 textwindow->dialog = lives_standard_dialog_new(title, FALSE, window_width,
1405 LIVES_SHOULD_EXPAND_HEIGHT ? DEF_DIALOG_HEIGHT
1406 : DEF_DIALOG_HEIGHT >> 1);
1407 lives_window_add_accel_group(LIVES_WINDOW(textwindow->dialog), accel_group);
1408
1409 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(textwindow->dialog));
1410 textwindow->vbox = lives_vbox_new(FALSE, 0);
1411 lives_box_pack_start(LIVES_BOX(dialog_vbox), textwindow->vbox, TRUE, TRUE, 0);
1412
1413 textwindow->textview = textwindow->table = NULL;
1414
1415 woat = widget_opts.apply_theme;
1416 widget_opts.apply_theme = 0;
1417 if (textbuffer || text)
1418 textwindow->scrolledwindow = scrolled_textview(text, textbuffer, window_width, &textwindow->textview);
1419 else {
1420 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH;
1421 textwindow->table = lives_standard_table_new(1, 1, FALSE);
1422 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1423 textwindow->scrolledwindow = lives_standard_scrolled_window_new(window_width, RFX_WINSIZE_V, textwindow->table);
1424 }
1425 widget_opts.apply_theme = woat;
1426
1427 lives_box_pack_start(LIVES_BOX(textwindow->vbox), textwindow->scrolledwindow, TRUE, TRUE, 0);
1428
1429 if (add_buttons && (text || mainw->iochan || textwindow->table)) {
1430 if (!textwindow->table) {
1431 LiVESWidget *savebutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(textwindow->dialog),
1432 LIVES_STOCK_SAVE, _("_Save to file"), LIVES_RESPONSE_YES);
1433 lives_signal_sync_connect(LIVES_GUI_OBJECT(savebutton), LIVES_WIDGET_CLICKED_SIGNAL,
1434 LIVES_GUI_CALLBACK(on_save_textview_clicked), textwindow->textview);
1435 }
1436
1437 textwindow->button = lives_dialog_add_button_from_stock(LIVES_DIALOG(textwindow->dialog),
1438 LIVES_STOCK_CLOSE, _("_Close Window"), LIVES_RESPONSE_CANCEL);
1439
1440 lives_button_grab_default_special(textwindow->button);
1441
1442 lives_signal_sync_connect(LIVES_GUI_OBJECT(textwindow->button), LIVES_WIDGET_CLICKED_SIGNAL,
1443 LIVES_GUI_CALLBACK(lives_general_button_clicked), textwindow);
1444
1445 lives_widget_add_accelerator(textwindow->button, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
1446 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
1447 lives_widget_add_accelerator(textwindow->button, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
1448 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
1449 }
1450
1451 if (prefs->show_gui)
1452 lives_widget_show_all(textwindow->dialog);
1453
1454 return textwindow;
1455 }
1456
1457
create_insert_dialog(void)1458 _insertw *create_insert_dialog(void) {
1459 LiVESWidget *dialog_vbox;
1460 LiVESWidget *hbox1;
1461 LiVESWidget *hbox;
1462 LiVESWidget *table;
1463 LiVESWidget *radiobutton;
1464 LiVESWidget *vseparator;
1465 LiVESWidget *cancelbutton;
1466 LiVESWidget *okbutton;
1467 LiVESWidget *label;
1468
1469 LiVESSList *radiobutton1_group = NULL;
1470 LiVESSList *radiobutton2_group = NULL;
1471
1472 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
1473
1474 char *tmp, *tmp2;
1475
1476 _insertw *insertw = (_insertw *)(lives_malloc(sizeof(_insertw)));
1477
1478 insertw->insert_dialog = lives_standard_dialog_new(_("Insert"), FALSE, -1, -1);
1479 lives_signal_handlers_disconnect_by_func(insertw->insert_dialog, LIVES_GUI_CALLBACK(return_true),
1480 NULL);
1481
1482 lives_window_add_accel_group(LIVES_WINDOW(insertw->insert_dialog), accel_group);
1483
1484 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(insertw->insert_dialog));
1485
1486 hbox1 = lives_hbox_new(FALSE, 0);
1487
1488 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox1, TRUE, TRUE, widget_opts.packing_height);
1489
1490 hbox = lives_hbox_new(FALSE, 0);
1491 lives_box_pack_start(LIVES_BOX(hbox1), hbox, FALSE, FALSE, widget_opts.packing_width);
1492
1493 insertw->spinbutton_times = lives_standard_spin_button_new(_("_Number of times to insert"),
1494 1., 1., 10000., 1., 10., 0., LIVES_BOX(hbox), NULL);
1495
1496 lives_widget_grab_focus(insertw->spinbutton_times);
1497
1498 add_fill_to_box(LIVES_BOX(hbox1));
1499
1500 hbox = lives_hbox_new(FALSE, 0);
1501
1502 lives_box_pack_start(LIVES_BOX(hbox1), hbox, FALSE, FALSE, widget_opts.packing_width);
1503
1504 if (cfile->frames == 0)
1505 insertw->fit_checkbutton = lives_standard_check_button_new(_("_Insert to fit audio"), mainw->fx1_bool, LIVES_BOX(hbox), NULL);
1506 else
1507 insertw->fit_checkbutton = lives_standard_check_button_new(_("_Insert from selection end to audio end"),
1508 mainw->fx1_bool, LIVES_BOX(hbox), NULL);
1509 label = widget_opts.last_label;
1510 add_hsep_to_box(LIVES_BOX(dialog_vbox));
1511
1512 table = lives_table_new(2, 3, FALSE);
1513 lives_box_pack_start(LIVES_BOX(dialog_vbox), table, TRUE, TRUE, widget_opts.packing_height);
1514 lives_table_set_col_spacings(LIVES_TABLE(table), widget_opts.packing_width * 4);
1515 lives_table_set_row_spacings(LIVES_TABLE(table), widget_opts.packing_height * 2);
1516
1517 hbox = lives_hbox_new(FALSE, 0);
1518
1519 radiobutton = lives_standard_radio_button_new((tmp = (_("Insert _before selection"))),
1520 &radiobutton1_group, LIVES_BOX(hbox),
1521 (tmp2 = (_("Insert clipboard before selected frames"))));
1522
1523 lives_free(tmp);
1524 lives_free(tmp2);
1525
1526 lives_table_attach(LIVES_TABLE(table), hbox, 0, 1, 0, 1,
1527 (LiVESAttachOptions)(LIVES_FILL),
1528 (LiVESAttachOptions)(0), 0, 0);
1529
1530 if (cfile->frames == 0) lives_widget_set_sensitive(radiobutton, FALSE);
1531
1532 toggle_sets_sensitive_cond(LIVES_TOGGLE_BUTTON(insertw->fit_checkbutton), radiobutton, &cfile->frames, NULL, TRUE);
1533
1534 hbox = lives_hbox_new(FALSE, 0);
1535
1536 radiobutton = lives_standard_radio_button_new((tmp = (_("Insert _after selection"))),
1537 &radiobutton1_group, LIVES_BOX(hbox),
1538 (tmp2 = (_("Insert clipboard after selected frames"))));
1539
1540 lives_table_attach(LIVES_TABLE(table), hbox, 0, 1, 1, 2,
1541 (LiVESAttachOptions)(LIVES_FILL),
1542 (LiVESAttachOptions)(0), 0, 0);
1543
1544 toggle_sets_sensitive(LIVES_TOGGLE_BUTTON(radiobutton), insertw->fit_checkbutton, FALSE);
1545 toggle_sets_sensitive(LIVES_TOGGLE_BUTTON(insertw->fit_checkbutton), radiobutton, TRUE);
1546 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton), mainw->insert_after);
1547
1548 hbox = lives_hbox_new(FALSE, 0);
1549
1550 if (clipboard->achans == 0)
1551 insertw->with_sound = lives_standard_radio_button_new(_("Insert _with silence"),
1552 &radiobutton2_group, LIVES_BOX(hbox), NULL);
1553 else
1554 insertw->with_sound = lives_standard_radio_button_new(_("Insert _with sound"),
1555 &radiobutton2_group, LIVES_BOX(hbox), NULL);
1556
1557 lives_table_attach(LIVES_TABLE(table), hbox, 2, 3, 0, 1,
1558 (LiVESAttachOptions)(LIVES_FILL),
1559 (LiVESAttachOptions)(0), 0, 0);
1560
1561 hbox = lives_hbox_new(FALSE, 0);
1562
1563 insertw->without_sound = lives_standard_radio_button_new(_("Insert with_out sound"),
1564 &radiobutton2_group, LIVES_BOX(hbox), NULL);
1565
1566 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(insertw->with_sound),
1567 (cfile->achans > 0 || clipboard->achans > 0) && mainw->ccpd_with_sound);
1568
1569 lives_table_attach(LIVES_TABLE(table), hbox, 2, 3, 1, 2,
1570 (LiVESAttachOptions)(LIVES_FILL),
1571 (LiVESAttachOptions)(0), 0, 0);
1572
1573 vseparator = lives_vseparator_new();
1574 lives_table_attach(LIVES_TABLE(table), vseparator, 1, 2, 0, 1,
1575 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
1576 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
1577
1578 vseparator = lives_vseparator_new();
1579 lives_table_attach(LIVES_TABLE(table), vseparator, 1, 2, 1, 2,
1580 (LiVESAttachOptions)(LIVES_FILL),
1581 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
1582
1583 add_fill_to_box(LIVES_BOX(dialog_vbox));
1584
1585 if (cfile->achans == 0 || (double)cfile->end / cfile->fps >= cfile->laudio_time - 0.0001) {
1586 lives_widget_set_no_show_all(insertw->fit_checkbutton, TRUE);
1587 lives_widget_set_no_show_all(label, TRUE);
1588 } else {
1589 toggle_toggles_var(LIVES_TOGGLE_BUTTON(insertw->fit_checkbutton), &mainw->fx1_bool, FALSE);
1590 toggle_sets_sensitive(LIVES_TOGGLE_BUTTON(insertw->fit_checkbutton), insertw->spinbutton_times, TRUE);
1591 toggle_sets_sensitive(LIVES_TOGGLE_BUTTON(insertw->fit_checkbutton), insertw->with_sound, TRUE);
1592 toggle_sets_sensitive(LIVES_TOGGLE_BUTTON(insertw->fit_checkbutton), insertw->without_sound, TRUE);
1593 }
1594
1595 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(insertw->insert_dialog), LIVES_STOCK_CANCEL, NULL,
1596 LIVES_RESPONSE_CANCEL);
1597 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(insertw->insert_dialog), LIVES_STOCK_OK, NULL,
1598 LIVES_RESPONSE_OK);
1599
1600 lives_button_grab_default_special(okbutton);
1601
1602 lives_signal_sync_connect(LIVES_GUI_OBJECT(insertw->with_sound), LIVES_WIDGET_TOGGLED_SIGNAL,
1603 LIVES_GUI_CALLBACK(on_insertwsound_toggled), NULL);
1604 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton), LIVES_WIDGET_TOGGLED_SIGNAL,
1605 LIVES_GUI_CALLBACK(on_boolean_toggled), &mainw->insert_after);
1606 lives_signal_sync_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
1607 LIVES_GUI_CALLBACK(lives_general_button_clicked), insertw);
1608 lives_signal_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
1609 LIVES_GUI_CALLBACK(on_insert_activate), NULL);
1610 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(insertw->spinbutton_times), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
1611 LIVES_GUI_CALLBACK(on_spin_value_changed), LIVES_INT_TO_POINTER(1));
1612
1613 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
1614 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
1615
1616 lives_widget_show_all(insertw->insert_dialog);
1617
1618 return insertw;
1619 }
1620
1621
trash_rb(LiVESButtonBox * parent)1622 LiVESWidget *trash_rb(LiVESButtonBox *parent) {
1623 /// parent should be a bbox
1624 LiVESWidget *rb = NULL;
1625
1626 if (check_for_executable(&capable->has_gio, EXEC_GIO)) {
1627 LiVESSList *rb_group = NULL;
1628 LiVESWidget *vbox, *hbox;
1629 char *tmp, *tmp2;
1630
1631 hbox = lives_hbox_new(FALSE, 0);
1632 vbox = lives_vbox_new(FALSE, 0);
1633 lives_box_pack_start(LIVES_BOX(hbox), vbox, FALSE, FALSE, widget_opts.packing_width);
1634
1635 widget_opts.expand = LIVES_EXPAND_DEFAULT_WIDTH;
1636 rb = lives_standard_radio_button_new((tmp = (_("Send to Trash"))), &rb_group,
1637 LIVES_BOX(vbox), (tmp2 = (H_("Send deleted items to filesystem Trash\n"
1638 "instead of erasing them permanently"))));
1639 lives_free(tmp); lives_free(tmp2);
1640
1641 rb = lives_standard_radio_button_new((tmp = (_("Delete"))), &rb_group, LIVES_BOX(vbox),
1642 (tmp2 = (H_("Permanently erase items from the disk"))));
1643
1644 lives_free(tmp); lives_free(tmp2);
1645 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1646
1647 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(rb), !prefs->pref_trash);
1648
1649 lives_signal_sync_connect(LIVES_GUI_OBJECT(rb), LIVES_WIDGET_ACTIVATE_SIGNAL,
1650 LIVES_GUI_CALLBACK(toggle_sets_pref), PREF_PREF_TRASH);
1651
1652 lives_box_pack_start(LIVES_BOX(parent), hbox, FALSE, FALSE, 0);
1653 lives_button_box_make_first(LIVES_BUTTON_BOX(parent), hbox);
1654 }
1655 return rb;
1656 }
1657
1658 static LiVESResponseType filtresp;
1659 static char *rec_text = NULL, *rem_text = NULL, *leave_text = NULL;
1660
filt_cb_toggled(LiVESWidget * cb,lives_file_dets_t * filedets)1661 static void filt_cb_toggled(LiVESWidget *cb, lives_file_dets_t *filedets) {
1662 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(cb))) {
1663 if (filedets->widgets[1]) {
1664 lives_widget_set_sensitive(filedets->widgets[1], TRUE);
1665 if (lives_toggle_button_get_active(filedets->widgets[1]))
1666 lives_label_set_text(LIVES_LABEL(filedets->widgets[8]), rec_text);
1667 else
1668 lives_label_set_text(LIVES_LABEL(filedets->widgets[8]), rem_text);
1669 } else
1670 lives_label_set_text(LIVES_LABEL(filedets->widgets[8]), rem_text);
1671 } else {
1672 if (filedets->widgets[1]) {
1673 lives_widget_set_sensitive(filedets->widgets[1], FALSE);
1674 }
1675 lives_label_set_text(LIVES_LABEL(filedets->widgets[8]), leave_text);
1676 }
1677 }
1678
filt_sw_toggled(LiVESWidget * sw,lives_file_dets_t * filedets)1679 static void filt_sw_toggled(LiVESWidget *sw, lives_file_dets_t *filedets) {
1680 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(sw)))
1681 lives_label_set_text(LIVES_LABEL(filedets->widgets[8]), rec_text);
1682 else
1683 lives_label_set_text(LIVES_LABEL(filedets->widgets[8]), rem_text);
1684 }
1685
filt_all_toggled(LiVESWidget * cb,LiVESList * list)1686 static void filt_all_toggled(LiVESWidget *cb, LiVESList *list) {
1687 lives_file_dets_t *filedets;
1688 boolean act = lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(cb));
1689 for (; list && list->data; list = list->next) {
1690 filedets = (lives_file_dets_t *)(list->data);
1691 lives_toggle_button_set_active(filedets->widgets[0], act);
1692 }
1693 }
1694
filt_reset_clicked(LiVESWidget * layout,LiVESWidget * rbut)1695 static void filt_reset_clicked(LiVESWidget *layout, LiVESWidget *rbut) {
1696 LiVESList *list, *xlist;
1697 LiVESWidget *cb =
1698 (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(layout), "cb");
1699 int ptype;
1700 lives_file_dets_t *filedets;
1701
1702 if (!cb) return;
1703
1704 ptype = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(layout), "ptype"));
1705 xlist = list = (LiVESList *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(layout), "list");
1706
1707 switch (ptype) {
1708 case 0:
1709 for (; xlist && xlist->data; xlist = xlist->next) {
1710 filedets = (lives_file_dets_t *)(xlist->data);
1711 lives_toggle_button_set_active(filedets->widgets[1], TRUE);
1712 }
1713 // fall through
1714 case 1:
1715 if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(cb)))
1716 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(cb), TRUE);
1717 else
1718 filt_all_toggled(cb, list);
1719 break;
1720 case 2:
1721 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(cb)))
1722 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(cb), FALSE);
1723 else
1724 filt_all_toggled(cb, list);
1725 break;
1726 default: break;
1727 }
1728 }
1729
filtc_response(LiVESWidget * w,LiVESResponseType resp,livespointer data)1730 static boolean filtc_response(LiVESWidget *w, LiVESResponseType resp, livespointer data) {
1731 filtresp = resp;
1732 return TRUE;
1733 }
1734
1735 #define NMLEN_MAX 33
fill_filt_section(LiVESList ** listp,int pass,int type,LiVESWidget * layout)1736 static boolean fill_filt_section(LiVESList **listp, int pass, int type, LiVESWidget *layout) {
1737 LiVESList *list = (LiVESList *)*listp;
1738 lives_file_dets_t *filedets;
1739 LiVESWidget *dialog = NULL;
1740 LiVESWidget *hbox;
1741 LiVESWidget *cb = NULL;
1742
1743 char *txt, *dtxt;
1744 boolean needs_recheck = FALSE;
1745
1746 if (!pass) widget_opts.mnemonic_label = FALSE;
1747
1748 if (!list->data) {
1749 if (!pass) {
1750 txt = lives_strdup_printf(" - %s - ",
1751 mainw->string_constants[LIVES_STRING_CONSTANT_NONE]);
1752 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
1753 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1754 lives_layout_add_label(LIVES_LAYOUT(layout), txt, FALSE);
1755 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;;
1756 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1757 lives_free(txt);
1758 widget_opts.mnemonic_label = TRUE;
1759 }
1760 return FALSE;
1761 }
1762 if (!pass) {
1763 int woat = widget_opts.apply_theme;
1764 int woph = widget_opts.packing_height;
1765
1766 if (!rec_text) rec_text = (_("Recover"));
1767 if (!rem_text) rem_text = (_("Delete"));
1768 if (!leave_text) leave_text = (_("Leave"));
1769
1770 dialog = lives_widget_get_toplevel(layout);
1771
1772 widget_opts.apply_theme = 2;
1773 hbox = lives_layout_row_new(LIVES_LAYOUT(layout));
1774
1775 //widget_opts.expand = LIVES_EXPAND_NONE;
1776
1777 // do this to counter effect of setting margin
1778 widget_opts.packing_height = 0;
1779 cb = lives_standard_check_button_new(_("All"), type != 2, LIVES_BOX(hbox), NULL);
1780 widget_opts.packing_height = woph;
1781 lives_widget_set_margin(cb, widget_opts.border_width >> 1);
1782 lives_box_set_child_packing(LIVES_BOX(hbox), cb, FALSE, FALSE, widget_opts.packing_width >> 1,
1783 LIVES_PACK_START);
1784
1785 lives_widget_set_sensitive(cb, FALSE);
1786 //set_child_alt_colour(hbox, FALSE);
1787 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout), "cb", (livespointer)cb);
1788
1789 if (!type) {
1790 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1791 lives_layout_add_label(LIVES_LAYOUT(layout), _("Action"), TRUE);
1792 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1793 }
1794
1795 lives_layout_add_label(LIVES_LAYOUT(layout), _("Name"), TRUE);
1796 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1797 lives_layout_add_label(LIVES_LAYOUT(layout), _("Size"), TRUE);
1798 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1799 lives_layout_add_label(LIVES_LAYOUT(layout), _("Modified Date"), TRUE);
1800 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1801 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
1802 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1803 lives_layout_add_label(LIVES_LAYOUT(layout), _("Details"), TRUE);
1804 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1805 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1806 widget_opts.apply_theme = woat;
1807 lives_layout_add_separator(LIVES_LAYOUT(layout), FALSE);
1808 }
1809
1810 while (list->data) {
1811 // put from recover subdir
1812 filedets = (lives_file_dets_t *)(list->data);
1813 if (!pass) {
1814 hbox = lives_layout_row_new(LIVES_LAYOUT(layout));
1815
1816 filedets->widgets[0] = lives_standard_check_button_new("", type != 2, LIVES_BOX(hbox), NULL);
1817 filedets->widgets[8] = widget_opts.last_label;
1818
1819 if (!type) {
1820 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1821 filedets->widgets[1] = lives_standard_switch_new(NULL, TRUE, LIVES_BOX(hbox), NULL);
1822 lives_signal_sync_connect(LIVES_GUI_OBJECT(filedets->widgets[1]), LIVES_WIDGET_TOGGLED_SIGNAL,
1823 LIVES_GUI_CALLBACK(filt_sw_toggled), (livespointer)filedets);
1824 } else filedets->widgets[1] = NULL;
1825
1826 lives_signal_sync_connect(LIVES_GUI_OBJECT(filedets->widgets[0]), LIVES_WIDGET_TOGGLED_SIGNAL,
1827 LIVES_GUI_CALLBACK(filt_cb_toggled), (livespointer)filedets);
1828
1829 filt_cb_toggled(filedets->widgets[0], filedets);
1830
1831 txt = lives_pad_ellipsize(filedets->name, NMLEN_MAX, LIVES_ALIGN_START, LIVES_ELLIPSIZE_MIDDLE);
1832 lives_layout_add_label(LIVES_LAYOUT(layout), txt, TRUE);
1833 if (txt != filedets->name) {
1834 lives_free(txt);
1835 lives_widget_set_tooltip_text(widget_opts.last_label, filedets->name);
1836 }
1837 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1838 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1839
1840 filedets->widgets[2] = lives_standard_label_new(NULL);
1841 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[2]);
1842 lives_widget_hide(filedets->widgets[2]);
1843 lives_widget_set_no_show_all(filedets->widgets[2], TRUE);
1844
1845 if (filedets->size == -1) {
1846 filedets->widgets[3] = lives_spinner_new();
1847 if (filedets->widgets[3]) {
1848 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[3]);
1849 lives_spinner_start(LIVES_SPINNER(filedets->widgets[3]));
1850 } else filedets->widgets[3] = filedets->widgets[2];
1851 } else filedets->widgets[3] = filedets->widgets[2];
1852 }
1853
1854 if (filedets->widgets[3]) {
1855 if (filedets->size != -1) {
1856 if (filedets->widgets[3] != filedets->widgets[2]) {
1857 lives_spinner_stop(LIVES_SPINNER(filedets->widgets[3]));
1858 lives_widget_hide(filedets->widgets[3]);
1859 lives_widget_set_no_show_all(filedets->widgets[3], TRUE);
1860 }
1861 lives_widget_set_no_show_all(filedets->widgets[2], FALSE);
1862 lives_widget_show_all(filedets->widgets[2]);
1863
1864 if (filedets->size == -2) {
1865 lives_label_set_text(LIVES_LABEL(filedets->widgets[2]), "????");
1866 }
1867 if (filedets->size > 0) {
1868 txt = lives_format_storage_space_string(filedets->size);
1869 lives_label_set_text(LIVES_LABEL(filedets->widgets[2]), txt);
1870 lives_free(txt);
1871 }
1872 filedets->widgets[3] = NULL;
1873 } else needs_recheck = TRUE;
1874 }
1875
1876 if (!pass) {
1877 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1878 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1879 filedets->widgets[4] = lives_standard_label_new(NULL);
1880 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[4]);
1881 lives_widget_hide(filedets->widgets[4]);
1882 lives_widget_set_no_show_all(filedets->widgets[4], TRUE);
1883
1884 if (!filedets->extra_details) {
1885 filedets->widgets[5] = lives_spinner_new();
1886 if (filedets->widgets[5]) {
1887 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[5]);
1888 lives_spinner_start(LIVES_SPINNER(filedets->widgets[5]));
1889 } else filedets->widgets[5] = filedets->widgets[4];
1890 } else filedets->widgets[5] = filedets->widgets[4];
1891
1892 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
1893 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1894 filedets->widgets[6] = lives_standard_label_new(NULL);
1895 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[6]);
1896 lives_widget_hide(filedets->widgets[6]);
1897 lives_widget_set_no_show_all(filedets->widgets[6], TRUE);
1898
1899 if (!filedets->extra_details) {
1900 filedets->widgets[7] = lives_spinner_new();
1901 if (filedets->widgets[7]) {
1902 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1903 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
1904 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[7]);
1905 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1906 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1907 lives_spinner_start(LIVES_SPINNER(filedets->widgets[7]));
1908 } else filedets->widgets[7] = filedets->widgets[6];
1909 } else filedets->widgets[7] = filedets->widgets[6];
1910 }
1911
1912 if (filedets->widgets[5]) {
1913 if (filedets->extra_details) {
1914 if (filedets->widgets[5] != filedets->widgets[4]) {
1915 lives_spinner_stop(LIVES_SPINNER(filedets->widgets[5]));
1916 lives_widget_hide(filedets->widgets[5]);
1917 lives_widget_set_no_show_all(filedets->widgets[5], TRUE);
1918 }
1919 lives_widget_set_no_show_all(filedets->widgets[4], FALSE);
1920 lives_widget_show_all(filedets->widgets[4]);
1921
1922 if (!filedets->mtime_sec) {
1923 lives_label_set_text(LIVES_LABEL(filedets->widgets[4]), "????");
1924 } else {
1925 txt = lives_datetime(filedets->mtime_sec, TRUE);
1926 dtxt = lives_datetime_rel(txt);
1927 lives_label_set_text(LIVES_LABEL(filedets->widgets[4]), dtxt);
1928 if (dtxt != txt) lives_free(dtxt);
1929 lives_free(txt);
1930 }
1931
1932 if (filedets->widgets[7] != filedets->widgets[6]) {
1933 lives_spinner_stop(LIVES_SPINNER(filedets->widgets[7]));
1934 lives_widget_hide(filedets->widgets[7]);
1935 lives_widget_set_no_show_all(filedets->widgets[7], TRUE);
1936 }
1937 lives_widget_set_no_show_all(filedets->widgets[6], FALSE);
1938 lives_widget_show_all(filedets->widgets[6]);
1939
1940 if ((filedets->type & LIVES_FILE_TYPE_MASK) == LIVES_FILE_TYPE_UNKNOWN) {
1941 lives_label_set_text(LIVES_LABEL(filedets->widgets[6]), "????");
1942 } else {
1943 if (LIVES_FILE_IS_FILE(filedets->type))
1944 txt = lives_strdup_printf(_("\tFile\t\t:\t%s"),
1945 filedets->extra_details ? filedets->extra_details : " - ");
1946 else if (LIVES_FILE_IS_DIRECTORY(filedets->type))
1947 txt = lives_strdup_printf(_("\tDirectory\t\t:\t%s"),
1948 filedets->extra_details ? filedets->extra_details : " - ");
1949 else
1950 txt = lives_strdup_printf(_("\t????????\t\t:\t%s"),
1951 filedets->extra_details ? filedets->extra_details : " - ");
1952 lives_label_set_text(LIVES_LABEL(filedets->widgets[6]), txt);
1953 lives_free(txt);
1954 }
1955 filedets->widgets[5] = NULL;
1956 } else needs_recheck = TRUE;
1957 }
1958
1959 if (!pass) {
1960 lives_widget_show_all(dialog);
1961 do {
1962 lives_widget_context_update();
1963 //lives_widget_process_updates(dialog);
1964 lives_nanosleep(100);
1965 } while (!list->next && filtresp == LIVES_RESPONSE_NONE);
1966 }
1967 if (filtresp != LIVES_RESPONSE_NONE) goto ffxdone;
1968 list = list->next;
1969 }
1970 if (cb) {
1971 lives_signal_sync_connect(LIVES_GUI_OBJECT(cb), LIVES_WIDGET_TOGGLED_SIGNAL,
1972 LIVES_GUI_CALLBACK(filt_all_toggled), (livespointer)*listp);
1973 lives_widget_set_sensitive(cb, TRUE);
1974 }
1975 ffxdone:
1976 widget_opts.mnemonic_label = TRUE;
1977 return needs_recheck;
1978 }
1979
1980
filter_cleanup(const char * trashdir,LiVESList ** rec_list,LiVESList ** rem_list,LiVESList ** left_list)1981 LiVESResponseType filter_cleanup(const char *trashdir, LiVESList **rec_list, LiVESList **rem_list,
1982 LiVESList **left_list) {
1983 LiVESWidget *dialog;
1984 LiVESWidget *layout, *layout_rec, *layout_rem, *layout_leave;
1985 LiVESWidget *top_vbox;
1986 LiVESWidget *scrolledwindow;
1987 LiVESWidget *cancelb;
1988 LiVESWidget *resetb = NULL;
1989 LiVESWidget *accb;
1990 LiVESWidget *vbox;
1991 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
1992
1993 int winsize_h = GUI_SCREEN_WIDTH - SCR_WIDTH_SAFETY;
1994 int winsize_v = GUI_SCREEN_HEIGHT - SCR_HEIGHT_SAFETY * 2;
1995 int rec_recheck, rem_recheck, leave_recheck;
1996 int pass = 0;
1997 int woat = widget_opts.apply_theme;
1998 int wopw = widget_opts.packing_width;
1999
2000 char *txt;
2001
2002 // get size, type (dir or file), nitems, extra_dets
2003 // cr dat, mod date
2004
2005 filtresp = LIVES_RESPONSE_NONE;
2006
2007 dialog = lives_standard_dialog_new(_("Disk Cleanup"), FALSE, winsize_h, winsize_v);
2008 lives_window_add_accel_group(LIVES_WINDOW(dialog), accel_group);
2009 lives_widget_set_maximum_size(dialog, winsize_h, winsize_v);
2010
2011 if ((*rec_list && (*rec_list)->data) || (*rem_list && (*rem_list)->data)
2012 || (*left_list && (*left_list)->data)) {
2013 LiVESWidget *bbox = lives_dialog_get_action_area(LIVES_DIALOG(dialog));
2014 cancelb = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog),
2015 LIVES_STOCK_CANCEL, NULL, LIVES_RESPONSE_CANCEL);
2016
2017 lives_widget_add_accelerator(cancelb, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
2018 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
2019
2020 resetb = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog),
2021 LIVES_STOCK_UNDO, _("_Reset"), LIVES_RESPONSE_NONE);
2022 lives_widget_set_sensitive(resetb, FALSE);
2023
2024 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
2025 accb = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog),
2026 LIVES_STOCK_GO_FORWARD, _("_Accept and Continue"), LIVES_RESPONSE_ACCEPT);
2027 widget_opts.expand = LIVES_EXPAND_DEFAULT;
2028 lives_widget_set_sensitive(accb, FALSE);
2029
2030 trash_rb(LIVES_BUTTON_BOX(bbox));
2031 lives_button_box_set_layout(LIVES_BUTTON_BOX(bbox), LIVES_BUTTONBOX_CENTER);
2032 } else {
2033 accb = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog),
2034 LIVES_STOCK_CLOSE, _("_Close Window"),
2035 LIVES_RESPONSE_OK);
2036 lives_widget_add_accelerator(accb, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
2037 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
2038 lives_button_grab_default_special(accb);
2039 }
2040
2041 lives_signal_sync_connect(dialog, LIVES_WIDGET_RESPONSE_SIGNAL,
2042 LIVES_GUI_CALLBACK(filtc_response), NULL);
2043
2044 top_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
2045
2046 layout = lives_layout_new(LIVES_BOX(top_vbox));
2047 lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
2048 txt = lives_strdup_printf(_("Analysis of directory: %s"), prefs->workdir);
2049 lives_layout_add_label(LIVES_LAYOUT(layout), txt, FALSE);
2050 lives_free(txt);
2051 lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
2052
2053 vbox = lives_vbox_new(FALSE, 0);
2054 widget_opts.apply_theme = 0;
2055 scrolledwindow = lives_standard_scrolled_window_new(winsize_h, winsize_v, vbox);
2056 widget_opts.apply_theme = woat;
2057 lives_box_pack_start(LIVES_BOX(top_vbox), scrolledwindow, TRUE, TRUE, widget_opts.packing_height);
2058
2059 /// items for recovery /////////////////////////
2060
2061 layout_rec = lives_layout_new(LIVES_BOX(vbox));
2062 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
2063 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2064 lives_layout_add_label(LIVES_LAYOUT(layout_rec), _("Possibly Recoverable Clips"), FALSE);
2065 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2066 widget_opts.expand = LIVES_EXPAND_DEFAULT;
2067 lives_layout_add_fill(LIVES_LAYOUT(layout_rec), FALSE);
2068
2069 lives_widget_show_all(dialog);
2070
2071 do {
2072 lives_widget_process_updates(dialog);
2073 if (!*rec_list && filtresp == LIVES_RESPONSE_NONE) lives_nanosleep(1000);
2074 } while (!*rec_list && filtresp == LIVES_RESPONSE_NONE);
2075
2076 if (filtresp != LIVES_RESPONSE_NONE) goto harlem_shuffle;
2077
2078 rec_recheck = fill_filt_section(rec_list, pass, 0, layout_rec);
2079 lives_layout_add_fill(LIVES_LAYOUT(layout_rec), FALSE);
2080
2081 add_hsep_to_box(LIVES_BOX(vbox));
2082
2083 layout_rem = lives_layout_new(LIVES_BOX(vbox));
2084 widget_opts.packing_width = wopw;
2085 lives_layout_add_fill(LIVES_LAYOUT(layout_rem), FALSE);
2086 lives_layout_add_fill(LIVES_LAYOUT(layout_rem), FALSE);
2087 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
2088 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2089 lives_layout_add_label(LIVES_LAYOUT(layout_rem), _("Items for Automatic Removal"), FALSE);
2090 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2091 widget_opts.expand = LIVES_EXPAND_DEFAULT;
2092 lives_layout_add_fill(LIVES_LAYOUT(layout_rem), FALSE);
2093
2094 lives_widget_show_all(dialog);
2095
2096 do {
2097 lives_widget_process_updates(dialog);
2098 if (!*rem_list && filtresp == LIVES_RESPONSE_NONE) lives_nanosleep(1000);
2099 } while (!*rem_list && filtresp == LIVES_RESPONSE_NONE);
2100
2101 if (filtresp != LIVES_RESPONSE_NONE) goto harlem_shuffle;
2102
2103 rem_recheck = fill_filt_section(rem_list, pass, 1, layout_rem);
2104 lives_layout_add_fill(LIVES_LAYOUT(layout_rem), FALSE);
2105
2106 add_hsep_to_box(LIVES_BOX(vbox));
2107
2108 /// items for manual removal
2109 layout_leave = lives_layout_new(LIVES_BOX(vbox));
2110 lives_layout_add_fill(LIVES_LAYOUT(layout_leave), FALSE);
2111 lives_layout_add_fill(LIVES_LAYOUT(layout_leave), FALSE);
2112 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
2113 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2114 lives_layout_add_label(LIVES_LAYOUT(layout_leave), _("Items for Manual Removal"), FALSE);
2115 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2116 widget_opts.expand = LIVES_EXPAND_DEFAULT;
2117 lives_layout_add_fill(LIVES_LAYOUT(layout_leave), FALSE);
2118
2119 lives_widget_show_all(dialog);
2120
2121 do {
2122 lives_widget_process_updates(dialog);
2123 if (!*left_list && filtresp == LIVES_RESPONSE_NONE) lives_nanosleep(1000);
2124 } while (!*left_list && filtresp == LIVES_RESPONSE_NONE);
2125
2126 if (filtresp != LIVES_RESPONSE_NONE) goto harlem_shuffle;
2127
2128 leave_recheck = fill_filt_section(left_list, pass, 2, layout_leave);
2129 lives_layout_add_fill(LIVES_LAYOUT(layout_leave), FALSE);
2130
2131
2132 if (resetb) {
2133 /// reset button
2134 if (!pass) {
2135 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout_rec), "list", *rec_list);
2136 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout_rec), "ptype",
2137 LIVES_INT_TO_POINTER(0));
2138 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout_rem), "list", *rem_list);
2139 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout_rem), "ptype",
2140 LIVES_INT_TO_POINTER(1));
2141 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout_leave), "list", *left_list);
2142 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(layout_leave), "ptype",
2143 LIVES_INT_TO_POINTER(2));
2144
2145 lives_signal_sync_connect_swapped(LIVES_GUI_OBJECT(resetb), LIVES_WIDGET_CLICKED_SIGNAL,
2146 LIVES_GUI_CALLBACK(filt_reset_clicked), layout_rec);
2147 lives_signal_sync_connect_swapped(LIVES_GUI_OBJECT(resetb), LIVES_WIDGET_CLICKED_SIGNAL,
2148 LIVES_GUI_CALLBACK(filt_reset_clicked), layout_rem);
2149 lives_signal_sync_connect_swapped(LIVES_GUI_OBJECT(resetb), LIVES_WIDGET_CLICKED_SIGNAL,
2150 LIVES_GUI_CALLBACK(filt_reset_clicked), layout_leave);
2151
2152 lives_widget_set_sensitive(resetb, TRUE);
2153 lives_widget_set_sensitive(accb, TRUE);
2154 lives_button_grab_default_special(accb);
2155 }
2156 }
2157
2158 /////////
2159 while (filtresp == LIVES_RESPONSE_NONE && (rec_recheck || rem_recheck || leave_recheck)) {
2160 ++pass;
2161 if (rec_recheck) rec_recheck = fill_filt_section(rec_list, pass, 0, layout_rec);
2162 if (rem_recheck) rem_recheck = fill_filt_section(rem_list, pass, 1, layout_rem);
2163 if (leave_recheck) leave_recheck = fill_filt_section(left_list, pass, 2, layout_leave);
2164 lives_widget_process_updates(dialog);
2165 if (filtresp == LIVES_RESPONSE_NONE && (rec_recheck || rem_recheck || leave_recheck)) lives_nanosleep(100);
2166 };
2167
2168 while (filtresp == LIVES_RESPONSE_NONE) lives_dialog_run(LIVES_DIALOG(dialog));
2169
2170 harlem_shuffle:
2171
2172 if (filtresp != LIVES_RESPONSE_CANCEL && filtresp != LIVES_RESPONSE_OK) {
2173 // we need to shuffle the lists around before destroying the dialog; caller will move
2174 // actual pointer files
2175 LiVESList *list, *listnext;
2176 lives_file_dets_t *filedets;
2177 lives_widget_hide(dialog);
2178 lives_widget_process_updates(dialog);
2179
2180 for (pass = 0; pass < 3; pass++) {
2181 if (!pass) list = *rec_list;
2182 else if (pass == 1) list = *rem_list;
2183 else list = *left_list;
2184 for (; list && list->data; list = listnext) {
2185 listnext = list->next;
2186 // entries can move to rem_list or left_list
2187 // we no longer care about type, so the field will be reused to
2188 // store the origin list number
2189 // for this we will re-use pass, 0 -> rec_list, 1 -> rem_list, 2 -> left_list
2190 filedets = (lives_file_dets_t *)list->data;
2191 if (filedets->type & LIVES_FILE_TYPE_FLAG_SPECIAL) continue;
2192 filedets->type = ((uint64_t)pass | (uint64_t)LIVES_FILE_TYPE_FLAG_SPECIAL);
2193 if (!pass || pass == 2) {
2194 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(filedets->widgets[0]))) {
2195 if (pass == 2 || !lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(filedets->widgets[1]))) {
2196 // move into delete from recover or leave
2197 if (list->prev) list->prev->next = list->next;
2198 if (list->next) list->next->prev = list->prev;
2199 list->prev = NULL;
2200 if (list == *rec_list) *rec_list = list->next;
2201 else if (list == *left_list) *left_list = list->next;
2202 list->next = *rem_list;
2203 (*rem_list)->prev = list;
2204 *rem_list = list;
2205 }
2206 }
2207 }
2208 if (pass != 2) {
2209 if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(filedets->widgets[0]))) {
2210 // move to leave, from rec or rem
2211 if (list->prev) list->prev->next = list->next;
2212 if (list->next) list->next->prev = list->prev;
2213 list->prev = NULL;
2214 if (list == *rec_list) *rec_list = list->next;
2215 else if (list == *rem_list) *rem_list = list->next;
2216 list->next = *left_list;
2217 (*left_list)->prev = list;
2218 *left_list = list;
2219 // *INDENT-OFF*
2220 }}}}}
2221 // *INDENT-ON*
2222 lives_widget_destroy(dialog);
2223 //lives_widget_context_update();
2224 return filtresp;
2225 }
2226
2227
create_opensel_dialog(int frames,double fps)2228 LiVESWidget *create_opensel_dialog(int frames, double fps) {
2229 LiVESWidget *opensel_dialog;
2230 LiVESWidget *dialog_vbox;
2231 LiVESWidget *vbox;
2232 LiVESWidget *table;
2233 LiVESWidget *label;
2234 LiVESWidget *spinbutton;
2235 LiVESWidget *cancelbutton;
2236 LiVESWidget *okbutton;
2237
2238 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
2239
2240 double tottime = 0.;
2241
2242 char *text;
2243
2244 if (fps > 0.) tottime = (double)frames / fps;
2245
2246 opensel_dialog = lives_standard_dialog_new(_("Open Selection"), FALSE, -1, -1);
2247
2248 lives_window_add_accel_group(LIVES_WINDOW(opensel_dialog), accel_group);
2249
2250 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(opensel_dialog));
2251
2252 vbox = lives_vbox_new(FALSE, 0);
2253 lives_box_pack_start(LIVES_BOX(dialog_vbox), vbox, TRUE, TRUE, 0);
2254 lives_widget_set_size_request(LIVES_WIDGET(opensel_dialog), RFX_WINSIZE_H, RFX_WINSIZE_V);
2255
2256 table = lives_table_new(2, 3, FALSE);
2257 lives_table_set_column_homogeneous(LIVES_TABLE(table), FALSE);
2258 lives_box_pack_start(LIVES_BOX(vbox), table, FALSE, TRUE, widget_opts.packing_height * 4);
2259
2260 lives_table_set_row_spacings(LIVES_TABLE(table), widget_opts.packing_height * 4);
2261
2262 label = lives_standard_label_new(_("Selection start time (sec)"));
2263 lives_table_attach(LIVES_TABLE(table), label, 0, 1, 0, 1,
2264 (LiVESAttachOptions)(LIVES_FILL | LIVES_EXPAND),
2265 (LiVESAttachOptions)(0), 0, 0);
2266 lives_widget_set_halign(label, LIVES_ALIGN_END);
2267
2268 if (frames > 0 && fps > 0.)
2269 text = lives_strdup_printf(_("[ maximum = %.2f ]"), tottime);
2270 else text = lives_strdup("");
2271 label = lives_standard_label_new(text);
2272 lives_free(text);
2273
2274 lives_table_attach(LIVES_TABLE(table), label, 2, 3, 0, 1,
2275 (LiVESAttachOptions)(LIVES_FILL | LIVES_EXPAND),
2276 (LiVESAttachOptions)(0), 0, 0);
2277 lives_widget_set_halign(label, LIVES_ALIGN_START);
2278
2279 label = lives_standard_label_new(_("Number of frames to open"));
2280 lives_table_attach(LIVES_TABLE(table), label, 0, 1, 1, 2,
2281 (LiVESAttachOptions)(LIVES_FILL | LIVES_EXPAND),
2282 (LiVESAttachOptions)(0), 0, 0);
2283 lives_widget_set_halign(label, LIVES_ALIGN_END);
2284
2285 if (frames > 0)
2286 text = lives_strdup_printf(_("[ maximum = %d ]"), frames);
2287 else text = lives_strdup("");
2288
2289 label = lives_standard_label_new(text);
2290 lives_free(text);
2291
2292 lives_table_attach(LIVES_TABLE(table), label, 2, 3, 1, 2,
2293 (LiVESAttachOptions)(LIVES_FILL | LIVES_EXPAND),
2294 (LiVESAttachOptions)(0), 0, 0);
2295 lives_widget_set_halign(label, LIVES_ALIGN_START);
2296
2297 spinbutton = lives_standard_spin_button_new(NULL, mainw->fx1_val, 0., tottime, 1., 1., 2, NULL, NULL);
2298 lives_widget_set_halign(spinbutton, LIVES_ALIGN_START);
2299
2300 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
2301 LIVES_GUI_CALLBACK(on_spin_value_changed),
2302 LIVES_INT_TO_POINTER(1));
2303
2304 lives_table_attach(LIVES_TABLE(table), spinbutton, 1, 2, 0, 1,
2305 (LiVESAttachOptions)(LIVES_FILL),
2306 (LiVESAttachOptions)(0), widget_opts.packing_height * 2 + 2, 0);
2307
2308 spinbutton = lives_standard_spin_button_new(NULL, (double)mainw->fx2_val, 1., (double)frames, 1., 1., 0, NULL, NULL);
2309 lives_widget_set_halign(spinbutton, LIVES_ALIGN_START);
2310
2311 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
2312 LIVES_GUI_CALLBACK(on_spin_value_changed),
2313 LIVES_INT_TO_POINTER(2));
2314
2315 lives_table_attach(LIVES_TABLE(table), spinbutton, 1, 2, 1, 2,
2316 (LiVESAttachOptions)(LIVES_FILL),
2317 (LiVESAttachOptions)(0), widget_opts.packing_height * 2 + 2, 0);
2318
2319 widget_add_preview(opensel_dialog, LIVES_BOX(vbox), LIVES_BOX(vbox), LIVES_BOX(vbox), LIVES_PREVIEW_TYPE_RANGE);
2320
2321 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(opensel_dialog), LIVES_STOCK_CANCEL, NULL,
2322 LIVES_RESPONSE_CANCEL);
2323
2324 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
2325 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
2326
2327 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(opensel_dialog), LIVES_STOCK_OK, NULL,
2328 LIVES_RESPONSE_OK);
2329
2330 lives_button_grab_default_special(okbutton);
2331
2332 lives_signal_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
2333 LIVES_GUI_CALLBACK(on_cancel_opensel_clicked), NULL);
2334
2335 lives_signal_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
2336 LIVES_GUI_CALLBACK(on_opensel_range_ok_clicked), NULL);
2337
2338 lives_window_set_resizable(LIVES_WINDOW(opensel_dialog), TRUE);
2339
2340 if (prefs->open_maximised || prefs->fileselmax) {
2341 lives_window_maximize(LIVES_WINDOW(opensel_dialog));
2342 }
2343
2344 lives_widget_show_all(opensel_dialog);
2345
2346 return opensel_dialog;
2347 }
2348
2349
create_location_dialog(void)2350 _entryw *create_location_dialog(void) {
2351 LiVESWidget *dialog_vbox;
2352 LiVESWidget *cancelbutton;
2353 LiVESWidget *okbutton;
2354 LiVESWidget *label;
2355 LiVESWidget *checkbutton;
2356 LiVESWidget *hbox;
2357
2358 _entryw *locw = (_entryw *)(lives_malloc(sizeof(_entryw)));
2359
2360 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
2361
2362 char *title, *tmp, *tmp2;
2363
2364 title = (_("Open Location"));
2365
2366 locw->dialog = lives_standard_dialog_new(title, FALSE, -1, -1);
2367 lives_signal_handlers_disconnect_by_func(locw->dialog, LIVES_GUI_CALLBACK(return_true), NULL);
2368
2369 lives_free(title);
2370
2371 lives_window_add_accel_group(LIVES_WINDOW(locw->dialog), accel_group);
2372
2373 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(locw->dialog));
2374
2375 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2376
2377 label = lives_standard_label_new(
2378 _("\n\nTo open a stream, you must make sure that you have the correct libraries "
2379 "compiled in mplayer (or mpv).\n"
2380 "Also make sure you have set your bandwidth in Preferences|Streaming\n\n"));
2381
2382 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2383
2384 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, 0);
2385
2386 hbox = lives_hbox_new(FALSE, 0);
2387 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * 2);
2388
2389 locw->entry = lives_standard_entry_new(_("URL : "), "", LONG_ENTRY_WIDTH, 32768, LIVES_BOX(hbox), NULL);
2390
2391 add_fill_to_box(LIVES_BOX(hbox));
2392
2393 hbox = lives_hbox_new(FALSE, 0);
2394 checkbutton = lives_standard_check_button_new((tmp = (_("Do not send bandwidth information"))),
2395 prefs->no_bandwidth, LIVES_BOX(hbox),
2396 (tmp2 = (_("Try this setting if you are having problems getting a stream"))));
2397
2398 lives_free(tmp); lives_free(tmp2);
2399
2400 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height * 2);
2401
2402 lives_signal_sync_connect(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
2403 LIVES_GUI_CALLBACK(on_boolean_toggled),
2404 &prefs->no_bandwidth);
2405
2406 add_deinterlace_checkbox(LIVES_BOX(dialog_vbox));
2407
2408 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(locw->dialog), LIVES_STOCK_CANCEL, NULL,
2409 LIVES_RESPONSE_CANCEL);
2410
2411 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(locw->dialog), LIVES_STOCK_OK, NULL,
2412 LIVES_RESPONSE_OK);
2413 lives_button_grab_default_special(okbutton);
2414
2415 lives_signal_sync_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
2416 LIVES_GUI_CALLBACK(lives_general_button_clicked), locw);
2417
2418 lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
2419 LIVES_GUI_CALLBACK(on_location_select), NULL);
2420
2421 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
2422 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
2423
2424 lives_widget_show_all(locw->dialog);
2425
2426 return locw;
2427 }
2428
2429
mkszlabel(const char * set,ssize_t size,int ccount,int lcount)2430 static char *mkszlabel(const char *set, ssize_t size, int ccount, int lcount) {
2431 char *bit1 = lives_strdup_printf(_("Contents of Set %s"), set), *bit2;
2432 char *szstr, *label, *laystr, *clpstr;
2433 if (size < 0) szstr = lives_strdup(_("Calculating..."));
2434 else szstr = lives_format_storage_space_string(size);
2435 if (ccount == -1) clpstr = (_("counting..."));
2436 else clpstr = lives_strdup_printf("%d", ccount);
2437 if (lcount == -1) laystr = (_("counting..."));
2438 else laystr = lives_strdup_printf("%d", lcount);
2439 bit2 = lives_strdup_printf(_("Total size = %s\tclips: %s\tlayouts: %s"), szstr, clpstr, laystr);
2440 label = lives_strdup_printf("%s\n%s\n", bit1, bit2);
2441 lives_free(bit1); lives_free(bit2);
2442 lives_free(laystr); lives_free(clpstr);
2443 return label;
2444 }
2445
2446
on_set_exp(LiVESWidget * exp,_entryw * renamew)2447 static void on_set_exp(LiVESWidget * exp, _entryw * renamew) {
2448 lives_proc_thread_t layinfo = NULL, clipsinfo = NULL, sizinfo = NULL;
2449 LiVESList *lists[2];
2450 LiVESList **laylist = &lists[0], **clipslist = &lists[1];
2451
2452 *laylist = *clipslist = NULL;
2453
2454 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) {
2455 widget_opts.use_markup = TRUE;
2456 lives_expander_set_label(LIVES_EXPANDER(exp), _("<b>Show Contents</b>"));
2457 widget_opts.use_markup = FALSE;
2458 if (renamew->layouts_layout) {
2459 lives_widget_destroy(renamew->layouts_layout);
2460 renamew->layouts_layout = NULL;
2461 }
2462 if (renamew->clips_layout) {
2463 lives_widget_destroy(renamew->clips_layout);
2464 renamew->clips_layout = NULL;
2465 }
2466 lives_widget_set_sensitive(renamew->entry, TRUE);
2467 return;
2468 } else {
2469 lives_file_dets_t *filedets;
2470 const char *set = lives_entry_get_text(LIVES_ENTRY(renamew->entry));
2471 LiVESList *list;
2472 ssize_t totsize = -1;
2473 char *txt, *dtxt;
2474 char *setdir = lives_build_path(prefs->workdir, set, NULL);
2475 char *ldirname = lives_build_path(setdir, LAYOUTS_DIRNAME, NULL);
2476 char *ordfilename = lives_build_filename(setdir, CLIP_ORDER_FILENAME, NULL);
2477 int woat = widget_opts.apply_theme;
2478 int lcount = 0, ccount = 0;
2479
2480 sizinfo = lives_proc_thread_create(LIVES_THRDATTR_NONE, (lives_funcptr_t)get_dir_size, WEED_SEED_INT64, "s",
2481 setdir);
2482
2483 widget_opts.use_markup = TRUE;
2484 lives_expander_set_label(LIVES_EXPANDER(exp), _("<b>Hide Contents</b>"));
2485 widget_opts.use_markup = FALSE;
2486
2487 layinfo = dir_to_file_details(laylist, ldirname, NULL, 0);
2488
2489 clipsinfo =
2490 ordfile_to_file_details(clipslist, ordfilename, prefs->workdir,
2491 EXTRA_DETAILS_CLIPHDR | EXTRA_DETAILS_DIRSIZE
2492 | EXTRA_DETAILS_CHECK_MISSING);
2493
2494 if (lives_proc_thread_check(sizinfo)) totsize = lives_proc_thread_join_int64(sizinfo);
2495 txt = mkszlabel(set, totsize, -1, -1);
2496 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2497 lives_free(txt);
2498
2499 lives_free(ldirname); lives_free(ordfilename);
2500
2501 lives_widget_set_sensitive(renamew->entry, FALSE);
2502
2503 // layouts
2504 renamew->layouts_layout = lives_layout_new(LIVES_BOX(renamew->exp_vbox));
2505 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
2506 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2507 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), _("Layouts"), FALSE);
2508 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2509 widget_opts.expand = LIVES_EXPAND_DEFAULT;
2510 lives_layout_add_fill(LIVES_LAYOUT(renamew->layouts_layout), FALSE);
2511
2512 lives_widget_show_all(renamew->expander);
2513
2514 do {
2515 lives_widget_process_updates(renamew->dialog);
2516 if (!*laylist && lives_expander_get_expanded(LIVES_EXPANDER(exp))) lives_nanosleep(1000);
2517 } while (!*laylist && lives_expander_get_expanded(LIVES_EXPANDER(exp)));
2518
2519 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) goto thrdjoin;
2520
2521 if (totsize == -1) {
2522 if (lives_proc_thread_check(sizinfo)) totsize = lives_proc_thread_join_int64(sizinfo);
2523 txt = mkszlabel(set, totsize, -1, -1);
2524 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2525 lives_free(txt);
2526 }
2527
2528 list = *laylist;
2529 if (!list->data) {
2530 // NONE label
2531 //lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), mainw->string_constants[LIVES_STRING_CONSTANT_NONE], FALSE);
2532 lives_widget_hide(renamew->layouts_layout);
2533 txt = mkszlabel(set, totsize, -1, 0);
2534 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2535 lives_free(txt);
2536 } else {
2537 widget_opts.apply_theme = 2;
2538 lives_layout_add_row(LIVES_LAYOUT(renamew->layouts_layout));
2539 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), _("Modified Date"), TRUE);
2540 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), _("Size"), TRUE);
2541 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), _("Name"), TRUE);
2542 widget_opts.apply_theme = woat;
2543
2544 lives_widget_show_all(renamew->layouts_layout);
2545
2546 while (list->data && lives_expander_get_expanded(LIVES_EXPANDER(exp))) {
2547 lcount++;
2548 filedets = (lives_file_dets_t *)(list->data);
2549 do {
2550 // wait for size
2551 lives_widget_process_updates(renamew->dialog);
2552 if (lives_expander_get_expanded(LIVES_EXPANDER(exp))) {
2553 if (!filedets->extra_details) lives_nanosleep(1000);
2554 if (totsize == -1) {
2555 if (lives_proc_thread_check(sizinfo)) {
2556 totsize = lives_proc_thread_join_int64(sizinfo);
2557 txt = mkszlabel(set, totsize, -1, lcount);
2558 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2559 lives_free(txt);
2560 }
2561 }
2562 }
2563 } while (!filedets->extra_details && lives_expander_get_expanded(LIVES_EXPANDER(exp)));
2564 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) goto thrdjoin;
2565 lives_layout_add_row(LIVES_LAYOUT(renamew->layouts_layout));
2566 txt = lives_datetime(filedets->mtime_sec, TRUE);
2567 dtxt = lives_datetime_rel(txt);
2568 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), dtxt, TRUE);
2569 if (dtxt != txt) lives_free(dtxt);
2570 lives_free(txt);
2571 txt = lives_format_storage_space_string(filedets->size);
2572 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), txt, TRUE);
2573 lives_free(txt);
2574 lives_layout_add_label(LIVES_LAYOUT(renamew->layouts_layout), filedets->name, TRUE);
2575 lives_widget_show_all(renamew->expander);
2576 do {
2577 lives_widget_process_updates(renamew->dialog);
2578 if (lives_expander_get_expanded(LIVES_EXPANDER(exp))) {
2579 if (totsize == -1) {
2580 if (lives_proc_thread_check(sizinfo)) {
2581 totsize = lives_proc_thread_join_int64(sizinfo);
2582 txt = mkszlabel(set, totsize, -1, lcount);
2583 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2584 lives_free(txt);
2585 lives_widget_process_updates(renamew->dialog);
2586 }
2587 }
2588 }
2589 if (lives_expander_get_expanded(LIVES_EXPANDER(exp)) && !list->next) lives_nanosleep(1000);
2590 } while (!list->next && lives_expander_get_expanded(LIVES_EXPANDER(exp)));
2591 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) goto thrdjoin;
2592 list = list->next;
2593 }
2594 }
2595
2596 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) goto thrdjoin;
2597
2598 do {
2599 lives_widget_process_updates(renamew->dialog);
2600 if (lives_expander_get_expanded(LIVES_EXPANDER(exp))) {
2601 if (totsize == -1) {
2602 if (lives_proc_thread_check(sizinfo)) {
2603 totsize = lives_proc_thread_join_int64(sizinfo);
2604 txt = mkszlabel(set, totsize, lcount, -1);
2605 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2606 lives_free(txt);
2607 lives_widget_process_updates(renamew->dialog);
2608 }
2609 }
2610 }
2611 if (!*clipslist && lives_expander_get_expanded(LIVES_EXPANDER(exp))) lives_nanosleep(1000);
2612 } while (!*clipslist && lives_expander_get_expanded(LIVES_EXPANDER(exp)));
2613
2614 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) goto thrdjoin;
2615
2616 // clips
2617 renamew->clips_layout = lives_layout_new(LIVES_BOX(renamew->exp_vbox));
2618 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
2619 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2620 lives_layout_add_label(LIVES_LAYOUT(renamew->clips_layout), _("Clips"), FALSE);
2621 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2622 widget_opts.expand = LIVES_EXPAND_DEFAULT;
2623 lives_layout_add_fill(LIVES_LAYOUT(renamew->clips_layout), FALSE);
2624
2625 list = *clipslist;
2626 if (!list->data) {
2627 // NONE label
2628 lives_layout_add_label(LIVES_LAYOUT(renamew->clips_layout), mainw->string_constants[LIVES_STRING_CONSTANT_NONE], FALSE);
2629 } else {
2630 int pass = 0;
2631 widget_opts.apply_theme = 2;
2632 lives_layout_add_row(LIVES_LAYOUT(renamew->clips_layout));
2633 lives_layout_add_label(LIVES_LAYOUT(renamew->clips_layout), _("Modified Date"), TRUE);
2634 lives_layout_add_label(LIVES_LAYOUT(renamew->clips_layout), _("Size"), TRUE);
2635 lives_layout_add_label(LIVES_LAYOUT(renamew->clips_layout), _("Details"), TRUE);
2636 widget_opts.apply_theme = woat;
2637
2638 while (list->data && lives_expander_get_expanded(LIVES_EXPANDER(exp))) {
2639 boolean needs_more = FALSE;
2640 filedets = (lives_file_dets_t *)(list->data);
2641
2642 if (!pass) {
2643 ccount++;
2644 lives_layout_add_row(LIVES_LAYOUT(renamew->clips_layout));
2645 if (!filedets->mtime_sec) dtxt = txt = lives_strdup("????");
2646 else {
2647 txt = lives_datetime(filedets->mtime_sec, TRUE);
2648 dtxt = lives_datetime_rel(txt);
2649 }
2650 filedets->widgets[0] = lives_layout_add_label(LIVES_LAYOUT(renamew->clips_layout), dtxt, TRUE);
2651 if (dtxt != txt) lives_free(dtxt);
2652 lives_free(txt);
2653 }
2654
2655 if (!pass) {
2656 LiVESWidget *hbox = lives_layout_hbox_new(LIVES_LAYOUT(renamew->clips_layout));
2657 filedets->widgets[1] = lives_standard_label_new(NULL);
2658 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[1]);
2659 if (filedets->size == -1) {
2660 lives_widget_hide(filedets->widgets[1]);
2661 lives_widget_set_no_show_all(filedets->widgets[1], TRUE);
2662 filedets->widgets[2] = lives_spinner_new();
2663 if (filedets->widgets[2]) {
2664 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[2]);
2665 lives_spinner_start(LIVES_SPINNER(filedets->widgets[2]));
2666 } else filedets->widgets[2] = filedets->widgets[1];
2667 } else filedets->widgets[2] = filedets->widgets[1];
2668 }
2669
2670 if (filedets->size == -1) {
2671 needs_more = TRUE;
2672 }
2673
2674 if (filedets->size != -1) {
2675 if (filedets->mtime_sec) {
2676 txt = lives_datetime(filedets->mtime_sec, TRUE);
2677 dtxt = lives_datetime_rel(txt);
2678 lives_label_set_text(LIVES_LABEL(filedets->widgets[0]), dtxt);
2679 if (dtxt != txt) lives_free(dtxt);
2680 lives_free(txt);
2681 }
2682 if (filedets->widgets[2]) {
2683 if (filedets->widgets[2] != filedets->widgets[1]) {
2684 // remove spinner
2685 lives_spinner_stop(LIVES_SPINNER(filedets->widgets[2]));
2686 lives_widget_destroy(filedets->widgets[2]);
2687 }
2688 if (filedets->size == -2) {
2689 lives_label_set_text(LIVES_LABEL(filedets->widgets[1]), "????");
2690 }
2691 if (filedets->size > 0) {
2692 txt = lives_format_storage_space_string(filedets->size);
2693 lives_label_set_text(LIVES_LABEL(filedets->widgets[1]), txt);
2694 lives_free(txt);
2695 }
2696 lives_widget_set_no_show_all(filedets->widgets[1], FALSE);
2697 lives_widget_show(filedets->widgets[1]);
2698 filedets->widgets[2] = NULL;
2699 }
2700 }
2701
2702 if (!pass) {
2703 LiVESWidget *hbox = lives_layout_hbox_new(LIVES_LAYOUT(renamew->clips_layout));
2704 filedets->widgets[3] = lives_standard_label_new(NULL);
2705 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[3]);
2706 if (!filedets->extra_details) {
2707 lives_widget_hide(filedets->widgets[3]);
2708 lives_widget_set_no_show_all(filedets->widgets[3], TRUE);
2709 filedets->widgets[4] = lives_spinner_new();
2710 if (filedets->widgets[4]) {
2711 lives_layout_pack(LIVES_BOX(hbox), filedets->widgets[4]);
2712 lives_spinner_start(LIVES_SPINNER(filedets->widgets[4]));
2713 } else filedets->widgets[4] = filedets->widgets[3];
2714 } else filedets->widgets[4] = filedets->widgets[3];
2715 }
2716
2717 if (!filedets->extra_details) {
2718 needs_more = TRUE;
2719 }
2720
2721 if (filedets->extra_details) {
2722 if (filedets->widgets[4]) {
2723 if (filedets->widgets[4] != filedets->widgets[3]) {
2724 // remove spinner
2725 lives_spinner_stop(LIVES_SPINNER(filedets->widgets[4]));
2726 lives_widget_destroy(filedets->widgets[4]);
2727 }
2728 lives_label_set_text(LIVES_LABEL(filedets->widgets[3]), filedets->extra_details);
2729 lives_widget_set_no_show_all(filedets->widgets[3], FALSE);
2730 lives_widget_show(filedets->widgets[3]);
2731 if (LIVES_FILE_IS_MISSING(filedets->type))
2732 show_warn_image(filedets->widgets[3], NULL);
2733 filedets->widgets[4] = NULL;
2734 }
2735 }
2736 lives_widget_show_all(renamew->clips_layout);
2737
2738 do {
2739 lives_widget_process_updates(renamew->dialog);
2740 if (lives_expander_get_expanded(LIVES_EXPANDER(exp)) && !pass && !list->next) lives_nanosleep(1000);
2741 if (totsize == -1) {
2742 if (lives_proc_thread_check(sizinfo)) {
2743 totsize = lives_proc_thread_join_int64(sizinfo);
2744 txt = mkszlabel(set, totsize, ccount, lcount);
2745 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2746 lives_free(txt);
2747 lives_widget_process_updates(renamew->dialog);
2748 }
2749 }
2750 } while (!pass && !list->next && lives_expander_get_expanded(LIVES_EXPANDER(exp)));
2751
2752 if (!lives_expander_get_expanded(LIVES_EXPANDER(exp))) goto thrdjoin;
2753 list = list->next;
2754 if (!list->data && needs_more) {
2755 list = *clipslist;
2756 pass++;
2757 }
2758 }
2759 }
2760 while (lives_expander_get_expanded(LIVES_EXPANDER(exp)) && totsize == -1) {
2761 if (lives_proc_thread_check(sizinfo)) {
2762 totsize = lives_proc_thread_join_int64(sizinfo);
2763 }
2764 if (lives_expander_get_expanded(LIVES_EXPANDER(exp))) lives_widget_process_updates(renamew->dialog);
2765 if (lives_expander_get_expanded(LIVES_EXPANDER(exp))) lives_nanosleep(1000);
2766 }
2767 txt = mkszlabel(set, totsize, ccount, lcount);
2768 lives_label_set_text(LIVES_LABEL(renamew->exp_label), txt);
2769 lives_free(txt);
2770 if (lives_expander_get_expanded(LIVES_EXPANDER(exp))) lives_widget_process_updates(renamew->dialog);
2771 }
2772
2773 thrdjoin:
2774 lives_proc_thread_cancel(layinfo);
2775 lives_proc_thread_cancel(clipsinfo);
2776 lives_proc_thread_dontcare(sizinfo);
2777 if (*laylist) free_fdets_list(laylist);
2778 if (*clipslist) free_fdets_list(clipslist);
2779 }
2780
2781
close_expander(LiVESWidget * button,_entryw * renamew)2782 static void close_expander(LiVESWidget * button, _entryw * renamew) {
2783 if (lives_expander_get_expanded(LIVES_EXPANDER(renamew->expander)))
2784 lives_expander_set_expanded(LIVES_EXPANDER(renamew->expander), FALSE);
2785 }
2786
renamew_entry_changed(LiVESEntry * entry,LiVESWidget * other)2787 static void renamew_entry_changed(LiVESEntry * entry, LiVESWidget * other) {
2788 if (!*(lives_entry_get_text(entry))) lives_widget_set_sensitive(other, FALSE);
2789 else lives_widget_set_sensitive(other, TRUE);
2790 }
2791
create_rename_dialog(int type)2792 _entryw *create_rename_dialog(int type) {
2793 // type 1 = rename clip in menu
2794 // type 2 = save clip set
2795 // type 3 = reload clip set
2796 // type 4 = save clip set from mt
2797 // type 5 = save clip set for project export
2798
2799 // type 6 = initial workdir / change workdir
2800
2801 // type 7 = rename track in mt
2802
2803 // type 8 = export theme
2804
2805 LiVESWidget *dialog_vbox;
2806 LiVESWidget *hbox;
2807 LiVESWidget *label;
2808 LiVESWidget *checkbutton;
2809 LiVESWidget *set_combo;
2810
2811 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
2812
2813 char *title = NULL, *workdir, *tmp, *tmp2;
2814
2815 _entryw *renamew = (_entryw *)(lives_calloc(1, sizeof(_entryw)));
2816
2817 if (type == 1) {
2818 title = (_("Rename Clip"));
2819 } else if (type == 2 || type == 4 || type == 5) {
2820 title = (_("Enter Set Name to Save as"));
2821 } else if (type == 3) {
2822 title = (_("Enter a Set Name to Reload"));
2823 } else if (type == 6) {
2824 title = (_("Choose a Working Directory"));
2825 } else if (type == 7) {
2826 title = (_("Rename Current Track"));
2827 } else if (type == 8) {
2828 title = (_("Enter a Name for Your Theme"));
2829 }
2830
2831 renamew->dialog = lives_standard_dialog_new(title, FALSE, -1, -1);
2832 lives_free(title);
2833
2834 lives_signal_handlers_disconnect_by_func(renamew->dialog, LIVES_GUI_CALLBACK(return_true), NULL);
2835
2836 lives_window_add_accel_group(LIVES_WINDOW(renamew->dialog), accel_group);
2837
2838 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(renamew->dialog));
2839
2840 if (type == 4) {
2841 label = lives_standard_label_new
2842 (_("You need to enter a name for the current clip set.\n"
2843 "This will allow you reload the layout with the same clips later.\n"
2844 "Please enter the set name you wish to use.\n"
2845 "LiVES will remind you to save the clip set later when you try to exit.\n"));
2846 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, 0);
2847 }
2848
2849 if (type == 5) {
2850 label = lives_standard_label_new
2851 (_("In order to export this project, you must enter a name for this clip set.\n"
2852 "This will also be used for the project name.\n"));
2853 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, 0);
2854 }
2855
2856 if (type == 6 && !mainw->is_ready) {
2857 tmp = lives_big_and_bold(_("Welcome to LiVES !"));
2858 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2859 widget_opts.use_markup = TRUE;
2860 label = lives_standard_label_new(tmp);
2861 widget_opts.use_markup = FALSE;
2862 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2863 lives_free(tmp);
2864 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
2865
2866 label = lives_standard_label_new
2867 (_("This startup wizard will guide you through the\n"
2868 "initial install so that you can get the most from this application."));
2869 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
2870
2871 label = lives_standard_label_new
2872 (_("First of all you need to choose a working directory for LiVES.\n"
2873 "This should be a directory with plenty of disk space available."));
2874 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
2875 }
2876
2877 if (type == 6 && mainw->is_ready) {
2878 label = lives_standard_label_new(_("If the value of the working directory is changed, the contents of the existing\n"
2879 "working directory will be moved and if applicable added to the new location\n"));
2880 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
2881 }
2882
2883 hbox = lives_hbox_new(FALSE, 0);
2884
2885 if (type == 3) {
2886 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height * 4);
2887 } else if (type == 2 || type == 4 || type == 5) {
2888 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * 2);
2889 } else {
2890 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * 4);
2891 }
2892
2893 if (type == 1 || type == 7) {
2894 label = lives_standard_label_new(_("New name "));
2895 } else if (type == 2 || type == 3 || type == 4 || type == 5) {
2896 label = lives_standard_label_new(_("Set name "));
2897 } else if (type == 8) {
2898 label = lives_standard_label_new(_("Theme name "));
2899 } else {
2900 label = lives_standard_label_new("");
2901 }
2902
2903 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_width * 4);
2904
2905 if (type == 3) {
2906 if (mainw->num_sets == -1) {
2907 mainw->set_list = get_set_list(prefs->workdir, TRUE);
2908 if (mainw->set_list) {
2909 mainw->num_sets = lives_list_length(mainw->set_list);
2910 if (mainw->was_set) mainw->num_sets--;
2911 } else mainw->num_sets = 0;
2912 if (!mainw->num_sets) {
2913 do_no_sets_dialog(prefs->workdir);
2914 return NULL;
2915 }
2916 }
2917 mainw->set_list = lives_list_sort_alpha(mainw->set_list, TRUE);
2918 set_combo = lives_standard_combo_new(NULL, mainw->set_list, LIVES_BOX(hbox), NULL);
2919 renamew->entry = lives_combo_get_entry(LIVES_COMBO(set_combo));
2920 lives_entry_set_editable(LIVES_ENTRY(renamew->entry), TRUE);
2921 lives_entry_set_max_length(LIVES_ENTRY(renamew->entry), MAX_SET_NAME_LEN);
2922
2923 if (*prefs->ar_clipset_name) {
2924 // set default to our auto-reload clipset
2925 lives_entry_set_text(LIVES_ENTRY(renamew->entry), prefs->ar_clipset_name);
2926 }
2927 lives_entry_set_completion_from_list(LIVES_ENTRY(renamew->entry), mainw->set_list);
2928 } else {
2929 if (type == 6) {
2930 LiVESWidget *dirbutton;
2931 if (*prefs->workdir) workdir = lives_strdup(prefs->workdir);
2932 else workdir = lives_build_path(capable->home_dir, LIVES_DEF_WORK_NAME, NULL);
2933 renamew->entry = lives_standard_direntry_new("", (tmp = F2U8(workdir)),
2934 LONG_ENTRY_WIDTH, PATH_MAX, LIVES_BOX(hbox),
2935 (tmp2 = (_("LiVES working directory."))));
2936
2937 dirbutton = lives_label_get_mnemonic_widget(LIVES_LABEL(widget_opts.last_label));
2938 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(dirbutton), FILESEL_TYPE_KEY,
2939 LIVES_INT_TO_POINTER(LIVES_DIR_SELECTION_WORKDIR));
2940
2941 lives_free(tmp);
2942 lives_free(workdir);
2943 } else {
2944 renamew->entry = lives_standard_entry_new(NULL, NULL, -1, -1, LIVES_BOX(hbox), NULL);
2945 lives_entry_set_max_length(LIVES_ENTRY(renamew->entry), type == 6 ? PATH_MAX
2946 : type == 7 ? 16 : 128);
2947 if (type == 2 && *mainw->set_name) {
2948 lives_entry_set_text(LIVES_ENTRY(renamew->entry), (tmp = F2U8(mainw->set_name)));
2949 lives_free(tmp);
2950 }
2951 }
2952 }
2953
2954 add_fill_to_box(LIVES_BOX(dialog_vbox));
2955
2956 if (type == 3) {
2957 /// add set details expander
2958 int winsize_h = RFX_WINSIZE_H * 2;
2959 int winsize_v = RFX_WINSIZE_V / 2;
2960 LiVESWidget *layout;
2961 LiVESWidget *scrolledwindow;
2962 LiVESWidget *vbox = lives_vbox_new(FALSE, 0);
2963 int woat = widget_opts.apply_theme;
2964
2965 layout = lives_layout_new(LIVES_BOX(vbox));
2966 lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
2967 renamew->exp_label = lives_layout_add_label(LIVES_LAYOUT(layout), "", FALSE);
2968 lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
2969
2970 renamew->exp_vbox = lives_vbox_new(FALSE, 0);
2971 widget_opts.apply_theme = 0;
2972 scrolledwindow = lives_standard_scrolled_window_new(winsize_h, winsize_v, renamew->exp_vbox);
2973 widget_opts.apply_theme = woat;
2974 lives_box_pack_start(LIVES_BOX(vbox), scrolledwindow, TRUE, TRUE, widget_opts.packing_height);
2975 widget_opts.justify = LIVES_JUSTIFY_CENTER;
2976 renamew->expander = lives_standard_expander_new(NULL, LIVES_BOX(dialog_vbox), vbox);
2977 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
2978 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(renamew->expander), LIVES_WIDGET_ACTIVATE_SIGNAL,
2979 LIVES_GUI_CALLBACK(on_set_exp), renamew);
2980 on_set_exp(renamew->expander, renamew);
2981 add_fill_to_box(LIVES_BOX(dialog_vbox));
2982 add_fill_to_box(LIVES_BOX(dialog_vbox));
2983 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(renamew->entry), LIVES_WIDGET_CHANGED_SIGNAL,
2984 LIVES_GUI_CALLBACK(renamew_entry_changed), renamew->expander);
2985 renamew_entry_changed(LIVES_ENTRY(renamew->entry), renamew->expander);
2986 }
2987
2988 if (type == 8) {
2989 mainw->fx1_bool = FALSE;
2990 hbox = lives_hbox_new(FALSE, 0);
2991 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * 4);
2992
2993 checkbutton = lives_standard_check_button_new(_("Save extended colors"), FALSE, LIVES_BOX(hbox), NULL);
2994
2995 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
2996 LIVES_GUI_CALLBACK(on_boolean_toggled), &mainw->fx1_bool);
2997 }
2998
2999 lives_entry_set_width_chars(LIVES_ENTRY(renamew->entry), MEDIUM_ENTRY_WIDTH);
3000
3001 if (!(type == 4 && !LIVES_IS_INTERACTIVE)) {
3002 renamew->cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(renamew->dialog), LIVES_STOCK_CANCEL, NULL,
3003 LIVES_RESPONSE_CANCEL);
3004 lives_widget_add_accelerator(renamew->cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
3005 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
3006 }
3007
3008 if (type == 6 && !mainw->is_ready) {
3009 renamew->okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(renamew->dialog), LIVES_STOCK_GO_FORWARD, _("_Next"),
3010 LIVES_RESPONSE_OK);
3011 } else renamew->okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(renamew->dialog), LIVES_STOCK_OK,
3012 NULL, LIVES_RESPONSE_OK);
3013
3014 lives_button_grab_default_special(renamew->okbutton);
3015
3016 if (type != 3 && renamew->cancelbutton) {
3017 lives_signal_sync_connect(LIVES_GUI_OBJECT(renamew->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3018 LIVES_GUI_CALLBACK(lives_general_button_clicked), renamew);
3019 }
3020
3021 if (type == 3) {
3022 if (renamew->cancelbutton) {
3023 lives_signal_sync_connect(LIVES_GUI_OBJECT(renamew->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3024 LIVES_GUI_CALLBACK(close_expander), renamew);
3025 }
3026 if (renamew->okbutton) {
3027 lives_signal_sync_connect(LIVES_GUI_OBJECT(renamew->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3028 LIVES_GUI_CALLBACK(close_expander), renamew);
3029 }
3030 }
3031
3032 if (type == 1) {
3033 lives_signal_sync_connect(LIVES_GUI_OBJECT(renamew->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3034 LIVES_GUI_CALLBACK(on_rename_clip_name), NULL);
3035 }
3036
3037 lives_widget_add_accelerator(renamew->cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
3038 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
3039
3040 lives_widget_show_all(renamew->dialog);
3041 lives_widget_grab_focus(renamew->entry);
3042
3043 return renamew;
3044 }
3045
3046
on_liveinp_advanced_clicked(LiVESButton * button,livespointer user_data)3047 void on_liveinp_advanced_clicked(LiVESButton * button, livespointer user_data) {
3048 lives_tvcardw_t *tvcardw = (lives_tvcardw_t *)(user_data);
3049
3050 tvcardw->use_advanced = !tvcardw->use_advanced;
3051
3052 if (tvcardw->use_advanced) {
3053 lives_widget_show(tvcardw->adv_vbox);
3054 lives_button_set_label(LIVES_BUTTON(tvcardw->advbutton), _("Use def_aults"));
3055 } else {
3056 lives_button_set_label(LIVES_BUTTON(tvcardw->advbutton), _("_Advanced"));
3057 lives_window_resize(LIVES_WINDOW(lives_widget_get_toplevel(tvcardw->adv_vbox)), 4, 40);
3058 lives_widget_hide(tvcardw->adv_vbox);
3059 }
3060
3061 lives_widget_queue_resize(lives_widget_get_parent(tvcardw->adv_vbox));
3062 }
3063
3064
rb_tvcarddef_toggled(LiVESToggleButton * tbut,livespointer user_data)3065 static void rb_tvcarddef_toggled(LiVESToggleButton * tbut, livespointer user_data) {
3066 lives_tvcardw_t *tvcardw = (lives_tvcardw_t *)(user_data);
3067
3068 if (!lives_toggle_button_get_active(tbut)) {
3069 lives_widget_set_sensitive(tvcardw->spinbuttonw, TRUE);
3070 lives_widget_set_sensitive(tvcardw->spinbuttonh, TRUE);
3071 lives_widget_set_sensitive(tvcardw->spinbuttonf, TRUE);
3072 } else {
3073 lives_widget_set_sensitive(tvcardw->spinbuttonw, FALSE);
3074 lives_widget_set_sensitive(tvcardw->spinbuttonh, FALSE);
3075 lives_widget_set_sensitive(tvcardw->spinbuttonf, FALSE);
3076 }
3077 }
3078
3079
after_dialog_combo_changed(LiVESWidget * combo,livespointer plist)3080 static void after_dialog_combo_changed(LiVESWidget * combo, livespointer plist) {
3081 // set mainw->fx1_val to the index of combo text in plist
3082 LiVESList *list = (LiVESList *)plist;
3083 const char *etext = lives_combo_get_active_text(LIVES_COMBO(combo));
3084 mainw->fx1_val = lives_list_strcmp_index(list, etext, TRUE);
3085 }
3086
3087
create_combo_dialog(int type,LiVESList * list)3088 LiVESWidget *create_combo_dialog(int type, LiVESList * list) {
3089 // create a dialog with combo box selector
3090
3091 // type 1 == unicap device
3092
3093 // afterwards, mainw->fx1_val points to index selected
3094
3095 LiVESWidget *combo_dialog;
3096 LiVESWidget *dialog_vbox;
3097 LiVESWidget *label;
3098 LiVESWidget *combo;
3099
3100 char *label_text = NULL, *title = NULL;
3101
3102 if (type == 1) {
3103 title = (_("Select input device"));
3104 }
3105
3106 combo_dialog = lives_standard_dialog_new(title, TRUE, -1, -1);
3107 if (title) lives_free(title);
3108
3109 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(combo_dialog));
3110
3111 if (type == 1) {
3112 label_text = (_("Select input device:"));
3113 }
3114
3115 label = lives_standard_label_new(label_text);
3116 if (label_text) lives_free(label_text);
3117
3118 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, TRUE, TRUE, 0);
3119
3120 widget_opts.packing_height <<= 1;
3121 combo = lives_standard_combo_new(NULL, list, LIVES_BOX(dialog_vbox), NULL);
3122 widget_opts.packing_height >>= 1;
3123
3124 lives_signal_sync_connect_after(LIVES_WIDGET_OBJECT(combo), LIVES_WIDGET_CHANGED_SIGNAL,
3125 LIVES_GUI_CALLBACK(after_dialog_combo_changed), list);
3126
3127 if (type == 1) {
3128 add_deinterlace_checkbox(LIVES_BOX(dialog_vbox));
3129 }
3130
3131 if (prefs->show_gui)
3132 lives_widget_show_all(combo_dialog);
3133
3134 return combo_dialog;
3135 }
3136
3137
create_cdtrack_dialog(int type,livespointer user_data)3138 LiVESWidget *create_cdtrack_dialog(int type, livespointer user_data) {
3139 // general purpose device dialog with label and up to 2 spinbuttons
3140
3141 // type 0 = cd track
3142 // type 1 = dvd title/chapter/aid
3143 // type 2 = vcd title -- do we need chapter as well ?
3144
3145 // type 3 = number of tracks in mt
3146
3147 // type 4 = TV card (device and channel)
3148 // type 5 = fw card
3149
3150 // TODO - for CD make this nicer - get track names
3151
3152 lives_tvcardw_t *tvcardw = NULL;
3153
3154 LiVESWidget *cd_dialog;
3155 LiVESWidget *dialog_vbox;
3156 LiVESWidget *hbox;
3157 LiVESWidget *spinbutton;
3158 LiVESWidget *cancelbutton;
3159 LiVESWidget *okbutton;
3160
3161 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
3162
3163 LiVESSList *radiobutton_group = NULL;
3164
3165 char *label_text = NULL, *title;
3166
3167 int ph_mult = 4;
3168
3169 if (type == LIVES_DEVICE_CD) {
3170 title = (_("Load CD Track"));
3171 } else if (type == LIVES_DEVICE_DVD) {
3172 title = (_("Select DVD Title/Chapter"));
3173 } else if (type == LIVES_DEVICE_VCD) {
3174 title = (_("Select VCD Title"));
3175 } else if (type == LIVES_DEVICE_INTERNAL) {
3176 title = (_("Change Maximum Visible Tracks"));
3177 } else {
3178 title = (_("Device details"));
3179 }
3180
3181 cd_dialog = lives_standard_dialog_new(title, FALSE, -1, -1);
3182 lives_free(title);
3183 lives_signal_handlers_disconnect_by_func(cd_dialog, LIVES_GUI_CALLBACK(return_true), NULL);
3184
3185 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(cd_dialog));
3186
3187 if (type == LIVES_DEVICE_DVD || type == LIVES_DEVICE_TV_CARD) ph_mult = 2;
3188
3189 hbox = lives_hbox_new(FALSE, widget_opts.packing_width * 5);
3190 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * ph_mult);
3191
3192 if (type == LIVES_DEVICE_CD) {
3193 label_text = lives_strdup_printf(_("Track to load (from %s)"), prefs->cdplay_device);
3194 } else if (type == LIVES_DEVICE_DVD) {
3195 label_text = (_("DVD Title"));
3196 } else if (type == LIVES_DEVICE_VCD) {
3197 label_text = (_("VCD Title"));
3198 } else if (type == LIVES_DEVICE_INTERNAL) {
3199 label_text = (_("Maximum number of tracks to display"));
3200 } else if (type == LIVES_DEVICE_TV_CARD) {
3201 label_text = (_("Device: /dev/video"));
3202 } else if (type == LIVES_DEVICE_FW_CARD) {
3203 label_text = (_("Device: fw:"));
3204 }
3205
3206 widget_opts.mnemonic_label = FALSE;
3207 if (type == LIVES_DEVICE_CD || type == LIVES_DEVICE_DVD || type == LIVES_DEVICE_VCD) {
3208 spinbutton = lives_standard_spin_button_new(label_text, mainw->fx1_val,
3209 1., 256., 1., 10., 0, LIVES_BOX(hbox), NULL);
3210 } else if (type == LIVES_DEVICE_INTERNAL) {
3211 spinbutton = lives_standard_spin_button_new(label_text, mainw->fx1_val,
3212 5., 15., 1., 1., 0, LIVES_BOX(hbox), NULL);
3213 } else {
3214 spinbutton = lives_standard_spin_button_new(label_text, 0.,
3215 0., 31., 1., 1., 0, LIVES_BOX(hbox), NULL);
3216 }
3217 widget_opts.mnemonic_label = TRUE;
3218
3219 lives_free(label_text);
3220
3221 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3222 LIVES_GUI_CALLBACK(on_spin_value_changed),
3223 LIVES_INT_TO_POINTER(1));
3224
3225 add_fill_to_box(LIVES_BOX(hbox));
3226
3227 if (type == LIVES_DEVICE_DVD || type == LIVES_DEVICE_TV_CARD) {
3228 hbox = lives_hbox_new(FALSE, widget_opts.packing_width * 5);
3229 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * ph_mult);
3230
3231 if (type == LIVES_DEVICE_DVD) {
3232 spinbutton = lives_standard_spin_button_new(_("Chapter "), mainw->fx2_val,
3233 1., 1024., 1., 10., 0, LIVES_BOX(hbox), NULL);
3234 } else {
3235 spinbutton = lives_standard_spin_button_new(_("Channel "), 1.,
3236 1., 69., 1., 1., 0, LIVES_BOX(hbox), NULL);
3237 }
3238
3239 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3240 LIVES_GUI_CALLBACK(on_spin_value_changed), LIVES_INT_TO_POINTER(2));
3241
3242 if (type == LIVES_DEVICE_DVD) {
3243 hbox = lives_hbox_new(FALSE, widget_opts.packing_width * 5);
3244 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * ph_mult);
3245
3246 spinbutton = lives_standard_spin_button_new(_("Audio ID "), mainw->fx3_val,
3247 DVD_AUDIO_CHAN_MIN, DVD_AUDIO_CHAN_MAX, 1., 1., 0, LIVES_BOX(hbox), NULL);
3248
3249 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3250 LIVES_GUI_CALLBACK(on_spin_value_changed),
3251 LIVES_INT_TO_POINTER(3));
3252 }
3253 }
3254
3255 if (type == LIVES_DEVICE_TV_CARD || type == LIVES_DEVICE_FW_CARD) {
3256 hbox = add_deinterlace_checkbox(LIVES_BOX(dialog_vbox));
3257 add_fill_to_box(LIVES_BOX(hbox));
3258 }
3259
3260 if (type == LIVES_DEVICE_TV_CARD) {
3261 LiVESList *dlist = NULL;
3262 LiVESList *olist = NULL;
3263 char const *str;
3264 char *tvcardtypes[] = LIVES_TV_CARD_TYPES;
3265 register int i;
3266
3267 tvcardw = (lives_tvcardw_t *)lives_malloc(sizeof(lives_tvcardw_t));
3268 tvcardw->use_advanced = FALSE;
3269
3270 for (i = 0; (str = tvcardtypes[i]); i++) {
3271 dlist = lives_list_append(dlist, (livespointer)tvcardtypes[i]);
3272 }
3273
3274 lives_box_set_spacing(LIVES_BOX(dialog_vbox), widget_opts.packing_height * 2);
3275
3276 hbox = lives_hbox_new(FALSE, widget_opts.packing_width * 5);
3277
3278 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height * 2);
3279
3280 add_fill_to_box(LIVES_BOX(hbox));
3281
3282 tvcardw->advbutton = lives_standard_button_new_from_stock(LIVES_STOCK_PREFERENCES, _("_Advanced"),
3283 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
3284
3285 lives_box_pack_start(LIVES_BOX(hbox), tvcardw->advbutton, TRUE, TRUE, widget_opts.packing_width * 4);
3286
3287 add_fill_to_box(LIVES_BOX(hbox));
3288
3289 tvcardw->adv_vbox = lives_vbox_new(FALSE, widget_opts.packing_width * 5);
3290 lives_box_pack_start(LIVES_BOX(dialog_vbox), tvcardw->adv_vbox, TRUE, TRUE, widget_opts.packing_height * 2);
3291
3292 // add input, width, height, fps, driver and outfmt
3293
3294 hbox = lives_hbox_new(FALSE, 0);
3295 lives_box_pack_start(LIVES_BOX(tvcardw->adv_vbox), hbox, TRUE, FALSE, 0);
3296
3297 tvcardw->spinbuttoni = lives_standard_spin_button_new(_("Input number"),
3298 0., 0., 16., 1., 1., 0, LIVES_BOX(hbox), NULL);
3299
3300 hbox = lives_hbox_new(FALSE, 0);
3301 lives_box_pack_start(LIVES_BOX(tvcardw->adv_vbox), hbox, TRUE, FALSE, 0);
3302
3303 tvcardw->radiobuttond = lives_standard_radio_button_new(_("Use default width, height and FPS"),
3304 &radiobutton_group, LIVES_BOX(hbox), NULL);
3305
3306 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(tvcardw->radiobuttond), LIVES_WIDGET_TOGGLED_SIGNAL,
3307 LIVES_GUI_CALLBACK(rb_tvcarddef_toggled), (livespointer)tvcardw);
3308
3309 hbox = lives_hbox_new(FALSE, 0);
3310 lives_box_pack_start(LIVES_BOX(tvcardw->adv_vbox), hbox, TRUE, FALSE, 0);
3311
3312 lives_standard_radio_button_new(NULL, &radiobutton_group, LIVES_BOX(hbox), NULL);
3313
3314 tvcardw->spinbuttonw = lives_standard_spin_button_new(_("Width"),
3315 640., 4., 4096., 4., 16., 0, LIVES_BOX(hbox), NULL);
3316
3317 lives_widget_set_sensitive(tvcardw->spinbuttonw, FALSE);
3318
3319 tvcardw->spinbuttonh = lives_standard_spin_button_new(_("Height"),
3320 480., 4., 4096., 4., 16., 0, LIVES_BOX(hbox), NULL);
3321
3322 lives_widget_set_sensitive(tvcardw->spinbuttonh, FALSE);
3323
3324 tvcardw->spinbuttonf = lives_standard_spin_button_new(_("FPS"),
3325 25., 1., FPS_MAX, 1., 10., 3, LIVES_BOX(hbox), NULL);
3326
3327 lives_widget_set_sensitive(tvcardw->spinbuttonf, FALSE);
3328
3329 hbox = lives_hbox_new(FALSE, 0);
3330
3331 tvcardw->combod = lives_standard_combo_new(_("_Driver"), dlist, LIVES_BOX(hbox), NULL);
3332 lives_combo_set_active_index(LIVES_COMBO(tvcardw->combod), 0);
3333
3334 tvcardw->comboo = lives_standard_combo_new(_("_Output format"), olist, LIVES_BOX(hbox), NULL);
3335
3336 lives_widget_show_all(hbox);
3337 lives_box_pack_start(LIVES_BOX(tvcardw->adv_vbox), hbox, TRUE, FALSE, 0);
3338
3339 lives_signal_sync_connect(LIVES_GUI_OBJECT(tvcardw->advbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3340 LIVES_GUI_CALLBACK(on_liveinp_advanced_clicked), tvcardw);
3341
3342 lives_widget_hide(tvcardw->adv_vbox);
3343
3344 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(cd_dialog), "tvcard_data", tvcardw);
3345 }
3346
3347 add_fill_to_box(LIVES_BOX(dialog_vbox));
3348
3349 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(cd_dialog), LIVES_STOCK_CANCEL, NULL,
3350 LIVES_RESPONSE_CANCEL);
3351 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(cd_dialog), LIVES_STOCK_OK, NULL,
3352 LIVES_RESPONSE_OK);
3353 lives_button_grab_default_special(okbutton);
3354
3355 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
3356 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
3357
3358 if (type != LIVES_DEVICE_TV_CARD && type != LIVES_DEVICE_FW_CARD) {
3359 lives_signal_sync_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3360 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
3361 }
3362
3363 if (type == LIVES_DEVICE_CD) {
3364 lives_signal_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3365 LIVES_GUI_CALLBACK(on_load_cdtrack_ok_clicked), NULL);
3366 } else if (type == LIVES_DEVICE_DVD || type == LIVES_DEVICE_VCD) {
3367 lives_signal_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3368 LIVES_GUI_CALLBACK(on_load_vcd_ok_clicked), LIVES_INT_TO_POINTER(type));
3369 } else if (type == LIVES_DEVICE_INTERNAL) {
3370 lives_signal_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3371 LIVES_GUI_CALLBACK(mt_change_disp_tracks_ok), user_data);
3372 }
3373
3374 lives_window_add_accel_group(LIVES_WINDOW(cd_dialog), accel_group);
3375
3376 lives_widget_show_all(cd_dialog);
3377
3378 if (type == LIVES_DEVICE_TV_CARD) lives_widget_hide(tvcardw->adv_vbox);
3379
3380 return cd_dialog;
3381 }
3382
3383
on_avolch_ok(LiVESButton * button,livespointer data)3384 static void on_avolch_ok(LiVESButton * button, livespointer data) {
3385 if (fabs(cfile->vol - mainw->fx1_val) > .005) {
3386 uint32_t chk_mask = WARN_MASK_LAYOUT_ALTER_AUDIO;
3387 char *tmp = (_("Changing the audio volume"));
3388 lives_general_button_clicked(button, NULL);
3389 if (check_for_layout_errors(tmp, mainw->current_file, 1,
3390 calc_frame_from_time4(mainw->current_file, CLIP_AUDIO_TIME(mainw->current_file)), &chk_mask)) {
3391 d_print(_("Adjusting clip volume..."));
3392 lives_set_cursor_style(LIVES_CURSOR_BUSY, NULL);
3393 if (!adjust_clip_volume(mainw->current_file, lives_vol_from_linear(mainw->fx1_val), !prefs->conserve_space)) {
3394 d_print_failed();
3395 unbuffer_lmap_errors(FALSE);
3396 lives_set_cursor_style(LIVES_CURSOR_NORMAL, NULL);
3397 return;
3398 }
3399 set_undoable(_("Volume Adjustment"), TRUE);
3400 cfile->undo_action = UNDO_AUDIO_VOL;
3401 update_timer_bars(0, 0, 0, 0, 2);
3402 update_timer_bars(0, 0, 0, 0, 3);
3403 d_print(_("clip volume adjusted by a factor of %.2f\n"), cfile->vol);
3404 cfile->vol = 1.;
3405 } else d_print_cancelled();
3406 lives_free(tmp);
3407 lives_set_cursor_style(LIVES_CURSOR_NORMAL, NULL);
3408 }
3409 }
3410
3411
redraw_timeline(int clipno)3412 void redraw_timeline(int clipno) {
3413 lives_clip_t *sfile;
3414
3415 if (mainw->ce_thumbs) return;
3416 if (!IS_VALID_CLIP(clipno)) return;
3417 sfile = mainw->files[clipno];
3418 if (sfile->clip_type == CLIP_TYPE_TEMP) return;
3419
3420 mainw->drawsrc = clipno;
3421
3422 if (!mainw->video_drawable) {
3423 mainw->video_drawable = lives_widget_create_painter_surface(mainw->video_draw);
3424 }
3425 update_timer_bars(0, 0, 0, 0, 1);
3426
3427 if (!sfile->laudio_drawable) {
3428 sfile->laudio_drawable = lives_widget_create_painter_surface(mainw->laudio_draw);
3429 mainw->laudio_drawable = sfile->laudio_drawable;
3430 clear_tbar_bgs(0, 0, 0, 0, 2);
3431 update_timer_bars(0, 0, 0, 0, 2);
3432 } else {
3433 mainw->laudio_drawable = sfile->laudio_drawable;
3434 if (!LIVES_IS_PLAYING) {
3435 update_timer_bars(0, 0, 0, 0, 2);
3436 }
3437 }
3438 if (!sfile->raudio_drawable) {
3439 sfile->raudio_drawable = lives_widget_create_painter_surface(mainw->raudio_draw);
3440 mainw->raudio_drawable = sfile->raudio_drawable;
3441 clear_tbar_bgs(0, 0, 0, 0, 3);
3442 update_timer_bars(0, 0, 0, 0, 3);
3443 } else {
3444 mainw->raudio_drawable = sfile->raudio_drawable;
3445 if (!LIVES_IS_PLAYING) {
3446 update_timer_bars(0, 0, 0, 0, 3);
3447 }
3448 }
3449
3450 lives_widget_queue_draw(mainw->video_draw);
3451 lives_widget_queue_draw(mainw->laudio_draw);
3452 lives_widget_queue_draw(mainw->raudio_draw);
3453 lives_widget_queue_draw(mainw->eventbox2);
3454 }
3455
3456
redraw_tl_idle(void * data)3457 boolean redraw_tl_idle(void *data) {
3458 redraw_timeline(mainw->current_file);
3459 return FALSE;
3460 }
3461
3462 //static void preview_aud_vol_cb(LiVESButton *button, livespointer data) {preview_aud_vol();}
3463
create_new_pb_speed(short type)3464 void create_new_pb_speed(short type) {
3465 // type 1 = change speed
3466 // type 2 = resample
3467 // type 3 = clip audio volume
3468
3469 LiVESWidget *new_pb_speed;
3470 LiVESWidget *dialog_vbox;
3471 LiVESWidget *vbox;
3472 LiVESWidget *hbox;
3473 LiVESWidget *ca_hbox;
3474 LiVESWidget *label;
3475 LiVESWidget *label2;
3476 LiVESWidget *radiobutton1 = NULL;
3477 LiVESWidget *radiobutton2 = NULL;
3478 LiVESWidget *spinbutton_pb_speed;
3479 LiVESWidget *spinbutton_pb_time = NULL;
3480 LiVESWidget *cancelbutton;
3481 LiVESWidget *change_pb_ok;
3482 LiVESWidget *change_audio_speed;
3483
3484 LiVESAccelGroup *accel_group;
3485
3486 LiVESSList *rbgroup = NULL;
3487
3488 char label_text[256];
3489
3490 char *title = NULL;
3491
3492 if (type == 1) {
3493 title = (_("Change Playback Speed"));
3494 } else if (type == 2) {
3495 title = (_("Resample Video"));
3496 } else {
3497 title = (_("Adjust Clip Volume"));
3498 }
3499
3500 new_pb_speed = lives_standard_dialog_new(title, FALSE, -1, -1);
3501 lives_signal_handlers_disconnect_by_func(new_pb_speed, LIVES_GUI_CALLBACK(return_true), NULL);
3502 lives_free(title);
3503
3504 accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
3505 lives_window_add_accel_group(LIVES_WINDOW(new_pb_speed), accel_group);
3506
3507 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(new_pb_speed));
3508
3509 vbox = lives_vbox_new(FALSE, widget_opts.packing_height * 2);
3510
3511 lives_box_pack_start(LIVES_BOX(dialog_vbox), vbox, TRUE, TRUE, 0);
3512
3513 if (type == 1) {
3514 lives_snprintf(label_text, 256,
3515 _("Current playback speed is %.3f frames per second.\n\n"
3516 "Please enter the desired playback speed\nin _frames per second"),
3517 cfile->fps);
3518 } else if (type == 2) {
3519 lives_snprintf(label_text, 256,
3520 _("Current playback speed is %.3f frames per second.\n\n"
3521 "Please enter the _resampled rate\nin frames per second"),
3522 cfile->fps);
3523 } else if (type == 3) {
3524 lives_snprintf(label_text, 256,
3525 _("Current volume level for this clip is %.2f.\n\n"
3526 "You may select a new _volume level here.\n\n"
3527 "Please note that the volume can also be varied during playback\n"
3528 "using the %s and %s keys.\nChanging it here will make "
3529 "the adjustment permanent.\n"), "'<'", "'>'", cfile->vol);
3530 }
3531
3532 label = lives_standard_label_new_with_mnemonic_widget(label_text, NULL);
3533
3534 hbox = lives_hbox_new(FALSE, 0);
3535 lives_box_pack_start(LIVES_BOX(vbox), label, FALSE, FALSE, widget_opts.packing_height);
3536 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
3537
3538 if (type == 3) {
3539 add_fill_to_box(LIVES_BOX(hbox));
3540 spinbutton_pb_speed = lives_standard_spin_button_new(NULL, (double)cfile->vol, 0., 4., .01, .01, 2, LIVES_BOX(hbox), NULL);
3541 add_fill_to_box(LIVES_BOX(hbox));
3542 } else if (type == 2) {
3543 add_fill_to_box(LIVES_BOX(hbox));
3544 spinbutton_pb_speed = lives_standard_spin_button_new(NULL, cfile->fps, 1., FPS_MAX, .01, .1, 3, LIVES_BOX(hbox), NULL);
3545 add_fill_to_box(LIVES_BOX(hbox));
3546 } else {
3547 radiobutton1 = lives_standard_radio_button_new(NULL, &rbgroup, LIVES_BOX(hbox), NULL);
3548
3549 spinbutton_pb_speed = lives_standard_spin_button_new(NULL, cfile->fps, 1., FPS_MAX, .01, .1, 3, LIVES_BOX(hbox), NULL);
3550
3551 hbox = lives_hbox_new(FALSE, 0);
3552 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
3553
3554 add_fill_to_box(LIVES_BOX(hbox));
3555
3556 label2 = lives_standard_label_new_with_mnemonic_widget(_("OR enter the desired clip length in _seconds"), NULL);
3557 lives_box_pack_start(LIVES_BOX(hbox), label2, TRUE, TRUE, widget_opts.packing_width);
3558
3559 add_fill_to_box(LIVES_BOX(hbox));
3560
3561 hbox = lives_hbox_new(FALSE, 0);
3562 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
3563
3564 radiobutton2 = lives_standard_radio_button_new(NULL, &rbgroup, LIVES_BOX(hbox), NULL);
3565
3566 spinbutton_pb_time = lives_standard_spin_button_new(NULL,
3567 (double)((int)(cfile->frames / cfile->fps * 100.)) / 100.,
3568 1. / FPS_MAX, cfile->frames, 1., 10., 2, LIVES_BOX(hbox), NULL);
3569
3570 lives_label_set_mnemonic_widget(LIVES_LABEL(label2), spinbutton_pb_time);
3571 }
3572
3573 lives_label_set_mnemonic_widget(LIVES_LABEL(label), spinbutton_pb_speed);
3574
3575 add_fill_to_box(LIVES_BOX(vbox));
3576
3577 if (type < 3) {
3578 ca_hbox = lives_hbox_new(FALSE, 0);
3579 change_audio_speed = lives_standard_check_button_new
3580 (_("Change the _audio speed as well"), FALSE, LIVES_BOX(ca_hbox), NULL);
3581
3582 lives_box_pack_start(LIVES_BOX(vbox), ca_hbox, TRUE, TRUE, widget_opts.packing_height);
3583
3584 add_fill_to_box(LIVES_BOX(vbox));
3585
3586 if (type != 1 || cfile->achans == 0) lives_widget_set_no_show_all(ca_hbox, TRUE);
3587 }
3588
3589 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(new_pb_speed), LIVES_STOCK_CANCEL, NULL,
3590 LIVES_RESPONSE_CANCEL);
3591
3592 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
3593 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
3594
3595 /// TODO: needs more work to enable easy playback of audio without the video
3596 /* if (type == 3) { */
3597 /* char *tmp; */
3598 /* LiVESWidget *playbutt = lives_dialog_add_button_from_stock(LIVES_DIALOG(new_pb_speed), */
3599 /* LIVES_STOCK_MEDIA_PLAY, */
3600 /* (tmp = (cfile->real_pointer_time > 0. || (cfile->start == 1 && cfile->end == cfile->frames) ? */
3601 /* (_("Preview audio")) : */
3602 /* (_("Preview audio in selected range")))), */
3603 /* LIVES_RESPONSE_CANCEL); */
3604 /* lives_free(tmp); */
3605 /* lives_signal_connect(LIVES_GUI_OBJECT(playbutt), LIVES_WIDGET_CLICKED_SIGNAL, */
3606 /* LIVES_GUI_CALLBACK(preview_aud_vol_cb), */
3607 /* NULL); */
3608 /* } */
3609
3610 change_pb_ok = lives_dialog_add_button_from_stock(LIVES_DIALOG(new_pb_speed), LIVES_STOCK_OK, NULL,
3611 LIVES_RESPONSE_OK);
3612
3613 lives_button_grab_default_special(change_pb_ok);
3614 lives_widget_grab_focus(spinbutton_pb_speed);
3615
3616 if (type < 3) {
3617 reorder_leave_back_set(FALSE);
3618 lives_signal_sync_connect(LIVES_GUI_OBJECT(change_audio_speed), LIVES_WIDGET_TOGGLED_SIGNAL,
3619 LIVES_GUI_CALLBACK(on_boolean_toggled), &mainw->fx1_bool);
3620 }
3621 lives_signal_sync_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
3622 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
3623 if (type == 1) {
3624 lives_signal_sync_connect(LIVES_GUI_OBJECT(change_pb_ok), LIVES_WIDGET_CLICKED_SIGNAL,
3625 LIVES_GUI_CALLBACK(on_change_speed_ok_clicked), NULL);
3626 } else if (type == 2) {
3627 lives_signal_connect(LIVES_GUI_OBJECT(change_pb_ok), LIVES_WIDGET_CLICKED_SIGNAL,
3628 LIVES_GUI_CALLBACK(on_resample_vid_ok), NULL);
3629
3630 } else if (type == 3) {
3631 lives_signal_sync_connect(LIVES_GUI_OBJECT(change_pb_ok), LIVES_WIDGET_CLICKED_SIGNAL,
3632 LIVES_GUI_CALLBACK(on_avolch_ok), NULL);
3633 }
3634
3635 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_pb_speed), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3636 LIVES_GUI_CALLBACK(on_spin_value_changed), LIVES_INT_TO_POINTER(1));
3637
3638 if (type == 1) {
3639 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_pb_time), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3640 LIVES_GUI_CALLBACK(on_spin_value_changed), LIVES_INT_TO_POINTER(2));
3641 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_pb_speed), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3642 LIVES_GUI_CALLBACK(widget_act_toggle), radiobutton1);
3643 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_pb_time), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
3644 LIVES_GUI_CALLBACK(widget_act_toggle), radiobutton2);
3645 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton2), LIVES_WIDGET_TOGGLED_SIGNAL,
3646 LIVES_GUI_CALLBACK(on_boolean_toggled), &mainw->fx2_bool);
3647 }
3648
3649 lives_widget_show_all(new_pb_speed);
3650 }
3651
3652
rb_aud_sel_pressed(LiVESButton * button,livespointer user_data)3653 static void rb_aud_sel_pressed(LiVESButton * button, livespointer user_data) {
3654 aud_dialog_t *audd = (aud_dialog_t *)user_data;
3655 audd->is_sel = !audd->is_sel;
3656 lives_widget_set_sensitive(audd->time_spin, !audd->is_sel);
3657 }
3658
3659
create_audfade_dialog(int type)3660 aud_dialog_t *create_audfade_dialog(int type) {
3661 // type 0 = fade in
3662 // type 1 = fade out
3663
3664 LiVESWidget *dialog_vbox;
3665 LiVESWidget *hbox;
3666 LiVESWidget *rb_sel;
3667 LiVESWidget *label;
3668
3669 char *label_text = NULL, *label_text2 = NULL, *title;
3670
3671 double max;
3672
3673 LiVESSList *radiobutton_group = NULL;
3674
3675 aud_dialog_t *audd = (aud_dialog_t *)lives_malloc(sizeof(aud_dialog_t));
3676
3677 if (type == 0) {
3678 title = (_("Fade Audio In"));
3679 } else {
3680 title = (_("Fade Audio Out"));
3681 }
3682
3683 audd->dialog = lives_standard_dialog_new(title, TRUE, -1, -1);
3684 lives_signal_handlers_disconnect_by_func(audd->dialog, LIVES_GUI_CALLBACK(return_true), NULL);
3685 lives_free(title);
3686
3687 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(audd->dialog));
3688
3689 hbox = lives_hbox_new(FALSE, TB_HEIGHT_AUD);
3690 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
3691
3692
3693
3694 if (type == 0) {
3695 label_text = (_("Fade in over "));
3696 label_text2 = (_("first"));
3697 } else if (type == 1) {
3698 label_text = (_("Fade out over "));
3699 label_text2 = (_("last"));
3700 }
3701
3702 label = lives_standard_label_new(label_text);
3703 if (label_text) lives_free(label_text);
3704
3705 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, 0);
3706
3707 hbox = lives_hbox_new(FALSE, widget_opts.packing_width * 5);
3708 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
3709
3710 lives_standard_radio_button_new(label_text2, &radiobutton_group, LIVES_BOX(hbox), NULL);
3711
3712 if (label_text2) lives_free(label_text2);
3713
3714 max = cfile->laudio_time;
3715
3716 widget_opts.swap_label = TRUE;
3717 audd->time_spin = lives_standard_spin_button_new(_("seconds."),
3718 max / 2. > DEF_AUD_FADE_SECS ? DEF_AUD_FADE_SECS : max / 2., .1, max, 1., 10., 2,
3719 LIVES_BOX(hbox), NULL);
3720 widget_opts.swap_label = FALSE;
3721
3722 hbox = lives_hbox_new(FALSE, widget_opts.packing_width * 5);
3723 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
3724
3725 rb_sel = lives_standard_radio_button_new(_("selection"), &radiobutton_group, LIVES_BOX(hbox), NULL);
3726 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(rb_sel), FALSE);
3727 audd->is_sel = FALSE;
3728
3729 if ((cfile->end - 1.) / cfile->fps > cfile->laudio_time) {
3730 // if selection is longer than audio time, we cannot use sel len
3731 lives_widget_set_sensitive(rb_sel, FALSE);
3732 }
3733
3734 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(rb_sel), LIVES_WIDGET_TOGGLED_SIGNAL,
3735 LIVES_GUI_CALLBACK(rb_aud_sel_pressed), (livespointer)audd);
3736
3737 add_fill_to_box(LIVES_BOX(hbox));
3738
3739 lives_widget_show_all(audd->dialog);
3740
3741 return audd;
3742 }
3743
3744
create_comments_dialog(lives_clip_t * sfile,char * filename)3745 _commentsw *create_comments_dialog(lives_clip_t *sfile, char *filename) {
3746 LiVESWidget *dialog_vbox;
3747 LiVESWidget *table;
3748 LiVESWidget *label;
3749 LiVESWidget *vbox;
3750 LiVESWidget *hbox;
3751 LiVESWidget *buttond;
3752
3753 char *extrabit, *title;
3754
3755 _commentsw *commentsw = (_commentsw *)(lives_malloc(sizeof(_commentsw)));
3756
3757 if (filename) extrabit = (_(" (Optional)"));
3758 else extrabit = lives_strdup("");
3759
3760 title = lives_strdup_printf(_("File Comments%s"), extrabit);
3761
3762 commentsw->comments_dialog = lives_standard_dialog_new(title, TRUE, -1, -1);
3763 lives_free(title);
3764 lives_free(extrabit);
3765 lives_signal_handlers_disconnect_by_func(commentsw->comments_dialog, LIVES_GUI_CALLBACK(return_true), NULL);
3766
3767 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(commentsw->comments_dialog));
3768
3769 if (filename) {
3770 widget_opts.mnemonic_label = FALSE;
3771 label = lives_standard_label_new((extrabit = lives_strdup_printf(_("File Name: %s"), filename)));
3772 widget_opts.mnemonic_label = TRUE;
3773 lives_free(extrabit);
3774 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, TRUE, TRUE, widget_opts.packing_height);
3775 }
3776
3777 table = lives_table_new(4, 2, FALSE);
3778 lives_container_set_border_width(LIVES_CONTAINER(table), widget_opts.border_width);
3779
3780 lives_table_set_row_spacings(LIVES_TABLE(table), widget_opts.packing_height * 4);
3781
3782 lives_box_pack_start(LIVES_BOX(dialog_vbox), table, TRUE, TRUE, widget_opts.packing_height);
3783
3784 label = lives_standard_label_new(_("Title/Name : "));
3785
3786 lives_table_attach(LIVES_TABLE(table), label, 0, 1, 0, 1, (LiVESAttachOptions)(LIVES_FILL),
3787 (LiVESAttachOptions)(0), 0, 0);
3788
3789 label = lives_standard_label_new(_("Author/Artist : "));
3790
3791 lives_table_attach(LIVES_TABLE(table), label, 0, 1, 1, 2,
3792 (LiVESAttachOptions)(LIVES_FILL),
3793 (LiVESAttachOptions)(0), 0, 0);
3794
3795 label = lives_standard_label_new(_("Comments : "));
3796
3797 lives_table_attach(LIVES_TABLE(table), label, 0, 1, 3, 4,
3798 (LiVESAttachOptions)(LIVES_FILL),
3799 (LiVESAttachOptions)(0), 0, 0);
3800
3801 commentsw->title_entry = lives_standard_entry_new(NULL, cfile->title, MEDIUM_ENTRY_WIDTH, 1023, NULL, NULL);
3802
3803 lives_table_attach(LIVES_TABLE(table), commentsw->title_entry, 1, 2, 0, 1,
3804 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
3805 (LiVESAttachOptions)(LIVES_EXPAND), 0, 0);
3806
3807 commentsw->author_entry = lives_standard_entry_new(NULL, cfile->author, MEDIUM_ENTRY_WIDTH, 1023, NULL, NULL);
3808
3809 lives_table_attach(LIVES_TABLE(table), commentsw->author_entry, 1, 2, 1, 2,
3810 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
3811 (LiVESAttachOptions)(LIVES_EXPAND), 0, 0);
3812
3813 commentsw->comment_entry = lives_standard_entry_new(NULL, cfile->comment, MEDIUM_ENTRY_WIDTH, 1023, NULL, NULL);
3814
3815 lives_table_attach(LIVES_TABLE(table), commentsw->comment_entry, 1, 2, 3, 4,
3816 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
3817 (LiVESAttachOptions)(LIVES_EXPAND), 0, 0);
3818
3819 if (filename) {
3820 // options
3821 vbox = lives_vbox_new(FALSE, 0);
3822
3823 add_fill_to_box(LIVES_BOX(vbox));
3824
3825 hbox = lives_hbox_new(FALSE, 0);
3826 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
3827
3828 commentsw->subt_checkbutton = lives_standard_check_button_new(_("Save _subtitles to file"), FALSE, LIVES_BOX(hbox), NULL);
3829
3830 if (!sfile->subt) {
3831 lives_widget_set_sensitive(commentsw->subt_checkbutton, FALSE);
3832 } else lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(commentsw->subt_checkbutton), TRUE);
3833
3834 hbox = lives_hbox_new(FALSE, 0);
3835 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
3836
3837 commentsw->subt_entry = lives_standard_entry_new(_("Subtitle file"), NULL, SHORT_ENTRY_WIDTH, -1, LIVES_BOX(hbox), NULL);
3838
3839 buttond = lives_standard_button_new_with_label(_("Browse..."), DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
3840
3841 lives_signal_sync_connect(buttond, LIVES_WIDGET_CLICKED_SIGNAL, LIVES_GUI_CALLBACK(on_save_subs_activate),
3842 (livespointer)commentsw->subt_entry);
3843
3844 lives_box_pack_start(LIVES_BOX(hbox), buttond, FALSE, FALSE, widget_opts.packing_width);
3845
3846 add_fill_to_box(LIVES_BOX(vbox));
3847
3848 if (!sfile->subt) {
3849 lives_widget_set_sensitive(commentsw->subt_entry, FALSE);
3850 lives_widget_set_sensitive(buttond, FALSE);
3851 } else {
3852 char xfilename[512];
3853 char *osubfname = NULL;
3854
3855 lives_snprintf(xfilename, 512, "%s", filename);
3856 get_filename(xfilename, FALSE); // strip extension
3857 switch (sfile->subt->type) {
3858 case SUBTITLE_TYPE_SRT:
3859 osubfname = lives_strdup_printf("%s.%s", xfilename, LIVES_FILE_EXT_SRT);
3860 break;
3861
3862 case SUBTITLE_TYPE_SUB:
3863 osubfname = lives_strdup_printf("%s.%s", xfilename, LIVES_FILE_EXT_SUB);
3864 break;
3865
3866 default:
3867 break;
3868 }
3869 lives_entry_set_text(LIVES_ENTRY(commentsw->subt_entry), osubfname);
3870 mainw->subt_save_file = osubfname; // assign instead of free
3871 }
3872
3873 lives_widget_set_size_request(vbox, ENC_DETAILS_WIN_H, ENC_DETAILS_WIN_V);
3874 lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
3875 lives_standard_expander_new(_("_Options"), LIVES_BOX(dialog_vbox), vbox);
3876 }
3877
3878 lives_widget_show_all(commentsw->comments_dialog);
3879
3880 return commentsw;
3881 }
3882
3883
3884 static char last_good_folder[PATH_MAX];
3885
chooser_check_dir(LiVESFileChooser * chooser,livespointer user_data)3886 static void chooser_check_dir(LiVESFileChooser * chooser, livespointer user_data) {
3887 char *cwd = lives_get_current_dir();
3888 char *new_dir;
3889
3890 #ifdef GUI_GTK
3891 new_dir = gtk_file_chooser_get_current_folder(chooser);
3892 #endif
3893 #ifdef GUI_QT
3894 QFileDialog *qchooser = static_cast<QFileDialog *>(chooser);
3895 new_dir = qchooser->directory().path().toLocal8Bit().data();
3896 #endif
3897
3898 if (!lives_strcmp(new_dir, last_good_folder)) {
3899 lives_free(cwd);
3900 return;
3901 }
3902
3903 if (lives_chdir(new_dir, TRUE)) {
3904 lives_free(cwd);
3905 #ifdef GUI_GTK
3906 gtk_file_chooser_set_current_folder(chooser, last_good_folder);
3907 #endif
3908 #ifdef GUI_QT
3909 qchooser->setDirectory(last_good_folder);
3910 #endif
3911 do_dir_perm_access_error(new_dir);
3912 lives_free(new_dir);
3913 return;
3914 }
3915 lives_snprintf(last_good_folder, PATH_MAX, "%s", new_dir);
3916 lives_chdir(cwd, FALSE);
3917 lives_free(new_dir);
3918 lives_free(cwd);
3919 }
3920
3921
3922 /**
3923 @brief callback for lives_standard filesel button
3924 same callback is used for dierctory buttons
3925 object_data in button refinses the behaviousr, see code for details
3926
3927 such buttons may be created independently (e.g for the RFX "fileread" / "filewrite" special types
3928 or via lives_standard_direntry_new() / lives_standard_fileentry_new()
3929 */
on_filesel_button_clicked(LiVESButton * button,livespointer user_data)3930 void on_filesel_button_clicked(LiVESButton * button, livespointer user_data) {
3931 LiVESWidget *tentry = LIVES_WIDGET(user_data);
3932 lives_rfx_t *rfx;
3933 char **filt = NULL;
3934 char *dirname = NULL, *fname, *tmp, *def_dir = NULL;
3935 boolean is_dir = TRUE, free_def_dir = FALSE;
3936 int filesel_type = LIVES_FILE_SELECTION_UNDEFINED;
3937
3938 if (button) {
3939 /// various data can be set in the button object, including:
3940 /// (set in lives_standard_file_button_new())
3941 /// DEFDIR_KEY (char *)
3942 /// ISDIR_KEY (boolean)
3943 ///
3944 /// FILTER_KEY (char **)
3945 /// FILESEL_TYPE_KEY (int (enum))
3946
3947 // selects between file mode and directory mode
3948 is_dir = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), ISDIR_KEY));
3949
3950 // default dir for directory mode
3951 def_dir = (char *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), DEFDIR_KEY);
3952
3953 /// NULL terminated array of char * filters (file extensions)
3954 filt = (char **)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), FILTER_KEY);
3955
3956 /// fine tunes for the file selection / dir selection target
3957 if (lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), FILESEL_TYPE_KEY)) {
3958 filesel_type = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), FILESEL_TYPE_KEY));
3959 }
3960 }
3961
3962 /// take the filename from the text entry widget
3963 if (LIVES_IS_TEXT_VIEW(tentry)) fname = lives_text_view_get_text(LIVES_TEXT_VIEW(tentry));
3964 else fname = lives_strdup(lives_entry_get_text(LIVES_ENTRY(tentry)));
3965
3966 /// TODO: only do this for directory mode, blank text is valid filename
3967 if (is_dir) {
3968 /// if no text, we look instead in def_dir (if present)
3969 if (!*fname) {
3970 lives_free(fname);
3971 fname = def_dir;
3972 }
3973 }
3974
3975 /// can this be removed ?
3976 lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
3977
3978 switch (filesel_type) {
3979 case LIVES_FILE_SELECTION_UNDEFINED:
3980 if (!is_dir && *fname && (!def_dir || !(*def_dir))) {
3981 def_dir = get_dir(fname);
3982 free_def_dir = TRUE;
3983 }
3984
3985 dirname = choose_file(is_dir ? fname : def_dir, is_dir ? NULL : fname, filt,
3986 is_dir ? LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER :
3987 (fname == def_dir && def_dir && !lives_strcmp(def_dir, LIVES_DEVICE_DIR))
3988 ? LIVES_FILE_CHOOSER_ACTION_SELECT_DEVICE :
3989 LIVES_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
3990 break;
3991
3992 case LIVES_DIR_SELECTION_CREATE_FOLDER:
3993 dirname = choose_file(fname, NULL, NULL, LIVES_FILE_CHOOSER_ACTION_CREATE_FOLDER, NULL, NULL);
3994 break;
3995 case LIVES_DIR_SELECTION_SELECT_FOLDER:
3996 dirname = choose_file(fname, NULL, NULL, LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL, NULL);
3997 break;
3998 case LIVES_DIR_SELECTION_WORKDIR:
3999 dirname = choose_file(fname, NULL, NULL, LIVES_FILE_CHOOSER_ACTION_CREATE_FOLDER, NULL, NULL);
4000
4001 if (strcmp(dirname, fname)) {
4002 /// apply extra validity checks (check writeable, warn if set to home dir, etc)
4003 if (check_workdir_valid(&dirname, LIVES_DIALOG(lives_widget_get_toplevel(LIVES_WIDGET(button))),
4004 FALSE) == LIVES_RESPONSE_RETRY) {
4005 lives_free(dirname);
4006 dirname = lives_strdup(fname);
4007 }
4008 }
4009 break;
4010 case LIVES_FILE_SELECTION_OPEN:
4011 case LIVES_FILE_SELECTION_SAVE: {
4012 char fnamex[PATH_MAX], dirnamex[PATH_MAX];
4013 boolean free_filt = FALSE;
4014
4015 lives_snprintf(dirnamex, PATH_MAX, "%s", fname);
4016 lives_snprintf(fnamex, PATH_MAX, "%s", fname);
4017
4018 get_dirname(dirnamex);
4019 get_basename(fnamex);
4020
4021 if (!is_dir && !filt && *fnamex) {
4022 /// for save and not is_dir, we break filename into directory, filename components
4023 /// and set a filter with the filename extension (can be overridden by setting FILTER_KEY)
4024 char *tmp;
4025 filt = (char **)lives_malloc(2 * sizeof(char *));
4026 filt[0] = lives_strdup_printf("*.%s", (tmp = get_extension(fnamex)));
4027 filt[1] = NULL;
4028 free_filt = TRUE;
4029 lives_free(tmp);
4030 }
4031
4032 dirname = choose_file(def_dir ? def_dir : dirnamex, fnamex, filt, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
4033
4034 if (filesel_type == LIVES_FILE_SELECTION_OPEN);
4035
4036 if (free_filt) {
4037 lives_free(filt[0]);
4038 lives_free(filt);
4039 }
4040 }
4041 break;
4042
4043 default: {
4044 /// other types get a filechooser with preview
4045 LiVESWidget *chooser = choose_file_with_preview(def_dir, fname, filt, filesel_type);
4046 int resp = lives_dialog_run(LIVES_DIALOG(chooser));
4047
4048 end_fs_preview();
4049
4050 if (resp == LIVES_RESPONSE_ACCEPT) {
4051 dirname = lives_file_chooser_get_filename(LIVES_FILE_CHOOSER(chooser));
4052 }
4053 lives_widget_destroy(LIVES_WIDGET(chooser));
4054 }
4055 }
4056
4057 if (fname && fname != def_dir) lives_free(fname);
4058 if (free_def_dir) lives_free(def_dir);
4059
4060 /// we set dirname in both file mode and dir mode
4061 if (!dirname) return;
4062
4063 /// update text widget
4064 if (LIVES_IS_ENTRY(tentry)) lives_entry_set_text(LIVES_ENTRY(tentry),
4065 (tmp = lives_filename_to_utf8(dirname, -1, NULL, NULL, NULL)));
4066 else lives_text_view_set_text(LIVES_TEXT_VIEW(tentry), (tmp = lives_filename_to_utf8(dirname, -1, NULL, NULL, NULL)), -1);
4067 lives_free(tmp); lives_free(dirname);
4068
4069 if ((rfx = (lives_rfx_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(tentry), "rfx")) != NULL) {
4070 /// if running inside a parameter window, reflect update in related paramter values
4071 int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(tentry), "param_number"));
4072 after_param_text_changed(tentry, rfx);
4073
4074 /// set to FALSE since no unapplied edits have been made
4075 rfx->params[param_number].edited = FALSE;
4076 }
4077 }
4078
4079
choose_file(const char * dir,const char * fname,char ** const filt,LiVESFileChooserAction act,const char * title,LiVESWidget * extra_widget)4080 char *choose_file(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act,
4081 const char *title, LiVESWidget * extra_widget) {
4082 // new style file chooser
4083
4084 // in/out values are in utf8 encoding
4085 LiVESWidget *chooser;
4086
4087 char *mytitle;
4088 char *filename = NULL;
4089
4090 int response;
4091 int i;
4092
4093 if (!title) {
4094 if (act == LIVES_FILE_CHOOSER_ACTION_SELECT_DEVICE) {
4095 mytitle = lives_strdup_printf(_("%sChoose a Device"), widget_opts.title_prefix);
4096 act = LIVES_FILE_CHOOSER_ACTION_OPEN;
4097 } else if (act == LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER) {
4098 mytitle = lives_strdup_printf(_("%sChoose a Directory"), widget_opts.title_prefix);
4099 } else {
4100 mytitle = lives_strdup_printf(_("%sChoose a File"), widget_opts.title_prefix);
4101 }
4102 } else mytitle = lives_strdup_printf("%s%s", widget_opts.title_prefix, title);
4103
4104 #ifdef GUI_GTK
4105 if (act != LIVES_FILE_CHOOSER_ACTION_SAVE) {
4106 const char *stocklabel;
4107 if (act == LIVES_FILE_CHOOSER_ACTION_OPEN) {
4108 stocklabel = LIVES_STOCK_LABEL_OPEN;
4109 } else stocklabel = LIVES_STOCK_LABEL_SELECT;
4110 chooser = gtk_file_chooser_dialog_new(mytitle, LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), (LiVESFileChooserAction)act,
4111 LIVES_STOCK_LABEL_CANCEL, LIVES_RESPONSE_CANCEL,
4112 stocklabel, LIVES_RESPONSE_ACCEPT, NULL);
4113 } else {
4114 chooser = gtk_file_chooser_dialog_new(mytitle, LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), (LiVESFileChooserAction)act,
4115 LIVES_STOCK_LABEL_CANCEL, LIVES_RESPONSE_CANCEL,
4116 LIVES_STOCK_LABEL_SAVE, LIVES_RESPONSE_ACCEPT, NULL);
4117 }
4118
4119 if (dir) {
4120 gtk_file_chooser_set_current_folder(LIVES_FILE_CHOOSER(chooser), dir);
4121 }
4122
4123 lives_widget_show_all(chooser);
4124
4125 if (prefs->fileselmax) {
4126 lives_window_maximize(LIVES_WINDOW(chooser));
4127 }
4128
4129 gtk_file_chooser_set_local_only(LIVES_FILE_CHOOSER(chooser), TRUE);
4130
4131 if (filt) {
4132 GtkFileFilter *filter = gtk_file_filter_new();
4133 for (i = 0; filt[i]; i++) gtk_file_filter_add_pattern(filter, filt[i]);
4134 gtk_file_chooser_set_filter(LIVES_FILE_CHOOSER(chooser), filter);
4135 if (i == 1 && act == LIVES_FILE_CHOOSER_ACTION_SAVE)
4136 gtk_file_chooser_set_current_name(LIVES_FILE_CHOOSER(chooser), filt[0]); //utf-8
4137 }
4138
4139 if (fname) {
4140 if (act == LIVES_FILE_CHOOSER_ACTION_SAVE || act == LIVES_FILE_CHOOSER_ACTION_CREATE_FOLDER) { // prevent assertion in gtk+
4141 gtk_file_chooser_set_current_name(LIVES_FILE_CHOOSER(chooser), fname); // utf-8
4142 if (fname && dir) {
4143 char *ffname = lives_build_filename(dir, fname, NULL);
4144 gtk_file_chooser_select_filename(LIVES_FILE_CHOOSER(chooser), ffname); // must be dir and file
4145 lives_free(ffname);
4146 }
4147 }
4148 }
4149
4150 /* if (extra_widget && extra_widget != LIVES_MAIN_WINDOW_WIDGET) { */
4151 /* gtk_file_chooser_set_extra_widget(LIVES_FILE_CHOOSER(chooser), extra_widget); */
4152 /* if (palette->style & STYLE_1) { */
4153 /* LiVESWidget *parent = lives_widget_get_parent(extra_widget); */
4154
4155 /* while (parent) { */
4156 /* lives_widget_set_fg_color(parent, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore); */
4157 /* lives_widget_set_bg_color(parent, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back); */
4158 /* parent = lives_widget_get_parent(parent); */
4159 /* } */
4160 /* } */
4161 /* } */
4162
4163 if (mainw->is_ready && palette->style & STYLE_1) {
4164 lives_widget_set_bg_color(chooser, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
4165 lives_widget_set_fg_color(chooser, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
4166 set_child_colour(chooser, FALSE);
4167 }
4168
4169 #endif
4170
4171 lives_container_set_border_width(LIVES_CONTAINER(chooser), widget_opts.border_width);
4172
4173 if (prefs->show_gui) {
4174 LiVESWindow *transient = widget_opts.transient;
4175 if (!transient) transient = get_transient_full();
4176 if (transient)
4177 lives_window_set_transient_for(LIVES_WINDOW(chooser), transient);
4178 }
4179
4180 lives_signal_sync_connect(chooser, LIVES_WIDGET_CURRENT_FOLDER_CHANGED_SIGNAL, LIVES_GUI_CALLBACK(chooser_check_dir), NULL);
4181 //lives_widget_grab_focus(chooser);
4182 lives_window_center(LIVES_WINDOW(chooser));
4183 lives_window_set_modal(LIVES_WINDOW(chooser), TRUE);
4184 lives_memset(last_good_folder, 0, 1);
4185
4186 //set this so we know when button is pressed, even if waiting for preview to finish
4187 mainw->fc_buttonresponse = LIVES_RESPONSE_NONE;
4188 //lives_signal_sync_connect(chooser, LIVES_WIDGET_RESPONSE_SIGNAL, LIVES_GUI_CALLBACK(chooser_response), NULL);
4189
4190 if (dir) {
4191 gtk_file_chooser_set_current_folder(LIVES_FILE_CHOOSER(chooser), dir);
4192 gtk_file_chooser_add_shortcut_folder(LIVES_FILE_CHOOSER(chooser), dir, NULL);
4193 }
4194
4195 if (extra_widget == LIVES_MAIN_WINDOW_WIDGET && LIVES_MAIN_WINDOW_WIDGET) {
4196 return (char *)chooser; // kludge to allow custom adding of extra widgets
4197 }
4198
4199 rundlg:
4200 if ((response = lives_dialog_run(LIVES_DIALOG(chooser))) != LIVES_RESPONSE_CANCEL) {
4201 char *tmp;
4202 filename = lives_filename_to_utf8((tmp = lives_file_chooser_get_filename(LIVES_FILE_CHOOSER(chooser))),
4203 -1, NULL, NULL, NULL);
4204 lives_free(tmp);
4205 } else filename = NULL;
4206
4207 if (response && filename && act == LIVES_FILE_CHOOSER_ACTION_SAVE) {
4208 if (!check_file(filename, TRUE)) {
4209 lives_free(filename);
4210 filename = NULL;
4211 goto rundlg;
4212 }
4213 }
4214
4215 lives_free(mytitle);
4216 lives_widget_destroy(chooser);
4217 mainw->fc_buttonresponse = response;
4218 return filename;
4219 }
4220
choose_file_bg(const char * dir,const char * fname,char ** const filt,LiVESFileChooserAction act,const char * title,LiVESWidget * extra_widget)4221 char *choose_file_bg(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act,
4222 const char *title, LiVESWidget * extra_widget) {
4223 return main_thread_execute((lives_funcptr_t)choose_file, WEED_SEED_STRING,
4224 NULL, "ssvisv", dir, fname, filt, act, title, extra_widget);
4225 }
4226
4227
choose_file_with_preview(const char * dir,const char * title,char ** const filt,int filesel_type)4228 LiVESWidget *choose_file_with_preview(const char *dir, const char *title, char **const filt, int filesel_type) {
4229 // filesel_type 1 - video and audio open (single - opensel)
4230 //LIVES_FILE_SELECTION_VIDEO_AUDIO
4231
4232 // preview type 2 - import audio
4233 // LIVES_FILE_SELECTION_AUDIO_ONLY
4234
4235 // filesel_type 3 - video and audio open (multiple)
4236 //LIVES_FILE_SELECTION_VIDEO_AUDIO_MULTI
4237
4238 // type 4
4239 // LIVES_FILE_SELECTION_VIDEO_RANGE
4240
4241 // type 5
4242 // LIVES_FILE_SELECTION_IMAGE_ONLY
4243
4244 // unfortunately we cannot simply run this and return a filename, in case there is a selection
4245
4246 LiVESWidget *chooser;
4247
4248 int preview_type;
4249
4250 if (filesel_type == LIVES_DIR_SELECTION_CREATE_FOLDER) {
4251 chooser = (LiVESWidget *)choose_file(dir, NULL, filt, LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER,
4252 title, LIVES_MAIN_WINDOW_WIDGET);
4253 gtk_file_chooser_set_create_folders(LIVES_FILE_CHOOSER(chooser), TRUE);
4254 } else if (filesel_type == LIVES_DIR_SELECTION_SELECT_FOLDER)
4255 chooser = (LiVESWidget *)choose_file(dir, NULL, filt, LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER,
4256 title, LIVES_MAIN_WINDOW_WIDGET);
4257
4258 chooser = (LiVESWidget *)choose_file(dir, NULL, filt, LIVES_FILE_CHOOSER_ACTION_OPEN, title, LIVES_MAIN_WINDOW_WIDGET);
4259
4260 if (filesel_type == LIVES_FILE_SELECTION_VIDEO_AUDIO_MULTI) {
4261 #ifdef GUI_GTK
4262 gtk_file_chooser_set_select_multiple(LIVES_FILE_CHOOSER(chooser), TRUE);
4263 #endif
4264 }
4265
4266 switch (filesel_type) {
4267 case LIVES_FILE_SELECTION_VIDEO_AUDIO:
4268 case LIVES_FILE_SELECTION_VIDEO_AUDIO_MULTI:
4269 preview_type = LIVES_PREVIEW_TYPE_VIDEO_AUDIO;
4270 break;
4271 case LIVES_FILE_SELECTION_IMAGE_ONLY:
4272 preview_type = LIVES_PREVIEW_TYPE_IMAGE_ONLY;
4273 break;
4274 default:
4275 preview_type = LIVES_PREVIEW_TYPE_AUDIO_ONLY;
4276 }
4277
4278 widget_add_preview(chooser, LIVES_BOX(lives_dialog_get_content_area(LIVES_DIALOG(chooser))),
4279 LIVES_BOX(lives_dialog_get_content_area(LIVES_DIALOG(chooser))),
4280 LIVES_BOX(lives_dialog_get_action_area(LIVES_DIALOG(chooser))),
4281 preview_type);
4282
4283 if (prefs->fileselmax) {
4284 int scr_width = GUI_SCREEN_WIDTH;
4285 int scr_height = GUI_SCREEN_HEIGHT;
4286 int bx, by, w, h;
4287
4288 lives_widget_show_all(chooser);
4289 lives_widget_process_updates(chooser);
4290
4291 get_border_size(chooser, &bx, &by);
4292 w = lives_widget_get_allocation_width(chooser);
4293 h = lives_widget_get_allocation_height(chooser);
4294
4295 if (w > scr_width - bx || h > scr_height - by) {
4296 if (w > scr_width - bx || h > scr_height - by) {
4297 int overflowx = w - (scr_width - bx);
4298 int overflowy = h - (scr_height - by);
4299
4300 int mywidth = lives_widget_get_allocation_width(chooser);
4301 int myheight = lives_widget_get_allocation_height(chooser);
4302
4303 #ifdef DEBUG_OVERFLOW
4304 g_print("overflow is %d X %d\n", overflowx, overflowy);
4305 #endif
4306 if (overflowx > 0) mywidth -= overflowx;
4307 if (overflowy > 0) myheight -= overflowy;
4308
4309 lives_widget_process_updates(chooser);
4310
4311 if (overflowx > 0 || overflowy > 0) {
4312 lives_widget_set_size_request(chooser, mywidth, myheight);
4313 }
4314 lives_widget_process_updates(chooser);
4315
4316 w = scr_width - bx;
4317 h = scr_height - by;
4318
4319 lives_window_unmaximize(LIVES_WINDOW(chooser));
4320 lives_widget_process_updates(chooser);
4321 lives_window_resize(LIVES_WINDOW(chooser), w, h);
4322 lives_widget_process_updates(chooser);
4323
4324 if (prefs->open_maximised) {
4325 lives_window_maximize(LIVES_WINDOW(chooser));
4326 }
4327 }
4328 } else {
4329 lives_window_maximize(LIVES_WINDOW(chooser));
4330 }
4331 lives_widget_process_updates(chooser);
4332 }
4333 return chooser;
4334 }
4335
4336 /* LiVESWidget *choose_file_with_preview(const char *dir, const char *title, char **const filt, int filesel_type) { */
4337 /* return main_thread_execute((lives_funcptr_t)_choose_file_with_preview, WEED_SEED_STRING, */
4338 /* NULL, "ssvi", dir, title, filt, filesel_type); */
4339 /* } */
4340
4341
make_autoreload_check(LiVESHBox * hbox,boolean is_active)4342 LIVES_GLOBAL_INLINE LiVESWidget *make_autoreload_check(LiVESHBox * hbox, boolean is_active) {
4343 return lives_standard_check_button_new(_("_Autoreload next time"), is_active, LIVES_BOX(hbox), NULL);
4344 }
4345
4346
4347 //cancel/discard/save dialog
create_cds_dialog(int type)4348 _entryw *create_cds_dialog(int type) {
4349 // values for type are:
4350 // 0 == leave multitrack, user pref is warn when leave multitrack
4351 // 1 == exit from LiVES, or save set
4352 // 2 == ?
4353 // 3 == wipe layout confirmation
4354 // 4 == prompt for render after recording / viewing in mt
4355
4356 LiVESWidget *dialog_vbox;
4357 LiVESWidget *cancelbutton;
4358 LiVESWidget *discardbutton;
4359 LiVESWidget *savebutton = NULL;
4360
4361 LiVESAccelGroup *accel_group;
4362
4363 char *labeltext = NULL;
4364
4365 _entryw *cdsw = (_entryw *)(lives_malloc(sizeof(_entryw)));
4366
4367 cdsw->warn_checkbutton = NULL;
4368
4369 if (type == 0) {
4370 if (!*mainw->multitrack->layout_name) {
4371 labeltext = lives_strdup(
4372 _("You are about to leave multitrack mode.\n"
4373 "The current layout has not been saved.\nWhat would you like to do ?\n"));
4374 } else {
4375 labeltext = lives_strdup(
4376 _("You are about to leave multitrack mode.\n"
4377 "The current layout has been changed since the last save.\n"
4378 "What would you like to do ?\n"));
4379 }
4380 } else if (type == 1) {
4381 if (!mainw->only_close) labeltext = lives_strdup(
4382 _("You are about to exit LiVES.\n"
4383 "The current clip set can be saved.\n"
4384 "What would you like to do ?\n"));
4385 else labeltext = (_("The current clip set has not been saved.\nWhat would you like to do ?\n"));
4386 } else if (type == 2 || type == 3) {
4387 if ((mainw->multitrack && mainw->multitrack->changed) || (mainw->stored_event_list &&
4388 mainw->stored_event_list_changed)) {
4389 labeltext = (_("The current layout has not been saved.\nWhat would you like to do ?\n"));
4390 } else {
4391 labeltext = lives_strdup(
4392 _("The current layout has *NOT BEEN CHANGED* since it was last saved.\n"
4393 "What would you like to do ?\n"));
4394 }
4395 } else if (type == 4) {
4396 labeltext = lives_strdup(
4397 _("You are about to leave multitrack mode.\n"
4398 "The current layout contains generated frames and cannot be retained.\n"
4399 "What do you wish to do ?"));
4400 }
4401
4402 cdsw->dialog = create_question_dialog(_("Save or Delete Set"), labeltext);
4403
4404 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(cdsw->dialog));
4405
4406 if (labeltext) lives_free(labeltext);
4407
4408 if (type == 1) {
4409 LiVESWidget *checkbutton;
4410 LiVESWidget *hbox = lives_hbox_new(FALSE, 0);
4411 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
4412
4413 cdsw->entry = lives_standard_entry_new(_("Clip set _name"), strlen(mainw->set_name)
4414 ? mainw->set_name : "",
4415 SHORT_ENTRY_WIDTH, 128, LIVES_BOX(hbox), NULL);
4416
4417 hbox = lives_hbox_new(FALSE, 0);
4418 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
4419
4420 prefs->ar_clipset = !mainw->only_close;
4421 checkbutton = make_autoreload_check(LIVES_HBOX(hbox), prefs->ar_clipset);
4422
4423 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(checkbutton), "cdsw", (livespointer)cdsw);
4424
4425 lives_signal_sync_connect(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
4426 LIVES_GUI_CALLBACK(toggle_sets_pref),
4427 (livespointer)PREF_AR_CLIPSET);
4428 }
4429
4430 if (type == 0 && !(prefs->warning_mask & WARN_MASK_EXIT_MT)) {
4431 add_warn_check(LIVES_BOX(dialog_vbox), WARN_MASK_EXIT_MT);
4432 }
4433
4434 accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
4435 lives_window_add_accel_group(LIVES_WINDOW(cdsw->dialog), accel_group);
4436
4437 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(cdsw->dialog), LIVES_STOCK_CANCEL, NULL,
4438 LIVES_RESPONSE_CANCEL);
4439
4440 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
4441 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
4442
4443 discardbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(cdsw->dialog), LIVES_STOCK_DELETE, NULL,
4444 (type == 2) ? LIVES_RESPONSE_ABORT : LIVES_RESPONSE_RESET);
4445
4446 if ((type == 0 && !*mainw->multitrack->layout_name) || type == 3 || type == 4)
4447 lives_button_set_label(LIVES_BUTTON(discardbutton), _("_Wipe layout"));
4448 else if (type == 0) lives_button_set_label(LIVES_BUTTON(discardbutton), _("_Ignore changes"));
4449 else if (type == 1) {
4450 if (mainw->was_set)
4451 lives_button_set_label(LIVES_BUTTON(discardbutton), _("_Delete clip set"));
4452 else
4453 lives_button_set_label(LIVES_BUTTON(discardbutton), _("_Discard all clips"));
4454 } else if (type == 2) lives_button_set_label(LIVES_BUTTON(discardbutton), _("_Delete layout"));
4455
4456 if (type != 4) savebutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(cdsw->dialog), LIVES_STOCK_SAVE, NULL,
4457 (type == 2) ? LIVES_RESPONSE_RETRY : LIVES_RESPONSE_ACCEPT);
4458 if (type == 0 || type == 3) lives_button_set_label(LIVES_BUTTON(savebutton), _("_Save layout"));
4459 else if (type == 1) lives_button_set_label(LIVES_BUTTON(savebutton), _("_Save clip set"));
4460 else if (type == 2) lives_button_set_label(LIVES_BUTTON(savebutton), _("_Wipe layout"));
4461 if (type == 1 || type == 2) lives_button_grab_default_special(savebutton);
4462
4463 lives_widget_show_all(cdsw->dialog);
4464
4465 if (type == 1) {
4466 lives_widget_grab_focus(cdsw->entry);
4467 }
4468
4469 if (!LIVES_IS_INTERACTIVE) lives_widget_set_sensitive(cancelbutton, FALSE);
4470
4471 return cdsw;
4472 }
4473
4474
flip_cdisk_bit(LiVESToggleButton * t,livespointer user_data)4475 static void flip_cdisk_bit(LiVESToggleButton * t, livespointer user_data) {
4476 uint32_t bitmask = LIVES_POINTER_TO_INT(user_data);
4477 prefs->clear_disk_opts ^= bitmask;
4478 }
4479
4480
create_cleardisk_advanced_dialog(void)4481 LiVESWidget *create_cleardisk_advanced_dialog(void) {
4482 LiVESWidget *dialog;
4483 LiVESWidget *dialog_vbox;
4484 LiVESWidget *scrollw;
4485 LiVESWidget *vbox;
4486 LiVESWidget *hbox;
4487 LiVESWidget *checkbutton;
4488 LiVESWidget *okbutton;
4489
4490 int woat = widget_opts.apply_theme;
4491
4492 char *tmp, *tmp2;
4493
4494 dialog = lives_standard_dialog_new(_("Disk Recovery Options"), FALSE, DEF_DIALOG_WIDTH, DEF_DIALOG_HEIGHT);
4495
4496 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
4497
4498 vbox = lives_vbox_new(FALSE, 0);
4499 lives_container_set_border_width(LIVES_CONTAINER(vbox), widget_opts.border_width * 2);
4500
4501 widget_opts.apply_theme = 0;
4502 scrollw = lives_standard_scrolled_window_new(DEF_DIALOG_WIDTH, DEF_DIALOG_HEIGHT, vbox);
4503 widget_opts.apply_theme = woat;
4504
4505 lives_container_add(LIVES_CONTAINER(dialog_vbox), scrollw);
4506
4507 hbox = lives_hbox_new(FALSE, 0);
4508 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, TRUE, widget_opts.packing_height);
4509
4510 checkbutton = lives_standard_check_button_new((tmp = (_("Check for Lost Clips"))),
4511 !(prefs->clear_disk_opts & LIVES_CDISK_REMOVE_ORPHAN_CLIPS), LIVES_BOX(hbox),
4512 (tmp2 = (H_("Enable attempted recovery of potential lost clips before deleting them.\n"
4513 "Can be overriden after disk analysis."))));
4514
4515 lives_free(tmp); lives_free(tmp2);
4516
4517 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
4518 LIVES_GUI_CALLBACK(flip_cdisk_bit),
4519 LIVES_INT_TO_POINTER(LIVES_CDISK_REMOVE_ORPHAN_CLIPS));
4520
4521 hbox = lives_hbox_new(FALSE, 0);
4522 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, TRUE, widget_opts.packing_height);
4523
4524 checkbutton = lives_standard_check_button_new((tmp = (_("Remove Empty Directories"))),
4525 !(prefs->clear_disk_opts & LIVES_CDISK_LEAVE_EMPTY_DIRS), LIVES_BOX(hbox),
4526 (tmp2 = (H_("Remove any empty directories within the working directory"))));
4527
4528 lives_free(tmp); lives_free(tmp2);
4529
4530 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
4531 LIVES_GUI_CALLBACK(flip_cdisk_bit),
4532 LIVES_INT_TO_POINTER(LIVES_CDISK_LEAVE_ORPHAN_SETS));
4533
4534 hbox = lives_hbox_new(FALSE, 0);
4535 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, TRUE, widget_opts.packing_height);
4536
4537 checkbutton = lives_standard_check_button_new((tmp = (_("Delete _Orphaned Clips"))),
4538 !(prefs->clear_disk_opts & LIVES_CDISK_LEAVE_ORPHAN_SETS), LIVES_BOX(hbox),
4539 (tmp2 = (H_("Delete any clips which are not currently loaded or part of a set\n"
4540 "If 'Check for Lost Clips' is set, LiVES will try to recover them first"))));
4541
4542 lives_free(tmp); lives_free(tmp2);
4543
4544 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
4545 LIVES_GUI_CALLBACK(flip_cdisk_bit),
4546 LIVES_INT_TO_POINTER(LIVES_CDISK_LEAVE_ORPHAN_SETS));
4547
4548 hbox = lives_hbox_new(FALSE, 0);
4549 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, TRUE, widget_opts.packing_height);
4550
4551 checkbutton = lives_standard_check_button_new(_("Clear Useless _Backup Files from Clips"),
4552 !(prefs->clear_disk_opts & LIVES_CDISK_LEAVE_BFILES), LIVES_BOX(hbox), NULL);
4553
4554 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
4555 LIVES_GUI_CALLBACK(flip_cdisk_bit),
4556 LIVES_INT_TO_POINTER(LIVES_CDISK_LEAVE_BFILES));
4557
4558 hbox = lives_hbox_new(FALSE, 0);
4559 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, TRUE, widget_opts.packing_height);
4560
4561 checkbutton = lives_standard_check_button_new(_("Remove Sets which have _Layouts but no Clips"),
4562 (prefs->clear_disk_opts & LIVES_CDISK_REMOVE_ORPHAN_LAYOUTS), LIVES_BOX(hbox), NULL);
4563
4564 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
4565 LIVES_GUI_CALLBACK(flip_cdisk_bit),
4566 LIVES_INT_TO_POINTER(LIVES_CDISK_REMOVE_ORPHAN_LAYOUTS));
4567
4568 // resetbutton
4569 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_REFRESH, _("_Reset to Defaults"),
4570 LIVES_RESPONSE_RETRY);
4571
4572 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
4573 LIVES_RESPONSE_OK);
4574
4575 lives_button_grab_default_special(okbutton);
4576
4577 return dialog;
4578 }
4579
4580
4581 #ifdef GTK_TEXT_VIEW_DRAW_BUG
4582
4583 static ulong expt;
4584
exposetview(LiVESWidget * widget,lives_painter_t * cr,livespointer user_data)4585 static boolean exposetview(LiVESWidget * widget, lives_painter_t *cr, livespointer user_data) {
4586 LiVESWidgetColor fgcol, bgcol;
4587 lives_colRGBA64_t fg, bg;
4588 LingoLayout *layout = NULL;
4589 lives_painter_surface_t *surface;
4590 char *text = lives_text_view_get_text(LIVES_TEXT_VIEW(widget));
4591 double top = 0;
4592 int offsx = 0;
4593 int height = lives_widget_get_allocation_height(widget);
4594
4595 lives_signal_handler_block(widget, expt);
4596
4597 surface = lives_painter_get_target(cr);
4598 lives_painter_surface_flush(surface);
4599
4600 lives_widget_get_fg_state_color(widget, lives_widget_get_state(widget), &fgcol);
4601 lives_widget_get_bg_state_color(widget, lives_widget_get_state(widget), &bgcol);
4602
4603 widget_color_to_lives_rgba(&fg, &fgcol);
4604 widget_color_to_lives_rgba(&bg, &bgcol);
4605
4606 layout = render_text_to_cr(widget, cr, text, "", 0.0,
4607 LIVES_TEXT_MODE_FOREGROUND_ONLY, &fg, &bg, FALSE, FALSE, &top, &offsx,
4608 lives_widget_get_allocation_width(widget), &height);
4609
4610 lives_free(text);
4611
4612 if (layout) {
4613 if (LINGO_IS_LAYOUT(layout)) {
4614 lingo_painter_show_layout(cr, layout);
4615 }
4616 lives_widget_object_unref(layout);
4617 //if (LIVES_IS_WIDGET_OBJECT(layout)) lives_widget_object_unref(layout);
4618 }
4619
4620 //lives_painter_fill(cr);
4621
4622 lives_signal_handler_unblock(widget, expt);
4623
4624 return FALSE;
4625 }
4626
4627 #endif
4628
4629
create_output_textview(void)4630 LiVESTextView *create_output_textview(void) {
4631 LiVESWidget *textview = lives_standard_text_view_new(NULL, NULL);
4632
4633 #ifdef GTK_TEXT_VIEW_DRAW_BUG
4634 expt = lives_signal_sync_connect(LIVES_GUI_OBJECT(textview), LIVES_WIDGET_EXPOSE_EVENT,
4635 LIVES_GUI_CALLBACK(exposetview), NULL);
4636 #endif
4637 lives_widget_object_ref(textview);
4638 return LIVES_TEXT_VIEW(textview);
4639 }
4640
4641
4642 static int currow;
4643
pair_add(LiVESWidget * table,const char * key,const char * meaning)4644 static void pair_add(LiVESWidget * table, const char *key, const char *meaning) {
4645 LiVESWidget *labelk, *labelm, *align;
4646 double kalign = 0., malign = 0.;
4647 boolean key_all = FALSE;
4648
4649 if (!key) {
4650 // NULL, NULL -> hsep all TODO
4651 if (!meaning) {
4652 labelk = lives_standard_hseparator_new();
4653 key_all = TRUE;
4654 } else {
4655 if (*meaning) {
4656 // NULL, meaning -> centered meaning; hsep key
4657 pair_add(table, meaning, "");
4658 pair_add(table, NULL, "");
4659 return;
4660 } else {
4661 // NULL, "" -> hsep key
4662 labelk = lives_standard_hseparator_new();
4663 labelm = lives_standard_label_new("");
4664 }
4665 }
4666 } else {
4667 if (!*key) {
4668 // "", NULL -> hsep meaning
4669 if (!meaning) {
4670 labelk = lives_standard_label_new("");
4671 labelm = lives_standard_hseparator_new();
4672 } else {
4673 if (!*meaning) {
4674 //// "", "" -> newline
4675 labelk = lives_standard_label_new("");
4676 labelm = lives_standard_label_new("");
4677 } else {
4678 /// "", meaning -> "" | centered meaning
4679 labelk = lives_standard_label_new("");
4680 labelm = lives_standard_label_new(meaning);
4681 malign = .5;
4682 }
4683 }
4684 } else {
4685 // key, NULL -> all centered key
4686 if (!meaning) {
4687 labelk = lives_standard_label_new(key);
4688 kalign = .5;
4689 key_all = TRUE;
4690 } else {
4691 // key, meaning -> key | meaning
4692 if (*meaning) {
4693 labelk = lives_standard_label_new(key);
4694 labelm = lives_standard_label_new(meaning);
4695 } else {
4696 // key, "" -> center key
4697 labelk = lives_standard_label_new(key);
4698 labelm = lives_standard_label_new(" ");
4699 kalign = .5;
4700 // *INDENT-OFF*
4701 }}}}
4702 // *INDENT-ON*
4703
4704 align = lives_alignment_new(kalign, .5, 1., 0.);
4705 lives_container_add(LIVES_CONTAINER(align), labelk);
4706
4707 if (!key_all) {
4708 lives_table_attach(LIVES_TABLE(table), align, 0, 1, currow, currow + 1,
4709 (LiVESAttachOptions)(LIVES_FILL),
4710 (LiVESAttachOptions)(0), 0, 0);
4711
4712 align = lives_alignment_new(malign, .5, 0., 0.);
4713 lives_container_add(LIVES_CONTAINER(align), labelm);
4714
4715 lives_table_attach(LIVES_TABLE(table), align, 1, 40, currow, currow + 1,
4716 (LiVESAttachOptions)(LIVES_EXPAND),
4717 (LiVESAttachOptions)(0), 0, 0);
4718 } else {
4719 lives_table_attach(LIVES_TABLE(table), align, 0, 40, currow, currow + 1,
4720 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
4721 (LiVESAttachOptions)(0), 0, 0);
4722 }
4723
4724 currow++;
4725
4726 lives_widget_show_all(table);
4727 }
4728
4729
4730 #define ADD_KEYDEF(key, desc) pair_add(textwindow->table, (tmp = lives_strdup(key)), (tmp2 = lives_strdup(desc))); \
4731 lives_free(tmp); lives_free(tmp2)
4732
do_keys_window(void)4733 void do_keys_window(void) {
4734 char *tmp = (_("Show Keys")), *tmp2;
4735 text_window *textwindow;
4736
4737 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
4738 textwindow = create_text_window(tmp, NULL, NULL, TRUE);
4739 lives_free(tmp);
4740 widget_opts.expand = LIVES_EXPAND_DEFAULT;;
4741
4742 lives_table_resize(LIVES_TABLE(textwindow->table), 1, 40);
4743 currow = 0;
4744
4745 ADD_KEYDEF(_("You can use the following keys during playback to control LiVES:-"), NULL);
4746 ADD_KEYDEF(NULL, NULL);
4747 ADD_KEYDEF(NULL, _("Recordable keys (press 'r' before playback to make a recording)"));
4748 ADD_KEYDEF(_("ctrl-left"), _("skip / scratch backwards (video only)\nWhen not playing moves the playback cursor"));
4749 ADD_KEYDEF(_("ctrl-right"), _("skip / scratch forwards (video only)\nWhen not playing moves the playback cursor"));
4750 ADD_KEYDEF(_("ctrl-up"), _("play faster"));
4751 ADD_KEYDEF(_("ctrl-down"), _("play slower"));
4752 ADD_KEYDEF(_("ctrl-shift-up"), _("background clip play faster"));
4753 ADD_KEYDEF(_("ctrl-shift-down"), _("background clip play slower"));
4754 ADD_KEYDEF(_("ctrl-alt-up"), _("increase effect parameter for keygrabbed effect"));
4755 ADD_KEYDEF(_("ctrl-alt-down"), _("decrease effect parameter for keybrabbed effect"));
4756 ADD_KEYDEF(_("ctrl-enter"), _("reset frame rate / resync audio (foreground clip)"));
4757 ADD_KEYDEF(_("ctrl-shift-enter"), _("reset frame rate (background clip)"));
4758 ADD_KEYDEF(_("ctrl-space"), _("reverse direction (foreground clip)"));
4759 ADD_KEYDEF(_("ctrl-shift-space"), _("reverse direction (background clip)"));
4760 ADD_KEYDEF(_("ctrl-alt-space"),
4761 _("Loop Lock\n(press once to mark IN point, then again to mark OUT point;\n"
4762 "ctrl-space, ctrl-enter, or switching clips clears)"));
4763 ADD_KEYDEF(_("ctrl-backspace"), _("freeze frame (foreground and background)"));
4764 ADD_KEYDEF(_("ctrl-alt-backspace"), _("freeze frame (background clip only)"));
4765 ADD_KEYDEF("a",
4766 _("audio lock ON: lock audio to the current foreground clip;\nignore video clip switches and rate / direction changes"));
4767 ADD_KEYDEF("A", _("audio lock OFF; audio follows the foreground video clip\n(unless overridden in Preferences)"));
4768 ADD_KEYDEF("n", _("nervous mode"));
4769 ADD_KEYDEF(_("ctrl-page-up"), _("previous clip"));
4770 ADD_KEYDEF(_("ctrl-page-down"), _("next clip"));
4771 ADD_KEYDEF("", "");
4772 ADD_KEYDEF(_("ctrl-1"), _("toggle real-time effect 1"));
4773 ADD_KEYDEF(_("ctrl-2"), _("toggle real-time effect 2"));
4774 ADD_KEYDEF(_("...etc..."), "");
4775 ADD_KEYDEF(_("ctrl-9"), _("toggle real-time effect 9"));
4776 ADD_KEYDEF(_("ctrl-0"), _("real-time effects (1 - 9) OFF"));
4777 ADD_KEYDEF(_("ctrl-minus"), _("toggle real-time effect 10 (unaffected by ctrl-0)"));
4778 ADD_KEYDEF(_("ctrl-equals"), _("toggle real-time effect 11 (unaffected by ctrl-0)"));
4779 ADD_KEYDEF("x", _("swap background / foreground clips"));
4780 ADD_KEYDEF("", "");
4781 ADD_KEYDEF("k", _("grab keyboard for last activated effect key\n(affects m, M, t, tab and ctrl-alt-up, ctrl-alt-down keys)"));
4782 ADD_KEYDEF("m", _("next effect mode (for whichever key has keyboard grab)"));
4783 ADD_KEYDEF("M", _("previous effect mode (for whichever key has keyboard grab)"));
4784 ADD_KEYDEF(_("ctrl-alt-1"), _("grab keyboard for effect key 1 (similar to k key)"));
4785 ADD_KEYDEF(_("ctrl-alt-2"), _("grab keyboard for effect key 2"));
4786 ADD_KEYDEF(_("...etc..."), "");
4787 ADD_KEYDEF("t", _("enter text parameter (when effect has keyboard grab)"));
4788 ADD_KEYDEF(_("TAB"), _("leave text parameter (reverse of 't')"));
4789 ADD_KEYDEF(_("F1"), _("store/switch to bookmark 1 (first press stores clip and frame)"));
4790 ADD_KEYDEF(_("F2"), _("store/switch to bookmark 2"));
4791 ADD_KEYDEF(_("...etc..."), "");
4792 ADD_KEYDEF(_("F12"), _("clear function keys (bookmarks)"));
4793 ADD_KEYDEF("", "");
4794 ADD_KEYDEF(NULL, _("Other playback keys"));
4795 ADD_KEYDEF("p", _("play all"));
4796 ADD_KEYDEF("y", _("play selection"));
4797 ADD_KEYDEF("q", _("stop"));
4798 ADD_KEYDEF("f", _("fullscreen"));
4799 ADD_KEYDEF("s", _("separate window"));
4800 ADD_KEYDEF("d", _("double sized playarea (only in clip edit mode)"));
4801 ADD_KEYDEF("r", _("toggle recording mode (clip edit mode only)"));
4802 ADD_KEYDEF("b", _("blank / unblank the interface background (clip editor only)"));
4803 ADD_KEYDEF("o", _("activate / deactivate continuous looping"));
4804 ADD_KEYDEF("g", _("enable / disable ping pong looping"));
4805 ADD_KEYDEF("l", _("enable / disable stop on audio end\n(ignored if continuous loop is active)"));
4806 ADD_KEYDEF("<", _("lower the volume of current audio clip"));
4807 ADD_KEYDEF(">", _("increase the volume of current audio clip"));
4808 ADD_KEYDEF("w", _("display a/v sync status (developer mode)"));
4809 ADD_KEYDEF("", "");
4810 }
4811
4812
do_mt_keys_window(void)4813 void do_mt_keys_window(void) {
4814 text_window *textwindow;
4815 char *tmp = (_("Multitrack Keys")), *tmp2;
4816
4817 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
4818 textwindow = create_text_window(tmp, NULL, NULL, TRUE);
4819 lives_free(tmp);
4820 widget_opts.expand = LIVES_EXPAND_DEFAULT;;
4821
4822 lives_table_resize(LIVES_TABLE(textwindow->table), 1, 40);
4823 currow = 0;
4824
4825 ADD_KEYDEF(_("You can use the following keys to control the multitrack window:"), NULL);
4826 ADD_KEYDEF(NULL, NULL);
4827 ADD_KEYDEF(_("ctrl-left-arrow"), _("move timeline cursor left 1 second"));
4828 ADD_KEYDEF(_("ctrl-right-arrow"), _("move timeline cursor right 1 second"));
4829 ADD_KEYDEF(_("shift-left-arrow"), _("move timeline cursor left 1 frame"));
4830 ADD_KEYDEF(_("shift-right-arrow"), _("move timeline cursor right 1 frame"));
4831 ADD_KEYDEF(_("ctrl-up-arrow"), _("move current track up"));
4832 ADD_KEYDEF(_("ctrl-down-arrow"), _("move current track down"));
4833 ADD_KEYDEF(_("ctrl-page-up"), _("select previous clip"));
4834 ADD_KEYDEF(_("ctrl-page-down"), _("select next clip"));
4835 ADD_KEYDEF(_("ctrl-space"), _("select/deselect current track"));
4836 ADD_KEYDEF(_("ctrl-plus"), _("zoom in"));
4837 ADD_KEYDEF(_("ctrl-minus"), _("zoom out"));
4838 ADD_KEYDEF("m", _("make a mark on the timeline (during playback)"));
4839 ADD_KEYDEF("w", _("rewind to play start."));
4840 ADD_KEYDEF("", "");
4841 ADD_KEYDEF("", _("For other keys, see the menus.\n"));
4842 ADD_KEYDEF("", "");
4843 }
4844
4845
autolives_pre_dialog(void)4846 autolives_window *autolives_pre_dialog(void) {
4847 // dialog for autolives activation
4848 // options: trigger: auto, time
4849 // omc - user1
4850
4851 // TODO: add port numbers, add change types and probabilities.
4852 autolives_window *alwindow;
4853
4854 LiVESWidget *trigframe;
4855 LiVESWidget *dialog_vbox;
4856 LiVESWidget *label;
4857 LiVESWidget *vbox;
4858 LiVESWidget *hbox;
4859 LiVESWidget *radiobutton;
4860
4861 LiVESSList *radiobutton1_group = NULL;
4862 LiVESSList *radiobutton2_group = NULL;
4863
4864 char *tmp, *tmp2;
4865
4866 alwindow = (autolives_window *)lives_malloc(sizeof(autolives_window));
4867
4868 alwindow->dialog = lives_standard_dialog_new(_("Autolives Options"), TRUE, DEF_DIALOG_WIDTH, DEF_DIALOG_HEIGHT);
4869
4870 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(alwindow->dialog));
4871
4872 trigframe = lives_standard_frame_new(_("Trigger"), 0., FALSE);
4873
4874 lives_box_pack_start(LIVES_BOX(dialog_vbox), trigframe, FALSE, FALSE, widget_opts.packing_height);
4875
4876 vbox = lives_vbox_new(FALSE, 0);
4877 lives_container_set_border_width(LIVES_CONTAINER(vbox), widget_opts.border_width);
4878 lives_container_add(LIVES_CONTAINER(trigframe), vbox);
4879
4880 hbox = lives_hbox_new(FALSE, widget_opts.packing_width);
4881 lives_box_pack_start(LIVES_BOX(vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
4882 alwindow->atrigger_button = lives_standard_radio_button_new((tmp = (_("Timed:"))),
4883 &radiobutton1_group, LIVES_BOX(hbox),
4884 (tmp2 = (_("Trigger a change based on time"))));
4885
4886 lives_free(tmp); lives_free(tmp2);
4887
4888 alwindow->atrigger_spin = lives_standard_spin_button_new(_("change time (seconds)"), 1., 1., 1800.,
4889 1., 10., 0, LIVES_BOX(hbox), NULL);
4890
4891 hbox = lives_hbox_new(FALSE, widget_opts.packing_width);
4892 lives_box_pack_start(LIVES_BOX(vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
4893 radiobutton = lives_standard_radio_button_new((tmp = (_("OMC"))),
4894 &radiobutton1_group, LIVES_BOX(hbox),
4895 (tmp2 = (_("Trigger a change based on receiving an OSC message"))));
4896
4897 lives_free(tmp); lives_free(tmp2);
4898
4899 if (has_devicemap(OSC_NOTIFY)) {
4900 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton), TRUE);
4901 }
4902
4903 vbox = lives_vbox_new(FALSE, 0);
4904 lives_box_pack_start(LIVES_BOX(dialog_vbox), vbox, TRUE, FALSE, widget_opts.packing_height * 2.);
4905
4906 hbox = lives_hbox_new(FALSE, 0);
4907 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
4908
4909 label = lives_standard_label_new(_("Playback start:"));
4910 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, TRUE, 0);
4911
4912 add_fill_to_box(LIVES_BOX(hbox));
4913
4914 hbox = lives_hbox_new(FALSE, widget_opts.packing_width);
4915 lives_box_pack_start(LIVES_BOX(vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
4916 alwindow->apb_button = lives_standard_radio_button_new((tmp = (_("Automatic"))),
4917 &radiobutton2_group, LIVES_BOX(hbox),
4918 (tmp2 = (_("Start playback automatically"))));
4919
4920 lives_free(tmp); lives_free(tmp2);
4921
4922 radiobutton = lives_standard_radio_button_new((tmp = (_("Manual"))),
4923 &radiobutton2_group, LIVES_BOX(hbox),
4924 (tmp2 = (_("Wait for the user to start playback"))));
4925
4926 lives_free(tmp); lives_free(tmp2);
4927
4928 hbox = lives_hbox_new(FALSE, widget_opts.packing_width);
4929 lives_box_pack_start(LIVES_BOX(vbox), hbox, TRUE, TRUE, widget_opts.packing_height * 2);
4930
4931 alwindow->mute_button = lives_standard_check_button_new
4932 ((tmp = (_("Mute internal audio during playback"))), FALSE, LIVES_BOX(hbox),
4933 (tmp2 = (_("Mute the audio in LiVES during playback by setting the audio source to external."))));
4934
4935 lives_free(tmp); lives_free(tmp2);
4936
4937 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(alwindow->mute_button), TRUE);
4938
4939 add_hsep_to_box(LIVES_BOX(dialog_vbox));
4940
4941 hbox = lives_hbox_new(FALSE, 0);
4942 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
4943
4944 alwindow->debug_button = lives_standard_check_button_new
4945 ((tmp = (_("Debug mode"))), FALSE, LIVES_BOX(hbox),
4946 (tmp2 = (_("Show debug output on stderr."))));
4947
4948 lives_free(tmp); lives_free(tmp2);
4949
4950 lives_widget_show_all(alwindow->dialog);
4951 return alwindow;
4952 }
4953
4954
special_cleanup_cb(LiVESWidget * widget,void * userdata)4955 static boolean special_cleanup_cb(LiVESWidget * widget, void *userdata) {
4956 // need to call special_cleanup(TRUE) before destroying the toplevel if you want to prompt
4957 // for filewrite overwrites
4958 special_cleanup(FALSE);
4959 return FALSE;
4960 }
4961
4962
add_aspect_ratio_button(LiVESSpinButton * sp_width,LiVESSpinButton * sp_height,LiVESBox * box)4963 const lives_special_aspect_t *add_aspect_ratio_button(LiVESSpinButton * sp_width, LiVESSpinButton * sp_height, LiVESBox * box) {
4964 static lives_param_t aspect_width, aspect_height;
4965
4966 init_special();
4967
4968 aspect_width.widgets[0] = (LiVESWidget *)sp_width;
4969 aspect_height.widgets[0] = (LiVESWidget *)sp_height;
4970
4971 set_aspect_ratio_widgets(&aspect_width, &aspect_height);
4972
4973 check_for_special(NULL, &aspect_width, box);
4974 check_for_special(NULL, &aspect_height, box);
4975
4976 lives_signal_sync_connect(LIVES_GUI_OBJECT(sp_width), LIVES_WIDGET_DESTROY_SIGNAL,
4977 LIVES_GUI_CALLBACK(special_cleanup_cb), NULL);
4978
4979 return paramspecial_get_aspect();
4980 }
4981
4982
add_list_expander(LiVESBox * box,const char * title,int width,int height,LiVESList * xlist)4983 LiVESWidget *add_list_expander(LiVESBox * box, const char *title, int width, int height, LiVESList * xlist) {
4984 // add widget to preview affected layouts
4985
4986 LiVESWidget *expander;
4987 LiVESWidget *textview = lives_text_view_new();
4988 LiVESTextBuffer *textbuffer = lives_text_view_get_buffer(LIVES_TEXT_VIEW(textview));
4989
4990 LiVESWidget *scrolledwindow =
4991 lives_standard_scrolled_window_new(width, height, LIVES_WIDGET(textview));
4992
4993 lives_text_view_set_editable(LIVES_TEXT_VIEW(textview), FALSE);
4994
4995 lives_widget_set_size_request(scrolledwindow, width, height);
4996
4997 expander = lives_standard_expander_new(title, LIVES_BOX(box), scrolledwindow);
4998
4999 if (palette->style & STYLE_1) {
5000 LiVESWidget *label = lives_expander_get_label_widget(LIVES_EXPANDER(expander));
5001 lives_widget_set_fg_color(label, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
5002 lives_widget_set_fg_color(label, LIVES_WIDGET_STATE_PRELIGHT, &palette->normal_fore);
5003 lives_widget_set_fg_color(expander, LIVES_WIDGET_STATE_PRELIGHT, &palette->normal_fore);
5004 lives_widget_set_bg_color(expander, LIVES_WIDGET_STATE_PRELIGHT, &palette->normal_back);
5005
5006 lives_widget_set_base_color(textview, LIVES_WIDGET_STATE_NORMAL, &palette->info_base);
5007 lives_widget_set_text_color(textview, LIVES_WIDGET_STATE_NORMAL, &palette->info_text);
5008 lives_widget_set_base_color(scrolledwindow, LIVES_WIDGET_STATE_NORMAL, &palette->info_base);
5009 lives_widget_set_text_color(scrolledwindow, LIVES_WIDGET_STATE_NORMAL, &palette->info_text);
5010 }
5011
5012 lives_text_buffer_insert_at_cursor(textbuffer, "\n", strlen("\n"));
5013
5014 for (; xlist; xlist = xlist->next) {
5015 lives_text_buffer_insert_at_cursor(textbuffer, (const char *)xlist->data, strlen((char *)xlist->data));
5016 lives_text_buffer_insert_at_cursor(textbuffer, "\n", strlen("\n"));
5017 }
5018 return expander;
5019 }
5020
5021
5022 #ifdef ALLOW_NONFREE_CODECS
on_freedom_toggled(LiVESToggleButton * togglebutton,livespointer user_data)5023 static void on_freedom_toggled(LiVESToggleButton * togglebutton, livespointer user_data) {
5024 LiVESWidget *label = (LiVESWidget *)user_data;
5025 if (!lives_toggle_button_get_active(togglebutton)) lives_label_set_text(LIVES_LABEL(label), "." LIVES_FILE_EXT_WEBM);
5026 else lives_label_set_text(LIVES_LABEL(label), "." LIVES_FILE_EXT_MP4);
5027 }
5028 #endif
5029
5030 static LiVESWidget *spinbutton_width;
5031 static LiVESWidget *spinbutton_height;
5032 static const lives_special_aspect_t *aspect;
5033
utsense(LiVESToggleButton * togglebutton,livespointer user_data)5034 static void utsense(LiVESToggleButton * togglebutton, livespointer user_data) {
5035 boolean sensitive = (boolean)LIVES_POINTER_TO_INT(user_data);
5036 if (!lives_toggle_button_get_active(togglebutton)) return;
5037 lives_widget_set_sensitive(spinbutton_width, sensitive);
5038 lives_widget_set_sensitive(spinbutton_height, sensitive);
5039 if (aspect) lives_widget_set_sensitive(aspect->lockbutton, sensitive);
5040 }
5041
dl_url_changed(LiVESWidget * urlw,livespointer user_data)5042 static void dl_url_changed(LiVESWidget * urlw, livespointer user_data) {
5043 LiVESWidget *namew = (LiVESWidget *)user_data;
5044 static size_t oldlen = 0;
5045 size_t ulen = lives_strlen(lives_entry_get_text(LIVES_ENTRY(urlw)));
5046 if (!(*(lives_entry_get_text(LIVES_ENTRY(namew))))) {
5047 if (ulen > oldlen + 1) lives_widget_grab_focus(namew);
5048 }
5049 oldlen = ulen;
5050 }
5051
5052
on_utupinfo_clicked(LiVESWidget * b,livespointer data)5053 static void on_utupinfo_clicked(LiVESWidget * b, livespointer data) {
5054 do_info_dialogf(_("LiVES will only update %s if you have a local user copy installed.\n"
5055 "Otherwise you may need to update it manually when prompted\n\n"
5056 "Checking the button for the first time will cause the program to be copied\n"
5057 "to your home directory.\n"
5058 "After this it can be updated without needing root privileges.\n"),
5059 EXEC_YOUTUBE_DL);
5060 }
5061
5062 // prompt for the following:
5063 // - URL
5064 // save dir
5065 // format selection (free / nonfree)
5066 // filename
5067 // approx file size
5068 // update youtube-dl
5069 // advanced :: audio selection / save subs / sub language [TODO]
5070
run_youtube_dialog(lives_remote_clip_request_t * req)5071 lives_remote_clip_request_t *run_youtube_dialog(lives_remote_clip_request_t *req) {
5072 LiVESWidget *dialog_vbox;
5073 LiVESWidget *label;
5074 LiVESWidget *ext_label;
5075 LiVESWidget *hbox;
5076 LiVESWidget *dialog;
5077 LiVESWidget *url_entry;
5078 LiVESWidget *name_entry;
5079 LiVESWidget *dir_entry;
5080 LiVESWidget *checkbutton_update;
5081 LiVESWidget *cb_debug = NULL;
5082 #ifdef ALLOW_NONFREE_CODECS
5083 LiVESWidget *radiobutton_free;
5084 LiVESWidget *radiobutton_nonfree;
5085 #endif
5086 LiVESWidget *radiobutton_approx;
5087 LiVESWidget *radiobutton_atleast;
5088 LiVESWidget *radiobutton_atmost;
5089 LiVESWidget *radiobutton_smallest;
5090 LiVESWidget *radiobutton_largest;
5091 LiVESWidget *radiobutton_choose;
5092 LiVESWidget *button;
5093
5094 double width_step = 4.;
5095 double height_step = 4.;
5096
5097 char *fname;
5098
5099 #ifdef ALLOW_NONFREE_CODECS
5100 LiVESSList *radiobutton_group = NULL;
5101 #endif
5102 LiVESSList *radiobutton_group2 = NULL;
5103
5104 char *title, *tmp, *tmp2, *msg;
5105 char *dfile = NULL, *url = NULL;
5106
5107 char dirname[PATH_MAX];
5108 #ifdef YTDL_URL
5109 uint64_t gflags = 0;
5110 #endif
5111
5112 LiVESResponseType response;
5113 boolean only_free = TRUE;
5114 boolean debug = FALSE;
5115 static boolean firsttime = TRUE;
5116
5117 if (!req || !req->do_update) {
5118 #ifdef YTDL_URL
5119 /// thanks RIAA...
5120 gflags |= INSTALL_CANLOCAL;
5121 #endif
5122 if (!check_for_executable(&capable->has_youtube_dl, EXEC_YOUTUBE_DL) &&
5123 !check_for_executable(&capable->has_youtube_dlc, EXEC_YOUTUBE_DLC)
5124 ) {
5125 if (!do_please_install_either(EXEC_YOUTUBE_DL, EXEC_YOUTUBE_DLC)) {
5126 capable->has_youtube_dl = capable->has_youtube_dlc = UNCHECKED;
5127 return NULL;
5128 }
5129 }
5130 if (capable->has_youtube_dl != LOCAL) {
5131 /// local version not found, so try first with system version
5132 firsttime = FALSE;
5133 }
5134 } else if (firsttime) {
5135 if (!check_for_executable(&capable->has_pip, EXEC_PIP)) {
5136 /// requirement is missing, if the user does set it checked, we will warn
5137 firsttime = FALSE;
5138 }
5139 }
5140
5141 #ifdef ALLOW_NONFREE_CODECS
5142 if (req) only_free = !req->allownf;
5143 #endif
5144
5145 if (req) debug = req->debug;
5146
5147 title = (_("Open Online Clip"));
5148
5149 dialog = lives_standard_dialog_new(title, TRUE, -1, -1);
5150 lives_signal_handlers_disconnect_by_func(dialog, LIVES_GUI_CALLBACK(return_true), NULL);
5151
5152 lives_free(title);
5153
5154 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
5155
5156 widget_opts.justify = LIVES_JUSTIFY_CENTER;
5157 msg = lives_strdup_printf(_("To open a clip from Youtube or another video site, LiVES will first download it with %s.\n"),
5158 EXEC_YOUTUBE_DL);
5159 label = lives_standard_label_new(msg);
5160 lives_free(msg);
5161
5162 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, 0);
5163
5164 hbox = lives_hbox_new(FALSE, 0);
5165 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height * 2);
5166
5167 add_spring_to_box(LIVES_BOX(hbox), 0);
5168
5169 msg = lives_big_and_bold(_("<--- Install or Update local copy of %s ?"), EXEC_YOUTUBE_DL);
5170 widget_opts.use_markup = TRUE;
5171 checkbutton_update = lives_standard_check_button_new(msg, firsttime || (req && req->do_update),
5172 LIVES_BOX(hbox),
5173 H_("If checked then LiVES will attempt to update\n"
5174 "it to the most recent version\n"
5175 "before attempting the download."));
5176 widget_opts.use_markup = FALSE;
5177 lives_free(msg);
5178
5179 button = lives_standard_button_new_from_stock_full(LIVES_STOCK_DIALOG_INFO, _("_Info"),
5180 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT, LIVES_BOX(hbox), TRUE, NULL);
5181
5182 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
5183 LIVES_GUI_CALLBACK(on_utupinfo_clicked), NULL);
5184
5185 add_spring_to_box(LIVES_BOX(hbox), 0);
5186
5187 label = lives_standard_label_new(_("Enter the URL of the clip below.\n"
5188 "E.g: http://www.youtube.com/watch?v=WCR6f6WzjP8"));
5189 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
5190
5191 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, 0);
5192
5193 hbox = lives_hbox_new(FALSE, 0);
5194 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, TRUE, widget_opts.packing_height);
5195
5196 url_entry = lives_standard_entry_new(_("Clip URL : "), req ? req->URI : "",
5197 LONG_ENTRY_WIDTH, URL_MAX, LIVES_BOX(hbox), NULL);
5198
5199 hbox = lives_hbox_new(FALSE, 0);
5200 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height);
5201
5202 if (only_free)
5203 ext_label = lives_standard_label_new("." LIVES_FILE_EXT_WEBM);
5204 else
5205 ext_label = lives_standard_label_new("." LIVES_FILE_EXT_MP4);
5206
5207 #ifdef ALLOW_NONFREE_CODECS
5208 label = lives_standard_label_new(_("Format selection:"));
5209
5210 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_width);
5211
5212 radiobutton_free =
5213 lives_standard_radio_button_new((tmp = (_("_Free (eg. vp9 / opus / webm)"))), &radiobutton_group, LIVES_BOX(hbox),
5214 (tmp2 = (_("Download clip using Free codecs and support the community"))));
5215
5216 lives_free(tmp); lives_free(tmp2);
5217
5218 add_fill_to_box(LIVES_BOX(hbox));
5219
5220 #endif
5221 name_entry = lives_standard_entry_new(_("_File Name : "), req ? req->fname : "",
5222 SHORT_ENTRY_WIDTH, PATH_MAX, LIVES_BOX(hbox), NULL);
5223
5224 lives_box_pack_start(LIVES_BOX(hbox), ext_label, FALSE, FALSE, 0);
5225 lives_signal_sync_connect(LIVES_GUI_OBJECT(url_entry), LIVES_WIDGET_CHANGED_SIGNAL,
5226 LIVES_GUI_CALLBACK(dl_url_changed), name_entry);
5227
5228 #ifdef ALLOW_NONFREE_CODECS
5229 //
5230 hbox = lives_hbox_new(FALSE, 0);
5231
5232 lives_widget_show_all(dialog);
5233 lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
5234 lives_box_pack_start(LIVES_BOX(dialog_vbox), align_horizontal_with(hbox, radiobutton_free),
5235 TRUE, FALSE, widget_opts.packing_height);
5236
5237 radiobutton_nonfree = lives_standard_radio_button_new((tmp = (_("_Non-free (eg. h264 / aac / mp4)"))),
5238 &radiobutton_group, LIVES_BOX(hbox),
5239 (tmp2 = (_("Download clip using non-free codecs and support commercial interests"))));
5240
5241 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton_nonfree), !only_free);
5242
5243 lives_free(tmp); lives_free(tmp2);
5244
5245 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_nonfree), LIVES_WIDGET_TOGGLED_SIGNAL,
5246 LIVES_GUI_CALLBACK(on_freedom_toggled), (livespointer)ext_label);
5247
5248 #endif
5249
5250 toggle_toggles_var(LIVES_TOGGLE_BUTTON(radiobutton_free), &only_free, FALSE);
5251
5252 hbox = lives_hbox_new(FALSE, 0);
5253 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height * 3);
5254
5255 dir_entry = lives_standard_direntry_new(_("_Directory to save to: "),
5256 req ? req->save_dir : mainw->vid_dl_dir,
5257 LONG_ENTRY_WIDTH, PATH_MAX, LIVES_BOX(hbox), NULL);
5258
5259 if (prefs->show_dev_opts) {
5260 cb_debug = lives_standard_check_button_new("Debug mode", debug,
5261 LIVES_BOX(hbox), NULL);
5262 hbox = lives_hbox_new(FALSE, 0);
5263 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height * 3);
5264 toggle_toggles_var(LIVES_TOGGLE_BUTTON(cb_debug), &debug, FALSE);
5265 }
5266
5267 add_hsep_to_box(LIVES_BOX(dialog_vbox));
5268
5269 hbox = lives_hbox_new(FALSE, 0);
5270 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height);
5271
5272 label = lives_standard_label_new(_("Desired frame size:"));
5273 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_width);
5274
5275 hbox = lives_hbox_new(FALSE, 0);
5276 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height);
5277
5278 radiobutton_approx = lives_standard_radio_button_new((tmp = (_("- Approximately:"))),
5279 &radiobutton_group2, LIVES_BOX(hbox),
5280 (tmp2 = (_("Download the closest to this size"))));
5281
5282 lives_free(tmp); lives_free(tmp2);
5283
5284 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_approx), LIVES_WIDGET_TOGGLED_SIGNAL,
5285 LIVES_GUI_CALLBACK(utsense), LIVES_INT_TO_POINTER(TRUE));
5286
5287 radiobutton_atleast = lives_standard_radio_button_new((tmp = (_("- At _least"))), &radiobutton_group2,
5288 LIVES_BOX(hbox),
5289 (tmp2 = (_("Frame size should be at least this size"))));
5290 lives_free(tmp); lives_free(tmp2);
5291
5292 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_atleast), LIVES_WIDGET_TOGGLED_SIGNAL,
5293 LIVES_GUI_CALLBACK(utsense), LIVES_INT_TO_POINTER(TRUE));
5294
5295 radiobutton_atmost = lives_standard_radio_button_new((tmp = (_("- At _most:"))), &radiobutton_group2,
5296 LIVES_BOX(hbox),
5297 (tmp2 = (_("Frame size should be at most this size"))));
5298 lives_free(tmp); lives_free(tmp2);
5299
5300 add_param_label_to_box(LIVES_BOX(hbox), FALSE, "------>");
5301
5302 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_atmost), LIVES_WIDGET_TOGGLED_SIGNAL,
5303 LIVES_GUI_CALLBACK(utsense), LIVES_INT_TO_POINTER(TRUE));
5304
5305 add_fill_to_box(LIVES_BOX(hbox));
5306
5307 spinbutton_width = lives_standard_spin_button_new(_("_Width"),
5308 CURRENT_CLIP_HAS_VIDEO ? cfile->hsize : DEF_GEN_WIDTH,
5309 width_step, 100000., width_step, width_step, 0, LIVES_BOX(hbox), NULL);
5310
5311 lives_spin_button_set_snap_to_multiples(LIVES_SPIN_BUTTON(spinbutton_width), width_step);
5312 lives_spin_button_update(LIVES_SPIN_BUTTON(spinbutton_width));
5313
5314 spinbutton_height = lives_standard_spin_button_new(_("X\t_Height"),
5315 CURRENT_CLIP_HAS_VIDEO ? cfile->vsize : DEF_GEN_HEIGHT,
5316 height_step, 100000., height_step, height_step, 0, LIVES_BOX(hbox), NULL);
5317
5318 lives_spin_button_set_snap_to_multiples(LIVES_SPIN_BUTTON(spinbutton_height), height_step);
5319 lives_spin_button_update(LIVES_SPIN_BUTTON(spinbutton_height));
5320
5321 label = lives_standard_label_new(_("\tpixels"));
5322 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, 0);
5323
5324 // add "aspectratio" widget
5325 if (CURRENT_CLIP_HAS_VIDEO) {
5326 aspect = add_aspect_ratio_button(LIVES_SPIN_BUTTON(spinbutton_width),
5327 LIVES_SPIN_BUTTON(spinbutton_height), LIVES_BOX(hbox));
5328 } else aspect = NULL;
5329
5330 hbox = lives_hbox_new(FALSE, 0);
5331 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height);
5332
5333 label = lives_standard_label_new(_(" or:"));
5334 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_width);
5335
5336 hbox = lives_hbox_new(FALSE, 0);
5337 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height);
5338
5339 radiobutton_smallest = lives_standard_radio_button_new((tmp = (_("- The _smallest"))),
5340 &radiobutton_group2, LIVES_BOX(hbox),
5341 (tmp2 = (_("Download the lowest resolution available"))));
5342
5343 lives_free(tmp); lives_free(tmp2);
5344
5345 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_smallest), LIVES_WIDGET_TOGGLED_SIGNAL,
5346 LIVES_GUI_CALLBACK(utsense), LIVES_INT_TO_POINTER(FALSE));
5347
5348 radiobutton_largest = lives_standard_radio_button_new((tmp = (_("- The _largest"))),
5349 &radiobutton_group2, LIVES_BOX(hbox),
5350 (tmp2 = (_("Download the highest resolution available"))));
5351
5352 lives_free(tmp); lives_free(tmp2);
5353
5354 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_largest), LIVES_WIDGET_TOGGLED_SIGNAL,
5355 LIVES_GUI_CALLBACK(utsense), LIVES_INT_TO_POINTER(FALSE));
5356
5357 add_fill_to_box(LIVES_BOX(hbox));
5358 add_fill_to_box(LIVES_BOX(hbox));
5359
5360 radiobutton_choose = lives_standard_radio_button_new((tmp = (_("- Let me choose..."))),
5361 &radiobutton_group2, LIVES_BOX(hbox),
5362 (tmp2 = (_("Choose the resolution from a list (opens in new window)"))));
5363
5364 lives_free(tmp); lives_free(tmp2);
5365
5366 lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton_choose), LIVES_WIDGET_TOGGLED_SIGNAL,
5367 LIVES_GUI_CALLBACK(utsense), LIVES_INT_TO_POINTER(FALSE));
5368
5369 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton_choose), TRUE);
5370
5371 ///////
5372
5373 hbox = lives_hbox_new(FALSE, 0);
5374 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, TRUE, FALSE, widget_opts.packing_height * 2);
5375
5376 add_spring_to_box(LIVES_BOX(hbox), 0);
5377 lives_standard_expander_new(_("_Other options (e.g audio, subtitles)..."), LIVES_BOX(hbox), NULL);
5378 add_spring_to_box(LIVES_BOX(hbox), 0);
5379
5380 lives_widget_grab_focus(url_entry);
5381
5382 // TODO - add other options
5383
5384 //lives_widget_show_all(dialog);
5385
5386 while (1) {
5387 response = lives_dialog_run(LIVES_DIALOG(dialog));
5388 if (response == LIVES_RESPONSE_CANCEL) {
5389 mainw->cancelled = CANCEL_USER;
5390 return NULL;
5391 }
5392
5393 ///////
5394
5395 if (!*lives_entry_get_text(LIVES_ENTRY(name_entry))) {
5396 do_error_dialog(_("Please enter the name of the file to save the downloaded clip as.\n"));
5397 continue;
5398 }
5399
5400 url = lives_strdup(lives_entry_get_text(LIVES_ENTRY(url_entry)));
5401
5402 if (!(*url)) {
5403 lives_free(url);
5404 do_error_dialog(_("Please enter a valid URL for the download.\n"));
5405 continue;
5406 }
5407
5408 fname = ensure_extension(lives_entry_get_text(LIVES_ENTRY(name_entry)), only_free ? LIVES_FILE_EXT_WEBM
5409 : LIVES_FILE_EXT_MP4);
5410 lives_snprintf(dirname, PATH_MAX, "%s", lives_entry_get_text(LIVES_ENTRY(dir_entry)));
5411 ensure_isdir(dirname);
5412 dfile = lives_build_filename(dirname, fname, NULL);
5413 lives_free(fname);
5414 if (!check_file(dfile, TRUE)) {
5415 lives_free(dfile);
5416 lives_free(url);
5417 continue;
5418 }
5419 break;
5420 }
5421
5422 lives_snprintf(mainw->vid_dl_dir, PATH_MAX, "%s", dirname);
5423
5424 if (!req) {
5425 req = (lives_remote_clip_request_t *)lives_calloc(1, sizeof(lives_remote_clip_request_t));
5426 if (!req) {
5427 lives_widget_destroy(dialog);
5428 lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
5429 lives_free(url); lives_free(dfile);
5430 LIVES_ERROR("Could not alloc memory for remote clip request");
5431 mainw->error = TRUE;
5432 return NULL;
5433 }
5434 req->allownf = !only_free;
5435 }
5436
5437 req->debug = debug;
5438
5439 mainw->error = FALSE;
5440 d_print(_("Downloading %s to %s..."), url, dfile);
5441 lives_free(dfile);
5442
5443 lives_snprintf(req->URI, 8192, "%s", url);
5444 lives_free(url);
5445 lives_snprintf(req->save_dir, PATH_MAX, "%s", dirname);
5446 lives_snprintf(req->fname, PATH_MAX, "%s", lives_entry_get_text(LIVES_ENTRY(name_entry)));
5447 #ifdef ALLOW_NONFREE_CODECS
5448 if (!req->allownf)
5449 lives_snprintf(req->format, 256, "%s", LIVES_FILE_EXT_WEBM);
5450 else
5451 lives_snprintf(req->format, 256, "%s", LIVES_FILE_EXT_MP4);
5452 #else
5453 lives_snprintf(req->format, 256, "%s", LIVES_FILE_EXT_WEBM);
5454 #endif
5455 req->desired_width = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton_width));
5456 req->desired_height = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton_height));
5457 req->desired_fps = 0.;
5458 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton_approx)))
5459 req->matchsize = LIVES_MATCH_NEAREST;
5460 else if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton_atleast)))
5461 req->matchsize = LIVES_MATCH_AT_LEAST;
5462 else if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton_atmost)))
5463 req->matchsize = LIVES_MATCH_AT_MOST;
5464 else if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton_smallest)))
5465 req->matchsize = LIVES_MATCH_HIGHEST;
5466 else if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton_largest)))
5467 req->matchsize = LIVES_MATCH_LOWEST;
5468 else if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton_choose)))
5469 req->matchsize = LIVES_MATCH_CHOICE;
5470 if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(checkbutton_update))) req->do_update = FALSE;
5471 else {
5472 req->do_update = TRUE;
5473 }
5474 *req->vidchoice = 0;
5475 *req->audchoice = 0;
5476
5477 lives_widget_destroy(dialog);
5478 lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
5479 firsttime = FALSE;
5480 return req;
5481 }
5482
5483
on_ebox_click(LiVESWidget * widget,LiVESXEventButton * event,livespointer user_data)5484 static boolean on_ebox_click(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
5485 // want to get doubleclick and then exit somehow
5486 int val = LIVES_POINTER_TO_INT(user_data);
5487 if (event->type != LIVES_BUTTON_PRESS) {
5488 lives_dialog_response(LIVES_DIALOG(lives_widget_get_toplevel(widget)), val);
5489 lives_widget_destroy(lives_widget_get_toplevel(LIVES_WIDGET(widget)));
5490 }
5491 return TRUE;
5492 }
5493
5494
youtube_select_format(lives_remote_clip_request_t * req)5495 boolean youtube_select_format(lives_remote_clip_request_t *req) {
5496 // need to set req->vidchoice
5497 int numlines, npieces;
5498 int width, height;
5499 int i, j, dbw, pdone;
5500 int scrw = GUI_SCREEN_WIDTH;
5501 int scrh = GUI_SCREEN_HEIGHT;
5502 int row = 1;
5503 int response;
5504
5505 size_t slen;
5506
5507 char **lines, **pieces;
5508 char *title, *txt;
5509
5510 char *notes;
5511
5512 LiVESWidget *dialog, *dialog_vbox, *scrollw, *table;
5513 LiVESWidget *label, *eventbox, *cancelbutton;
5514 LiVESWidget *abox;
5515
5516 LiVESList *allids = NULL;
5517
5518 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
5519
5520 if (lives_strlen(mainw->msg) < 10) return FALSE;
5521 numlines = get_token_count(mainw->msg, '|');
5522 if (numlines < 2) return FALSE;
5523 lines = lives_strsplit(mainw->msg, "|", numlines);
5524 if (strcmp(lines[0], "completed")) {
5525 lives_strfreev(lines);
5526 return FALSE;
5527 }
5528
5529 // create the dialog with a scrolledwindow
5530 width = scrw - SCR_WIDTH_SAFETY;
5531 height = (scrh - SCR_HEIGHT_SAFETY) / 2;
5532
5533 title = (_("Select Video Format to Download"));
5534 dialog = lives_standard_dialog_new(title, FALSE, 8, 8);
5535 lives_free(title);
5536
5537 abox = lives_dialog_get_action_area(LIVES_DIALOG(dialog));
5538 if (LIVES_IS_BOX(abox)) {
5539 label = lives_standard_label_new(_("Double click on a format to load it, or click Cancel to exit."));
5540 lives_box_pack_start(LIVES_BOX(abox), label, FALSE, TRUE, widget_opts.border_width);
5541
5542 add_fill_to_box(LIVES_BOX(abox));
5543 }
5544
5545 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
5546 LIVES_RESPONSE_CANCEL);
5547
5548 lives_signal_sync_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
5549 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
5550
5551 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
5552 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
5553
5554 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
5555
5556 table = lives_table_new(numlines + 1, 5, FALSE);
5557 lives_table_set_row_spacings(LIVES_TABLE(table), widget_opts.packing_height * 2);
5558
5559 dbw = widget_opts.border_width;
5560
5561 // need to set a large enough default here
5562 scrollw = lives_standard_scrolled_window_new(width * .8, height * 1., table);
5563 widget_opts.border_width = dbw;
5564
5565 lives_box_pack_start(LIVES_BOX(dialog_vbox), scrollw, FALSE, TRUE, 0);
5566 lives_container_set_border_width(LIVES_CONTAINER(table), 0);
5567
5568 notes = lives_strdup("");
5569
5570 // set the column headings
5571 label = lives_standard_label_new(_("ID"));
5572 lives_table_attach(LIVES_TABLE(table), label, 0, 1, 0, 1,
5573 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5574 (LiVESAttachOptions)(0), 0, 0);
5575 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5576 lives_widget_set_valign(label, LIVES_ALIGN_END);
5577
5578 label = lives_standard_label_new(_("Format"));
5579 lives_table_attach(LIVES_TABLE(table), label, 1, 2, 0, 1,
5580 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5581 (LiVESAttachOptions)(0), 0, 0);
5582 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5583 lives_widget_set_valign(label, LIVES_ALIGN_END);
5584
5585 label = lives_standard_label_new(_("Resolution"));
5586 lives_table_attach(LIVES_TABLE(table), label, 2, 3, 0, 1,
5587 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5588 (LiVESAttachOptions)(0), 0, 0);
5589 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5590 lives_widget_set_valign(label, LIVES_ALIGN_END);
5591
5592 label = lives_standard_label_new(_("Notes"));
5593 lives_table_attach(LIVES_TABLE(table), label, 3, 4, 0, 1,
5594 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5595 (LiVESAttachOptions)(0), 0, 0);
5596 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5597 lives_widget_set_valign(label, LIVES_ALIGN_END);
5598
5599
5600 for (i = 1; i < numlines; i++) {
5601 npieces = get_token_count(lines[i], ' ');
5602 pieces = lives_strsplit(lines[i], " ", npieces);
5603 pdone = 0;
5604
5605 for (j = 0; j < npieces; j++) {
5606 if (pdone < 3 && !*pieces[j]) continue;
5607
5608 if (pdone == 0) {
5609 // id no
5610 txt = lives_strdup_printf("\n%s\n", pieces[j]);
5611 label = lives_standard_label_new(txt);
5612 lives_free(txt);
5613 lives_widget_apply_theme3(label, LIVES_WIDGET_STATE_NORMAL);
5614 eventbox = lives_event_box_new();
5615 lives_container_add(LIVES_CONTAINER(eventbox), label);
5616 lives_event_box_set_above_child(LIVES_EVENT_BOX(eventbox), TRUE);
5617 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
5618 LIVES_GUI_CALLBACK(on_ebox_click),
5619 LIVES_INT_TO_POINTER(row - 1));
5620 lives_table_attach(LIVES_TABLE(table), eventbox, 0, 1, row, row + 1,
5621 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5622 (LiVESAttachOptions)(0), 0, 0);
5623 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5624 allids = lives_list_append(allids, lives_strdup(pieces[j]));
5625 pdone = 1;
5626 continue;
5627 }
5628
5629 if (pdone == 1) {
5630 // format
5631 txt = lives_strdup_printf("\n%s\n", pieces[j]);
5632 label = lives_standard_label_new(txt);
5633 lives_free(txt);
5634 lives_widget_apply_theme3(label, LIVES_WIDGET_STATE_NORMAL);
5635 eventbox = lives_event_box_new();
5636 lives_container_add(LIVES_CONTAINER(eventbox), label);
5637 lives_event_box_set_above_child(LIVES_EVENT_BOX(eventbox), TRUE);
5638 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
5639 LIVES_GUI_CALLBACK(on_ebox_click),
5640 LIVES_INT_TO_POINTER(row - 1));
5641 lives_table_attach(LIVES_TABLE(table), eventbox, 1, 2, row, row + 1,
5642 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5643 (LiVESAttachOptions)(0), 0, 0);
5644 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5645 pdone = 2;
5646 continue;
5647 }
5648
5649 if (pdone == 2) {
5650 // res
5651 txt = lives_strdup_printf("\n%s\n", pieces[j]);
5652 label = lives_standard_label_new(txt);
5653 lives_free(txt);
5654 lives_widget_apply_theme3(label, LIVES_WIDGET_STATE_NORMAL);
5655 eventbox = lives_event_box_new();
5656 lives_container_add(LIVES_CONTAINER(eventbox), label);
5657 lives_event_box_set_above_child(LIVES_EVENT_BOX(eventbox), TRUE);
5658 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
5659 LIVES_GUI_CALLBACK(on_ebox_click),
5660 LIVES_INT_TO_POINTER(row - 1));
5661 lives_table_attach(LIVES_TABLE(table), eventbox, 2, 3, row, row + 1,
5662 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5663 (LiVESAttachOptions)(0), 0, 0);
5664 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
5665 pdone = 3;
5666 continue;
5667 }
5668 notes = lives_strdup_printf("%s %s", notes, pieces[j]);
5669 }
5670
5671 lives_strfreev(pieces);
5672
5673 slen = lives_strlen(notes);
5674 // strip trailing newline
5675 if (slen > 0 && notes[slen - 1] == '\n') notes[slen - 1] = 0;
5676
5677 txt = lives_strdup_printf("\n%s\n", notes);
5678 label = lives_standard_label_new(txt);
5679 lives_free(txt);
5680 lives_widget_apply_theme3(label, LIVES_WIDGET_STATE_NORMAL);
5681 eventbox = lives_event_box_new();
5682 lives_container_add(LIVES_CONTAINER(eventbox), label);
5683 lives_event_box_set_above_child(LIVES_EVENT_BOX(eventbox), TRUE);
5684 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
5685 LIVES_GUI_CALLBACK(on_ebox_click),
5686 LIVES_INT_TO_POINTER(row - 1));
5687 lives_table_attach(LIVES_TABLE(table), eventbox, 3, 4, row, row + 1,
5688 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
5689 (LiVESAttachOptions)(0), 0, 0);
5690 lives_free(notes);
5691 notes = lives_strdup("");
5692 row++;
5693 }
5694
5695 lives_strfreev(lines);
5696 lives_free(notes);
5697
5698 lives_widget_show_all(dialog);
5699
5700 response = lives_dialog_run(LIVES_DIALOG(dialog));
5701 if (response < 0) {
5702 // user cancelled
5703 lives_list_free_all(&allids);
5704 return FALSE;
5705 }
5706
5707 // set req->vidchoice and return
5708 lives_snprintf(req->vidchoice, 512, "%s", (char *)lives_list_nth_data(allids, response));
5709 lives_list_free_all(&allids);
5710 return TRUE;
5711 }
5712
5713
5714 /// disk quota window
5715
lives_show_after(LiVESWidget * button,livespointer data)5716 static void lives_show_after(LiVESWidget * button, livespointer data) {
5717 LiVESWidget *showme = (LiVESWidget *)data;
5718 lives_general_button_clicked(LIVES_BUTTON(button), NULL);
5719 if (showme) lives_widget_show(showme);
5720 }
5721
workdir_query_cb(LiVESWidget * w,LiVESWidget * dlg)5722 static void workdir_query_cb(LiVESWidget * w, LiVESWidget * dlg) {
5723 lives_widget_hide(dlg);
5724 if (do_workdir_query()) {
5725 if (lives_strcmp(prefs->workdir, future_prefs->workdir)) {
5726 char *msg = workdir_ch_warning();
5727 if (do_warning_dialog(msg)) {
5728 lives_free(msg);
5729 do_shutdown_msg();
5730 lives_widget_destroy(dlg);
5731 on_quit_activate(NULL, NULL);
5732 }
5733 } else {
5734 do_info_dialog(_("\nDirectory was not changed\n"));
5735 }
5736 *future_prefs->workdir = 0;
5737 }
5738 lives_widget_show(dlg);
5739 }
5740
cleards_cb(LiVESWidget * w,LiVESWidget * dlg)5741 static void cleards_cb(LiVESWidget * w, LiVESWidget * dlg) {
5742 lives_widget_hide(dlg);
5743 on_cleardisk_activate(NULL, NULL);
5744 lives_widget_show(dlg);
5745
5746 }
5747
run_diskspace_dialog_cb(LiVESWidget * w,livespointer data)5748 void run_diskspace_dialog_cb(LiVESWidget * w, livespointer data) {
5749 run_diskspace_dialog();
5750 }
5751
run_diskspace_dialog_idle(livespointer data)5752 boolean run_diskspace_dialog_idle(livespointer data) {
5753 run_diskspace_dialog();
5754 return FALSE;
5755 }
5756
5757 ///////
5758
manclips_del(LiVESWidget * button,_entryw * renamew)5759 static void manclips_del(LiVESWidget * button, _entryw * renamew) {
5760 boolean is_curset = FALSE;
5761 const char *setname = lives_entry_get_text(LIVES_ENTRY(renamew->entry));
5762 char *fsetname;
5763 if (!*setname) return;
5764
5765 retry1:
5766 if (mainw->was_set && !lives_strcmp(setname, mainw->set_name)) {
5767 is_curset = TRUE;
5768 fsetname = lives_strdup(_("current set"));
5769 } else
5770 fsetname = lives_strdup_printf(_("set %s"), setname);
5771 if (check_for_executable(&capable->has_gio, EXEC_GIO)) mainw->add_trash_rb = TRUE;
5772 if (do_warning_dialogf(_("The %s will be permanently deleted from the disk.\n"
5773 "Are you sure ?"), fsetname)) {
5774 mainw->add_trash_rb = FALSE;
5775 lives_free(fsetname);
5776 if (is_curset) {
5777 del_current_set(FALSE);
5778 } else {
5779 char *setdir = lives_build_path(prefs->workdir, setname, NULL);
5780 if (mainw->add_trash_rb && prefs->pref_trash) {
5781 if (send_to_trash(setdir) == LIVES_RESPONSE_CANCEL) goto retry1;
5782 } else lives_rmdir(setdir, TRUE);
5783 mainw->num_sets--;
5784 }
5785 if (!mainw->num_sets && !mainw->clips_available) {
5786 do_info_dialog(_("All Sets have been erased from the disk"));
5787 lives_widget_destroy(renamew->dialog);
5788 lives_widget_show(renamew->parent);
5789 lives_free(renamew);
5790 renamew = NULL;
5791 lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
5792 return;
5793 }
5794 // refresh entry
5795 lives_entry_set_text(LIVES_ENTRY(renamew->entry), "");
5796 lives_widget_queue_draw(renamew->dialog);
5797 }
5798 mainw->add_trash_rb = FALSE;
5799 lives_free(fsetname);
5800 }
5801
manclips_reload(LiVESWidget * button,_entryw * renamew)5802 static void manclips_reload(LiVESWidget * button, _entryw * renamew) {
5803 char *setname = (char *)lives_entry_get_text(LIVES_ENTRY(renamew->entry));
5804 if (!*setname) return;
5805 setname = lives_strdup(lives_entry_get_text(LIVES_ENTRY(renamew->entry)));
5806 if (mainw->was_set && !lives_strcmp(setname, mainw->set_name)) {
5807 do_info_dialogf(_("The set %s is already loaded !"), setname);
5808 return;
5809 }
5810 if (mainw->cliplist) {
5811 do_info_dialog(_("The current clips must be saved before reloading another set"));
5812 mainw->only_close = TRUE;
5813 if (!on_save_set_activate(button, NULL)) return;
5814 mainw->only_close = FALSE;
5815 }
5816
5817 do_info_dialog(_("After reloading the Set you can inspect it and use it as normal.\n"
5818 "Should you decide to delete it or re-save it, click on\nFile | Close/Save all Clips "
5819 "in the menu of the Clip Editor\n"
5820 "You will then be returned to the Manage Sets dialog,\n"
5821 "where you may choose to continue this process further\n"));
5822 lives_widget_destroy(renamew->dialog);
5823 lives_widget_destroy(renamew->parent);
5824 lives_free(renamew);
5825 reload_set(setname);
5826 if (mainw->num_sets > -1) mainw->num_sets--;
5827 if (mainw->clips_available) mainw->cs_manage = TRUE;
5828 }
5829
manclips_ok(LiVESWidget * button,LiVESWidget * dialog)5830 static void manclips_ok(LiVESWidget * button, LiVESWidget * dialog) {
5831 lives_general_button_clicked(LIVES_BUTTON(button), NULL);
5832
5833 //mainw->cs_manage = TRUE;
5834 /// show list of all sets, excluding current
5835
5836 lives_widget_hide(dialog);
5837
5838 renamew = create_rename_dialog(3);
5839 if (!renamew) return; ///< no sets available
5840
5841 renamew->parent = dialog;
5842
5843 /// show buttons "Cancel", "Delete", "Reload"
5844
5845 lives_signal_sync_connect(LIVES_GUI_OBJECT(renamew->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
5846 LIVES_GUI_CALLBACK(lives_show_after), dialog);
5847
5848 lives_button_ungrab_default_special(renamew->okbutton);
5849 lives_widget_destroy(renamew->okbutton);
5850
5851 button = lives_dialog_add_button_from_stock(LIVES_DIALOG(renamew->dialog), LIVES_STOCK_DELETE,
5852 NULL, LIVES_RESPONSE_RESET);
5853
5854 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
5855 LIVES_GUI_CALLBACK(manclips_del), renamew);
5856
5857 // reaload will exit dlg and set mainw->cs_managed, after close/save all we come back here
5858 button = lives_dialog_add_button_from_stock(LIVES_DIALOG(renamew->dialog), LIVES_STOCK_OPEN,
5859 _("_Reload"), LIVES_RESPONSE_YES);
5860
5861 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
5862 LIVES_GUI_CALLBACK(manclips_reload), renamew);
5863
5864 lives_widget_show_all(renamew->dialog);
5865 }
5866
manclips_cb(LiVESWidget * w,livespointer data)5867 static void manclips_cb(LiVESWidget * w, livespointer data) {
5868 LiVESWidget *parent = (LiVESWidget *)data;
5869 LiVESWidget *dialog;
5870 LiVESWidget *button;
5871 char *text, *extra;
5872
5873 lives_widget_hide(parent);
5874
5875 if (mainw->was_set) {
5876 extra = (_(" including the current set."));
5877 } else extra = lives_strdup("");
5878
5879 text = lives_strdup_printf(_("<b>The current working directory contains %d Clip Sets%s</b>\n"
5880 "You may be able to free up some disk space by deleting "
5881 "unwanted ones.\n\n"
5882 "After selecting an existing Set, "
5883 "you will be presented with the options to "
5884 "erase it from the disk\n"
5885 "or to reload it first to inspect the contents\n\n"
5886 "Please select an option below\n"), mainw->num_sets
5887 + (mainw->was_set ? 1 : 0), extra);
5888 lives_free(extra);
5889 widget_opts.use_markup = TRUE;
5890 dialog = create_question_dialog(_("Manage Clipsets"), text);
5891 widget_opts.use_markup = FALSE;
5892 lives_free(text);
5893
5894 button = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_GO_BACK,
5895 _("Go back"), LIVES_RESPONSE_CANCEL);
5896 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
5897 LIVES_GUI_CALLBACK(lives_show_after), data);
5898
5899 button = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_GO_FORWARD,
5900 _("Continue"), LIVES_RESPONSE_OK);
5901 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
5902 LIVES_GUI_CALLBACK(manclips_ok), parent);
5903
5904 lives_widget_show_all(dialog);
5905 }
5906
5907
5908 static _dsquotaw *dsq = NULL;
5909
draw_dsu_widget(LiVESWidget * dsu_widget)5910 void draw_dsu_widget(LiVESWidget * dsu_widget) {
5911 double scale, xw, offs_x = 0;
5912 lives_painter_t *cr;
5913 int width, height;
5914
5915 if (!dsq->dsu_surface) return;
5916 cr = lives_painter_create_from_surface(dsq->dsu_surface);
5917 if (!cr) return;
5918
5919 if (capable->ds_used == -1 || capable->ds_free == -1 || capable->ds_tot == -1) return;
5920
5921 width = lives_widget_get_allocation_width(dsu_widget);
5922 height = lives_widget_get_allocation_height(dsu_widget);
5923
5924 if (width <= 0 || height <= 0) return;
5925
5926 scale = (double)capable->ds_tot / (double)width;
5927
5928 /// paint bg
5929 lives_painter_set_source_rgb(cr, 1., 1., 1.);
5930 lives_painter_rectangle(cr, 0, 0, width, height);
5931 lives_painter_fill(cr);
5932
5933 /// space used by other apps
5934 xw = (double)(capable->ds_tot - capable->ds_used - capable->ds_free) / scale;
5935 lives_painter_set_source_rgb(cr, 0., 0., 1.);
5936 lives_painter_rectangle(cr, 0, 0, xw, height);
5937 lives_painter_fill(cr);
5938
5939 offs_x += xw;
5940
5941 /// space used by lives
5942 xw = (double)capable->ds_used / scale;
5943 lives_painter_set_source_rgb(cr, 0., 1., 1.);
5944 lives_painter_rectangle(cr, offs_x, 0, offs_x + xw, height);
5945 lives_painter_fill(cr);
5946
5947 offs_x += xw;
5948
5949 /// draw quota (if set)
5950 if (future_prefs->disk_quota > capable->ds_used) {
5951 uint64_t qq = future_prefs->disk_quota - capable->ds_used;
5952 if (qq > capable->ds_free - prefs->ds_warn_level) qq = capable->ds_free - prefs->ds_warn_level;
5953 if (qq > 0) {
5954 xw = (double)qq / scale;
5955 if (xw > 0.) {
5956 lives_painter_set_source_rgb(cr, 1., 1., 0.);
5957 lives_painter_rectangle(cr, offs_x, 0, offs_x + xw, height);
5958 lives_painter_fill(cr);
5959 offs_x += xw;
5960 }
5961 }
5962 }
5963
5964 /// draw ds_free
5965 xw = (double)(capable->ds_free) / scale;
5966 if (prefs->ds_warn_level > 0)
5967 xw -= (double)prefs->ds_warn_level / scale;
5968 if (future_prefs->disk_quota > capable->ds_used)
5969 xw -= (double)(future_prefs->disk_quota - capable->ds_used) / scale;
5970
5971 if (xw > 0.) {
5972 lives_painter_set_source_rgb(cr, 0., 1., 0.);
5973 lives_painter_rectangle(cr, offs_x, 0, offs_x + xw, height);
5974 lives_painter_fill(cr);
5975 offs_x += xw;
5976 }
5977
5978 /// ds warning level
5979 if (prefs->ds_warn_level > 0) {
5980 xw = (double)(prefs->ds_warn_level - prefs->ds_crit_level) / scale;
5981 if (xw > 0.) {
5982 lives_painter_set_source_rgb(cr, 1., .5, 0.);
5983 lives_painter_rectangle(cr, offs_x, 0, offs_x + xw, height);
5984 lives_painter_fill(cr);
5985 offs_x += xw;
5986 }
5987 }
5988
5989 /// ds critical level
5990 if (prefs->ds_crit_level > 0) {
5991 xw = (double)prefs->ds_crit_level / scale;
5992 if (xw > 0.) {
5993 lives_painter_set_source_rgb(cr, 1., 0., 0.);
5994 lives_painter_rectangle(cr, offs_x, 0, offs_x + xw, height);
5995 lives_painter_fill(cr);
5996 offs_x += xw;
5997 }
5998 }
5999 lives_painter_destroy(cr);
6000 lives_widget_queue_draw(dsu_widget);
6001 }
6002
6003
dsu_set_toplabel(void)6004 static void dsu_set_toplabel(void) {
6005 char *ltext = NULL, *dtxt, *dtxt2;
6006 widget_opts.text_size = LIVES_TEXT_SIZE_LARGE;
6007
6008 if (mainw->dsu_valid && !dsq->scanning) {
6009 if (capable->ds_free < prefs->ds_crit_level) {
6010 if (!capable->mountpoint) capable->mountpoint = get_mountpoint_for(prefs->workdir);
6011 dtxt = lives_format_storage_space_string(prefs->ds_crit_level);
6012 dtxt2 = lives_markup_escape_text(capable->mountpoint, -1);
6013 ltext = lives_strdup_printf(_("<b>ALERT ! FREE SPACE IN %s IS BELOW THE CRITICAL LEVEL OF %s\n"
6014 "YOU SHOULD EXIT LIVES IMMEDIATELY TO AVOID POSSIBLE DATA LOSS</b>"),
6015 dtxt2, dtxt);
6016 lives_free(dtxt); lives_free(dtxt2);
6017 widget_opts.use_markup = TRUE;
6018 lives_label_set_text(LIVES_LABEL(dsq->top_label), ltext);
6019 widget_opts.use_markup = FALSE;
6020 widget_opts.text_size = LIVES_TEXT_SIZE_NORMAL;
6021 if (!dsq->crit_dism) {
6022 dsq->crit_dism = TRUE;
6023 lives_free(ltext);
6024 ltext = ds_critical_msg(prefs->workdir, &capable->mountpoint, capable->ds_free);
6025 widget_opts.use_markup = TRUE;
6026 do_abort_ok_dialog(ltext);
6027 widget_opts.use_markup = FALSE;
6028 }
6029 lives_free(ltext);
6030 return;
6031 }
6032 if (capable->ds_free < prefs->ds_warn_level) {
6033 if (!capable->mountpoint) capable->mountpoint = get_mountpoint_for(prefs->workdir);
6034 dtxt = lives_format_storage_space_string(prefs->ds_crit_level);
6035 ltext = lives_strdup_printf(_("WARNING ! Free space in %s is below the warning level of %s\n"
6036 "Action should be taken to remedy this"),
6037 capable->mountpoint, dtxt);
6038 lives_free(dtxt);
6039 } else if (prefs->disk_quota) {
6040 if (capable->ds_used > prefs->disk_quota) {
6041 uint64_t xs = capable->ds_used - prefs->disk_quota;
6042 dtxt = lives_format_storage_space_string(xs);
6043 ltext = lives_strdup_printf(_("WARNING ! LiVES has exceeded its quota by %s"), dtxt);
6044 lives_free(dtxt);
6045 } else if (capable->ds_used >= (int64_t)((double)prefs->disk_quota * prefs->quota_limit / 100.)) {
6046 double pcused = (double)capable->ds_used / (double)prefs->disk_quota * 100.;
6047 ltext = lives_strdup_printf(_("ATTENTION: LiVES is currently using over %d%% of its assigned quota"), (int)pcused);
6048 } else if (prefs->disk_quota - capable->ds_used + prefs->ds_warn_level > capable->ds_free) {
6049 ltext = lives_strdup(_("ATTENTION ! There is insufficient free space on the disk for LiVES' current quota"));
6050 }
6051 }
6052 }
6053 if (!ltext) {
6054 ltext = lives_strdup(_("LiVES can help limit the amount of diskspace used by projects (sets)."));
6055 }
6056 lives_label_set_text(LIVES_LABEL(dsq->top_label), ltext);
6057 lives_free(ltext);
6058 widget_opts.text_size = LIVES_TEXT_SIZE_NORMAL;
6059 }
6060
dsu_label_notset(void)6061 LIVES_LOCAL_INLINE char *dsu_label_notset(void) {return _("Value not set");}
dsu_label_calculating(void)6062 LIVES_LOCAL_INLINE char *dsu_label_calculating(void) {return _("Calculating....");}
6063
update_dsu(livespointer data)6064 boolean update_dsu(livespointer data) {
6065 static boolean set_label = FALSE;
6066 int64_t dsu = -1;
6067 char *txt;
6068 if ((!dsq || dsq->scanning) && (dsu = disk_monitor_check_result(prefs->workdir)) < 0) {
6069 if (!dsq || !dsq->visible) {
6070 return FALSE;
6071 }
6072 if (!set_label) {
6073 set_label = TRUE;
6074 lives_label_set_text(LIVES_LABEL(dsq->used_label), (txt = dsu_label_calculating()));
6075 lives_free(txt);
6076 }
6077 } else {
6078 if (mainw->dsu_valid) {
6079 if (dsu > -1) capable->ds_used = dsu;
6080 dsu = capable->ds_used;
6081 mainw->ds_status = get_storage_status(prefs->workdir, mainw->next_ds_warn_level, &dsu, 0);
6082 capable->ds_free = dsu;
6083 dsq->scanning = FALSE;
6084 if (mainw->dsu_widget) {
6085 txt = lives_format_storage_space_string(capable->ds_used);
6086 lives_label_set_text(LIVES_LABEL(dsq->used_label), txt);
6087 lives_free(txt);
6088 draw_dsu_widget(mainw->dsu_widget);
6089 dsu_set_toplabel();
6090 dsu_fill_details(NULL, NULL);
6091 qslider_changed(dsq->slider, dsq);
6092 if (capable->ds_free < prefs->ds_warn_level || mainw->has_session_workdir)
6093 lives_widget_set_sensitive(dsq->button, FALSE);
6094 if (capable->ds_free < prefs->ds_crit_level) {
6095 lives_widget_set_no_show_all(dsq->abort_button, FALSE);
6096 lives_widget_show_all(dsq->abort_button);
6097 }
6098 }
6099 set_label = FALSE;
6100 mainw->dsu_valid = TRUE;
6101 return FALSE;
6102 }
6103 }
6104 return TRUE;
6105 }
6106
qslider_changed(LiVESWidget * slid,livespointer data)6107 static void qslider_changed(LiVESWidget * slid, livespointer data) {
6108 char *txt, *dtxt;
6109 if (mainw->dsu_valid && !dsq->scanning) {
6110 uint64_t min = capable->ds_used;
6111 uint64_t max = capable->ds_free + min - prefs->ds_warn_level;
6112 double value = 0.;
6113 if (dsq->setting) {
6114 value = lives_range_get_value(LIVES_RANGE(slid)) / 100.;
6115 lives_signal_handler_block(dsq->checkbutton, dsq->checkfunc);
6116 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(dsq->checkbutton), FALSE);
6117 lives_signal_handler_unblock(dsq->checkbutton, dsq->checkfunc);
6118 future_prefs->disk_quota = (uint64_t)(min + value * (max - min) + .5);
6119 draw_dsu_widget(mainw->dsu_widget);
6120 } else {
6121 if (future_prefs->disk_quota > 0) {
6122 if (future_prefs->disk_quota >= capable->ds_used) {
6123 uint64_t dq = future_prefs->disk_quota;
6124 dq -= min;
6125 value = 100. * (double)dq / (double)(max - min);
6126 if (value > 100.) value = 100.;
6127 }
6128 }
6129 lives_signal_handler_block(dsq->slider, dsq->sliderfunc);
6130 lives_range_set_value(LIVES_RANGE(dsq->slider), value);
6131 lives_signal_handler_unblock(dsq->slider, dsq->sliderfunc);
6132 }
6133 }
6134
6135 if (future_prefs->disk_quota > 0.) {
6136 txt = lives_format_storage_space_string(future_prefs->disk_quota);
6137 dtxt = lives_strdup_printf("<b>%s</b>", txt);
6138 widget_opts.use_markup = TRUE;
6139 lives_label_set_text(LIVES_LABEL(dsq->vlabel), dtxt);
6140 widget_opts.use_markup = FALSE;
6141 lives_free(txt); lives_free(dtxt);
6142 if (mainw->dsu_valid && !dsq->scanning) {
6143 double pcused = 100. * (double)capable->ds_used
6144 / (double)future_prefs->disk_quota;
6145
6146 if (pcused < 100.) txt = lives_strdup_printf(_("%.2f%% used"), pcused);
6147 else {
6148 txt = lives_strdup_printf(_("<b>%.2f%% used !!</b>"), pcused);
6149 widget_opts.use_markup = TRUE;
6150 }
6151 lives_label_set_text(LIVES_LABEL(dsq->pculabel), txt);
6152 widget_opts.use_markup = FALSE;
6153 lives_free(txt);
6154 if (pcused >= prefs->quota_limit) {
6155 txt = lives_strdup_printf(_("LiVES is currently using over %d%% of its available quota"), (int)prefs->quota_limit);
6156 show_warn_image(dsq->pculabel, txt);
6157 lives_free(txt);
6158 } else hide_warn_image(dsq->pculabel);
6159 } else {
6160 hide_warn_image(dsq->pculabel);
6161 lives_label_set_text(LIVES_LABEL(dsq->pculabel), _("Calculating %% used"));
6162 }
6163 } else {
6164 hide_warn_image(dsq->pculabel);
6165 lives_label_set_text(LIVES_LABEL(dsq->pculabel), NULL);
6166 txt = dsu_label_notset();
6167 dtxt = lives_strdup_printf("<b>%s</b>", txt);
6168 widget_opts.use_markup = TRUE;
6169 lives_label_set_text(LIVES_LABEL(dsq->vlabel), dtxt);
6170 widget_opts.use_markup = FALSE;
6171 lives_free(dtxt); lives_free(txt);
6172 }
6173 }
6174
dsq_check_toggled(LiVESWidget * cbutt,livespointer data)6175 static void dsq_check_toggled(LiVESWidget * cbutt, livespointer data) {
6176 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(cbutt))) {
6177 future_prefs->disk_quota = 0;
6178 } else {
6179 lives_widget_set_sensitive(dsq->slider, TRUE);
6180 future_prefs->disk_quota = prefs->disk_quota;
6181 }
6182 dsq->setting = FALSE;
6183 qslider_changed(dsq->slider, NULL);
6184 dsq->setting = TRUE;
6185 draw_dsu_widget(mainw->dsu_widget);
6186 }
6187
6188 static boolean mouse_on = FALSE;
6189
dsu_widget_clicked(LiVESWidget * widget,LiVESXEventButton * event,livespointer is_clickp)6190 static boolean dsu_widget_clicked(LiVESWidget * widget, LiVESXEventButton * event, livespointer is_clickp) {
6191 boolean is_click;
6192 is_click = LIVES_POINTER_TO_INT(is_clickp);
6193 if (is_click) mouse_on = TRUE;
6194 else if (!mouse_on) return TRUE;
6195
6196 if (!mainw->dsu_valid || dsq->scanning) return TRUE;
6197 else {
6198 int width = lives_widget_get_allocation_width(widget);
6199 if (width <= 0) return TRUE;
6200 else {
6201 int x;
6202 lives_widget_get_pointer((LiVESXDevice *)mainw->mgeom[widget_opts.monitor].mouse_device,
6203 widget, &x, NULL);
6204 if (x > 0) {
6205 uint64_t min = capable->ds_tot - capable->ds_free;
6206 uint64_t max = capable->ds_tot - prefs->ds_warn_level;
6207 double scale = (double)capable->ds_tot / (double)width;
6208 double value = (double)x * scale;
6209 value -= (double)min;
6210 value = 100. * value / (double)(max - min);
6211 if (value < 0.) value = 0.;
6212 if (value > 100.) value = 100.;
6213 lives_range_set_value(LIVES_RANGE(dsq->slider), value);
6214 // *INDENT-OFF*
6215 }}}
6216 // *INDENT-ON*
6217
6218 return TRUE;
6219 }
6220
dsu_widget_released(LiVESWidget * widget,LiVESXEventButton * event,livespointer is_clickp)6221 static boolean dsu_widget_released(LiVESWidget * widget, LiVESXEventButton * event, livespointer is_clickp) {
6222 mouse_on = FALSE;
6223 return TRUE;
6224 }
6225
dsu_ok_clicked(LiVESWidget * butt,LiVESWidget * toshow)6226 static void dsu_ok_clicked(LiVESWidget * butt, LiVESWidget * toshow) {
6227 dsq->visible = FALSE;
6228 mainw->dsu_widget = NULL;
6229 lives_show_after(butt, toshow);
6230 }
6231
dsu_fill_details(LiVESWidget * widget,livespointer data)6232 static void dsu_fill_details(LiVESWidget * widget, livespointer data) {
6233 uint64_t dsval;
6234 char *txt;
6235 LiVESWidget *layout2;
6236
6237 if (dsq->exp_layout) lives_widget_destroy(dsq->exp_layout);
6238 dsq->exp_layout = NULL;
6239 if (!lives_expander_get_expanded(LIVES_EXPANDER(dsq->expander))) {
6240 widget_opts.use_markup = TRUE;
6241 lives_expander_set_label(LIVES_EXPANDER(dsq->expander), _("<b>Full _Details</b>"));
6242 widget_opts.use_markup = FALSE;
6243 return;
6244 }
6245
6246 widget_opts.use_markup = TRUE;
6247 lives_expander_set_label(LIVES_EXPANDER(dsq->expander), _("<b>Hide _Details</b>"));
6248 widget_opts.use_markup = FALSE;
6249
6250 dsq->exp_layout = lives_layout_new(LIVES_BOX(dsq->exp_vbox));
6251 layout2 = dsq->exp_layout;
6252
6253 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Working directory"), TRUE);
6254 lives_layout_add_label(LIVES_LAYOUT(layout2), prefs->workdir, TRUE);
6255
6256 lives_layout_add_row(LIVES_LAYOUT(layout2));
6257 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Mount point"), TRUE);
6258 if (!capable->mountpoint) capable->mountpoint = get_mountpoint_for(prefs->workdir);
6259 lives_layout_add_label(LIVES_LAYOUT(layout2), capable->mountpoint, TRUE);
6260
6261 lives_layout_add_row(LIVES_LAYOUT(layout2));
6262 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Total size"), TRUE);
6263 if (!mainw->dsu_valid || dsq->scanning)
6264 txt = dsu_label_calculating();
6265 else
6266 txt = lives_format_storage_space_string(capable->ds_tot);
6267 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6268 lives_free(txt);
6269
6270 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Disk space free"), TRUE);
6271 if (!mainw->dsu_valid || dsq->scanning)
6272 txt = dsu_label_calculating();
6273 else
6274 txt = lives_format_storage_space_string(capable->ds_free);
6275 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6276 lives_free(txt);
6277
6278 if (mainw->dsu_valid && !dsq->scanning) {
6279 if (capable->ds_free <= prefs->ds_crit_level)
6280 show_warn_image(widget_opts.last_label, _("Free diskspace is below the critical level"));
6281 else if (capable->ds_free <= prefs->ds_warn_level)
6282 show_warn_image(widget_opts.last_label, _("Free diskspace is below the warning level"));
6283 }
6284
6285 lives_layout_add_row(LIVES_LAYOUT(layout2));
6286 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Used by other applications"), TRUE);
6287 if (!mainw->dsu_valid || dsq->scanning)
6288 txt = dsu_label_calculating();
6289 else {
6290 dsval = capable->ds_tot - capable->ds_free - capable->ds_used;
6291 txt = lives_format_storage_space_string(dsval);
6292 }
6293 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6294 lives_free(txt);
6295
6296 //lives_layout_add_row(LIVES_LAYOUT(layout2));
6297 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Used by LiVES"), TRUE);
6298
6299 if (!mainw->dsu_valid || dsq->scanning)
6300 txt = dsu_label_calculating();
6301 else
6302 txt = lives_format_storage_space_string(capable->ds_used);
6303 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6304 lives_free(txt);
6305
6306 lives_layout_add_row(LIVES_LAYOUT(layout2));
6307 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Sets on disk"), TRUE);
6308 txt = lives_strdup_printf("%d", mainw->num_sets + mainw->was_set ? 1 : 0);
6309 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6310 lives_free(txt);
6311
6312 //lives_layout_add_row(LIVES_LAYOUT(layout2));
6313 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Currently opened clips"), TRUE);
6314 txt = lives_strdup_printf("%d", mainw->clips_available);
6315 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6316 lives_free(txt);
6317
6318 lives_layout_add_row(LIVES_LAYOUT(layout2));
6319 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Disk quota"), TRUE);
6320 if (prefs->disk_quota)
6321 txt = lives_format_storage_space_string(prefs->disk_quota);
6322 else
6323 txt = dsu_label_notset();
6324 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6325 lives_free(txt);
6326
6327 if (prefs->disk_quota) {
6328 double pcu = 0.;
6329
6330 if (!mainw->dsu_valid || dsq->scanning)
6331 txt = dsu_label_calculating();
6332 else {
6333 uint64_t qq = prefs->disk_quota, over = 0;
6334 if (qq > capable->ds_used) {
6335 qq -= capable->ds_used;
6336 if (qq + prefs->ds_warn_level > capable->ds_free)
6337 over = qq + prefs->ds_warn_level - capable->ds_free;
6338 if (over) {
6339 char *txt2;
6340 txt = lives_format_storage_space_string(over);
6341 txt2 = lives_strdup_printf(_("Quota is reduced by %s due to free disk space limitations"), txt);
6342 show_warn_image(widget_opts.last_label, txt2);
6343 lives_free(txt); lives_free(txt2);
6344 }
6345 if (qq < over) qq = 0;
6346 else qq -= over;
6347 pcu = (double)qq / (double)prefs->disk_quota;
6348 }
6349 txt = lives_strdup_printf("%.2f%%", pcu * 100.);
6350 }
6351
6352 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Unused quota"), TRUE);
6353 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6354 lives_free(txt);
6355 pcu = 100. * (1. - pcu);
6356 if (pcu > prefs->quota_limit) {
6357 txt = lives_strdup_printf(_("LiVES is currently using over %d%% of its available quota"), (int)prefs->quota_limit);
6358 show_warn_image(widget_opts.last_label, txt);
6359 lives_free(txt);
6360 }
6361 }
6362 lives_layout_add_row(LIVES_LAYOUT(layout2));
6363 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Disk warning level"), TRUE);
6364 lives_widget_set_tooltip_text(widget_opts.last_label, H_("value can be set in Preferences . Warnings"));
6365 if (prefs->ds_warn_level)
6366 txt = lives_format_storage_space_string(prefs->ds_warn_level);
6367 else
6368 txt = dsu_label_notset();
6369 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6370 lives_free(txt);
6371
6372 //lives_layout_add_row(LIVES_LAYOUT(layout2));
6373 lives_layout_add_label(LIVES_LAYOUT(layout2), _("Disk critical level"), TRUE);
6374 lives_widget_set_tooltip_text(widget_opts.last_label, H_("value can be set in Preferences . Warnings"));
6375 if (prefs->ds_crit_level)
6376 txt = lives_format_storage_space_string(prefs->ds_crit_level);
6377 else
6378 txt = dsu_label_notset();
6379 lives_layout_add_label(LIVES_LAYOUT(layout2), txt, TRUE);
6380 lives_free(txt);
6381 lives_widget_show_all(dsq->exp_layout);
6382 }
6383
6384
changequota_cb(LiVESWidget * butt,livespointer data)6385 static void changequota_cb(LiVESWidget * butt, livespointer data) {
6386 static char *otxt = NULL;
6387
6388 if (dsq->scanning || !mainw->dsu_valid) {
6389 lives_label_set_text(LIVES_LABEL(dsq->inst_label), _("Still calculating...please wait and try again..."));
6390 return;
6391 }
6392
6393 if (!dsq->setting) {
6394 otxt = lives_strdup(lives_standard_button_get_label(LIVES_BUTTON(butt)));
6395 widget_opts.use_markup = TRUE;
6396 lives_label_set_text(LIVES_LABEL(dsq->inst_label), _("<b>Change the quota by clicking in the free space area "
6397 "in the disk map above,\n"
6398 "or by dragging the slider below</b>"));
6399 widget_opts.use_markup = FALSE;
6400 lives_widget_set_sensitive(dsq->checkbutton, TRUE);
6401 lives_widget_set_sensitive(dsq->vvlabel, TRUE);
6402 lives_widget_set_sensitive(dsq->vlabel, TRUE);
6403 lives_widget_set_sensitive(dsq->slider, TRUE);
6404 lives_standard_button_set_label(LIVES_BUTTON(butt), _("APPLY _QUOTA"));
6405 lives_widget_hide(dsq->note_label);
6406 lives_widget_set_no_show_all(dsq->resbutton, FALSE);
6407 lives_widget_show_all(dsq->resbutton);
6408 dsq->setting = TRUE;
6409 } else {
6410 pref_factory_int64(PREF_DISK_QUOTA, future_prefs->disk_quota, TRUE);
6411 dsu_set_toplabel();
6412 widget_opts.use_markup = TRUE;
6413 lives_label_set_text(LIVES_LABEL(dsq->inst_label), _("<b>Updated !</b>"));
6414 widget_opts.use_markup = FALSE;
6415 lives_widget_set_frozen(dsq->checkbutton, TRUE);
6416 lives_widget_set_frozen(dsq->vvlabel, TRUE);
6417 lives_widget_set_frozen(dsq->vlabel, TRUE);
6418 lives_widget_set_frozen(dsq->slider, TRUE);
6419 lives_standard_button_set_label(LIVES_BUTTON(dsq->button), otxt);
6420 dsq->setting = FALSE;
6421 dsu_fill_details(NULL, NULL);
6422 qslider_changed(dsq->slider, dsq);
6423 }
6424 }
6425
resquota_cb(LiVESWidget * butt,livespointer data)6426 static void resquota_cb(LiVESWidget * butt, livespointer data) {
6427 lives_widget_hide(butt);
6428 lives_widget_show(dsq->note_label);
6429 lives_label_set_text(LIVES_LABEL(dsq->inst_label), NULL);
6430 future_prefs->disk_quota = prefs->disk_quota;
6431 lives_signal_handler_block(dsq->checkbutton, dsq->checkfunc);
6432 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(dsq->checkbutton), !prefs->disk_quota);
6433 lives_signal_handler_unblock(dsq->checkbutton, dsq->checkfunc);
6434
6435 dsq->setting = TRUE;
6436 changequota_cb(dsq->button, NULL);
6437 lives_label_set_text(LIVES_LABEL(dsq->inst_label), NULL);
6438 draw_dsu_widget(mainw->dsu_widget);
6439 }
6440
dsu_abort_clicked(LiVESWidget * butt,livespointer data)6441 static void dsu_abort_clicked(LiVESWidget * butt, livespointer data) {
6442 if (do_abort_check()) abort();
6443 }
6444
run_diskspace_dialog(void)6445 void run_diskspace_dialog(void) {
6446 LiVESWidget *dialog, *dialog_vbox;
6447 LiVESWidget *layout;
6448 LiVESWidget *label;
6449 LiVESWidget *entry;
6450 LiVESWidget *button;
6451 LiVESWidget *hbox, *hbox2;
6452 LiVESWidget *cbut;
6453 LiVESWidget *okbutton;
6454 LiVESWidget *rembutton;
6455
6456 LiVESBox *aar;
6457
6458 LiVESWidgetColor colr;
6459
6460 char *title, *tmp;
6461 int wofl;
6462
6463 /// kick off a bg process to get free ds and ds used
6464
6465 if (!dsq) dsq = (_dsquotaw *)lives_calloc(1, sizeof(_dsquotaw));
6466
6467 dsq->scanning = TRUE;
6468 disk_monitor_start(prefs->workdir);
6469
6470 dsq->setting = FALSE;
6471 dsq->visible = TRUE;
6472 dsq->crit_dism = FALSE;
6473
6474 dsq->exp_layout = NULL;
6475
6476 if (dsq->dsu_surface) lives_painter_surface_destroy(dsq->dsu_surface);
6477 dsq->dsu_surface = NULL;
6478
6479 if (prefsw) lives_widget_hide(prefsw->prefs_dialog);
6480
6481 title = (_("Disk Space Quota"));
6482
6483 dialog = lives_standard_dialog_new(title, FALSE, -1, -1);
6484 lives_signal_handlers_disconnect_by_func(dialog, LIVES_GUI_CALLBACK(return_true), NULL);
6485
6486 lives_free(title);
6487
6488 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
6489 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
6490
6491 widget_opts.text_size = LIVES_TEXT_SIZE_LARGE;
6492 widget_opts.justify = LIVES_JUSTIFY_CENTER;
6493 dsq->top_label = lives_layout_add_label(LIVES_LAYOUT(layout), NULL, FALSE);
6494 dsu_set_toplabel();
6495
6496 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
6497 widget_opts.text_size = LIVES_TEXT_SIZE_NORMAL;
6498
6499 if (prefs->startup_phase) add_fill_to_box(LIVES_BOX(dialog_vbox));
6500 else {
6501 lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
6502
6503 hbox = lives_layout_row_new(LIVES_LAYOUT(layout));
6504
6505 entry = lives_standard_entry_new(_("Current working directory"), prefs->workdir, -1, PATH_MAX,
6506 LIVES_BOX(hbox),
6507 H_("The directory where LiVES will save projects (sets)"));
6508
6509 lives_entry_set_editable(LIVES_ENTRY(entry), FALSE);
6510
6511 //lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
6512
6513 //hbox = lives_layout_row_new(LIVES_LAYOUT(layout));
6514 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6515
6516 button = lives_standard_button_new_from_stock(LIVES_STOCK_PREFERENCES, _("Change Directory"),
6517 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
6518 lives_widget_set_focus_on_click(button, FALSE);
6519
6520 lives_box_pack_start(LIVES_BOX(hbox), button, FALSE, TRUE, widget_opts.packing_width * 4);
6521
6522 lives_signal_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
6523 LIVES_GUI_CALLBACK(workdir_query_cb), dialog);
6524 }
6525
6526 lives_layout_add_row(LIVES_LAYOUT(layout));
6527
6528 widget_opts.text_size = LIVES_TEXT_SIZE_LARGE;
6529 widget_opts.use_markup = TRUE;
6530 lives_layout_add_label(LIVES_LAYOUT(layout), (_("<b>Disk space used by LiVES:</b>")), TRUE);
6531 widget_opts.use_markup = FALSE;
6532
6533 dsq->used_label = lives_layout_add_label(LIVES_LAYOUT(layout), NULL, TRUE);
6534
6535 if (!capable->mountpoint) capable->mountpoint = get_mountpoint_for(prefs->workdir);
6536 if (capable->mountpoint) {
6537 char *txt = lives_strdup_printf(_("in %s"), capable->mountpoint);
6538 lives_layout_add_label(LIVES_LAYOUT(layout), txt, TRUE);
6539 lives_free(txt);
6540 }
6541
6542 widget_opts.text_size = LIVES_TEXT_SIZE_NORMAL;
6543
6544 add_hsep_to_box(LIVES_BOX(dialog_vbox));
6545
6546 hbox = lives_hbox_new(FALSE, 0);
6547 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, TRUE, widget_opts.packing_height >> 1);
6548
6549 if (prefs->startup_phase) add_fill_to_box(LIVES_BOX(dialog_vbox));
6550
6551 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
6552
6553 /// dsu widget
6554 mainw->dsu_widget = lives_standard_drawing_area_new(LIVES_GUI_CALLBACK(all_expose), &dsq->dsu_surface);
6555 lives_widget_add_events(mainw->dsu_widget, LIVES_BUTTON_PRESS_MASK | LIVES_BUTTON_RELEASE_MASK | LIVES_BUTTON1_MOTION_MASK);
6556
6557 lives_signal_sync_connect(LIVES_GUI_OBJECT(mainw->dsu_widget), LIVES_WIDGET_BUTTON_PRESS_EVENT,
6558 LIVES_GUI_CALLBACK(dsu_widget_clicked), LIVES_INT_TO_POINTER(TRUE));
6559
6560 lives_signal_sync_connect(LIVES_GUI_OBJECT(mainw->dsu_widget), LIVES_WIDGET_MOTION_NOTIFY_EVENT,
6561 LIVES_GUI_CALLBACK(dsu_widget_clicked), LIVES_INT_TO_POINTER(FALSE));
6562
6563 lives_signal_sync_connect(LIVES_GUI_OBJECT(mainw->dsu_widget), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
6564 LIVES_GUI_CALLBACK(dsu_widget_released), NULL);
6565
6566 lives_box_pack_start(LIVES_BOX(hbox), mainw->dsu_widget, TRUE, TRUE, 0);
6567
6568 lives_widget_set_size_request(mainw->dsu_widget, -1, widget_opts.css_min_height);
6569
6570 hbox = lives_hbox_new(TRUE, 0);
6571 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, TRUE, 0);
6572
6573 colr.alpha = 1.;
6574
6575 hbox2 = lives_hbox_new(FALSE, 0);
6576 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, TRUE, 0);
6577 colr.red = colr.green = 0.; colr.blue = 1.;
6578 cbut = lives_color_button_new_with_color(&colr);
6579 lives_box_pack_start(LIVES_BOX(hbox2), cbut, FALSE, FALSE, widget_opts.packing_width);
6580 label = lives_standard_label_new(_("Used by other apps"));
6581 lives_box_pack_start(LIVES_BOX(hbox2), label, FALSE, FALSE, widget_opts.packing_width);
6582
6583 hbox2 = lives_hbox_new(FALSE, 0);
6584 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, TRUE, 0);
6585 colr.red = 0.; colr.green = colr.blue = 1.;
6586 cbut = lives_color_button_new_with_color(&colr);
6587 lives_box_pack_start(LIVES_BOX(hbox2), cbut, FALSE, FALSE, widget_opts.packing_width);
6588 label = lives_standard_label_new(_("Used by LiVES"));
6589 lives_box_pack_start(LIVES_BOX(hbox2), label, FALSE, FALSE, widget_opts.packing_width);
6590
6591 hbox2 = lives_hbox_new(FALSE, 0);
6592 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, TRUE, 0);
6593 colr.red = colr.green = 1.; colr.blue = 0.;
6594 cbut = lives_color_button_new_with_color(&colr);
6595 lives_box_pack_start(LIVES_BOX(hbox2), cbut, FALSE, FALSE, widget_opts.packing_width);
6596 label = lives_standard_label_new(_("Quota"));
6597 lives_box_pack_start(LIVES_BOX(hbox2), label, FALSE, FALSE, widget_opts.packing_width);
6598
6599 hbox2 = lives_hbox_new(FALSE, 0);
6600 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, TRUE, 0);
6601 colr.red = colr.blue = 0.; colr.green = 1.;
6602 cbut = lives_color_button_new_with_color(&colr);
6603 lives_box_pack_start(LIVES_BOX(hbox2), cbut, FALSE, FALSE, widget_opts.packing_width);
6604 label = lives_standard_label_new(_("Free space"));
6605 lives_box_pack_start(LIVES_BOX(hbox2), label, FALSE, FALSE, widget_opts.packing_width);
6606
6607 hbox2 = lives_hbox_new(FALSE, 0);
6608 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, TRUE, 0);
6609 colr.red = 1.; colr.green = .5; colr.blue = 0.;
6610 cbut = lives_color_button_new_with_color(&colr);
6611 lives_box_pack_start(LIVES_BOX(hbox2), cbut, FALSE, FALSE, widget_opts.packing_width);
6612 label = lives_standard_label_new(_("Warn level"));
6613 lives_box_pack_start(LIVES_BOX(hbox2), label, FALSE, FALSE, widget_opts.packing_width);
6614
6615 hbox2 = lives_hbox_new(FALSE, 0);
6616 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, TRUE, 0);
6617 colr.red = 1.; colr.green = colr.blue = 0.;
6618 cbut = lives_color_button_new_with_color(&colr);
6619 lives_box_pack_start(LIVES_BOX(hbox2), cbut, FALSE, FALSE, widget_opts.packing_width);
6620 label = lives_standard_label_new(_("Critical level"));
6621 lives_box_pack_start(LIVES_BOX(hbox2), label, FALSE, FALSE, widget_opts.packing_width);
6622
6623 //// expander section ////
6624 dsq->exp_vbox = lives_vbox_new(FALSE, 0);
6625
6626 if (prefs->startup_phase) add_fill_to_box(LIVES_BOX(dialog_vbox));
6627
6628 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
6629 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6630 dsq->expander = lives_standard_expander_new(NULL, LIVES_BOX(hbox), dsq->exp_vbox);
6631 lives_layout_expansion_row_new(LIVES_LAYOUT(layout), dsq->expander);
6632
6633 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(dsq->expander), LIVES_WIDGET_ACTIVATE_SIGNAL,
6634 LIVES_GUI_CALLBACK(dsu_fill_details), dsq);
6635
6636 dsu_fill_details(dsq->expander, dsq);
6637
6638 lives_layout_add_row(LIVES_LAYOUT(layout));
6639
6640 wofl = widget_opts.filler_len;
6641 widget_opts.filler_len = def_widget_opts.filler_len * 6;
6642 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
6643 widget_opts.filler_len = wofl;
6644
6645 if (prefs->startup_phase) lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
6646
6647 widget_opts.use_markup = TRUE;
6648 if (!mainw->has_session_workdir)
6649 dsq->note_label = lives_layout_add_label(LIVES_LAYOUT(layout), (_("Note: LiVES cannot <b>guarantee"
6650 "</b> not to exceed its quota\n"
6651 "but it can warn you if this is detected.")), TRUE);
6652 else
6653 dsq->note_label = lives_layout_add_label(LIVES_LAYOUT(layout), (_("<b>Quota checking is disabled when workdir\n"
6654 "is set via commandline option.</b>")), TRUE);
6655
6656 widget_opts.use_markup = FALSE;
6657 hbox = widget_opts.last_container;
6658
6659 dsq->resbutton = lives_standard_button_new_from_stock(LIVES_STOCK_UNDO, _("Reset"),
6660 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
6661 lives_widget_set_focus_on_click(dsq->resbutton, FALSE);
6662
6663 lives_box_pack_start(LIVES_BOX(hbox), dsq->resbutton, FALSE, FALSE, widget_opts.packing_width * 4);
6664
6665 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(dsq->resbutton), LIVES_WIDGET_CLICKED_SIGNAL,
6666 LIVES_GUI_CALLBACK(resquota_cb), NULL);
6667
6668 lives_widget_set_no_show_all(dsq->resbutton, TRUE);
6669
6670 // quota button
6671
6672 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6673
6674 dsq->button = lives_standard_button_new_from_stock(LIVES_STOCK_PREFERENCES, _("Change _Quota"),
6675 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
6676 lives_widget_set_focus_on_click(dsq->button, FALSE);
6677
6678 lives_box_pack_start(LIVES_BOX(hbox), dsq->button, FALSE, FALSE, widget_opts.packing_width * 4);
6679
6680 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(dsq->button), LIVES_WIDGET_CLICKED_SIGNAL,
6681 LIVES_GUI_CALLBACK(changequota_cb), NULL);
6682
6683 dsq->inst_label = lives_layout_add_label(LIVES_LAYOUT(layout), NULL, TRUE);
6684
6685 if (prefs->startup_phase) add_fill_to_box(LIVES_BOX(dialog_vbox));
6686
6687 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
6688
6689 lives_layout_add_label(LIVES_LAYOUT(layout), (_("Quota:")), TRUE);
6690
6691 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6692 dsq->checkbutton =
6693 lives_standard_check_button_new((tmp = (_("Unlimited"))), future_prefs->disk_quota == 0,
6694 LIVES_BOX(hbox), NULL);
6695
6696 lives_widget_set_frozen(dsq->checkbutton, TRUE);
6697 lives_widget_set_frozen(widget_opts.last_label, TRUE);
6698
6699 dsq->checkfunc = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(dsq->checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
6700 LIVES_GUI_CALLBACK(dsq_check_toggled), NULL);
6701
6702 dsq->vvlabel = lives_layout_add_label(LIVES_LAYOUT(layout), (_("Value:")), TRUE);
6703 lives_widget_set_frozen(dsq->vvlabel, TRUE);
6704 dsq->vlabel = label = lives_layout_add_label(LIVES_LAYOUT(layout), NULL, TRUE);
6705 lives_widget_set_frozen(dsq->vlabel, TRUE);
6706 lives_label_set_width_chars(LIVES_LABEL(dsq->vlabel), 12);
6707
6708 add_fill_to_box(LIVES_BOX(lives_widget_get_parent(label)));
6709
6710 dsq->slider = lives_standard_hscale_new(NULL);
6711 lives_widget_set_size_request(dsq->slider, DEF_SLIDER_WIDTH * 3, widget_opts.css_min_height);
6712 lives_widget_set_sensitive(dsq->slider, TRUE);
6713 lives_range_set_range(LIVES_RANGE(dsq->slider), 0., 100.);
6714
6715 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6716 lives_layout_pack(LIVES_HBOX(hbox), dsq->slider);
6717
6718 lives_widget_set_sensitive(dsq->slider, FALSE);
6719
6720 dsq->sliderfunc = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(dsq->slider), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
6721 LIVES_GUI_CALLBACK(qslider_changed), NULL);
6722
6723 dsq->pculabel = lives_layout_add_label(LIVES_LAYOUT(layout), NULL, TRUE);
6724
6725 if (prefs->startup_phase) add_fill_to_box(LIVES_BOX(dialog_vbox));
6726
6727 if (!prefs->startup_phase) {
6728 add_hsep_to_box(LIVES_BOX(dialog_vbox));
6729
6730 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
6731
6732 lives_layout_add_label(LIVES_LAYOUT(layout), _("Diskspace Management Options"), FALSE);
6733 lives_layout_add_fill(LIVES_LAYOUT(layout), FALSE);
6734
6735 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
6736 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
6737 widget_opts.expand = LIVES_EXPAND_DEFAULT;
6738
6739 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6740 button = lives_standard_button_new_from_stock(LIVES_STOCK_PREFERENCES, _("Clean Up Diskspace"),
6741 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
6742 lives_widget_set_focus_on_click(button, FALSE);
6743 lives_box_pack_start(LIVES_BOX(hbox), button, FALSE, FALSE, widget_opts.packing_width * 4);
6744
6745 lives_signal_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
6746 LIVES_GUI_CALLBACK(cleards_cb), dialog);
6747
6748 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
6749 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6750
6751 button = lives_standard_button_new_from_stock(LIVES_STOCK_PREFERENCES, _("Manage Clip Sets"),
6752 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
6753 lives_widget_set_focus_on_click(button, FALSE);
6754
6755 lives_box_pack_start(LIVES_BOX(hbox), button, FALSE, FALSE, widget_opts.packing_width * 4);
6756
6757 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
6758 LIVES_GUI_CALLBACK(manclips_cb), dialog);
6759
6760 if (mainw->num_sets == -1) {
6761 mainw->set_list = get_set_list(prefs->workdir, TRUE);
6762 if (mainw->set_list) {
6763 mainw->num_sets = lives_list_length(mainw->set_list);
6764 if (mainw->was_set) mainw->num_sets--;
6765 } else mainw->num_sets = 0;
6766 }
6767
6768 if (mainw->num_sets <= 0) lives_widget_set_sensitive(button, FALSE);
6769
6770 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
6771 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
6772
6773 button = lives_standard_button_new_from_stock(LIVES_STOCK_CLOSE, _("Close Current Clips"),
6774 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
6775 lives_widget_set_focus_on_click(button, FALSE);
6776
6777 //if (!mainw->clips_available) lives_widget_set_sensitive(button, FALSE);
6778 lives_widget_set_sensitive(button, FALSE); // TODO
6779
6780 lives_box_pack_start(LIVES_BOX(hbox), button, FALSE, FALSE, widget_opts.packing_width * 4);
6781
6782 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
6783 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
6784 widget_opts.expand = LIVES_EXPAND_DEFAULT;
6785 }
6786 ////
6787
6788 add_fill_to_box(LIVES_BOX(dialog_vbox));
6789
6790 aar = LIVES_BOX(lives_dialog_get_action_area(LIVES_DIALOG(dialog)));
6791
6792 rembutton =
6793 lives_standard_check_button_new(_("Show this dialog on startup"), prefs->show_disk_quota, aar,
6794 (tmp = lives_strdup(H_("These settings can also be changed "
6795 "in Preferences / Warnings"))));
6796
6797 lives_signal_sync_connect(LIVES_GUI_OBJECT(rembutton), LIVES_WIDGET_TOGGLED_SIGNAL,
6798 LIVES_GUI_CALLBACK(toggle_sets_pref), PREF_SHOW_QUOTA);
6799
6800 lives_button_box_make_first(LIVES_BUTTON_BOX(aar), widget_opts.last_container);
6801
6802 dsq->abort_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_QUIT,
6803 _("Abort"), LIVES_RESPONSE_ABORT);
6804
6805 lives_button_uncenter(dsq->abort_button, DLG_BUTTON_WIDTH * 2.);
6806
6807 lives_signal_sync_connect(LIVES_GUI_OBJECT(dsq->abort_button), LIVES_WIDGET_CLICKED_SIGNAL,
6808 LIVES_GUI_CALLBACK(dsu_abort_clicked),
6809 prefsw ? prefsw->prefs_dialog : NULL);
6810 lives_widget_set_no_show_all(dsq->abort_button, TRUE);
6811
6812 if (prefs->startup_phase)
6813 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK,
6814 _("FINISH"), LIVES_RESPONSE_OK);
6815 else
6816 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK,
6817 _("Continue with current values"), LIVES_RESPONSE_OK);
6818
6819 lives_button_uncenter(okbutton, DLG_BUTTON_WIDTH * 2.);
6820
6821 lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
6822 LIVES_GUI_CALLBACK(dsu_ok_clicked),
6823 prefsw ? prefsw->prefs_dialog : NULL);
6824
6825 lives_button_grab_default_special(okbutton);
6826 lives_widget_grab_focus(okbutton);
6827
6828 lives_widget_show_all(dialog);
6829
6830 qslider_changed(dsq->slider, NULL);
6831
6832 if (prefs->startup_phase) {
6833 char *wid = lives_strdup_printf("0x%08lx", (uint64_t)LIVES_XWINDOW_XID(lives_widget_get_xwindow(dialog)));
6834 if (!wid || !activate_x11_window(wid)) lives_window_set_keep_above(LIVES_WINDOW(dialog), TRUE);
6835 lives_dialog_run(LIVES_DIALOG(dialog));
6836 } else lives_idle_add_simple(update_dsu, NULL);
6837 if (mainw->cs_manage && mainw->num_sets) {
6838 mainw->cs_manage = FALSE;
6839 manclips_cb(NULL, dialog);
6840 } else mainw->cs_manage = FALSE;
6841 }
6842
6843
6844 //// message area functions
6845 //#define DEBUG_OVERFLOW
6846
6847 static int vmin = -10000000;
6848 static int hmin = -10000000;
6849 static int reqheight = -1; // presumed height of msg_area
6850 static int reqwidth = -1; // presumed width of msg_area
6851
6852
get_screen_usable_size(int * w,int * h)6853 boolean get_screen_usable_size(int *w, int *h) {
6854 *w = GUI_SCREEN_WIDTH - ((hmin > 0) ? hmin : 0);
6855 *h = GUI_SCREEN_HEIGHT - ((vmin > 0) ? vmin : 0);
6856 if (vmin > 0 || hmin > 0) return TRUE;
6857 return FALSE;
6858 }
6859
6860
msg_area_scroll_to(LiVESWidget * widget,int msgno,boolean recompute,LiVESAdjustment * adj)6861 static boolean msg_area_scroll_to(LiVESWidget * widget, int msgno, boolean recompute, LiVESAdjustment * adj) {
6862 // "scroll" the message area so that the last message appears at the bottom
6863 LingoLayout *layout;
6864 lives_colRGBA64_t fg, bg;
6865
6866 int width;
6867 int height = -1, lh;
6868 int nlines;
6869
6870 static int last_height = -1;
6871
6872 if (!prefs->show_msg_area) return FALSE;
6873 if (mainw->n_messages <= 0) return FALSE;
6874
6875 if (!LIVES_IS_WIDGET(widget)) return FALSE;
6876
6877 height = lives_widget_get_allocation_height(LIVES_WIDGET(widget));
6878 //if (reqheight != -1) height = reqheight;
6879 width = lives_widget_get_allocation_width(LIVES_WIDGET(widget));
6880 if (reqwidth != -1) width = reqwidth;
6881 //g_print("GET LINGO xx %d %d\n", width, height);
6882
6883 layout = (LingoLayout *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout");
6884 if (layout) {
6885 if (LINGO_IS_LAYOUT(layout)) lingo_layout_set_text(layout, "", -1);
6886 lives_widget_object_unref(layout);
6887 }
6888 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(widget), "layout", NULL);
6889
6890 if (width < LAYOUT_SIZE_MIN || height < LAYOUT_SIZE_MIN) return FALSE;
6891
6892 if (msgno < 0) msgno = 0;
6893 if (msgno >= mainw->n_messages) msgno = mainw->n_messages - 1;
6894
6895 // redraw the layout ///////////////////////
6896 lives_widget_set_text_size(widget, LIVES_WIDGET_STATE_NORMAL, lives_textsize_to_string(prefs->msg_textsize));
6897
6898 layout = layout_nth_message_at_bottom(msgno, width, height, LIVES_WIDGET(widget), &nlines);
6899 if (!LINGO_IS_LAYOUT(layout) || !layout) {
6900 return FALSE;
6901 }
6902
6903 lingo_layout_get_size(layout, NULL, &lh);
6904 lh /= LINGO_SCALE;
6905 if (height != last_height) recompute = TRUE;
6906 last_height = height;
6907
6908 if (recompute) {
6909 // redjust the page size
6910 if (nlines > 0) {
6911 double linesize = lh / nlines;
6912 double page_size = (double)((int)((double)height / linesize));
6913 //g_print("VALS3 lh = %d, nlines = %d, lsize = %f, height = %d, ps = %f\n", lh, nlines, linesize, height, page_size);
6914 lives_widget_object_freeze_notify(LIVES_WIDGET_OBJECT(adj));
6915 lives_adjustment_set_lower(adj, page_size);
6916 lives_adjustment_set_upper(adj, (double)(mainw->n_messages + page_size - 2));
6917 lives_adjustment_set_page_size(adj, page_size);
6918 lives_adjustment_set_value(adj, (double)msgno);
6919 lives_widget_object_thaw_notify(LIVES_WIDGET_OBJECT(adj));
6920 //g_print("PAGE SIZE is %f\n", page_size);
6921 }
6922 }
6923
6924 widget_color_to_lives_rgba(&fg, &palette->info_text);
6925 widget_color_to_lives_rgba(&bg, &palette->info_base);
6926
6927 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(widget), "layout", layout);
6928 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(widget), "layout_height", LIVES_INT_TO_POINTER(lh + .5));
6929 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(widget), "layout_lines", LIVES_INT_TO_POINTER(nlines));
6930 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(widget), "layout_last", LIVES_INT_TO_POINTER(msgno));
6931
6932 return TRUE;
6933 }
6934
6935 //#define DEBUG_OVERFLOW
6936 static int height, lheight;
6937
msg_area_config(LiVESWidget * widget)6938 boolean msg_area_config(LiVESWidget * widget) {
6939 static int wiggle_room = 0;
6940 static int last_height = -1;
6941 static int last_textsize = -1;
6942
6943 static int old_scr_width = -1;
6944 static int old_scr_height = -1;
6945
6946 static int last_overflowy = 10000000;
6947 static int last_overflowx = 10000000;
6948
6949 static int gui_posx = 1000000;
6950 static int gui_posy = 1000000;
6951
6952 LingoLayout *layout;
6953 lives_rect_t rect;
6954
6955 boolean mustret = FALSE;
6956
6957 int width;
6958 int lineheight, llines, llast;
6959 int scr_width = GUI_SCREEN_WIDTH;
6960 int scr_height = mainw->mgeom[0].phys_height; //GUI_SCREEN_HEIGHT;
6961 int bx, by, w = -1, h = -1, posx, posy;
6962 int overflowx = 0, overflowy = 0, xoverflowx, xoverflowy;
6963 int ww, hh, vvmin, hhmin;
6964 int paisize = 0, opaisize;
6965
6966 if (!mainw->is_ready) return FALSE;
6967 if (!prefs->show_msg_area) return FALSE;
6968 if (LIVES_IS_PLAYING && prefs->msgs_pbdis) return FALSE;
6969
6970 if (mainw->multitrack && lives_widget_get_allocation_height(mainw->multitrack->top_vbox) < 32)
6971 return FALSE;
6972
6973 lives_widget_set_vexpand(widget, TRUE);
6974
6975 layout = (LingoLayout *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout");
6976
6977 if (last_textsize == -1) last_textsize = prefs->msg_textsize;
6978
6979 width = lives_widget_get_allocation_width(widget);
6980 height = lives_widget_get_allocation_height(widget);
6981
6982 if (reqwidth != -1) width = reqwidth;
6983 reqwidth = -1;
6984 if (reqheight != -1) height = reqheight;
6985 reqheight = -1;
6986
6987 // the expose event for the message area is a good opportunity to recheck the window size
6988
6989 //if (width < LAYOUT_SIZE_MIN || height < LAYOUT_SIZE_MIN) return FALSE;
6990
6991 llast = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget),
6992 "layout_last"));
6993
6994 if (mainw->is_ready && (scr_width != old_scr_width || scr_height != old_scr_height)) {
6995 vmin = -10000000;
6996 hmin = -10000000;
6997 reqheight = -1; // presumed height of msg_area
6998 reqwidth = -1; // presumed width of msg_area
6999 wiggle_room = 0;
7000 last_height = -1;
7001 last_textsize = -1;
7002
7003 last_overflowy = 10000000;
7004 last_overflowx = 10000000;
7005
7006 old_scr_height = scr_height;
7007 old_scr_width = scr_width;
7008 gui_posx = gui_posy = 1000000;
7009 }
7010
7011 lives_xwindow_get_frame_extents(lives_widget_get_xwindow(LIVES_MAIN_WINDOW_WIDGET), &rect);
7012
7013 get_border_size(LIVES_MAIN_WINDOW_WIDGET, &bx, &by);
7014
7015 ww = lives_widget_get_allocation_width(LIVES_MAIN_WINDOW_WIDGET);
7016 w = mainw->assumed_width;
7017 if (w == -1) w = ww;
7018 hh = lives_widget_get_allocation_height(LIVES_MAIN_WINDOW_WIDGET);
7019 h = mainw->assumed_height;
7020 if (h == -1) h = hh;
7021
7022 if (!mainw->multitrack) {
7023 overflowx = ww - (scr_width - bx);
7024 overflowy = hh - (scr_height - by);
7025 #ifdef DEBUG_OVERFLOW
7026 //g_print("ADJ A %d = %d - (%d - %d) + (%d - %d) %d %d\n", overflowy, h, scr_height, by, hh,
7027 // mainw->assumed_height, ABS(overflowy), vmin);
7028 #endif
7029 if (overflowx >= 0 && mainw->assumed_width != -1) {
7030 xoverflowx = ww - w;
7031 if (xoverflowx > overflowx) {
7032 #ifdef DEBUG_OVERFLOW
7033 g_print("ADJ B1 %d = %d - %d - %d\n", xoverflowx, rect.width, w, bx);
7034 #endif
7035 overflowx = xoverflowx;
7036 }
7037 }
7038
7039 if (overflowy >= 0 && mainw->assumed_height != -1) {
7040 xoverflowy = hh - h;
7041 if (xoverflowy > overflowy) {
7042 #ifdef DEBUG_OVERFLOW
7043 g_print("ADJ B2 %d = %d - %d - %d\n", xoverflowy, rect.height, h, by);
7044 #endif
7045 overflowy = xoverflowy;
7046 }
7047 }
7048
7049 if (ABS(overflowx) <= hmin) overflowx = 0;
7050 if (ABS(overflowy) <= vmin) overflowy = 0;
7051
7052 #ifdef DEBUG_OVERFLOW
7053 g_print("overflow2 is %d : %d %d %d X %d : %d %d %d [%d %d %d]\n", overflowx, w, scr_width, bx, overflowy,
7054 h, scr_height, by, h,
7055 rect.height, lives_widget_get_allocation_height(LIVES_MAIN_WINDOW_WIDGET));
7056 #endif
7057
7058 if (overflowx != 0 && w < scr_width && ww <= scr_width && overflowx == last_overflowx) {
7059 int xhmin = ABS(overflowx);
7060 if (xhmin < ABS(hmin)) {
7061 hmin = xhmin;
7062 mustret = TRUE;
7063 }
7064 }
7065 last_overflowx = overflowx;
7066
7067 #ifdef DEBUG_OVERFLOW
7068 g_print("NOW %d %d %d %d %d\n", overflowy, h, scr_height, hh, last_overflowy);
7069 #endif
7070 if (overflowy != 0 && h <= scr_height && hh <= scr_height && overflowy == last_overflowy) {
7071 int xvmin = ABS(overflowy);
7072 if (xvmin < ABS(vmin)) {
7073 vmin = xvmin;
7074 mustret = TRUE;
7075 }
7076 }
7077 last_overflowy = overflowy;
7078
7079 #ifdef DEBUG_OVERFLOW
7080 g_print("WIDG SIZE %d X %d, %d,%d and %d %d %d\n", width, height, hmin, vmin, bx, by, mustret);
7081 #endif
7082 vvmin = by - vmin;
7083 if (vvmin < by && by - vmin < vmin) vmin = by - vmin;
7084
7085 hhmin = bx - hmin;
7086 if (hhmin < bx && bx - hmin < hmin) hmin = bx - hmin;
7087
7088 if (mustret) {
7089 lives_widget_queue_draw(mainw->msg_area);
7090 return FALSE;
7091 }
7092 }
7093
7094 if (overflowx != 0 || overflowy != 0) {
7095 #ifdef DEBUG_OVERFLOW
7096 g_print("overflow is %d X %d : %d %d\n", overflowx, overflowy, width, height);
7097 #endif
7098 width -= overflowx;
7099 height -= overflowy;
7100
7101 if (!mainw->multitrack) {
7102 if (height <= MIN_MSGBAR_HEIGHT) {
7103 height = MIN_MSGBAR_HEIGHT;
7104 mainw->mbar_res = height;
7105 if (!LIVES_IS_PLAYING && CURRENT_CLIP_IS_VALID) redraw_timeline(mainw->current_file);
7106 }
7107
7108 if (width < 0 || height < 0) return FALSE;
7109 }
7110
7111 w -= overflowx;
7112 h -= overflowy;
7113
7114 if (!prefs->open_maximised) {
7115 mainw->assumed_width = w;
7116 mainw->assumed_height = h;
7117 lives_window_resize(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), w, h);
7118 lives_xwindow_get_origin(lives_widget_get_xwindow(LIVES_MAIN_WINDOW_WIDGET), &posx, &posy);
7119 #ifdef DEBUG_OVERFLOW
7120 g_print("2MOVE to %d X %d\n", posx, posy);
7121 #endif
7122 } else {
7123 mainw->assumed_width = rect.width - overflowx - bx;
7124 mainw->assumed_height = rect.height - overflowy - by;
7125 }
7126
7127 if (!prefs->open_maximised) {
7128 if (overflowx > 0) posx -= overflowx;
7129 else posx = -overflowx;
7130 if (posx < 0) posx = 0;
7131 if (overflowy > 0) posy = overflowy - posy;
7132 if (posy < 0) posy = 0;
7133
7134 if (posx > gui_posx) posx = gui_posx;
7135 if (posy > gui_posy) posy = gui_posy;
7136
7137 #ifdef DEBUG_OVERFLOW
7138 g_print("MOVE to %d X %d\n", posx, posy);
7139 #endif
7140 lives_window_move(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), posx, posy);
7141
7142 gui_posx = posx;
7143 gui_posy = posy;
7144 }
7145
7146 if (height > 0 && width > 0) {
7147 if (mainw->multitrack) {
7148 if (height <= MIN_MSGBAR_HEIGHT) {
7149 int pos = lives_paned_get_position(LIVES_PANED(mainw->multitrack->top_vpaned));
7150 pos = pos + height - MIN_MSGBAR_HEIGHT;
7151 height = MIN_MSGBAR_HEIGHT;
7152 lives_container_child_set_shrinkable(LIVES_CONTAINER(mainw->multitrack->top_vpaned),
7153 mainw->multitrack->vpaned, FALSE);
7154 lives_paned_set_position(LIVES_PANED(mainw->multitrack->top_vpaned), pos);
7155 } else
7156 lives_container_child_set_shrinkable(LIVES_CONTAINER(mainw->multitrack->top_vpaned),
7157 mainw->multitrack->vpaned, TRUE);
7158 } else {
7159 if (mainw->mbar_res && height >= mainw->mbar_res * 2) {
7160 mainw->mbar_res = 0;
7161 height -= mainw->mbar_res;
7162 }
7163 }
7164
7165 lives_widget_set_size_request(widget, width, height);
7166 reqwidth = width;
7167 reqheight = height;
7168 }
7169
7170 if (prefs->show_msg_area) lives_widget_show_all(mainw->message_box);
7171
7172 if (!prefs->open_maximised)
7173 lives_window_move(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), posx, posy);
7174 else
7175 lives_window_maximize(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET));
7176 }
7177
7178 opaisize = paisize;
7179 paisize = lives_widget_get_allocation_width(lives_widget_get_parent(widget));
7180
7181 if (!layout || !LINGO_IS_LAYOUT(layout) || paisize != opaisize) {
7182 // this can happen e.g if we open the app. with no clips
7183 msg_area_scroll_to_end(widget, mainw->msg_adj);
7184
7185 // reget this as it may have changed
7186 layout = (LingoLayout *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout");
7187 if (!layout || !LINGO_IS_LAYOUT(layout)) {
7188 return FALSE;
7189 }
7190 }
7191
7192 if (!prefs->open_maximised && !mainw->multitrack && gui_posx < 1000000)
7193 lives_window_move(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), gui_posx, gui_posy);
7194
7195 gui_posx = gui_posy = 1000000;
7196
7197 // check if we could request more
7198 lheight = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout_height"));
7199 if (lheight == 0) return FALSE;
7200
7201 if (height != last_height) wiggle_room = 0;
7202 last_height = height;
7203
7204 #ifdef DEBUG_OVERFLOW
7205 g_print("VALS %d, %d %d\n", lheight, height, wiggle_room);
7206 #endif
7207
7208 llines = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout_lines"));
7209 lineheight = CEIL(lheight / llines, 1);
7210
7211 if (height / lineheight < MIN_MSGBOX_LLINES) {
7212 /// try a smaller font size if we can
7213 if (prefs->msg_textsize > 1) prefs->msg_textsize--;
7214 else if (height < lineheight) return FALSE;
7215 mainw->max_textsize = prefs->msg_textsize;
7216 }
7217
7218 if (lheight < height - wiggle_room || prefs->msg_textsize != last_textsize) {
7219 #ifdef DEBUG_OVERFLOW
7220 g_print("VALS2 %d %d %d : %d %d\n", height / lineheight, llines + 1, llast, prefs->msg_textsize, last_textsize);
7221 #endif
7222 if ((height / lineheight >= llines + 1 && llast > llines) || (prefs->msg_textsize != last_textsize)) {
7223 #ifdef DEBUG_OVERFLOW
7224 g_print("VALS22 %d %d %d : %d %d\n", height / lineheight, llines + 1, llast, prefs->msg_textsize, last_textsize);
7225 #endif
7226 // recompute if the window grew or the text size changed
7227 last_textsize = prefs->msg_textsize;
7228 msg_area_scroll_to(widget, llast, TRUE, mainw->msg_adj); // window grew, re-get layout
7229 layout = (LingoLayout *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout");
7230 if (!layout || !LINGO_IS_LAYOUT(layout)) {
7231 return FALSE;
7232 }
7233 lheight = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget),
7234 "layout_height"));
7235 wiggle_room = height - lheight;
7236 }
7237 }
7238 return FALSE;
7239 }
7240
7241
reshow_msg_area(LiVESWidget * widget,lives_painter_t * cr,livespointer psurf)7242 boolean reshow_msg_area(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
7243 lives_painter_t *cr2;
7244 LingoLayout *layout;
7245 LiVESWidgetState state = lives_widget_get_state(widget);
7246
7247 if (!prefs->show_msg_area) return TRUE;
7248
7249 if (state & LIVES_WIDGET_STATE_BACKDROP) return TRUE;
7250
7251 layout = (LingoLayout *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget), "layout");
7252
7253 if (layout && LINGO_IS_LAYOUT(layout)) {
7254 lives_colRGBA64_t fg, bg;
7255 int rwidth = lives_widget_get_allocation_width(widget);
7256 int rheight = lives_widget_get_allocation_height(widget);
7257
7258 widget_color_to_lives_rgba(&fg, &palette->info_text);
7259 widget_color_to_lives_rgba(&bg, &palette->info_base);
7260
7261 cr2 = lives_painter_create_from_surface(mainw->msg_surface);
7262 lives_painter_render_background(widget, cr2, 0., 0., rwidth, rheight);
7263
7264 height = lives_widget_get_allocation_height(widget);
7265
7266 layout_to_lives_painter(layout, cr2, LIVES_TEXT_MODE_FOREGROUND_AND_BACKGROUND, &fg, &bg, rwidth, rheight,
7267 0., 0., 0., height - lheight - 4);
7268 lingo_painter_show_layout(cr2, layout);
7269 lives_painter_destroy(cr2);
7270 }
7271 lives_painter_set_source_surface(cr, mainw->msg_surface, 0., 0.);
7272 lives_painter_paint(cr);
7273 return FALSE;
7274 }
7275
7276
msg_area_scroll_to_end(LiVESWidget * widget,LiVESAdjustment * adj)7277 LIVES_GLOBAL_INLINE void msg_area_scroll_to_end(LiVESWidget * widget, LiVESAdjustment * adj) {
7278 if (!prefs->show_msg_area) return;
7279 msg_area_scroll_to(widget, mainw->n_messages - 2, TRUE, adj);
7280 // expose_msg_area(widget, NULL, NULL);
7281 }
7282
7283
msg_area_scroll(LiVESAdjustment * adj,livespointer userdata)7284 void msg_area_scroll(LiVESAdjustment * adj, livespointer userdata) {
7285 // scrollbar callback
7286 LiVESWidget *widget = (LiVESWidget *)userdata;
7287 double val;
7288 if (!prefs->show_msg_area) return;
7289 if (!LIVES_IS_ADJUSTMENT(adj)) return;
7290 val = lives_adjustment_get_value(adj);
7291 //g_print("val is %f rnd %d\n", val, (int)(val + .5));
7292 if (msg_area_scroll_to(widget, (int)(val + .5), FALSE, adj))
7293 lives_widget_queue_draw(widget);
7294 //reshow_msg_area(widget);
7295 }
7296
7297
on_msg_area_scroll(LiVESWidget * widget,LiVESXEventScroll * event,livespointer user_data)7298 boolean on_msg_area_scroll(LiVESWidget * widget, LiVESXEventScroll * event, livespointer user_data) {
7299 // mouse scroll callback
7300 LiVESAdjustment *adj = (LiVESAdjustment *)user_data;
7301 if (lives_get_scroll_direction(event) == LIVES_SCROLL_UP) lives_adjustment_set_value(adj, lives_adjustment_get_value(adj) - 1.);
7302 if (lives_get_scroll_direction(event) == LIVES_SCROLL_DOWN) lives_adjustment_set_value(adj,
7303 lives_adjustment_get_value(adj) + 1.);
7304 return FALSE;
7305 }
7306