r136: This commit was manufactured by cvs2svn to create tag 'hv_1_1_8'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / batchrender.C
blobb6ba9ad6b5e31d87d696633b804de9e9ba07b868
1 #include "asset.h"
2 #include "batchrender.h"
3 #include "confirmsave.h"
4 #include "defaults.h"
5 #include "edl.h"
6 #include "edlsession.h"
7 #include "errorbox.h"
8 #include "filesystem.h"
9 #include "filexml.h"
10 #include "keys.h"
11 #include "language.h"
12 #include "mainsession.h"
13 #include "mwindow.h"
14 #include "mwindowgui.h"
15 #include "packagedispatcher.h"
16 #include "packagerenderer.h"
17 #include "preferences.h"
18 #include "render.h"
19 #include "theme.h"
20 #include "transportque.h"
21 #include "vframe.h"
27 static char *list_titles[] = 
29         "Enabled", 
30         "Output",
31         "EDL",
32         "Elapsed"
35 static int list_widths[] =
37         50,
38         100,
39         200,
40         100
43 BatchRenderMenuItem::BatchRenderMenuItem(MWindow *mwindow)
44  : BC_MenuItem(_("Batch Render..."))
46         this->mwindow = mwindow;
49 int BatchRenderMenuItem::handle_event()
51         mwindow->batch_render->start();
52         return 1;
62 BatchRenderJob::BatchRenderJob(MWindow *mwindow)
64         this->mwindow = mwindow;
65         asset = new Asset;
66         edl_path[0] = 0;
67         strategy = 0;
68         enabled = 1;
69         elapsed = 0;
72 BatchRenderJob::~BatchRenderJob()
74         delete asset;
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;
83         elapsed = 0;
86 void BatchRenderJob::load(FileXML *file)
88         int result = 0;
90         edl_path[0] = 0;
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);
95         fix_strategy();
97         result = file->read_tag();
98         if(!result)
99         {
100                 if(file->tag.title_is("ASSET"))
101                 {
102                         file->tag.get_property("SRC", asset->path);
103                         asset->read(file, 0);
104                 }
105         }
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);
114         file->append_tag();
115         file->append_newline();
116         asset->write(file,
117                 0,
118                 "");
119         file->tag.set_title("/JOB");
120         file->append_tag();
121         file->append_newline();
124 void BatchRenderJob::fix_strategy()
126         strategy = Render::fix_strategy(strategy, mwindow->preferences->use_renderfarm);
138 BatchRenderThread::BatchRenderThread(MWindow *mwindow)
139  : BC_DialogThread()
141         this->mwindow = mwindow;
142         current_job = 0;
143         rendering_job = -1;
144         is_rendering = 0;
147 void BatchRenderThread::handle_close_event(int result)
149 // Save settings
150         save_jobs();
151         save_defaults();
152         delete default_job;
153         jobs.remove_all_objects();
156 BC_Window* BatchRenderThread::new_gui()
158         current_start = 0.0;
159         current_end = 0.0;
160         default_job = new BatchRenderJob(mwindow);
162         load_jobs();
163         load_defaults();
164         this->gui = new BatchRenderGUI(mwindow, 
165                 this,
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();
171         return this->gui;
175 void BatchRenderThread::load_jobs()
177         char path[BCTEXTLEN];
178         FileXML file;
179         int result = 0;
181         jobs.remove_all_objects();
182         file.read_from_file(create_path(path));
184         while(!result)
185         {
186                 if(!(result = file.read_tag()))
187                 {
188                         if(file.tag.title_is("JOB"))
189                         {
190                                 BatchRenderJob *job;
191                                 jobs.append(job = new BatchRenderJob(mwindow));
192                                 job->load(&file);
193                         }
194                 }
195         }
198 void BatchRenderThread::save_jobs()
200         char path[BCTEXTLEN];
201         FileXML file;
203         for(int i = 0; i < jobs.total; i++)
204         {
205                 file.tag.set_title("JOB");
206                 jobs.values[i]->save(&file);
207         }
208         file.write_to_file(create_path(path));
211 void BatchRenderThread::load_defaults()
213         default_job->asset->load_defaults(mwindow->defaults,
214                 "BATCHRENDER_",
215                 1,
216                 1,
217                 1,
218                 1,
219                 1);
220         default_job->fix_strategy();
222         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
223         {
224                 char string[BCTEXTLEN];
225                 sprintf(string, "BATCHRENDER_COLUMN%d", i);
226                 column_width[i] = mwindow->defaults->get(string, list_widths[i]);
227         }
228 //      current_job = mwindow->defaults->get("BATCHRENDER_JOB", 0);
231 void BatchRenderThread::save_defaults()
233         default_job->asset->save_defaults(mwindow->defaults,
234                 "BATCHRENDER_",
235                 1,
236                 1,
237                 1,
238                 1,
239                 1);
240         mwindow->defaults->update("BATCHRENDER_STRATEGY", default_job->strategy);
241         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
242         {
243                 char string[BCTEXTLEN];
244                 sprintf(string, "BATCHRENDER_COLUMN%d", i);
245                 mwindow->defaults->update(string, column_width[i]);
246         }
247 //      mwindow->defaults->update("BATCHRENDER_JOB", current_job);
248         mwindow->save_defaults();
251 char* BatchRenderThread::create_path(char *string)
253         FileSystem fs;
254         sprintf(string, "%s", BCASTDIR);
255         fs.complete_path(string);
256         strcat(string, "batchrender.rc");
257         return string;
260 void BatchRenderThread::new_job()
262         BatchRenderJob *result = new BatchRenderJob(mwindow);
263         result->copy_from(get_current_job());
264         jobs.append(result);
265         current_job = jobs.total - 1;
266         gui->create_list(1);
267         gui->change_job();
270 void BatchRenderThread::delete_job()
272         if(current_job < jobs.total && current_job >= 0)
273         {
274                 jobs.remove_object_number(current_job);
275                 if(current_job > 0) current_job--;
276                 gui->create_list(1);
277                 gui->change_job();
278         }
281 BatchRenderJob* BatchRenderThread::get_current_job()
283         BatchRenderJob *result;
284         if(current_job >= jobs.total || current_job < 0)
285         {
286                 result = default_job;
287         }
288         else
289         {
290                 result = jobs.values[current_job];
291         }
292         return result;
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;
310         is_rendering = 1;
311         save_jobs();
312         save_defaults();
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++)
318         {
319                 if(jobs.values[i]->enabled)
320                 {
321                         FILE *fd = fopen(jobs.values[i]->edl_path, "r");
322                         if(!fd)
323                         {
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();
331                                 is_rendering = 0;
332                                 gui->new_batch->enable();
333                                 gui->delete_batch->enable();
334                                 is_rendering = 0;
335                                 return;
336                         }
337                         else
338                         {
339                                 fclose(fd);
340                         }
341                 }
342         }
344 // Predict all destination paths
345         ArrayList<char*> paths;
346         for(int i = 0; i < jobs.total; i++)
347         {
348                 BatchRenderJob *job = jobs.values[i];
349                 if(job->enabled)
350                 {
351                         PackageDispatcher *packages = new PackageDispatcher;
353 // Load EDL
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, 
361                                 file, 
362                                 LOAD_ALL);
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,
369                                 command->get_edl(),
370                                 mwindow->preferences,
371                                 job->strategy, 
372                                 job->asset, 
373                                 command->start_position, 
374                                 command->end_position,
375                                 0);
377 // Append output paths allocated to total
378                         for(int j = 0; j < packages->get_total_packages(); j++)
379                         {
380                                 RenderPackage *package = packages->get_package(j);
381                                 paths.append(strdup(package->path));
382                         }
384 // Delete package harness
385                         delete packages;
386                         delete command;
387                         delete file;
388                 }
389         }
392 // Test destination files for overwrite
393         int result = ConfirmSave::test_files(mwindow, &paths);
394         paths.remove_all_objects();
396 // User cancelled
397         if(result)
398         {
399                 is_rendering = 0;
400                 gui->new_batch->enable();
401                 gui->delete_batch->enable();
402                 return;
403         }
405         mwindow->render->start_batches(&jobs);
408 void BatchRenderThread::stop_rendering()
410         if(!is_rendering) return;
411         mwindow->render->stop_operation();
412         is_rendering = 0;
415 void BatchRenderThread::update_active(int number)
417         gui->lock_window("BatchRenderThread::update_active");
418         if(number >= 0)
419         {
420                 current_job = number;
421                 rendering_job = number;
422         }
423         else
424         {
425                 rendering_job = -1;
426                 is_rendering = 0;
427         }
428         gui->create_list(1);
429         gui->unlock_window();
432 void BatchRenderThread::update_done(int number, 
433         int create_list, 
434         double elapsed_time)
436         gui->lock_window("BatchRenderThread::update_done");
437         if(number < 0)
438         {
439                 gui->new_batch->enable();
440                 gui->delete_batch->enable();
441         }
442         else
443         {
444                 jobs.values[number]->enabled = 0;
445                 jobs.values[number]->elapsed = elapsed_time;
446                 if(create_list) gui->create_list(1);
447         }
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;
456         if(dst != src)
457         {
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;
464                 gui->create_list(1);
465         }
476 BatchRenderGUI::BatchRenderGUI(MWindow *mwindow, 
477         BatchRenderThread *thread,
478         int x,
479         int y,
480         int w,
481         int h)
482  : BC_Window(PROGRAM_NAME ": Batch Render", 
483         x,
484         y,
485         w, 
486         h, 
487         50, 
488         50, 
489         1,
490         0, 
491         1)
493         this->mwindow = mwindow;
494         this->thread = thread;
497 BatchRenderGUI::~BatchRenderGUI()
499         delete format_tools;
503 void BatchRenderGUI::create_objects()
505         mwindow->theme->get_batchrender_sizes(this, get_w(), get_h());
506         create_list(0);
508         int x = mwindow->theme->batchrender_x1;
509         int y = 5;
510         int x1 = mwindow->theme->batchrender_x1;
511         int x2 = mwindow->theme->batchrender_x2;
512         int x3 = mwindow->theme->batchrender_x3;
513         int y1 = y;
514         int y2;
516 // output file
517         add_subwindow(output_path_title = new BC_Title(x1, y, _("Output path:")));
518         y += 20;
519         format_tools = new BatchFormat(mwindow,
520                                         this, 
521                                         thread->get_current_asset());
522         format_tools->create_objects(x, 
523                                                 y, 
524                                                 1, 
525                                                 1, 
526                                                 1, 
527                                                 1, 
528                                                 0, 
529                                                 1, 
530                                                 0, 
531                                                 0, 
532                                                 &thread->get_current_job()->strategy, 
533                                                 0);
535         x2 = x;
536         y2 = y + 10;
537         x += format_tools->get_w();
538         y = y1;
539         x1 = x;
540         x3 = x + 80;
542 // input EDL
543         x = x1;
544         add_subwindow(edl_path_title = new BC_Title(x, y, _("EDL Path:")));
545         y += 20;
546         add_subwindow(edl_path_text = new BatchRenderEDLPath(
547                 thread, 
548                 x, 
549                 y, 
550                 get_w() - x - 40, 
551                 thread->get_current_edl()));
553         x += edl_path_text->get_w();
554         add_subwindow(edl_path_browse = new BrowseButton(
555                 mwindow,
556                 this,
557                 edl_path_text, 
558                 x, 
559                 y, 
560                 thread->get_current_edl(),
561                 _("Input EDL"),
562                 _("Select an EDL to load:"),
563                 0));
565         x = x1;
567         y += 30;
568         add_subwindow(new_batch = new BatchRenderNew(thread, 
569                 x, 
570                 y));
571         x += new_batch->get_w() + 10;
573         add_subwindow(delete_batch = new BatchRenderDelete(thread, 
574                 x, 
575                 y));
576         x += delete_batch->get_w() + 10;
578         x = x2;
579         y = y2;
580         add_subwindow(list_title = new BC_Title(x, y, _("Batches to render:")));
581         y += 20;
582         add_subwindow(batch_list = new BatchRenderList(thread, 
583                 x, 
584                 y,
585                 get_w() - x - 10,
586                 get_h() - y - 50));
588         y += batch_list->get_h() + 10;
589         add_subwindow(start_button = new BatchRenderStart(thread, 
590             x, 
591             y));
592         x = get_w() / 2 -
593                 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
594         add_subwindow(stop_button = new BatchRenderStop(thread, 
595                 x, 
596                 y));
597         x = get_w() - 
598                 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() - 
599                 10;
600         add_subwindow(cancel_button = new BatchRenderCancel(thread, 
601                 x, 
602                 y));
604         show_window();
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;
614         int y = 5;
615         int x1 = mwindow->theme->batchrender_x1;
616         int x2 = mwindow->theme->batchrender_x2;
617         int x3 = mwindow->theme->batchrender_x3;
618         int y1 = y;
619         int y2;
621         output_path_title->reposition_window(x1, y);
622         y += 20;
623         format_tools->reposition_window(x, y);
624         x2 = x;
625         y2 = y + 10;
626         y = y1;
627         x += format_tools->get_w();
628         x1 = x;
629         x3 = x + 80;
631         x = x1;
632         edl_path_title->reposition_window(x, y);
633         y += 20;
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);
638         x = x1;
639 //      y += 30;
640 //      status_title->reposition_window(x, y);
641 //      x = x3;
642 //      status_text->reposition_window(x, y);
643 //      x = x1;
644 //      y += 30;
645 //      progress_bar->reposition_window(x, y, w - x - 10);
647         y += 30;
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;
653         x = x2;
654         y = y2;
655         list_title->reposition_window(x, y);
656         y += 20;
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);
661         x = w / 2 - 
662                 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
663         stop_button->reposition_window(x, y);
664         x = w -
665                 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() - 
666                 10;
667         cancel_button->reposition_window(x, y);
668         return 1;
671 int BatchRenderGUI::translation_event()
673         mwindow->session->batchrender_x = get_x();
674         mwindow->session->batchrender_y = get_y();
675         return 1;
678 int BatchRenderGUI::close_event()
680 // Stop batch rendering
681         unlock_window();
682         thread->stop_rendering();
683         lock_window("BatchRenderGUI::close_event");
684         set_done(1);
685         return 1;
688 void BatchRenderGUI::create_list(int update_widget)
690         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
691         {
692                 list_columns[i].remove_all_objects();
693         }
695         for(int i = 0; i < thread->jobs.total; i++)
696         {
697                 BatchRenderJob *job = thread->jobs.values[i];
698                 char string[BCTEXTLEN];
699                 BC_ListBoxItem *enabled = new BC_ListBoxItem(job->enabled ? 
700                         (char*)"X" : 
701                         (char*)" ");
702                 BC_ListBoxItem *item1 = new BC_ListBoxItem(job->asset->path);
703                 BC_ListBoxItem *item2 = new BC_ListBoxItem(job->edl_path);
704                 BC_ListBoxItem *item3;
705                 if(job->elapsed)
706                         item3 = new BC_ListBoxItem(
707                                 Units::totext(string,
708                                         job->elapsed,
709                                         TIME_HMS2));
710                 else
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)
717                 {
718                         enabled->set_selected(1);
719                         item1->set_selected(1);
720                         item2->set_selected(1);
721                         item3->set_selected(1);
722                 }
723                 if(i == thread->rendering_job)
724                 {
725                         enabled->set_color(RED);
726                         item1->set_color(RED);
727                         item2->set_color(RED);
728                         item3->set_color(RED);
729                 }
730         }
732         if(update_widget)
733         {
734                 batch_list->update(list_columns,
735                                                 list_titles,
736                                                 thread->column_width,
737                                                 BATCHRENDER_COLUMNS,
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
742                                                 1);
743         }
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,
761                         BatchRenderGUI *gui,
762                         Asset *asset)
763  : FormatTools(mwindow, gui, asset)
765         this->gui = gui;
766         this->mwindow = mwindow;
769 BatchFormat::~BatchFormat()
774 int BatchFormat::handle_event()
776         gui->create_list(1);
777         return 1;
790 BatchRenderEDLPath::BatchRenderEDLPath(BatchRenderThread *thread, 
791         int x, 
792         int y, 
793         int w, 
794         char *text)
795  : BC_TextBox(x, 
796                 y, 
797                 w, 
798                 1,
799                 text)
801         this->thread = thread;
805 int BatchRenderEDLPath::handle_event()
807         strcpy(thread->get_current_edl(), get_text());
808         thread->gui->create_list(1);
809         return 1;
817 BatchRenderNew::BatchRenderNew(BatchRenderThread *thread, 
818         int x, 
819         int y)
820  : BC_GenericButton(x, y, _("New"))
822         this->thread = thread;
825 int BatchRenderNew::handle_event()
827         thread->new_job();
828         return 1;
831 BatchRenderDelete::BatchRenderDelete(BatchRenderThread *thread, 
832         int x, 
833         int y)
834  : BC_GenericButton(x, y, _("Delete"))
836         this->thread = thread;
839 int BatchRenderDelete::handle_event()
841         thread->delete_job();
842         return 1;
850 BatchRenderList::BatchRenderList(BatchRenderThread *thread, 
851         int x, 
852         int y,
853         int w,
854         int h)
855  : BC_ListBox(x, 
856         y, 
857         w, 
858         h, 
859         LISTBOX_TEXT,
860         thread->gui->list_columns,
861         list_titles,
862         thread->column_width,
863         BATCHRENDER_COLUMNS,
864         0,
865         0,
866         LISTBOX_SINGLE,
867         ICON_LEFT,
868         1)
870         this->thread = thread;
871         dragging_item = 0;
872         set_process_drag(0);
875 int BatchRenderList::handle_event()
877         return 1;
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])
885         {
886                 BatchRenderJob *job = thread->get_current_job();
887                 job->enabled = !job->enabled;
888                 thread->gui->create_list(1);
889         }
890         return 1;
893 int BatchRenderList::column_resize_event()
895         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
896         {
897                 thread->column_width[i] = get_column_width(i);
898         }
899         return 1;
902 int BatchRenderList::drag_start_event()
904         if(BC_ListBox::drag_start_event())
905         {
906                 dragging_item = 1;
907                 return 1;
908         }
910         return 0;
913 int BatchRenderList::drag_motion_event()
915         if(BC_ListBox::drag_motion_event())
916         {
917                 return 1;
918         }
919         return 0;
922 int BatchRenderList::drag_stop_event()
924         if(dragging_item)
925         {
926                 int src = get_selection_number(0, 0);
927                 int dst = get_highlighted_item();
928                 if(src != dst)
929                 {
930                         thread->move_batch(src, dst);
931                 }
932                 BC_ListBox::drag_stop_event();
933         }
948 BatchRenderStart::BatchRenderStart(BatchRenderThread *thread, 
949         int x, 
950         int y)
951  : BC_Button(x, 
952         y, 
953         thread->mwindow->theme->get_image_set(_("batch_render_start")))
955         this->thread = thread;
958 int BatchRenderStart::handle_event()
960         thread->start_rendering();
961         return 1;
964 BatchRenderStop::BatchRenderStop(BatchRenderThread *thread, 
965         int x, 
966         int y)
967  : BC_Button(x, 
968         y, 
969         thread->mwindow->theme->get_image_set(_("batch_render_stop")))
971         this->thread = thread;
974 int BatchRenderStop::handle_event()
976         unlock_window();
977         thread->stop_rendering();
978         lock_window("BatchRenderStop::handle_event");
979         return 1;
983 BatchRenderCancel::BatchRenderCancel(BatchRenderThread *thread, 
984         int x, 
985         int y)
986  : BC_Button(x, 
987         y, 
988         thread->mwindow->theme->get_image_set(_("batch_render_cancel")))
990         this->thread = thread;
993 int BatchRenderCancel::handle_event()
995         unlock_window();
996         thread->stop_rendering();
997         lock_window("BatchRenderCancel::handle_event");
998         thread->gui->set_done(1);
999         return 1;
1002 int BatchRenderCancel::keypress_event()
1004         if(get_keypress() == ESC) 
1005         {
1006                 unlock_window();
1007                 thread->stop_rendering();
1008                 lock_window("BatchRenderCancel::keypress_event");
1009                 thread->gui->set_done(1);
1010                 return 1;
1011         }
1012         return 0;