2 #include "batchrender.h"
3 #include "confirmsave.h"
6 #include "edlsession.h"
8 #include "filesystem.h"
12 #include "mainsession.h"
14 #include "mwindowgui.h"
15 #include "packagedispatcher.h"
16 #include "packagerenderer.h"
17 #include "preferences.h"
20 #include "transportque.h"
27 static char *list_titles[] =
35 static int list_widths[] =
43 BatchRenderMenuItem::BatchRenderMenuItem(MWindow *mwindow)
44 : BC_MenuItem(_("Batch Render..."))
46 this->mwindow = mwindow;
49 int BatchRenderMenuItem::handle_event()
51 mwindow->batch_render->start();
62 BatchRenderJob::BatchRenderJob(Preferences *preferences)
64 this->preferences = preferences;
72 BatchRenderJob::~BatchRenderJob()
77 void BatchRenderJob::copy_from(BatchRenderJob *src)
79 asset->copy_from(src->asset, 0);
80 strcpy(edl_path, src->edl_path);
81 strategy = src->strategy;
82 enabled = src->enabled;
86 void BatchRenderJob::load(FileXML *file)
91 file->tag.get_property("EDL_PATH", edl_path);
92 strategy = file->tag.get_property("STRATEGY", strategy);
93 enabled = file->tag.get_property("ENABLED", enabled);
94 elapsed = file->tag.get_property("ELAPSED", elapsed);
97 result = file->read_tag();
100 if(file->tag.title_is("ASSET"))
102 file->tag.get_property("SRC", asset->path);
103 asset->read(file, 0);
108 void BatchRenderJob::save(FileXML *file)
110 file->tag.set_property("EDL_PATH", edl_path);
111 file->tag.set_property("STRATEGY", strategy);
112 file->tag.set_property("ENABLED", enabled);
113 file->tag.set_property("ELAPSED", elapsed);
115 file->append_newline();
119 file->tag.set_title("/JOB");
121 file->append_newline();
124 void BatchRenderJob::fix_strategy()
126 strategy = Render::fix_strategy(strategy, preferences->use_renderfarm);
138 BatchRenderThread::BatchRenderThread(MWindow *mwindow)
141 this->mwindow = mwindow;
148 BatchRenderThread::BatchRenderThread()
158 void BatchRenderThread::handle_close_event(int result)
161 char path[BCTEXTLEN];
164 save_defaults(mwindow->defaults);
167 jobs.remove_all_objects();
170 BC_Window* BatchRenderThread::new_gui()
174 default_job = new BatchRenderJob(mwindow->preferences);
176 char path[BCTEXTLEN];
178 load_jobs(path, mwindow->preferences);
179 load_defaults(mwindow->defaults);
180 this->gui = new BatchRenderGUI(mwindow,
182 mwindow->session->batchrender_x,
183 mwindow->session->batchrender_y,
184 mwindow->session->batchrender_w,
185 mwindow->session->batchrender_h);
186 this->gui->create_objects();
191 void BatchRenderThread::load_jobs(char *path, Preferences *preferences)
196 jobs.remove_all_objects();
198 file.read_from_file(path);
200 file.read_from_file(create_path(path));
204 if(!(result = file.read_tag()))
206 if(file.tag.title_is("JOB"))
209 jobs.append(job = new BatchRenderJob(preferences));
216 void BatchRenderThread::save_jobs(char *path)
220 for(int i = 0; i < jobs.total; i++)
222 file.tag.set_title("JOB");
223 jobs.values[i]->save(&file);
227 file.write_to_file(path);
229 file.write_to_file(create_path(path));
232 void BatchRenderThread::load_defaults(Defaults *defaults)
236 default_job->asset->load_defaults(defaults,
243 default_job->fix_strategy();
246 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
248 char string[BCTEXTLEN];
249 sprintf(string, "BATCHRENDER_COLUMN%d", i);
250 column_width[i] = defaults->get(string, list_widths[i]);
254 void BatchRenderThread::save_defaults(Defaults *defaults)
258 default_job->asset->save_defaults(defaults,
265 defaults->update("BATCHRENDER_STRATEGY", default_job->strategy);
267 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
269 char string[BCTEXTLEN];
270 sprintf(string, "BATCHRENDER_COLUMN%d", i);
271 defaults->update(string, column_width[i]);
273 // defaults->update("BATCHRENDER_JOB", current_job);
275 mwindow->save_defaults();
280 char* BatchRenderThread::create_path(char *string)
283 sprintf(string, "%s", BCASTDIR);
284 fs.complete_path(string);
285 strcat(string, BATCH_PATH);
289 void BatchRenderThread::new_job()
291 BatchRenderJob *result = new BatchRenderJob(mwindow->preferences);
292 result->copy_from(get_current_job());
294 current_job = jobs.total - 1;
299 void BatchRenderThread::delete_job()
301 if(current_job < jobs.total && current_job >= 0)
303 jobs.remove_object_number(current_job);
304 if(current_job > 0) current_job--;
310 BatchRenderJob* BatchRenderThread::get_current_job()
312 BatchRenderJob *result;
313 if(current_job >= jobs.total || current_job < 0)
315 result = default_job;
319 result = jobs.values[current_job];
325 Asset* BatchRenderThread::get_current_asset()
327 return get_current_job()->asset;
330 char* BatchRenderThread::get_current_edl()
332 return get_current_job()->edl_path;
336 // Test EDL files for existence
337 int BatchRenderThread::test_edl_files()
339 for(int i = 0; i < jobs.total; i++)
341 if(jobs.values[i]->enabled)
343 FILE *fd = fopen(jobs.values[i]->edl_path, "r");
346 char string[BCTEXTLEN];
347 sprintf(string, _("EDL %s not found.\n"), jobs.values[i]->edl_path);
350 ErrorBox error_box(PROGRAM_NAME ": Error",
351 mwindow->gui->get_abs_cursor_x(),
352 mwindow->gui->get_abs_cursor_y());
353 error_box.create_objects(string);
354 error_box.run_window();
355 gui->new_batch->enable();
356 gui->delete_batch->enable();
377 void BatchRenderThread::calculate_dest_paths(ArrayList<char*> *paths,
378 Preferences *preferences,
379 ArrayList<PluginServer*> *plugindb)
381 for(int i = 0; i < jobs.total; i++)
383 BatchRenderJob *job = jobs.values[i];
386 PackageDispatcher *packages = new PackageDispatcher;
389 TransportCommand *command = new TransportCommand;
390 FileXML *file = new FileXML;
391 file->read_from_file(job->edl_path);
393 // Use command to calculate range.
394 command->command = NORMAL_FWD;
395 command->get_edl()->load_xml(plugindb,
398 command->change_type = CHANGE_ALL;
399 command->set_playback_range();
400 command->adjust_playback_range();
402 // Create test packages
403 packages->create_packages(mwindow,
408 command->start_position,
409 command->end_position,
412 // Append output paths allocated to total
413 for(int j = 0; j < packages->get_total_packages(); j++)
415 RenderPackage *package = packages->get_package(j);
416 paths->append(strdup(package->path));
419 // Delete package harness
428 void BatchRenderThread::start_rendering(char *config_path,
431 Defaults *boot_defaults;
432 Preferences *preferences;
434 ArrayList<PluginServer*> *plugindb;
436 // Initialize stuff which MWindow does.
437 MWindow::init_defaults(boot_defaults, config_path);
438 load_defaults(boot_defaults);
439 preferences = new Preferences;
440 preferences->load_defaults(boot_defaults);
441 MWindow::init_plugins(preferences, plugindb, 0);
443 load_jobs(batch_path, preferences);
444 save_jobs(batch_path);
445 save_defaults(boot_defaults);
447 // Test EDL files for existence
448 if(test_edl_files()) return;
451 // Predict all destination paths
452 ArrayList<char*> paths;
453 calculate_dest_paths(&paths,
457 int result = ConfirmSave::test_files(0, &paths);
458 // Abort on any existing file because it's so hard to set this up.
461 render = new Render(0);
462 render->start_batches(&jobs,
468 void BatchRenderThread::start_rendering()
470 if(is_rendering) return;
473 char path[BCTEXTLEN];
476 save_defaults(mwindow->defaults);
477 gui->new_batch->disable();
478 gui->delete_batch->disable();
480 // Test EDL files for existence
481 if(test_edl_files()) return;
483 // Predict all destination paths
484 ArrayList<char*> paths;
485 calculate_dest_paths(&paths,
486 mwindow->preferences,
489 // Test destination files for overwrite
490 int result = ConfirmSave::test_files(mwindow, &paths);
491 paths.remove_all_objects();
497 gui->new_batch->enable();
498 gui->delete_batch->enable();
502 mwindow->render->start_batches(&jobs);
505 void BatchRenderThread::stop_rendering()
507 if(!is_rendering) return;
508 mwindow->render->stop_operation();
512 void BatchRenderThread::update_active(int number)
514 gui->lock_window("BatchRenderThread::update_active");
517 current_job = number;
518 rendering_job = number;
526 gui->unlock_window();
529 void BatchRenderThread::update_done(int number,
533 gui->lock_window("BatchRenderThread::update_done");
536 gui->new_batch->enable();
537 gui->delete_batch->enable();
541 jobs.values[number]->enabled = 0;
542 jobs.values[number]->elapsed = elapsed_time;
543 if(create_list) gui->create_list(1);
545 gui->unlock_window();
548 void BatchRenderThread::move_batch(int src, int dst)
550 BatchRenderJob *src_job = jobs.values[src];
551 if(dst < 0) dst = jobs.total - 1;
555 for(int i = src; i < jobs.total - 1; i++)
556 jobs.values[i] = jobs.values[i + 1];
557 // if(dst > src) dst--;
558 for(int i = jobs.total - 1; i > dst; i--)
559 jobs.values[i] = jobs.values[i - 1];
560 jobs.values[dst] = src_job;
573 BatchRenderGUI::BatchRenderGUI(MWindow *mwindow,
574 BatchRenderThread *thread,
579 : BC_Window(PROGRAM_NAME ": Batch Render",
590 this->mwindow = mwindow;
591 this->thread = thread;
594 BatchRenderGUI::~BatchRenderGUI()
600 void BatchRenderGUI::create_objects()
602 mwindow->theme->get_batchrender_sizes(this, get_w(), get_h());
605 int x = mwindow->theme->batchrender_x1;
607 int x1 = mwindow->theme->batchrender_x1;
608 int x2 = mwindow->theme->batchrender_x2;
609 int x3 = mwindow->theme->batchrender_x3;
614 add_subwindow(output_path_title = new BC_Title(x1, y, _("Output path:")));
616 format_tools = new BatchFormat(mwindow,
618 thread->get_current_asset());
619 format_tools->create_objects(x,
629 &thread->get_current_job()->strategy,
634 x += format_tools->get_w();
641 add_subwindow(edl_path_title = new BC_Title(x, y, _("EDL Path:")));
643 add_subwindow(edl_path_text = new BatchRenderEDLPath(
648 thread->get_current_edl()));
650 x += edl_path_text->get_w();
651 add_subwindow(edl_path_browse = new BrowseButton(
657 thread->get_current_edl(),
659 _("Select an EDL to load:"),
665 add_subwindow(new_batch = new BatchRenderNew(thread,
668 x += new_batch->get_w() + 10;
670 add_subwindow(delete_batch = new BatchRenderDelete(thread,
673 x += delete_batch->get_w() + 10;
677 add_subwindow(list_title = new BC_Title(x, y, _("Batches to render:")));
679 add_subwindow(batch_list = new BatchRenderList(thread,
685 y += batch_list->get_h() + 10;
686 add_subwindow(start_button = new BatchRenderStart(thread,
690 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
691 add_subwindow(stop_button = new BatchRenderStop(thread,
695 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() -
697 add_subwindow(cancel_button = new BatchRenderCancel(thread,
704 int BatchRenderGUI::resize_event(int w, int h)
706 mwindow->session->batchrender_w = w;
707 mwindow->session->batchrender_h = h;
708 mwindow->theme->get_batchrender_sizes(this, w, h);
710 int x = mwindow->theme->batchrender_x1;
712 int x1 = mwindow->theme->batchrender_x1;
713 int x2 = mwindow->theme->batchrender_x2;
714 int x3 = mwindow->theme->batchrender_x3;
718 output_path_title->reposition_window(x1, y);
720 format_tools->reposition_window(x, y);
724 x += format_tools->get_w();
729 edl_path_title->reposition_window(x, y);
731 edl_path_text->reposition_window(x, y, w - x - 40);
732 x += edl_path_text->get_w();
733 edl_path_browse->reposition_window(x, y);
737 // status_title->reposition_window(x, y);
739 // status_text->reposition_window(x, y);
742 // progress_bar->reposition_window(x, y, w - x - 10);
745 new_batch->reposition_window(x, y);
746 x += new_batch->get_w() + 10;
747 delete_batch->reposition_window(x, y);
748 x += delete_batch->get_w() + 10;
752 list_title->reposition_window(x, y);
754 batch_list->reposition_window(x, y, w - x - 10, h - y - 50);
756 y += batch_list->get_h() + 10;
757 start_button->reposition_window(x, y);
759 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
760 stop_button->reposition_window(x, y);
762 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() -
764 cancel_button->reposition_window(x, y);
768 int BatchRenderGUI::translation_event()
770 mwindow->session->batchrender_x = get_x();
771 mwindow->session->batchrender_y = get_y();
775 int BatchRenderGUI::close_event()
777 // Stop batch rendering
779 thread->stop_rendering();
780 lock_window("BatchRenderGUI::close_event");
785 void BatchRenderGUI::create_list(int update_widget)
787 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
789 list_columns[i].remove_all_objects();
792 for(int i = 0; i < thread->jobs.total; i++)
794 BatchRenderJob *job = thread->jobs.values[i];
795 char string[BCTEXTLEN];
796 BC_ListBoxItem *enabled = new BC_ListBoxItem(job->enabled ?
799 BC_ListBoxItem *item1 = new BC_ListBoxItem(job->asset->path);
800 BC_ListBoxItem *item2 = new BC_ListBoxItem(job->edl_path);
801 BC_ListBoxItem *item3;
803 item3 = new BC_ListBoxItem(
804 Units::totext(string,
808 item3 = new BC_ListBoxItem(_("Unknown"));
809 list_columns[0].append(enabled);
810 list_columns[1].append(item1);
811 list_columns[2].append(item2);
812 list_columns[3].append(item3);
813 if(i == thread->current_job)
815 enabled->set_selected(1);
816 item1->set_selected(1);
817 item2->set_selected(1);
818 item3->set_selected(1);
820 if(i == thread->rendering_job)
822 enabled->set_color(RED);
823 item1->set_color(RED);
824 item2->set_color(RED);
825 item3->set_color(RED);
831 batch_list->update(list_columns,
833 thread->column_width,
835 batch_list->get_xposition(),
836 batch_list->get_yposition(),
837 batch_list->get_highlighted_item(), // Flat index of item cursor is over
838 1, // set all autoplace flags to 1
843 void BatchRenderGUI::change_job()
845 BatchRenderJob *job = thread->get_current_job();
846 format_tools->update(job->asset, &job->strategy);
847 edl_path_text->update(job->edl_path);
857 BatchFormat::BatchFormat(MWindow *mwindow,
860 : FormatTools(mwindow, gui, asset)
863 this->mwindow = mwindow;
866 BatchFormat::~BatchFormat()
871 int BatchFormat::handle_event()
887 BatchRenderEDLPath::BatchRenderEDLPath(BatchRenderThread *thread,
898 this->thread = thread;
902 int BatchRenderEDLPath::handle_event()
904 strcpy(thread->get_current_edl(), get_text());
905 thread->gui->create_list(1);
914 BatchRenderNew::BatchRenderNew(BatchRenderThread *thread,
917 : BC_GenericButton(x, y, _("New"))
919 this->thread = thread;
922 int BatchRenderNew::handle_event()
928 BatchRenderDelete::BatchRenderDelete(BatchRenderThread *thread,
931 : BC_GenericButton(x, y, _("Delete"))
933 this->thread = thread;
936 int BatchRenderDelete::handle_event()
938 thread->delete_job();
947 BatchRenderList::BatchRenderList(BatchRenderThread *thread,
957 thread->gui->list_columns,
959 thread->column_width,
967 this->thread = thread;
972 int BatchRenderList::handle_event()
977 int BatchRenderList::selection_changed()
979 thread->current_job = get_selection_number(0, 0);
980 thread->gui->change_job();
981 if(get_cursor_x() < thread->column_width[0])
983 BatchRenderJob *job = thread->get_current_job();
984 job->enabled = !job->enabled;
985 thread->gui->create_list(1);
990 int BatchRenderList::column_resize_event()
992 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
994 thread->column_width[i] = get_column_width(i);
999 int BatchRenderList::drag_start_event()
1001 if(BC_ListBox::drag_start_event())
1010 int BatchRenderList::drag_motion_event()
1012 if(BC_ListBox::drag_motion_event())
1019 int BatchRenderList::drag_stop_event()
1023 int src = get_selection_number(0, 0);
1024 int dst = get_highlighted_item();
1027 thread->move_batch(src, dst);
1029 BC_ListBox::drag_stop_event();
1045 BatchRenderStart::BatchRenderStart(BatchRenderThread *thread,
1050 thread->mwindow->theme->get_image_set(_("batch_render_start")))
1052 this->thread = thread;
1055 int BatchRenderStart::handle_event()
1057 thread->start_rendering();
1061 BatchRenderStop::BatchRenderStop(BatchRenderThread *thread,
1066 thread->mwindow->theme->get_image_set(_("batch_render_stop")))
1068 this->thread = thread;
1071 int BatchRenderStop::handle_event()
1074 thread->stop_rendering();
1075 lock_window("BatchRenderStop::handle_event");
1080 BatchRenderCancel::BatchRenderCancel(BatchRenderThread *thread,
1085 thread->mwindow->theme->get_image_set(_("batch_render_cancel")))
1087 this->thread = thread;
1090 int BatchRenderCancel::handle_event()
1093 thread->stop_rendering();
1094 lock_window("BatchRenderCancel::handle_event");
1095 thread->gui->set_done(1);
1099 int BatchRenderCancel::keypress_event()
1101 if(get_keypress() == ESC)
1104 thread->stop_rendering();
1105 lock_window("BatchRenderCancel::keypress_event");
1106 thread->gui->set_done(1);