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(MWindow *mwindow)
64 this->mwindow = mwindow;
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, mwindow->preferences->use_renderfarm);
138 BatchRenderThread::BatchRenderThread(MWindow *mwindow)
141 this->mwindow = mwindow;
147 void BatchRenderThread::handle_close_event(int result)
153 jobs.remove_all_objects();
156 BC_Window* BatchRenderThread::new_gui()
160 default_job = new BatchRenderJob(mwindow);
164 this->gui = new BatchRenderGUI(mwindow,
166 mwindow->session->batchrender_x,
167 mwindow->session->batchrender_y,
168 mwindow->session->batchrender_w,
169 mwindow->session->batchrender_h);
170 this->gui->create_objects();
175 void BatchRenderThread::load_jobs()
177 char path[BCTEXTLEN];
181 jobs.remove_all_objects();
182 file.read_from_file(create_path(path));
186 if(!(result = file.read_tag()))
188 if(file.tag.title_is("JOB"))
191 jobs.append(job = new BatchRenderJob(mwindow));
198 void BatchRenderThread::save_jobs()
200 char path[BCTEXTLEN];
203 for(int i = 0; i < jobs.total; i++)
205 file.tag.set_title("JOB");
206 jobs.values[i]->save(&file);
208 file.write_to_file(create_path(path));
211 void BatchRenderThread::load_defaults()
213 default_job->asset->load_defaults(mwindow->defaults,
220 default_job->fix_strategy();
222 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
224 char string[BCTEXTLEN];
225 sprintf(string, "BATCHRENDER_COLUMN%d", i);
226 column_width[i] = mwindow->defaults->get(string, list_widths[i]);
228 // current_job = mwindow->defaults->get("BATCHRENDER_JOB", 0);
231 void BatchRenderThread::save_defaults()
233 default_job->asset->save_defaults(mwindow->defaults,
240 mwindow->defaults->update("BATCHRENDER_STRATEGY", default_job->strategy);
241 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
243 char string[BCTEXTLEN];
244 sprintf(string, "BATCHRENDER_COLUMN%d", i);
245 mwindow->defaults->update(string, column_width[i]);
247 // mwindow->defaults->update("BATCHRENDER_JOB", current_job);
248 mwindow->save_defaults();
251 char* BatchRenderThread::create_path(char *string)
254 sprintf(string, "%s", BCASTDIR);
255 fs.complete_path(string);
256 strcat(string, "batchrender.rc");
260 void BatchRenderThread::new_job()
262 BatchRenderJob *result = new BatchRenderJob(mwindow);
263 result->copy_from(get_current_job());
265 current_job = jobs.total - 1;
270 void BatchRenderThread::delete_job()
272 if(current_job < jobs.total && current_job >= 0)
274 jobs.remove_object_number(current_job);
275 if(current_job > 0) current_job--;
281 BatchRenderJob* BatchRenderThread::get_current_job()
283 BatchRenderJob *result;
284 if(current_job >= jobs.total || current_job < 0)
286 result = default_job;
290 result = jobs.values[current_job];
296 Asset* BatchRenderThread::get_current_asset()
298 return get_current_job()->asset;
301 char* BatchRenderThread::get_current_edl()
303 return get_current_job()->edl_path;
306 void BatchRenderThread::start_rendering()
308 if(is_rendering) return;
313 gui->new_batch->disable();
314 gui->delete_batch->disable();
316 // Test EDL files for existence
317 for(int i = 0; i < jobs.total; i++)
319 if(jobs.values[i]->enabled)
321 FILE *fd = fopen(jobs.values[i]->edl_path, "r");
324 ErrorBox error_box(PROGRAM_NAME ": Error",
325 mwindow->gui->get_abs_cursor_x(),
326 mwindow->gui->get_abs_cursor_y());
327 char string[BCTEXTLEN];
328 sprintf(string, _("EDL %s not found.\n"), jobs.values[i]->edl_path);
329 error_box.create_objects(string);
330 error_box.run_window();
332 gui->new_batch->enable();
333 gui->delete_batch->enable();
344 // Predict all destination paths
345 ArrayList<char*> paths;
346 for(int i = 0; i < jobs.total; i++)
348 BatchRenderJob *job = jobs.values[i];
351 PackageDispatcher *packages = new PackageDispatcher;
354 TransportCommand *command = new TransportCommand;
355 FileXML *file = new FileXML;
356 file->read_from_file(job->edl_path);
358 // Use command to calculate range.
359 command->command = NORMAL_FWD;
360 command->get_edl()->load_xml(mwindow->plugindb,
363 command->change_type = CHANGE_ALL;
364 command->set_playback_range();
365 command->adjust_playback_range();
367 // Create test packages
368 packages->create_packages(mwindow,
370 mwindow->preferences,
373 command->start_position,
374 command->end_position,
377 // Append output paths allocated to total
378 for(int j = 0; j < packages->get_total_packages(); j++)
380 RenderPackage *package = packages->get_package(j);
381 paths.append(strdup(package->path));
384 // Delete package harness
392 // Test destination files for overwrite
393 int result = ConfirmSave::test_files(mwindow, &paths);
394 paths.remove_all_objects();
400 gui->new_batch->enable();
401 gui->delete_batch->enable();
405 mwindow->render->start_batches(&jobs);
408 void BatchRenderThread::stop_rendering()
410 if(!is_rendering) return;
411 mwindow->render->stop_operation();
415 void BatchRenderThread::update_active(int number)
417 gui->lock_window("BatchRenderThread::update_active");
420 current_job = number;
421 rendering_job = number;
429 gui->unlock_window();
432 void BatchRenderThread::update_done(int number,
436 gui->lock_window("BatchRenderThread::update_done");
439 gui->new_batch->enable();
440 gui->delete_batch->enable();
444 jobs.values[number]->enabled = 0;
445 jobs.values[number]->elapsed = elapsed_time;
446 if(create_list) gui->create_list(1);
448 gui->unlock_window();
451 void BatchRenderThread::move_batch(int src, int dst)
453 BatchRenderJob *src_job = jobs.values[src];
454 if(dst < 0) dst = jobs.total - 1;
458 for(int i = src; i < jobs.total - 1; i++)
459 jobs.values[i] = jobs.values[i + 1];
460 // if(dst > src) dst--;
461 for(int i = jobs.total - 1; i > dst; i--)
462 jobs.values[i] = jobs.values[i - 1];
463 jobs.values[dst] = src_job;
476 BatchRenderGUI::BatchRenderGUI(MWindow *mwindow,
477 BatchRenderThread *thread,
482 : BC_Window(PROGRAM_NAME ": Batch Render",
493 this->mwindow = mwindow;
494 this->thread = thread;
497 BatchRenderGUI::~BatchRenderGUI()
503 void BatchRenderGUI::create_objects()
505 mwindow->theme->get_batchrender_sizes(this, get_w(), get_h());
508 int x = mwindow->theme->batchrender_x1;
510 int x1 = mwindow->theme->batchrender_x1;
511 int x2 = mwindow->theme->batchrender_x2;
512 int x3 = mwindow->theme->batchrender_x3;
517 add_subwindow(output_path_title = new BC_Title(x1, y, _("Output path:")));
519 format_tools = new BatchFormat(mwindow,
521 thread->get_current_asset());
522 format_tools->create_objects(x,
532 &thread->get_current_job()->strategy,
537 x += format_tools->get_w();
544 add_subwindow(edl_path_title = new BC_Title(x, y, _("EDL Path:")));
546 add_subwindow(edl_path_text = new BatchRenderEDLPath(
551 thread->get_current_edl()));
553 x += edl_path_text->get_w();
554 add_subwindow(edl_path_browse = new BrowseButton(
560 thread->get_current_edl(),
562 _("Select an EDL to load:"),
568 add_subwindow(new_batch = new BatchRenderNew(thread,
571 x += new_batch->get_w() + 10;
573 add_subwindow(delete_batch = new BatchRenderDelete(thread,
576 x += delete_batch->get_w() + 10;
580 add_subwindow(list_title = new BC_Title(x, y, _("Batches to render:")));
582 add_subwindow(batch_list = new BatchRenderList(thread,
588 y += batch_list->get_h() + 10;
589 add_subwindow(start_button = new BatchRenderStart(thread,
593 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
594 add_subwindow(stop_button = new BatchRenderStop(thread,
598 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() -
600 add_subwindow(cancel_button = new BatchRenderCancel(thread,
607 int BatchRenderGUI::resize_event(int w, int h)
609 mwindow->session->batchrender_w = w;
610 mwindow->session->batchrender_h = h;
611 mwindow->theme->get_batchrender_sizes(this, w, h);
613 int x = mwindow->theme->batchrender_x1;
615 int x1 = mwindow->theme->batchrender_x1;
616 int x2 = mwindow->theme->batchrender_x2;
617 int x3 = mwindow->theme->batchrender_x3;
621 output_path_title->reposition_window(x1, y);
623 format_tools->reposition_window(x, y);
627 x += format_tools->get_w();
632 edl_path_title->reposition_window(x, y);
634 edl_path_text->reposition_window(x, y, w - x - 40);
635 x += edl_path_text->get_w();
636 edl_path_browse->reposition_window(x, y);
640 // status_title->reposition_window(x, y);
642 // status_text->reposition_window(x, y);
645 // progress_bar->reposition_window(x, y, w - x - 10);
648 new_batch->reposition_window(x, y);
649 x += new_batch->get_w() + 10;
650 delete_batch->reposition_window(x, y);
651 x += delete_batch->get_w() + 10;
655 list_title->reposition_window(x, y);
657 batch_list->reposition_window(x, y, w - x - 10, h - y - 50);
659 y += batch_list->get_h() + 10;
660 start_button->reposition_window(x, y);
662 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
663 stop_button->reposition_window(x, y);
665 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() -
667 cancel_button->reposition_window(x, y);
671 int BatchRenderGUI::translation_event()
673 mwindow->session->batchrender_x = get_x();
674 mwindow->session->batchrender_y = get_y();
678 int BatchRenderGUI::close_event()
680 // Stop batch rendering
682 thread->stop_rendering();
683 lock_window("BatchRenderGUI::close_event");
688 void BatchRenderGUI::create_list(int update_widget)
690 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
692 list_columns[i].remove_all_objects();
695 for(int i = 0; i < thread->jobs.total; i++)
697 BatchRenderJob *job = thread->jobs.values[i];
698 char string[BCTEXTLEN];
699 BC_ListBoxItem *enabled = new BC_ListBoxItem(job->enabled ?
702 BC_ListBoxItem *item1 = new BC_ListBoxItem(job->asset->path);
703 BC_ListBoxItem *item2 = new BC_ListBoxItem(job->edl_path);
704 BC_ListBoxItem *item3;
706 item3 = new BC_ListBoxItem(
707 Units::totext(string,
711 item3 = new BC_ListBoxItem(_("Unknown"));
712 list_columns[0].append(enabled);
713 list_columns[1].append(item1);
714 list_columns[2].append(item2);
715 list_columns[3].append(item3);
716 if(i == thread->current_job)
718 enabled->set_selected(1);
719 item1->set_selected(1);
720 item2->set_selected(1);
721 item3->set_selected(1);
723 if(i == thread->rendering_job)
725 enabled->set_color(RED);
726 item1->set_color(RED);
727 item2->set_color(RED);
728 item3->set_color(RED);
734 batch_list->update(list_columns,
736 thread->column_width,
738 batch_list->get_xposition(),
739 batch_list->get_yposition(),
740 batch_list->get_highlighted_item(), // Flat index of item cursor is over
741 1, // set all autoplace flags to 1
746 void BatchRenderGUI::change_job()
748 BatchRenderJob *job = thread->get_current_job();
749 format_tools->update(job->asset, &job->strategy);
750 edl_path_text->update(job->edl_path);
760 BatchFormat::BatchFormat(MWindow *mwindow,
763 : FormatTools(mwindow, gui, asset)
766 this->mwindow = mwindow;
769 BatchFormat::~BatchFormat()
774 int BatchFormat::handle_event()
790 BatchRenderEDLPath::BatchRenderEDLPath(BatchRenderThread *thread,
801 this->thread = thread;
805 int BatchRenderEDLPath::handle_event()
807 strcpy(thread->get_current_edl(), get_text());
808 thread->gui->create_list(1);
817 BatchRenderNew::BatchRenderNew(BatchRenderThread *thread,
820 : BC_GenericButton(x, y, _("New"))
822 this->thread = thread;
825 int BatchRenderNew::handle_event()
831 BatchRenderDelete::BatchRenderDelete(BatchRenderThread *thread,
834 : BC_GenericButton(x, y, _("Delete"))
836 this->thread = thread;
839 int BatchRenderDelete::handle_event()
841 thread->delete_job();
850 BatchRenderList::BatchRenderList(BatchRenderThread *thread,
860 thread->gui->list_columns,
862 thread->column_width,
870 this->thread = thread;
875 int BatchRenderList::handle_event()
880 int BatchRenderList::selection_changed()
882 thread->current_job = get_selection_number(0, 0);
883 thread->gui->change_job();
884 if(get_cursor_x() < thread->column_width[0])
886 BatchRenderJob *job = thread->get_current_job();
887 job->enabled = !job->enabled;
888 thread->gui->create_list(1);
893 int BatchRenderList::column_resize_event()
895 for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
897 thread->column_width[i] = get_column_width(i);
902 int BatchRenderList::drag_start_event()
904 if(BC_ListBox::drag_start_event())
913 int BatchRenderList::drag_motion_event()
915 if(BC_ListBox::drag_motion_event())
922 int BatchRenderList::drag_stop_event()
926 int src = get_selection_number(0, 0);
927 int dst = get_highlighted_item();
930 thread->move_batch(src, dst);
932 BC_ListBox::drag_stop_event();
948 BatchRenderStart::BatchRenderStart(BatchRenderThread *thread,
953 thread->mwindow->theme->get_image_set(_("batch_render_start")))
955 this->thread = thread;
958 int BatchRenderStart::handle_event()
960 thread->start_rendering();
964 BatchRenderStop::BatchRenderStop(BatchRenderThread *thread,
969 thread->mwindow->theme->get_image_set(_("batch_render_stop")))
971 this->thread = thread;
974 int BatchRenderStop::handle_event()
977 thread->stop_rendering();
978 lock_window("BatchRenderStop::handle_event");
983 BatchRenderCancel::BatchRenderCancel(BatchRenderThread *thread,
988 thread->mwindow->theme->get_image_set(_("batch_render_cancel")))
990 this->thread = thread;
993 int BatchRenderCancel::handle_event()
996 thread->stop_rendering();
997 lock_window("BatchRenderCancel::handle_event");
998 thread->gui->set_done(1);
1002 int BatchRenderCancel::keypress_event()
1004 if(get_keypress() == ESC)
1007 thread->stop_rendering();
1008 lock_window("BatchRenderCancel::keypress_event");
1009 thread->gui->set_done(1);