r553: Modern gccs require __attribute__((used)) for variables used only in assembly.
[cinelerra_cv/mob.git] / cinelerra / batchrender.C
blob83ca341646bf8d78f329840adc5bafe76122bb45
1 #include "asset.h"
2 #include "batchrender.h"
3 #include "bcsignals.h"
4 #include "confirmsave.h"
5 #include "defaults.h"
6 #include "edl.h"
7 #include "edlsession.h"
8 #include "errorbox.h"
9 #include "filesystem.h"
10 #include "filexml.h"
11 #include "keys.h"
12 #include "language.h"
13 #include "mainsession.h"
14 #include "mwindow.h"
15 #include "mwindowgui.h"
16 #include "packagedispatcher.h"
17 #include "packagerenderer.h"
18 #include "preferences.h"
19 #include "render.h"
20 #include "theme.h"
21 #include "transportque.h"
22 #include "vframe.h"
28 static char *list_titles[] = 
30         N_("Enabled"), 
31         N_("Output"),
32         N_("EDL"),
33         N_("Elapsed")
36 static int list_widths[] =
38         50,
39         100,
40         200,
41         100
44 BatchRenderMenuItem::BatchRenderMenuItem(MWindow *mwindow)
45  : BC_MenuItem(_("Batch Render..."), "Shift-B", 'B')
47         set_shift(1); 
48         this->mwindow = mwindow;
51 int BatchRenderMenuItem::handle_event()
53         mwindow->batch_render->start();
54         return 1;
64 BatchRenderJob::BatchRenderJob(Preferences *preferences)
66         this->preferences = preferences;
67         asset = new Asset;
68         edl_path[0] = 0;
69         strategy = 0;
70         enabled = 1;
71         elapsed = 0;
74 BatchRenderJob::~BatchRenderJob()
76         delete asset;
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;
85         elapsed = 0;
88 void BatchRenderJob::load(FileXML *file)
90         int result = 0;
92         edl_path[0] = 0;
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);
97         fix_strategy();
99         result = file->read_tag();
100         if(!result)
101         {
102                 if(file->tag.title_is("ASSET"))
103                 {
104                         file->tag.get_property("SRC", asset->path);
105                         asset->read(file, 0);
106                 }
107         }
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");
121         file->append_tag();
122 TRACE("BatchRenderJob::save 1");
123         file->append_newline();
124 TRACE("BatchRenderJob::save 1");
125         asset->write(file,
126                 0,
127                 "");
128 TRACE("BatchRenderJob::save 1");
129         file->tag.set_title("/JOB");
130 TRACE("BatchRenderJob::save 1");
131         file->append_tag();
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)
152  : BC_DialogThread()
154         this->mwindow = mwindow;
155         current_job = 0;
156         rendering_job = -1;
157         is_rendering = 0;
158         default_job = 0;
161 BatchRenderThread::BatchRenderThread()
162  : BC_DialogThread()
164         mwindow = 0;
165         current_job = 0;
166         rendering_job = -1;
167         is_rendering = 0;
168         default_job = 0;
171 void BatchRenderThread::handle_close_event(int result)
173 // Save settings
174 TRACE("BatchRenderThread::handle_close_event 1");
175         char path[BCTEXTLEN];
176 TRACE("BatchRenderThread::handle_close_event 1");
177         path[0] = 0;
178 TRACE("BatchRenderThread::handle_close_event 1");
179         save_jobs(path);
180 TRACE("BatchRenderThread::handle_close_event 1");
181         save_defaults(mwindow->defaults);
182 TRACE("BatchRenderThread::handle_close_event 1");
183         delete default_job;
184 TRACE("BatchRenderThread::handle_close_event 1");
185         default_job = 0;
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()
193         current_start = 0.0;
194         current_end = 0.0;
195         default_job = new BatchRenderJob(mwindow->preferences);
197         char path[BCTEXTLEN];
198         path[0] = 0;
199         load_jobs(path, mwindow->preferences);
200         load_defaults(mwindow->defaults);
201         this->gui = new BatchRenderGUI(mwindow, 
202                 this,
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();
208         return this->gui;
212 void BatchRenderThread::load_jobs(char *path, Preferences *preferences)
214         FileXML file;
215         int result = 0;
217         jobs.remove_all_objects();
218         if(path[0])
219                 file.read_from_file(path);
220         else
221                 file.read_from_file(create_path(path));
223         while(!result)
224         {
225                 if(!(result = file.read_tag()))
226                 {
227                         if(file.tag.title_is("JOB"))
228                         {
229                                 BatchRenderJob *job;
230                                 jobs.append(job = new BatchRenderJob(preferences));
231                                 job->load(&file);
232                         }
233                 }
234         }
237 void BatchRenderThread::save_jobs(char *path)
239         FileXML file;
241         for(int i = 0; i < jobs.total; i++)
242         {
243                 file.tag.set_title("JOB");
244                 jobs.values[i]->save(&file);
245         }
247         if(path[0])
248                 file.write_to_file(path);
249         else
250                 file.write_to_file(create_path(path));
253 void BatchRenderThread::load_defaults(Defaults *defaults)
255         if(default_job)
256         {
257                 default_job->asset->load_defaults(defaults,
258                         "BATCHRENDER_",
259                         1,
260                         1,
261                         1,
262                         1,
263                         1);
264                 default_job->fix_strategy();
265         }
267         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
268         {
269                 char string[BCTEXTLEN];
270                 sprintf(string, "BATCHRENDER_COLUMN%d", i);
271                 column_width[i] = defaults->get(string, list_widths[i]);
272         }
275 void BatchRenderThread::save_defaults(Defaults *defaults)
277         if(default_job)
278         {
279                 default_job->asset->save_defaults(defaults,
280                         "BATCHRENDER_",
281                         1,
282                         1,
283                         1,
284                         1,
285                         1);
286                 defaults->update("BATCHRENDER_STRATEGY", default_job->strategy);
287         }
288         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
289         {
290                 char string[BCTEXTLEN];
291                 sprintf(string, "BATCHRENDER_COLUMN%d", i);
292                 defaults->update(string, column_width[i]);
293         }
294 //      defaults->update("BATCHRENDER_JOB", current_job);
295         if(mwindow)
296                 mwindow->save_defaults();
297         else
298                 defaults->save();
301 char* BatchRenderThread::create_path(char *string)
303         FileSystem fs;
304         sprintf(string, "%s", BCASTDIR);
305         fs.complete_path(string);
306         strcat(string, BATCH_PATH);
307         return string;
310 void BatchRenderThread::new_job()
312         BatchRenderJob *result = new BatchRenderJob(mwindow->preferences);
313         result->copy_from(get_current_job());
314         jobs.append(result);
315         current_job = jobs.total - 1;
316         gui->create_list(1);
317         gui->change_job();
320 void BatchRenderThread::delete_job()
322         if(current_job < jobs.total && current_job >= 0)
323         {
324                 jobs.remove_object_number(current_job);
325                 if(current_job > 0) current_job--;
326                 gui->create_list(1);
327                 gui->change_job();
328         }
331 BatchRenderJob* BatchRenderThread::get_current_job()
333         BatchRenderJob *result;
334         if(current_job >= jobs.total || current_job < 0)
335         {
336                 result = default_job;
337         }
338         else
339         {
340                 result = jobs.values[current_job];
341         }
342         return result;
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++)
361         {
362                 if(jobs.values[i]->enabled)
363                 {
364                         FILE *fd = fopen(jobs.values[i]->edl_path, "r");
365                         if(!fd)
366                         {
367                                 char string[BCTEXTLEN];
368                                 sprintf(string, _("EDL %s not found.\n"), jobs.values[i]->edl_path);
369                                 if(mwindow)
370                                 {
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();
378                                 }
379                                 else
380                                 {
381                                         fprintf(stderr, 
382                                                 "%s",
383                                                 string);
384                                 }
386                                 is_rendering = 0;
387                                 return 1;
388                         }
389                         else
390                         {
391                                 fclose(fd);
392                         }
393                 }
394         }
395         return 0;
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++)
403         {
404                 BatchRenderJob *job = jobs.values[i];
405                 if(job->enabled)
406                 {
407                         PackageDispatcher *packages = new PackageDispatcher;
409 // Load EDL
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, 
417                                 file, 
418                                 LOAD_ALL);
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,
425                                 command->get_edl(),
426                                 preferences,
427                                 job->strategy, 
428                                 job->asset, 
429                                 command->start_position, 
430                                 command->end_position,
431                                 0);
433 // Append output paths allocated to total
434                         for(int j = 0; j < packages->get_total_packages(); j++)
435                         {
436                                 RenderPackage *package = packages->get_package(j);
437                                 paths->append(strdup(package->path));
438                         }
440 // Delete package harness
441                         delete packages;
442                         delete command;
443                         delete file;
444                 }
445         }
449 void BatchRenderThread::start_rendering(char *config_path,
450         char *batch_path)
452         Defaults *boot_defaults;
453         Preferences *preferences;
454         Render *render;
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,
475                 preferences,
476                 plugindb);
478         int result = ConfirmSave::test_files(0, &paths);
479 // Abort on any existing file because it's so hard to set this up.
480         if(result) return;
482         render = new Render(0);
483         render->start_batches(&jobs, 
484                 boot_defaults,
485                 preferences,
486                 plugindb);
489 void BatchRenderThread::start_rendering()
491         if(is_rendering) return;
493         is_rendering = 1;
494         char path[BCTEXTLEN];
495         path[0] = 0;
496         save_jobs(path);
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,
508                 mwindow->plugindb);
510 // Test destination files for overwrite
511         int result = ConfirmSave::test_files(mwindow, &paths);
512         paths.remove_all_objects();
514 // User cancelled
515         if(result)
516         {
517                 is_rendering = 0;
518                 gui->new_batch->enable();
519                 gui->delete_batch->enable();
520                 return;
521         }
523         mwindow->render->start_batches(&jobs);
526 void BatchRenderThread::stop_rendering()
528         if(!is_rendering) return;
529         mwindow->render->stop_operation();
530         is_rendering = 0;
533 void BatchRenderThread::update_active(int number)
535         gui->lock_window("BatchRenderThread::update_active");
536         if(number >= 0)
537         {
538                 current_job = number;
539                 rendering_job = number;
540         }
541         else
542         {
543                 rendering_job = -1;
544                 is_rendering = 0;
545         }
546         gui->create_list(1);
547         gui->unlock_window();
550 void BatchRenderThread::update_done(int number, 
551         int create_list, 
552         double elapsed_time)
554         gui->lock_window("BatchRenderThread::update_done");
555         if(number < 0)
556         {
557                 gui->new_batch->enable();
558                 gui->delete_batch->enable();
559         }
560         else
561         {
562                 jobs.values[number]->enabled = 0;
563                 jobs.values[number]->elapsed = elapsed_time;
564                 if(create_list) gui->create_list(1);
565         }
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;
574         if(dst != src)
575         {
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;
582                 gui->create_list(1);
583         }
594 BatchRenderGUI::BatchRenderGUI(MWindow *mwindow, 
595         BatchRenderThread *thread,
596         int x,
597         int y,
598         int w,
599         int h)
600  : BC_Window(PROGRAM_NAME ": Batch Render", 
601         x,
602         y,
603         w, 
604         h, 
605         50, 
606         50, 
607         1,
608         0, 
609         1)
611         this->mwindow = mwindow;
612         this->thread = thread;
615 BatchRenderGUI::~BatchRenderGUI()
617         delete format_tools;
621 void BatchRenderGUI::create_objects()
623         mwindow->theme->get_batchrender_sizes(this, get_w(), get_h());
624         create_list(0);
626         int x = mwindow->theme->batchrender_x1;
627         int y = 5;
628         int x1 = mwindow->theme->batchrender_x1;
629         int x2 = mwindow->theme->batchrender_x2;
630         int x3 = mwindow->theme->batchrender_x3;
631         int y1 = y;
632         int y2;
634 // output file
635         add_subwindow(output_path_title = new BC_Title(x1, y, _("Output path:")));
636         y += 20;
637         format_tools = new BatchFormat(mwindow,
638                                         this, 
639                                         thread->get_current_asset());
640         format_tools->create_objects(x, 
641                                                 y, 
642                                                 1, 
643                                                 1, 
644                                                 1, 
645                                                 1, 
646                                                 0, 
647                                                 1, 
648                                                 0, 
649                                                 0, 
650                                                 &thread->get_current_job()->strategy, 
651                                                 0);
653         x2 = x;
654         y2 = y + 10;
655         x += format_tools->get_w();
656         y = y1;
657         x1 = x;
658         x3 = x + 80;
660 // input EDL
661         x = x1;
662         add_subwindow(edl_path_title = new BC_Title(x, y, _("EDL Path:")));
663         y += 20;
664         add_subwindow(edl_path_text = new BatchRenderEDLPath(
665                 thread, 
666                 x, 
667                 y, 
668                 get_w() - x - 40, 
669                 thread->get_current_edl()));
671         x += edl_path_text->get_w();
672         add_subwindow(edl_path_browse = new BrowseButton(
673                 mwindow,
674                 this,
675                 edl_path_text, 
676                 x, 
677                 y, 
678                 thread->get_current_edl(),
679                 _("Input EDL"),
680                 _("Select an EDL to load:"),
681                 0));
683         x = x1;
685         y += 30;
686         add_subwindow(new_batch = new BatchRenderNew(thread, 
687                 x, 
688                 y));
689         x += new_batch->get_w() + 10;
691         add_subwindow(delete_batch = new BatchRenderDelete(thread, 
692                 x, 
693                 y));
694         x += delete_batch->get_w() + 10;
696         x = x2;
697         y = y2;
698         add_subwindow(list_title = new BC_Title(x, y, _("Batches to render:")));
699         y += 20;
700         add_subwindow(batch_list = new BatchRenderList(thread, 
701                 x, 
702                 y,
703                 get_w() - x - 10,
704                 get_h() - y - 50));
706         y += batch_list->get_h() + 10;
707         add_subwindow(start_button = new BatchRenderStart(thread, 
708             x, 
709             y));
710         x = get_w() / 2 -
711                 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
712         add_subwindow(stop_button = new BatchRenderStop(thread, 
713                 x, 
714                 y));
715         x = get_w() - 
716                 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() - 
717                 10;
718         add_subwindow(cancel_button = new BatchRenderCancel(thread, 
719                 x, 
720                 y));
722         show_window();
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;
732         int y = 5;
733         int x1 = mwindow->theme->batchrender_x1;
734         int x2 = mwindow->theme->batchrender_x2;
735         int x3 = mwindow->theme->batchrender_x3;
736         int y1 = y;
737         int y2;
739         output_path_title->reposition_window(x1, y);
740         y += 20;
741         format_tools->reposition_window(x, y);
742         x2 = x;
743         y2 = y + 10;
744         y = y1;
745         x += format_tools->get_w();
746         x1 = x;
747         x3 = x + 80;
749         x = x1;
750         edl_path_title->reposition_window(x, y);
751         y += 20;
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);
756         x = x1;
757 //      y += 30;
758 //      status_title->reposition_window(x, y);
759 //      x = x3;
760 //      status_text->reposition_window(x, y);
761 //      x = x1;
762 //      y += 30;
763 //      progress_bar->reposition_window(x, y, w - x - 10);
765         y += 30;
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;
771         x = x2;
772         y = y2;
773         list_title->reposition_window(x, y);
774         y += 20;
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);
779         x = w / 2 - 
780                 mwindow->theme->get_image_set("batch_render_stop")[0]->get_w() / 2;
781         stop_button->reposition_window(x, y);
782         x = w -
783                 mwindow->theme->get_image_set("batch_render_cancel")[0]->get_w() - 
784                 10;
785         cancel_button->reposition_window(x, y);
786         return 1;
789 int BatchRenderGUI::translation_event()
791         mwindow->session->batchrender_x = get_x();
792         mwindow->session->batchrender_y = get_y();
793         return 1;
796 int BatchRenderGUI::close_event()
798 // Stop batch rendering
799         unlock_window();
800         thread->stop_rendering();
801         lock_window("BatchRenderGUI::close_event");
802         set_done(1);
803         return 1;
806 void BatchRenderGUI::create_list(int update_widget)
808         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
809         {
810                 list_columns[i].remove_all_objects();
811         }
813         for(int i = 0; i < thread->jobs.total; i++)
814         {
815                 BatchRenderJob *job = thread->jobs.values[i];
816                 char string[BCTEXTLEN];
817                 BC_ListBoxItem *enabled = new BC_ListBoxItem(job->enabled ? 
818                         (char*)"X" : 
819                         (char*)" ");
820                 BC_ListBoxItem *item1 = new BC_ListBoxItem(job->asset->path);
821                 BC_ListBoxItem *item2 = new BC_ListBoxItem(job->edl_path);
822                 BC_ListBoxItem *item3;
823                 if(job->elapsed)
824                         item3 = new BC_ListBoxItem(
825                                 Units::totext(string,
826                                         job->elapsed,
827                                         TIME_HMS2));
828                 else
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)
835                 {
836                         enabled->set_selected(1);
837                         item1->set_selected(1);
838                         item2->set_selected(1);
839                         item3->set_selected(1);
840                 }
841                 if(i == thread->rendering_job)
842                 {
843                         enabled->set_color(RED);
844                         item1->set_color(RED);
845                         item2->set_color(RED);
846                         item3->set_color(RED);
847                 }
848         }
850         if(update_widget)
851         {
852                 batch_list->update(list_columns,
853                                                 list_titles,
854                                                 thread->column_width,
855                                                 BATCHRENDER_COLUMNS,
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
860                                                 1);
861         }
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,
879                         BatchRenderGUI *gui,
880                         Asset *asset)
881  : FormatTools(mwindow, gui, asset)
883         this->gui = gui;
884         this->mwindow = mwindow;
887 BatchFormat::~BatchFormat()
892 int BatchFormat::handle_event()
894         gui->create_list(1);
895         return 1;
908 BatchRenderEDLPath::BatchRenderEDLPath(BatchRenderThread *thread, 
909         int x, 
910         int y, 
911         int w, 
912         char *text)
913  : BC_TextBox(x, 
914                 y, 
915                 w, 
916                 1,
917                 text)
919         this->thread = thread;
923 int BatchRenderEDLPath::handle_event()
925         strcpy(thread->get_current_edl(), get_text());
926         thread->gui->create_list(1);
927         return 1;
935 BatchRenderNew::BatchRenderNew(BatchRenderThread *thread, 
936         int x, 
937         int y)
938  : BC_GenericButton(x, y, _("New"))
940         this->thread = thread;
943 int BatchRenderNew::handle_event()
945         thread->new_job();
946         return 1;
949 BatchRenderDelete::BatchRenderDelete(BatchRenderThread *thread, 
950         int x, 
951         int y)
952  : BC_GenericButton(x, y, _("Delete"))
954         this->thread = thread;
957 int BatchRenderDelete::handle_event()
959         thread->delete_job();
960         return 1;
968 BatchRenderList::BatchRenderList(BatchRenderThread *thread, 
969         int x, 
970         int y,
971         int w,
972         int h)
973  : BC_ListBox(x, 
974         y, 
975         w, 
976         h, 
977         LISTBOX_TEXT,
978         thread->gui->list_columns,
979         list_titles,
980         thread->column_width,
981         BATCHRENDER_COLUMNS,
982         0,
983         0,
984         LISTBOX_SINGLE,
985         ICON_LEFT,
986         1)
988         this->thread = thread;
989         dragging_item = 0;
990         set_process_drag(0);
993 int BatchRenderList::handle_event()
995         return 1;
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])
1003         {
1004                 BatchRenderJob *job = thread->get_current_job();
1005                 job->enabled = !job->enabled;
1006                 thread->gui->create_list(1);
1007         }
1008         return 1;
1011 int BatchRenderList::column_resize_event()
1013         for(int i = 0; i < BATCHRENDER_COLUMNS; i++)
1014         {
1015                 thread->column_width[i] = get_column_width(i);
1016         }
1017         return 1;
1020 int BatchRenderList::drag_start_event()
1022         if(BC_ListBox::drag_start_event())
1023         {
1024                 dragging_item = 1;
1025                 return 1;
1026         }
1028         return 0;
1031 int BatchRenderList::drag_motion_event()
1033         if(BC_ListBox::drag_motion_event())
1034         {
1035                 return 1;
1036         }
1037         return 0;
1040 int BatchRenderList::drag_stop_event()
1042         if(dragging_item)
1043         {
1044                 int src = get_selection_number(0, 0);
1045                 int dst = get_highlighted_item();
1046                 if(src != dst)
1047                 {
1048                         thread->move_batch(src, dst);
1049                 }
1050                 BC_ListBox::drag_stop_event();
1051         }
1066 BatchRenderStart::BatchRenderStart(BatchRenderThread *thread, 
1067         int x, 
1068         int y)
1069  : BC_Button(x, 
1070         y, 
1071         thread->mwindow->theme->get_image_set(_("batch_render_start")))
1073         this->thread = thread;
1076 int BatchRenderStart::handle_event()
1078         thread->start_rendering();
1079         return 1;
1082 BatchRenderStop::BatchRenderStop(BatchRenderThread *thread, 
1083         int x, 
1084         int y)
1085  : BC_Button(x, 
1086         y, 
1087         thread->mwindow->theme->get_image_set(_("batch_render_stop")))
1089         this->thread = thread;
1092 int BatchRenderStop::handle_event()
1094         unlock_window();
1095         thread->stop_rendering();
1096         lock_window("BatchRenderStop::handle_event");
1097         return 1;
1101 BatchRenderCancel::BatchRenderCancel(BatchRenderThread *thread, 
1102         int x, 
1103         int y)
1104  : BC_Button(x, 
1105         y, 
1106         thread->mwindow->theme->get_image_set(_("batch_render_cancel")))
1108         this->thread = thread;
1111 int BatchRenderCancel::handle_event()
1113         unlock_window();
1114         thread->stop_rendering();
1115         lock_window("BatchRenderCancel::handle_event");
1116         thread->gui->set_done(1);
1117         return 1;
1120 int BatchRenderCancel::keypress_event()
1122         if(get_keypress() == ESC) 
1123         {
1124                 unlock_window();
1125                 thread->stop_rendering();
1126                 lock_window("BatchRenderCancel::keypress_event");
1127                 thread->gui->set_done(1);
1128                 return 1;
1129         }
1130         return 0;