2 #include "batchrender.h"
4 #include "confirmsave.h"
7 #include "edlsession.h"
9 #include "filesystem.h"
13 #include "mainsession.h"
15 #include "mwindowgui.h"
16 #include "packagedispatcher.h"
17 #include "packagerenderer.h"
18 #include "preferences.h"
21 #include "transportque.h"
28 static char *list_titles[] =
36 static int list_widths[] =
44 BatchRenderMenuItem::BatchRenderMenuItem(MWindow *mwindow)
45 : BC_MenuItem(_("Batch Render..."), "Shift-B", 'B')
48 this->mwindow = mwindow;
51 int BatchRenderMenuItem::handle_event()
53 mwindow->batch_render->start();
64 BatchRenderJob::BatchRenderJob(Preferences *preferences)
66 this->preferences = preferences;
74 BatchRenderJob::~BatchRenderJob()
79 void BatchRenderJob::copy_from(BatchRenderJob *src)
81 asset->copy_from(src->asset, 0);
82 strcpy(edl_path, src->edl_path);
83 strategy = src->strategy;
84 enabled = src->enabled;
88 void BatchRenderJob::load(FileXML *file)
93 file->tag.get_property("EDL_PATH", edl_path);
94 strategy = file->tag.get_property("STRATEGY", strategy);
95 enabled = file->tag.get_property("ENABLED", enabled);
96 elapsed = file->tag.get_property("ELAPSED", elapsed);
99 result = file->read_tag();
102 if(file->tag.title_is("ASSET"))
104 file->tag.get_property("SRC", asset->path);
105 asset->read(file, 0);
110 void BatchRenderJob::save(FileXML *file)
112 TRACE("BatchRenderJob::save 1");
113 file->tag.set_property("EDL_PATH", edl_path);
114 TRACE("BatchRenderJob::save 1");
115 file->tag.set_property("STRATEGY", strategy);
116 TRACE("BatchRenderJob::save 1");
117 file->tag.set_property("ENABLED", enabled);
118 TRACE("BatchRenderJob::save 1");
119 file->tag.set_property("ELAPSED", elapsed);
120 TRACE("BatchRenderJob::save 1");
122 TRACE("BatchRenderJob::save 1");
123 file->append_newline();
124 TRACE("BatchRenderJob::save 1");
128 TRACE("BatchRenderJob::save 1");
129 file->tag.set_title("/JOB");
130 TRACE("BatchRenderJob::save 1");
132 TRACE("BatchRenderJob::save 1");
133 file->append_newline();
134 TRACE("BatchRenderJob::save 10");
137 void BatchRenderJob::fix_strategy()
139 strategy = Render::fix_strategy(strategy, preferences->use_renderfarm);
151 BatchRenderThread::BatchRenderThread(MWindow *mwindow)
154 this->mwindow = mwindow;
161 BatchRenderThread::BatchRenderThread()
171 void BatchRenderThread::handle_close_event(int result)
174 TRACE("BatchRenderThread::handle_close_event 1");
175 char path[BCTEXTLEN];
176 TRACE("BatchRenderThread::handle_close_event 1");
178 TRACE("BatchRenderThread::handle_close_event 1");
180 TRACE("BatchRenderThread::handle_close_event 1");
181 save_defaults(mwindow->defaults);
182 TRACE("BatchRenderThread::handle_close_event 1");
184 TRACE("BatchRenderThread::handle_close_event 1");
186 TRACE("BatchRenderThread::handle_close_event 1");
187 jobs.remove_all_objects();
188 TRACE("BatchRenderThread::handle_close_event 100");
191 BC_Window* BatchRenderThread::new_gui()
195 default_job = new BatchRenderJob(mwindow->preferences);
197 char path[BCTEXTLEN];
199 load_jobs(path, mwindow->preferences);
200 load_defaults(mwindow->defaults);
201 this->gui = new BatchRenderGUI(mwindow,
203 mwindow->session->batchrender_x,
204 mwindow->session->batchrender_y,
205 mwindow->session->batchrender_w,
206 mwindow->session->batchrender_h);
207 this->gui->create_objects();
212 void BatchRenderThread::load_jobs(char *path, Preferences *preferences)
217 jobs.remove_all_objects();
219 file.read_from_file(path);
221 file.read_from_file(create_path(path));
225 if(!(result = file.read_tag()))
227 if(file.tag.title_is("JOB"))
230 jobs.append(job = new BatchRenderJob(preferences));
237 void BatchRenderThread::save_jobs(char *path)
241 for(int i = 0; i < jobs.total; i++)
243 file.tag.set_title("JOB");
244 jobs.values[i]->save(&file);
248 file.write_to_file(path);
250 file.write_to_file(create_path(path));
253 void BatchRenderThread::load_defaults(Defaults *defaults)
257 default_job->asset->load_defaults(defaults,
264 default_job->fix_strategy();
267 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
269 char string[BCTEXTLEN];
270 sprintf(string, "BATCHRENDER_COLUMN%d", i);
271 column_width[i] = defaults->get(string, list_widths[i]);
275 void BatchRenderThread::save_defaults(Defaults *defaults)
279 default_job->asset->save_defaults(defaults,
286 defaults->update("BATCHRENDER_STRATEGY", default_job->strategy);
288 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
290 char string[BCTEXTLEN];
291 sprintf(string, "BATCHRENDER_COLUMN%d", i);
292 defaults->update(string, column_width[i]);
294 // defaults->update("BATCHRENDER_JOB", current_job);
296 mwindow->save_defaults();
301 char* BatchRenderThread::create_path(char *string)
304 sprintf(string, "%s", BCASTDIR);
305 fs.complete_path(string);
306 strcat(string, BATCH_PATH);
310 void BatchRenderThread::new_job()
312 BatchRenderJob *result = new BatchRenderJob(mwindow->preferences);
313 result->copy_from(get_current_job());
315 current_job = jobs.total - 1;
320 void BatchRenderThread::delete_job()
322 if(current_job < jobs.total && current_job >= 0)
324 jobs.remove_object_number(current_job);
325 if(current_job > 0) current_job--;
331 BatchRenderJob* BatchRenderThread::get_current_job()
333 BatchRenderJob *result;
334 if(current_job >= jobs.total || current_job < 0)
336 result = default_job;
340 result = jobs.values[current_job];
346 Asset* BatchRenderThread::get_current_asset()
348 return get_current_job()->asset;
351 char* BatchRenderThread::get_current_edl()
353 return get_current_job()->edl_path;
357 // Test EDL files for existence
358 int BatchRenderThread::test_edl_files()
360 for(int i = 0; i < jobs.total; i++)
362 if(jobs.values[i]->enabled)
364 FILE *fd = fopen(jobs.values[i]->edl_path, "r");
367 char string[BCTEXTLEN];
368 sprintf(string, _("EDL %s not found.\n"), jobs.values[i]->edl_path);
371 ErrorBox error_box(PROGRAM_NAME ": Error",
372 mwindow->gui->get_abs_cursor_x(1),
373 mwindow->gui->get_abs_cursor_y(1));
374 error_box.create_objects(string);
375 error_box.run_window();
376 gui->new_batch->enable();
377 gui->delete_batch->enable();
398 void BatchRenderThread::calculate_dest_paths(ArrayList<char*> *paths,
399 Preferences *preferences,
400 ArrayList<PluginServer*> *plugindb)
402 for(int i = 0; i < jobs.total; i++)
404 BatchRenderJob *job = jobs.values[i];
407 PackageDispatcher *packages = new PackageDispatcher;
410 TransportCommand *command = new TransportCommand;
411 FileXML *file = new FileXML;
412 file->read_from_file(job->edl_path);
414 // Use command to calculate range.
415 command->command = NORMAL_FWD;
416 command->get_edl()->load_xml(plugindb,
419 command->change_type = CHANGE_ALL;
420 command->set_playback_range();
421 command->adjust_playback_range();
423 // Create test packages
424 packages->create_packages(mwindow,
429 command->start_position,
430 command->end_position,
433 // Append output paths allocated to total
434 for(int j = 0; j < packages->get_total_packages(); j++)
436 RenderPackage *package = packages->get_package(j);
437 paths->append(strdup(package->path));
440 // Delete package harness
449 void BatchRenderThread::start_rendering(char *config_path,
452 Defaults *boot_defaults;
453 Preferences *preferences;
455 ArrayList<PluginServer*> *plugindb;
457 // Initialize stuff which MWindow does.
458 MWindow::init_defaults(boot_defaults, config_path);
459 load_defaults(boot_defaults);
460 preferences = new Preferences;
461 preferences->load_defaults(boot_defaults);
462 MWindow::init_plugins(preferences, plugindb, 0);
464 load_jobs(batch_path, preferences);
465 save_jobs(batch_path);
466 save_defaults(boot_defaults);
468 // Test EDL files for existence
469 if(test_edl_files()) return;
472 // Predict all destination paths
473 ArrayList<char*> paths;
474 calculate_dest_paths(&paths,
478 int result = ConfirmSave::test_files(0, &paths);
479 // Abort on any existing file because it's so hard to set this up.
482 render = new Render(0);
483 render->start_batches(&jobs,
489 void BatchRenderThread::start_rendering()
491 if(is_rendering) return;
494 char path[BCTEXTLEN];
497 save_defaults(mwindow->defaults);
498 gui->new_batch->disable();
499 gui->delete_batch->disable();
501 // Test EDL files for existence
502 if(test_edl_files()) return;
504 // Predict all destination paths
505 ArrayList<char*> paths;
506 calculate_dest_paths(&paths,
507 mwindow->preferences,
510 // Test destination files for overwrite
511 int result = ConfirmSave::test_files(mwindow, &paths);
512 paths.remove_all_objects();
518 gui->new_batch->enable();
519 gui->delete_batch->enable();
523 mwindow->render->start_batches(&jobs);
526 void BatchRenderThread::stop_rendering()
528 if(!is_rendering) return;
529 mwindow->render->stop_operation();
533 void BatchRenderThread::update_active(int number)
535 gui->lock_window("BatchRenderThread::update_active");
538 current_job = number;
539 rendering_job = number;
547 gui->unlock_window();
550 void BatchRenderThread::update_done(int number,
554 gui->lock_window("BatchRenderThread::update_done");
557 gui->new_batch->enable();
558 gui->delete_batch->enable();
562 jobs.values[number]->enabled = 0;
563 jobs.values[number]->elapsed = elapsed_time;
564 if(create_list) gui->create_list(1);
566 gui->unlock_window();
569 void BatchRenderThread::move_batch(int src, int dst)
571 BatchRenderJob *src_job = jobs.values[src];
572 if(dst < 0) dst = jobs.total - 1;
576 for(int i = src; i < jobs.total - 1; i++)
577 jobs.values[i] = jobs.values[i + 1];
578 // if(dst > src) dst--;
579 for(int i = jobs.total - 1; i > dst; i--)
580 jobs.values[i] = jobs.values[i - 1];
581 jobs.values[dst] = src_job;
594 BatchRenderGUI::BatchRenderGUI(MWindow *mwindow,
595 BatchRenderThread *thread,
600 : BC_Window(PROGRAM_NAME ": Batch Render",
611 this->mwindow = mwindow;
612 this->thread = thread;
615 BatchRenderGUI::~BatchRenderGUI()
621 void BatchRenderGUI::create_objects()
623 mwindow->theme->get_batchrender_sizes(this, get_w(), get_h());
626 int x = mwindow->theme->batchrender_x1;
628 int x1 = mwindow->theme->batchrender_x1;
629 int x2 = mwindow->theme->batchrender_x2;
630 int x3 = mwindow->theme->batchrender_x3;
635 add_subwindow(output_path_title = new BC_Title(x1, y, _("Output path:")));
637 format_tools = new BatchFormat(mwindow,
639 thread->get_current_asset());
640 format_tools->create_objects(x,
650 &thread->get_current_job()->strategy,
655 x += format_tools->get_w();
662 add_subwindow(edl_path_title = new BC_Title(x, y, _("EDL Path:")));
664 add_subwindow(edl_path_text = new BatchRenderEDLPath(
669 thread->get_current_edl()));
671 x += edl_path_text->get_w();
672 add_subwindow(edl_path_browse = new BrowseButton(
678 thread->get_current_edl(),
680 _("Select an EDL to load:"),
686 add_subwindow(new_batch = new BatchRenderNew(thread,
689 x += new_batch->get_w() + 10;
691 add_subwindow(delete_batch = new BatchRenderDelete(thread,
694 x += delete_batch->get_w() + 10;
698 add_subwindow(list_title = new BC_Title(x, y, _("Batches to render:")));
700 add_subwindow(batch_list = new BatchRenderList(thread,
706 y += batch_list->get_h() + 10;
707 add_subwindow(start_button = new BatchRenderStart(thread,
711 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
712 add_subwindow(stop_button = new BatchRenderStop(thread,
716 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() -
718 add_subwindow(cancel_button = new BatchRenderCancel(thread,
725 int BatchRenderGUI::resize_event(int w, int h)
727 mwindow->session->batchrender_w = w;
728 mwindow->session->batchrender_h = h;
729 mwindow->theme->get_batchrender_sizes(this, w, h);
731 int x = mwindow->theme->batchrender_x1;
733 int x1 = mwindow->theme->batchrender_x1;
734 int x2 = mwindow->theme->batchrender_x2;
735 int x3 = mwindow->theme->batchrender_x3;
739 output_path_title->reposition_window(x1, y);
741 format_tools->reposition_window(x, y);
745 x += format_tools->get_w();
750 edl_path_title->reposition_window(x, y);
752 edl_path_text->reposition_window(x, y, w - x - 40);
753 x += edl_path_text->get_w();
754 edl_path_browse->reposition_window(x, y);
758 // status_title->reposition_window(x, y);
760 // status_text->reposition_window(x, y);
763 // progress_bar->reposition_window(x, y, w - x - 10);
766 new_batch->reposition_window(x, y);
767 x += new_batch->get_w() + 10;
768 delete_batch->reposition_window(x, y);
769 x += delete_batch->get_w() + 10;
773 list_title->reposition_window(x, y);
775 batch_list->reposition_window(x, y, w - x - 10, h - y - 50);
777 y += batch_list->get_h() + 10;
778 start_button->reposition_window(x, y);
780 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
781 stop_button->reposition_window(x, y);
783 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() -
785 cancel_button->reposition_window(x, y);
789 int BatchRenderGUI::translation_event()
791 mwindow->session->batchrender_x = get_x();
792 mwindow->session->batchrender_y = get_y();
796 int BatchRenderGUI::close_event()
798 // Stop batch rendering
800 thread->stop_rendering();
801 lock_window("BatchRenderGUI::close_event");
806 void BatchRenderGUI::create_list(int update_widget)
808 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
810 list_columns[i].remove_all_objects();
813 for(int i = 0; i < thread->jobs.total; i++)
815 BatchRenderJob *job = thread->jobs.values[i];
816 char string[BCTEXTLEN];
817 BC_ListBoxItem *enabled = new BC_ListBoxItem(job->enabled ?
820 BC_ListBoxItem *item1 = new BC_ListBoxItem(job->asset->path);
821 BC_ListBoxItem *item2 = new BC_ListBoxItem(job->edl_path);
822 BC_ListBoxItem *item3;
824 item3 = new BC_ListBoxItem(
825 Units::totext(string,
829 item3 = new BC_ListBoxItem(_("Unknown"));
830 list_columns[0].append(enabled);
831 list_columns[1].append(item1);
832 list_columns[2].append(item2);
833 list_columns[3].append(item3);
834 if(i == thread->current_job)
836 enabled->set_selected(1);
837 item1->set_selected(1);
838 item2->set_selected(1);
839 item3->set_selected(1);
841 if(i == thread->rendering_job)
843 enabled->set_color(RED);
844 item1->set_color(RED);
845 item2->set_color(RED);
846 item3->set_color(RED);
852 batch_list->update(list_columns,
854 thread->column_width,
856 batch_list->get_xposition(),
857 batch_list->get_yposition(),
858 batch_list->get_highlighted_item(), // Flat index of item cursor is over
859 1, // set all autoplace flags to 1
864 void BatchRenderGUI::change_job()
866 BatchRenderJob *job = thread->get_current_job();
867 format_tools->update(job->asset, &job->strategy);
868 edl_path_text->update(job->edl_path);
878 BatchFormat::BatchFormat(MWindow *mwindow,
881 : FormatTools(mwindow, gui, asset)
884 this->mwindow = mwindow;
887 BatchFormat::~BatchFormat()
892 int BatchFormat::handle_event()
908 BatchRenderEDLPath::BatchRenderEDLPath(BatchRenderThread *thread,
919 this->thread = thread;
923 int BatchRenderEDLPath::handle_event()
925 strcpy(thread->get_current_edl(), get_text());
926 thread->gui->create_list(1);
935 BatchRenderNew::BatchRenderNew(BatchRenderThread *thread,
938 : BC_GenericButton(x, y, _("New"))
940 this->thread = thread;
943 int BatchRenderNew::handle_event()
949 BatchRenderDelete::BatchRenderDelete(BatchRenderThread *thread,
952 : BC_GenericButton(x, y, _("Delete"))
954 this->thread = thread;
957 int BatchRenderDelete::handle_event()
959 thread->delete_job();
968 BatchRenderList::BatchRenderList(BatchRenderThread *thread,
978 thread->gui->list_columns,
980 thread->column_width,
988 this->thread = thread;
993 int BatchRenderList::handle_event()
998 int BatchRenderList::selection_changed()
1000 thread->current_job = get_selection_number(0, 0);
1001 thread->gui->change_job();
1002 if(get_cursor_x() < thread->column_width[0])
1004 BatchRenderJob *job = thread->get_current_job();
1005 job->enabled = !job->enabled;
1006 thread->gui->create_list(1);
1011 int BatchRenderList::column_resize_event()
1013 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
1015 thread->column_width[i] = get_column_width(i);
1020 int BatchRenderList::drag_start_event()
1022 if(BC_ListBox::drag_start_event())
1031 int BatchRenderList::drag_motion_event()
1033 if(BC_ListBox::drag_motion_event())
1040 int BatchRenderList::drag_stop_event()
1044 int src = get_selection_number(0, 0);
1045 int dst = get_highlighted_item();
1048 thread->move_batch(src, dst);
1050 BC_ListBox::drag_stop_event();
1066 BatchRenderStart::BatchRenderStart(BatchRenderThread *thread,
1071 thread->mwindow->theme->get_image_set(_("batch_render_start")))
1073 this->thread = thread;
1076 int BatchRenderStart::handle_event()
1078 thread->start_rendering();
1082 BatchRenderStop::BatchRenderStop(BatchRenderThread *thread,
1087 thread->mwindow->theme->get_image_set(_("batch_render_stop")))
1089 this->thread = thread;
1092 int BatchRenderStop::handle_event()
1095 thread->stop_rendering();
1096 lock_window("BatchRenderStop::handle_event");
1101 BatchRenderCancel::BatchRenderCancel(BatchRenderThread *thread,
1106 thread->mwindow->theme->get_image_set(_("batch_render_cancel")))
1108 this->thread = thread;
1111 int BatchRenderCancel::handle_event()
1114 thread->stop_rendering();
1115 lock_window("BatchRenderCancel::handle_event");
1116 thread->gui->set_done(1);
1120 int BatchRenderCancel::keypress_event()
1122 if(get_keypress() == ESC)
1125 thread->stop_rendering();
1126 lock_window("BatchRenderCancel::keypress_event");
1127 thread->gui->set_done(1);