1919package com .github .mfl28 .boundingboxeditor .controller ;
2020
2121import com .github .mfl28 .boundingboxeditor .model .Model ;
22- import com .github .mfl28 .boundingboxeditor .model .data .*;
22+ import com .github .mfl28 .boundingboxeditor .model .data .ImageAnnotation ;
23+ import com .github .mfl28 .boundingboxeditor .model .data .ImageMetaData ;
24+ import com .github .mfl28 .boundingboxeditor .model .data .IoMetaData ;
25+ import com .github .mfl28 .boundingboxeditor .model .data .ObjectCategory ;
2326import com .github .mfl28 .boundingboxeditor .model .io .*;
24- import com .github .mfl28 .boundingboxeditor .model .io .results .BoundingBoxPredictionResult ;
25- import com .github .mfl28 .boundingboxeditor .model .io .results .IOResult ;
26- import com .github .mfl28 .boundingboxeditor .model .io .results .ImageAnnotationImportResult ;
27- import com .github .mfl28 .boundingboxeditor .model .io .results .ImageMetaDataLoadingResult ;
28- import com .github .mfl28 .boundingboxeditor .model .io .services .BoundingBoxPredictorService ;
29- import com .github .mfl28 .boundingboxeditor .model .io .services .ImageAnnotationExportService ;
30- import com .github .mfl28 .boundingboxeditor .model .io .services .ImageAnnotationImportService ;
31- import com .github .mfl28 .boundingboxeditor .model .io .services .ImageMetaDataLoadingService ;
27+ import com .github .mfl28 .boundingboxeditor .model .io .results .*;
28+ import com .github .mfl28 .boundingboxeditor .model .io .services .*;
3229import com .github .mfl28 .boundingboxeditor .ui .*;
30+ import com .github .mfl28 .boundingboxeditor .ui .settings .SettingsDialogView ;
3331import com .github .mfl28 .boundingboxeditor .ui .statusevents .BoundingBoxPredictionSuccessfulEvent ;
3432import com .github .mfl28 .boundingboxeditor .ui .statusevents .ImageAnnotationsImportingSuccessfulEvent ;
3533import com .github .mfl28 .boundingboxeditor .ui .statusevents .ImageAnnotationsSavingSuccessfulEvent ;
3634import com .github .mfl28 .boundingboxeditor .ui .statusevents .ImageFilesLoadingSuccessfulEvent ;
3735import com .github .mfl28 .boundingboxeditor .utils .ColorUtils ;
36+ import com .github .mfl28 .boundingboxeditor .utils .UiUtils ;
3837import javafx .application .Platform ;
3938import javafx .beans .property .BooleanProperty ;
4039import javafx .beans .property .SimpleBooleanProperty ;
4443import javafx .concurrent .WorkerStateEvent ;
4544import javafx .scene .Cursor ;
4645import javafx .scene .control .ButtonBar ;
46+ import javafx .scene .control .ButtonType ;
4747import javafx .scene .control .TableColumn ;
4848import javafx .scene .image .Image ;
4949import javafx .scene .input .*;
@@ -139,6 +139,7 @@ public class Controller {
139139 private final ImageAnnotationImportService annotationImportService = new ImageAnnotationImportService ();
140140 private final ImageMetaDataLoadingService imageMetaDataLoadingService = new ImageMetaDataLoadingService ();
141141 private final BoundingBoxPredictorService boundingBoxPredictorService = new BoundingBoxPredictorService ();
142+ private final ModelNameFetchService modelNameFetchService = new ModelNameFetchService ();
142143 private final Stage stage ;
143144 private final MainView view = new MainView ();
144145 private final Model model = new Model ();
@@ -176,12 +177,17 @@ public Controller(final Stage mainStage) {
176177 connectServicesToView ();
177178 }
178179
179- private void connectServicesToView () {
180- view .connectAnnotationImportService (annotationImportService );
181- view .connectAnnotationExportService (annotationExportService );
182- view .connectImageMetaDataLoadingService (imageMetaDataLoadingService );
183- view .connectBoundingBoxPredictorService (boundingBoxPredictorService );
184- view .setUpProgressDialogs ();
180+ public void onRegisterSettingsAction () {
181+ final SettingsDialogView settingsDialog = view .getSettingsDialog ();
182+ settingsDialog .getInferenceSettings ()
183+ .setDisplayedSettingsFromConfig (model .getBoundingBoxPredictorClientConfig ());
184+ // TODO: update predictor config
185+ settingsDialog .showAndWait ();
186+ }
187+
188+ public void onRegisterSettingsApplyAction () {
189+ view .getSettingsDialog ().getInferenceSettings ()
190+ .applyDisplayedSettingsToConfig (model .getBoundingBoxPredictorClientConfig ());
185191 }
186192
187193 /**
@@ -277,6 +283,14 @@ public void onRegisterImportAnnotationsAction(ImageAnnotationLoadStrategy.Type l
277283 }
278284 }
279285
286+ public void onRegisterModelNameFetchingAction () {
287+ modelNameFetchService .reset ();
288+ final BoundingBoxPredictorClientConfig clientConfig = new BoundingBoxPredictorClientConfig ();
289+ view .getSettingsDialog ().getInferenceSettings ().applyDisplayedSettingsToConfig (clientConfig );
290+ modelNameFetchService .setClientConfig (clientConfig );
291+ modelNameFetchService .restart ();
292+ }
293+
280294 /**
281295 * Initiates the import of annotations.
282296 *
@@ -571,35 +585,6 @@ public Model getModel() {
571585 return model ;
572586 }
573587
574- private void onBoundingBoxPredictionSucceeded (WorkerStateEvent event ) {
575- final BoundingBoxPredictionResult predictionResult = boundingBoxPredictorService .getValue ();
576-
577- if (predictionResult .getNrSuccessfullyProcessedItems () != 0 ) {
578- model .updateFromImageAnnotationData (predictionResult .getImageAnnotationData ());
579- view .getStatusBar ().setStatusEvent (new BoundingBoxPredictionSuccessfulEvent (predictionResult ));
580- }
581-
582- updateViewFileExplorerFileInfoElements ();
583-
584- final ImageAnnotation annotation = model .getCurrentImageAnnotation ();
585-
586- if (annotation != null ) {
587- view .getObjectTree ().reset ();
588- view .getCurrentBoundingShapes ().removeListener (boundingShapeCountPerCategoryListener );
589- view .loadBoundingShapeViewsFromAnnotation (annotation );
590- view .getCurrentBoundingShapes ().addListener (boundingShapeCountPerCategoryListener );
591- view .getObjectCategoryTable ().refresh ();
592- view .getObjectTree ().refresh ();
593- }
594-
595- if (!predictionResult .getErrorTableEntries ().isEmpty ()) {
596- MainView .displayIOResultErrorInfoAlert (predictionResult );
597- } else if (predictionResult .getNrSuccessfullyProcessedItems () == 0 ) {
598- MainView .displayErrorAlert ("Bounding Box Prediction Error" ,
599- "Could not predict any bounding boxes." );
600- }
601- }
602-
603588 IoMetaData getIoMetaData () {
604589 return ioMetaData ;
605590 }
@@ -635,6 +620,44 @@ void initiateAnnotationExport(File destination, ImageAnnotationSaveStrategy.Type
635620 initiateAnnotationExport (destination , exportFormat , null );
636621 }
637622
623+ private void connectServicesToView () {
624+ view .connectAnnotationImportService (annotationImportService );
625+ view .connectAnnotationExportService (annotationExportService );
626+ view .connectImageMetaDataLoadingService (imageMetaDataLoadingService );
627+ view .connectBoundingBoxPredictorService (boundingBoxPredictorService );
628+ view .connectModelNameFetchingService (modelNameFetchService );
629+ view .setUpProgressDialogs ();
630+ }
631+
632+ private void onBoundingBoxPredictionSucceeded (WorkerStateEvent event ) {
633+ final BoundingBoxPredictionResult predictionResult = boundingBoxPredictorService .getValue ();
634+
635+ if (predictionResult .getNrSuccessfullyProcessedItems () != 0 ) {
636+ model .updateFromImageAnnotationData (predictionResult .getImageAnnotationData ());
637+ view .getStatusBar ().setStatusEvent (new BoundingBoxPredictionSuccessfulEvent (predictionResult ));
638+ }
639+
640+ updateViewFileExplorerFileInfoElements ();
641+
642+ final ImageAnnotation annotation = model .getCurrentImageAnnotation ();
643+
644+ if (annotation != null ) {
645+ view .getObjectTree ().reset ();
646+ view .getCurrentBoundingShapes ().removeListener (boundingShapeCountPerCategoryListener );
647+ view .loadBoundingShapeViewsFromAnnotation (annotation );
648+ view .getCurrentBoundingShapes ().addListener (boundingShapeCountPerCategoryListener );
649+ view .getObjectCategoryTable ().refresh ();
650+ view .getObjectTree ().refresh ();
651+ }
652+
653+ if (!predictionResult .getErrorTableEntries ().isEmpty ()) {
654+ MainView .displayIOResultErrorInfoAlert (predictionResult );
655+ } else if (predictionResult .getNrSuccessfullyProcessedItems () == 0 ) {
656+ MainView .displayErrorAlert ("Bounding Box Prediction Error" ,
657+ "Could not predict any bounding boxes." );
658+ }
659+ }
660+
638661 private void startAnnotationImportService (File source , ImageAnnotationLoadStrategy .Type importFormat ) {
639662 annotationImportService .reset ();
640663 annotationImportService .setSource (source );
@@ -659,9 +682,8 @@ private void startBoundingBoxPredictionService(File imageFile) {
659682 boundingBoxPredictorService .setImageMetaData (model .getImageFileNameToMetaDataMap ().get (imageFile .getName ()));
660683 boundingBoxPredictorService .setBoundingBoxPredictorConfig (model .getBoundingBoxPredictorConfig ());
661684
662- model .getBoundingBoxPredictorClientConfig ().setInferenceModelName ("fastrcnn" );
663-
664- boundingBoxPredictorService .setPredictorClient (BoundingBoxPredictorClient .create (model .getBoundingBoxPredictorClientConfig ()));
685+ boundingBoxPredictorService
686+ .setPredictorClient (BoundingBoxPredictorClient .create (model .getBoundingBoxPredictorClientConfig ()));
665687
666688 boundingBoxPredictorService .restart ();
667689 }
@@ -678,6 +700,32 @@ private void setUpServices() {
678700
679701 boundingBoxPredictorService .setOnSucceeded (this ::onBoundingBoxPredictionSucceeded );
680702 boundingBoxPredictorService .setOnFailed (this ::onIoServiceFailed );
703+
704+ modelNameFetchService .setOnSucceeded (this ::onModelNameFetchingSucceeded );
705+ // TODO: custom handling?
706+ modelNameFetchService .setOnFailed (this ::onIoServiceFailed );
707+ }
708+
709+ private void onModelNameFetchingSucceeded (WorkerStateEvent workerStateEvent ) {
710+ final ModelNameFetchResult result = modelNameFetchService .getValue ();
711+
712+ final List <String > modelNames = result .getModelNames ();
713+
714+ UiUtils .closeProgressDialog (view .getModelNameFetchingProgressDialog ());
715+
716+ if (!modelNames .isEmpty ()) {
717+ final Optional <String > modelChoice = MainView .displayChoiceDialogAndGetResult (modelNames .get (0 ),
718+ modelNames ,
719+ "Model choice" ,
720+ "Choose the model" +
721+ " used for performing predictions." ,
722+ "Model: " );
723+ modelChoice
724+ .ifPresent (s -> view .getSettingsDialog ().getInferenceSettings ().getSelectedModelLabel ().setText (s ));
725+
726+ } else {
727+ MainView .displayErrorAlert ("Model Name Fetching Error" , "The server did not report any models." );
728+ }
681729 }
682730
683731 private void onImageMetaDataLoadingSucceeded (WorkerStateEvent workerStateEvent ) {
@@ -688,13 +736,16 @@ private void onImageMetaDataLoadingSucceeded(WorkerStateEvent workerStateEvent)
688736 }
689737
690738 if (!ioResult .getErrorTableEntries ().isEmpty ()) {
739+ UiUtils .closeProgressDialog (view .getImageMetaDataLoadingProgressDialog ());
691740 MainView .displayIOResultErrorInfoAlert (ioResult );
692741 } else if (ioResult .getNrSuccessfullyProcessedItems () == 0 ) {
742+ UiUtils .closeProgressDialog (view .getImageMetaDataLoadingProgressDialog ());
693743 MainView .displayErrorAlert (IMAGE_IMPORT_ERROR_ALERT_TITLE , IMAGE_IMPORT_ERROR_ALERT_CONTENT );
694744 }
695745
696746 if (imageMetaDataLoadingService .isReload () && ioResult .getNrSuccessfullyProcessedItems () == 0 ) {
697- Controller .this .askToSaveExistingAnnotationDataAndClearModelAndView ();
747+ UiUtils .closeProgressDialog (view .getImageMetaDataLoadingProgressDialog ());
748+ askToSaveExistingAnnotationDataAndClearModelAndView ();
698749 }
699750 }
700751
@@ -704,6 +755,7 @@ private boolean handleSuccessfullyProcessedItemsPresent() {
704755 boolean keepExistingCategories = false ;
705756
706757 if (model .containsCategories ()) {
758+ UiUtils .closeProgressDialog (view .getImageMetaDataLoadingProgressDialog ());
707759 ButtonBar .ButtonData answer = imageMetaDataLoadingService .isReload () ?
708760 MainView .displayYesNoDialogAndGetResult (OPEN_IMAGE_FOLDER_OPTION_DIALOG_TITLE ,
709761 KEEP_EXISTING_CATEGORIES_DIALOG_TEXT ) :
@@ -718,6 +770,7 @@ private boolean handleSuccessfullyProcessedItemsPresent() {
718770 }
719771
720772 if (!model .isSaved ()) {
773+ UiUtils .closeProgressDialog (view .getImageMetaDataLoadingProgressDialog ());
721774 // First ask if user wants to save the existing annotations.
722775 ButtonBar .ButtonData answer = imageMetaDataLoadingService .isReload () ?
723776 MainView .displayYesNoDialogAndGetResult (RELOAD_IMAGE_FOLDER_OPTION_DIALOG_TITLE ,
@@ -733,8 +786,7 @@ private boolean handleSuccessfullyProcessedItemsPresent() {
733786 finalKeepExistingCategories ));
734787 } else {
735788 initiateAnnotationSavingWithFormatChoiceAndRunOnSaveSuccess (
736- () -> onValidFilesPresentHandler (
737- finalKeepExistingCategories ));
789+ () -> onValidFilesPresentHandler (finalKeepExistingCategories ));
738790 }
739791 } else if (answer == ButtonBar .ButtonData .NO || imageMetaDataLoadingService .isReload ()) {
740792 onValidFilesPresentHandler (keepExistingCategories );
@@ -794,8 +846,10 @@ private void onAnnotationImportSucceeded(WorkerStateEvent workerStateEvent) {
794846 }
795847
796848 if (!loadResult .getErrorTableEntries ().isEmpty ()) {
849+ UiUtils .closeProgressDialog (view .getAnnotationImportProgressDialog ());
797850 MainView .displayIOResultErrorInfoAlert (loadResult );
798851 } else if (loadResult .getNrSuccessfullyProcessedItems () == 0 ) {
852+ UiUtils .closeProgressDialog (view .getAnnotationImportProgressDialog ());
799853 MainView .displayErrorAlert (ANNOTATION_IMPORT_ERROR_TITLE ,
800854 ANNOTATION_IMPORT_ERROR_NO_VALID_FILES_CONTENT );
801855 return ;
@@ -821,6 +875,7 @@ private void onAnnotationExportSucceeded(WorkerStateEvent event) {
821875 }
822876
823877 if (!saveResult .getErrorTableEntries ().isEmpty ()) {
878+ UiUtils .closeProgressDialog (view .getAnnotationExportProgressDialog ());
824879 MainView .displayIOResultErrorInfoAlert (saveResult );
825880 } else {
826881 model .setSaved (true );
0 commit comments