Commit b9d7b793 authored by Luna Riegel's avatar Luna Riegel
Browse files

Refactor: Remove Zip file support

parent 1310568f
Pipeline #12076 failed with stage
in 58 seconds
...@@ -17,15 +17,10 @@ import de.hft.stuttgart.citydoctor2.gui.tree.node.OpeningNode; ...@@ -17,15 +17,10 @@ import de.hft.stuttgart.citydoctor2.gui.tree.node.OpeningNode;
import de.hft.stuttgart.citydoctor2.gui.tree.node.TopLevelCityObjectNode; import de.hft.stuttgart.citydoctor2.gui.tree.node.TopLevelCityObjectNode;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler; import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler;
import de.hft.stuttgart.citydoctor2.parser.*; import de.hft.stuttgart.citydoctor2.parser.*;
import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
import de.hft.stuttgart.citydoctor2.utils.Localization; import de.hft.stuttgart.citydoctor2.utils.Localization;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import de.hft.stuttgart.citydoctor2.zip.MalformedZipFileException;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.chart.XYChart.Data; import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series; import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog; import javafx.scene.control.Dialog;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
...@@ -33,18 +28,12 @@ import javafx.scene.control.TreeView; ...@@ -33,18 +28,12 @@ import javafx.scene.control.TreeView;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.FileChooser.ExtensionFilter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.CityModel; import org.citygml4j.core.model.core.CityModel;
import org.xml.sax.SAXParseException; import org.xml.sax.SAXParseException;
import java.awt.*;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
...@@ -63,9 +52,7 @@ public class CityDoctorController { ...@@ -63,9 +52,7 @@ public class CityDoctorController {
private CityDoctorModel model; private CityDoctorModel model;
private ParserConfiguration currentConfig; private ParserConfiguration currentConfig;
private String sourceFile; private String sourceFile;
private CityGmlZipArchive zipArchive;
private ZipEntryManager currentZipEntryManager;
private HashMap<CityDoctorModel, Checker> previousCheckers = null;
private Checker currentChecker; private Checker currentChecker;
private HighlightController highlightController; private HighlightController highlightController;
...@@ -100,7 +87,7 @@ public class CityDoctorController { ...@@ -100,7 +87,7 @@ public class CityDoctorController {
try { try {
Platform.runLater(() -> { Platform.runLater(() -> {
mainWindow.getOpenBtn().setDisable(true); mainWindow.getOpenBtn().setDisable(true);
mainWindow.getZipManagerBtn().setDisable(true);
mainWindow.getWriteReportButton().setDisable(true); mainWindow.getWriteReportButton().setDisable(true);
mainWindow.getMeshGroup().getChildren().clear(); mainWindow.getMeshGroup().getChildren().clear();
...@@ -108,12 +95,6 @@ public class CityDoctorController { ...@@ -108,12 +95,6 @@ public class CityDoctorController {
mainWindow.resetSearchBar(); mainWindow.resetSearchBar();
mainWindow.resetFilterComboBox(); mainWindow.resetFilterComboBox();
}); });
if (path.endsWith(".zip")) {
loadCityGmlZipFile(path, numberOfRoundingPlaces, useValidation, lowMemory);
return;
}
currentZipEntryManager = null;
previousCheckers = null;
currentChecker = null; currentChecker = null;
currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory); currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory);
GMLValidationHandler handler = null; GMLValidationHandler handler = null;
...@@ -160,7 +141,6 @@ public class CityDoctorController { ...@@ -160,7 +141,6 @@ public class CityDoctorController {
mainWindow.getSaveBtn().setDisable(false); mainWindow.getSaveBtn().setDisable(false);
mainWindow.getResetCameraBtn().setDisable(false); mainWindow.getResetCameraBtn().setDisable(false);
mainWindow.getHideRoofBtn().setDisable(false); mainWindow.getHideRoofBtn().setDisable(false);
mainWindow.getZipManagerBtn().setDisable(true);
mainWindow.getNorthArrow().setVisible(true); mainWindow.getNorthArrow().setVisible(true);
mainWindow.alignNorthArrow(); mainWindow.alignNorthArrow();
setupFeatureTabs(); setupFeatureTabs();
...@@ -171,103 +151,10 @@ public class CityDoctorController { ...@@ -171,103 +151,10 @@ public class CityDoctorController {
} }
} }
private void loadCityGmlZipFile(String path, int numberOfRoundingPlaces, boolean useValidation,
boolean lowMemory) {
currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory);
try {
zipArchive = CityGmlZipArchive.register(path);
} catch (MalformedZipFileException e) {
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.ERROR, e.getMessage());
alert.showAndWait();
});
} catch (Exception e) {
Platform.runLater(() -> {
ExceptionDialog exDialog = new ExceptionDialog();
exDialog.show(e);
});
}
if (zipArchive != null) {
previousCheckers = new HashMap<>();
Platform.runLater(() -> {
try {
currentZipEntryManager = new ZipEntryManager(mainWindow.getMainStage(), this);
currentZipEntryManager.show();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
public void decompressZipEntry(CityGmlZipEntry entry, ProgressListener l) {
entry.loadEntry(currentConfig, l);
}
public CityGmlZipArchive getZipArchive() {
return zipArchive;
}
public static int getMaxFeaturesPerChunk(){ public static int getMaxFeaturesPerChunk(){
return MAX_FEATURES_PER_CHUNK; return MAX_FEATURES_PER_CHUNK;
} }
public void loadZipEntry(CityGmlZipEntry entry) {
if (!entry.isLoaded()) {
entry.loadEntry(currentConfig);
}
if (entry.getErrorType() != null) {
throw new IllegalArgumentException("Attempted to load erroneous zip entry");
}
try {
Platform.runLater(() -> {
mainWindow.getOpenBtn().setDisable(true);
mainWindow.getZipManagerBtn().setDisable(true);
mainWindow.getWriteReportButton().setDisable(true);
mainWindow.getMeshGroup().getChildren().clear();
clearTrees();
mainWindow.resetSearchBar();
mainWindow.resetFilterComboBox();
});
model = entry.getModel();
currentChecker = previousCheckers.getOrDefault(model, null);
mainWindow.getClickHandler().setConfig(currentConfig);
sourceFile = entry.getArchive().getArchivePath().toString();
renderer.reset();
Platform.runLater(() -> {
mainWindow.addFileNameToTitle(entry.getArchive().getArchivePath().toString());
mainWindow.getCheckButton().setDisable(false);
mainWindow.getLod1Btn().setDisable(false);
mainWindow.getLod2Btn().setDisable(false);
mainWindow.getLod3Btn().setDisable(false);
mainWindow.getLod4Btn().setDisable(false);
mainWindow.getWorldBtn().setDisable(false);
mainWindow.getSaveBtn().setDisable(false);
mainWindow.getResetCameraBtn().setDisable(false);
mainWindow.getHideRoofBtn().setDisable(false);
mainWindow.getZipManagerBtn().setDisable(false);
mainWindow.getNorthArrow().setVisible(true);
mainWindow.alignNorthArrow();
setupFeatureTabs();
buildTrees();
updateFeatureTrees();
mainWindow.getWriteReportButton().setDisable(currentChecker == null);
});
} finally {
Platform.runLater(() -> mainWindow.getOpenBtn().setDisable(false));
}
}
public void showZipManager() {
Platform.runLater(() -> currentZipEntryManager.show());
}
private void setupFeatureTabs() { private void setupFeatureTabs() {
mainWindow.setDisableOfFeatureTab(FeatureType.BUILDING, model.getBuildingCount() == 0); mainWindow.setDisableOfFeatureTab(FeatureType.BUILDING, model.getBuildingCount() == 0);
mainWindow.setDisableOfFeatureTab(FeatureType.VEGETATION, model.getVegetationCount() == 0); mainWindow.setDisableOfFeatureTab(FeatureType.VEGETATION, model.getVegetationCount() == 0);
...@@ -1190,9 +1077,6 @@ public class CityDoctorController { ...@@ -1190,9 +1077,6 @@ public class CityDoctorController {
config.setNumberOfRoundingPlacesInGlobalParameters(currentConfig.getNumberOfRoundingPlaces()); config.setNumberOfRoundingPlacesInGlobalParameters(currentConfig.getNumberOfRoundingPlaces());
config.setParserConfig(currentConfig); config.setParserConfig(currentConfig);
currentChecker = new Checker(config, model); currentChecker = new Checker(config, model);
if (previousCheckers != null) {
previousCheckers.put(model, currentChecker);
}
currentChecker.runChecks(l); currentChecker.runChecks(l);
Platform.runLater(() -> { Platform.runLater(() -> {
...@@ -1213,138 +1097,6 @@ public class CityDoctorController { ...@@ -1213,138 +1097,6 @@ public class CityDoctorController {
} }
} }
public void startZipFileChecks(ValidationConfiguration config, ProgressListener l, boolean lowMemoryMode,
Path outputPath, boolean pdfReports, boolean xmlReports) {
if (zipArchive == null && logger.isWarnEnabled()) {
logger.warn(Localization.getText("CityDoctorController.noZipFile"));
}
if (lowMemoryMode) {
startZipFileCheckStream(config, outputPath, pdfReports, xmlReports);
return;
}
try {
Platform.runLater(() -> {
mainWindow.getCheckButton().setDisable(true);
mainWindow.getErrorTree().getRoot().getChildren().clear();
mainWindow.getGlobalErrorsView().getItems().clear();
});
previousCheckers = new HashMap<>();
zipArchive.mountArchive(currentConfig);
config.setNumberOfRoundingPlacesInGlobalParameters(currentConfig.getNumberOfRoundingPlaces());
config.setParserConfig(currentConfig);
int totalEntries = zipArchive.getEntries().size();
int checkedEntries = 0;
for (CityGmlZipEntry entry : zipArchive.getEntries()) {
if (entry.getErrorType() != null && entry.getModel() == null) {
continue;
}
model = entry.getModel();
currentChecker = new Checker(config, model);
currentChecker.runChecks();
previousCheckers.put(model, currentChecker);
checkedEntries++;
if (l != null) {
l.updateProgress((float) checkedEntries / totalEntries);
}
}
Platform.runLater(() -> {
// apply check results to tree views
buildTrees();
updateFeatureTrees();
updateTree(mainWindow.getPolygonsView().getRoot());
for (CheckError e : model.getGlobalErrors()) {
if (e instanceof SchematronError se) {
mainWindow.getGlobalErrorsView().getItems().add(se.getErrorIdString() + " - " + se.getNameOfAttribute());
}
}
renderer.refresh();
mainWindow.getWriteReportButton().setDisable(false);
currentZipEntryManager.refresh();
});
} finally {
Platform.runLater(() -> mainWindow.getCheckButton().setDisable(false));
}
}
private void startZipFileCheckStream(ValidationConfiguration valConfig, Path outputPath, boolean pdfReports,
boolean xmlReports) {
try {
Path outputZipDirectory = null;
if (outputPath.toFile().isDirectory()) {
String filename = FilenameUtils.removeExtension(zipArchive.getArchivePath().getFileName().toString());
filename = filename + "_validated";
outputZipDirectory = outputPath.resolve(filename);
Files.createDirectories(outputZipDirectory);
} else {
String filename = FilenameUtils.removeExtension(outputPath.toAbsolutePath().getFileName().toString());
outputZipDirectory = Path.of(filename);
}
String xmlReportsDirectory = null;
String pdfReportsDirectory = null;
if (xmlReports) {
xmlReportsDirectory = Files.createDirectories(
outputZipDirectory.resolve("xml_reports/")).toAbsolutePath().toString();
}
if (pdfReports) {
pdfReportsDirectory = Files.createDirectories(
outputZipDirectory.resolve("pdf_reports/")).toAbsolutePath().toString();
}
Checker.streamCheck(zipArchive, xmlReportsDirectory, pdfReportsDirectory, valConfig, outputZipDirectory.toString());
Desktop desktop = Desktop.getDesktop();
desktop.open(outputPath.toFile());
} catch (CityGmlParseException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void saveZipArchiveReports(File outputZipDirectory) {
if (zipArchive == null) {
return;
}
String directoryName = FilenameUtils.removeExtension(outputZipDirectory.getAbsolutePath());
Path tempOutput = Path.of(directoryName + File.separator);
File temp = null;
try {
temp = tempOutput.toFile();
for (CityGmlZipEntry entry : zipArchive.getEntries()) {
if (entry.getErrorType() != null || entry.getModel() == null) {
continue;
}
model = entry.getModel();
if (model.isValidated()) {
Checker checker = previousCheckers.get(model);
Files.createDirectories(tempOutput.resolve(entry.getEntrySubPath()).getParent());
checker.writeXmlReport(tempOutput.resolve(entry.getDisplayName() + "_report.xml").toString());
checker.writePdfReport(tempOutput.resolve(entry.getDisplayName() + "_report.pdf").toString());
}
}
ArchivePacker.packAndDeleteDirectory(tempOutput.toString());
temp = null;
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Export Report");
alert.setContentText(Localization.getText("CityDoctorController.saveZipArchiveReports"));
alert.showAndWait();
} catch (IOException e) {
logger.error(e);
} finally {
try {
if (temp != null) {
FileUtils.deleteDirectory(temp);
}
} catch (IOException e) {
logger.error(e);
}
}
}
void updateFeatureTrees() { void updateFeatureTrees() {
updateTree(mainWindow.getBuildingsView().getRoot()); updateTree(mainWindow.getBuildingsView().getRoot());
updateTree(mainWindow.getVegetationView().getRoot()); updateTree(mainWindow.getVegetationView().getRoot());
......
...@@ -85,12 +85,6 @@ public class MainToolBar { ...@@ -85,12 +85,6 @@ public class MainToolBar {
@FXML @FXML
private ImageView lod4View; private ImageView lod4View;
@FXML
private Button zipManagerBtn;
@FXML
private ImageView zipManagerView;
@FXML @FXML
private Button aboutBtn; private Button aboutBtn;
...@@ -153,7 +147,6 @@ public class MainToolBar { ...@@ -153,7 +147,6 @@ public class MainToolBar {
setupReportButton(); setupReportButton();
setupResetCameraButton(); setupResetCameraButton();
setupHideRoofButton(); setupHideRoofButton();
setupZipManagerButton();
loadImages(); loadImages();
gridButton.setOnAction(ae -> renderer.showWireFrame(gridButton.isSelected())); gridButton.setOnAction(ae -> renderer.showWireFrame(gridButton.isSelected()));
...@@ -232,10 +225,6 @@ public class MainToolBar { ...@@ -232,10 +225,6 @@ public class MainToolBar {
Image img = new Image(inStream); Image img = new Image(inStream);
hideRoofView.setImage(img); hideRoofView.setImage(img);
} }
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/zip.png")) {
Image img = new Image(inStream);
zipManagerView.setImage(img);
}
} catch (IOException e) { } catch (IOException e) {
// ignore close exception // ignore close exception
} }
...@@ -347,14 +336,6 @@ public class MainToolBar { ...@@ -347,14 +336,6 @@ public class MainToolBar {
} }
private void setupZipManagerButton() {
zipManagerBtn.setDisable(true);
zipManagerBtn.setTooltip(new Tooltip(Localization.getText("MainToolBar.zip")));
zipManagerBtn.setOnAction(ae -> {
mainWindow.showZipManager();
});
}
public Button getCheckButton() { public Button getCheckButton() {
return checkBtn; return checkBtn;
} }
...@@ -407,10 +388,6 @@ public class MainToolBar { ...@@ -407,10 +388,6 @@ public class MainToolBar {
return resetCameraBtn; return resetCameraBtn;
} }
public Button getZipManagerBtn() {
return zipManagerBtn;
}
public HBox getToolBar() { public HBox getToolBar() {
return toolBar; return toolBar;
} }
......
...@@ -1181,13 +1181,6 @@ public class MainWindow extends Application { ...@@ -1181,13 +1181,6 @@ public class MainWindow extends Application {
return mainToolBar.getOpenBtn(); return mainToolBar.getOpenBtn();
} }
public void showZipManager() {
controller.showZipManager();
}
public Button getZipManagerBtn() {
return mainToolBar.getZipManagerBtn();
}
public VertexClickHandler getClickHandler() { public VertexClickHandler getClickHandler() {
return clickHandler; return clickHandler;
......
...@@ -120,7 +120,7 @@ public class OpenFileDialog { ...@@ -120,7 +120,7 @@ public class OpenFileDialog {
if (fc == null) { if (fc == null) {
fc = new FileChooser(); fc = new FileChooser();
fc.setTitle(Localization.getText("OpenFileDialog.select")); fc.setTitle(Localization.getText("OpenFileDialog.select"));
fc.getExtensionFilters().add(new ExtensionFilter("GML/XML/ZIP", "*.gml", "*.xml", "*.zip")); fc.getExtensionFilters().add(new ExtensionFilter("GML/XML", "*.gml", "*.xml"));
fc.getExtensionFilters().add(new ExtensionFilter(Localization.getText("MainWindow.all"), "*.*")); fc.getExtensionFilters().add(new ExtensionFilter(Localization.getText("MainWindow.all"), "*.*"));
} }
File dir = new File(Settings.get(Settings.LAST_OPEN_FOLDER, "")); File dir = new File(Settings.get(Settings.LAST_OPEN_FOLDER, ""));
...@@ -153,9 +153,6 @@ public class OpenFileDialog { ...@@ -153,9 +153,6 @@ public class OpenFileDialog {
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
try { try {
if (path.endsWith(".zip")) {
Platform.runLater(() -> progress.setProgress(-1));
}
controller.loadCityGml(path, numberOfRoundingPlaces, progress::setProgress, useValidation, controller.loadCityGml(path, numberOfRoundingPlaces, progress::setProgress, useValidation,
lowMemory); lowMemory);
Platform.runLater(() -> stage.close()); Platform.runLater(() -> stage.close());
......
package de.hft.stuttgart.citydoctor2.gui;
import de.hft.stuttgart.citydoctor2.gui.tree.ZipEntryListCell;
import de.hft.stuttgart.citydoctor2.gui.tree.node.ZipEntryNode;
import de.hft.stuttgart.citydoctor2.utils.Localization;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import de.hft.stuttgart.citydoctor2.zip.ZipEntryErrorType;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Predicate;
/**
* This class implements a GUI for managing a loaded {@link CityGmlZipArchive} in CityDoctor.
*/
public class ZipEntryManager {
private static final Logger logger = LogManager.getLogger(ZipEntryManager.class);
private Stage stage;
private CityGmlZipArchive archive;
@FXML
private TitledPane entriesPane;
@FXML
private TitledPane metadataPane;
@FXML
private Label subpathLbl;
@FXML
private TextField subpathValueTxt;
@FXML
private Label erroneousLbl;
@FXML
private Label erroneousValue;
@FXML
private Label filesizeLbl;
@FXML
private Label filesizeValue;
@FXML
private Label validatedLbl;
@FXML
private Label validatedValue;
@FXML
private Label objectCountLbl;
@FXML
private Label objectCountValue;
@FXML
private Button cancelBtn;
@FXML
private Button loadBtn;
@FXML
private ImageView loadImageView;
@FXML
private Button decompressBtn;
@FXML
private ImageView decompressImageView;
@FXML
private Button decompressAllBtn;
@FXML
private ImageView decompressAllImageView;
@FXML
private Button checkAllBtn;
@FXML
private ImageView checkAllImageView;
@FXML
private Button showReportBtn;
@FXML
private ImageView showReportImageView;
@FXML
private Button saveBtn;
@FXML
private ImageView saveImageView;
@FXML
private ListView<ZipEntryNode> entryList;
@FXML
private ProgressBar progress;
@FXML
private ProgressBar subProgress;
private CityDoctorController controller;
private int currentlyLoadedEntry = -1;
private CheckDialog dialog;
private final String unknownValueText = Localization.getText("ZipEntryManager.unknownValue");
private static final Predicate<ZipEntryNode> entryDecompressed = node ->
(node.getEntry().isLoaded() || node.getEntry().getErrorType() != null);
private static final Predicate<ZipEntryNode> entryValidated = entryDecompressed.and(node ->
(node.getEntry().getModel() != null && node.getEntry().getModel().isValidated()));
public ZipEntryManager(Window parent, CityDoctorController controller) throws IOException {
FXMLLoader loader = new FXMLLoader(ZipEntryManager.class.getResource("ZipEntryManager.fxml"));
loader.setController(this);
this.controller = controller;
archive = controller.getZipArchive();
VBox box = loader.load();
stage = new Stage();
stage.getIcons().add(new Image(MainWindow.class.getResourceAsStream("icons/CityDoctor-Logo-rot_klein.jpg")));
stage.setScene(new Scene(box));
stage.initOwner(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle(Localization.getText("ZipEntryManager.title"));
stage.getScene().addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent event) -> {
if (event.getCode() == KeyCode.ESCAPE) {
stage.close();
}
});
dialog = new CheckDialog(null, parent, controller);
dialog.showZipArchiveOptions(true);
}
public void initialize() {
subProgress.setVisible(false);
entryList.getSelectionModel().selectedItemProperty().addListener((obs, oldI, newI) -> {
if (newI != null) {
showMetadata(newI.getEntry());
}
});
entryList.setCellFactory(param -> new ZipEntryListCell());
setupButtons();
applyLocalization();
populateZipEntryList();
}
private void setupButtons() {
try {
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/decompress_zipEntry.png")) {
Image img = new Image(inStream);
decompressImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/view_model.png")) {
Image img = new Image(inStream);
loadImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/decompress_all_zipEntries.png")) {
Image img = new Image(inStream);
decompressAllImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/check_all_zipEntries.png")) {
Image img = new Image(inStream);
checkAllImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/error_stat32x32.png")) {
Image img = new Image(inStream);
showReportImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/save.png")) {
Image img = new Image(inStream);
saveImageView.setImage(img);
}
} catch (IOException ignored) {
//ignore exceptions
}
decompressBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
Thread t = new Thread(() -> {
CityGmlZipEntry entry = entryList.getSelectionModel().getSelectedItem().getEntry();
logger.info("Decompressing entry \"{}\"", entry.getDisplayName());
controller.decompressZipEntry(entry, progressValue ->
Platform.runLater(() -> progress.setProgress(progressValue))
);
Platform.runLater(() -> {
refresh();
progress.setProgress(0);
setEntryListLocked(false);
});
});
t.setDaemon(true);
t.start();
});
loadBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
try {
int selectedIndex = entryList.getSelectionModel().getSelectedIndex();
if (selectedIndex == currentlyLoadedEntry) {
stage.hide();
return;
}
CityGmlZipEntry entry = entryList.getSelectionModel().getSelectedItem().getEntry();
if (entry.getErrorType() != null) {
logger.debug("IllegalState: loadBtn was pressed while an erroneous entry was selected");
populateZipEntryList(selectedIndex);
return;
}
controller.loadZipEntry(entry);
currentlyLoadedEntry = selectedIndex;
stage.hide();
} finally {
setEntryListLocked(false);
}
});
decompressAllBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
subProgress.setVisible(true);
subProgress.setProgress(0);
Thread t = new Thread(() -> {
progress.setProgress(0);
int count = 0;
int total = entryList.getItems().size();
for (ZipEntryNode node : entryList.getItems()) {
logger.info("Decompressing entry \"{}\"", node.getEntry().getDisplayName());
controller.decompressZipEntry(node.getEntry(), progressValue ->
Platform.runLater(() -> subProgress.setProgress(progressValue))
);
count++;
double progressValue = count * 1.0 / total;
Platform.runLater(() -> progress.setProgress(progressValue));
}
Platform.runLater(() -> {
subProgress.setVisible(false);
refresh();
progress.setProgress(0);
setEntryListLocked(false);
});
});
t.setDaemon(true);
t.start();
});
checkAllBtn.setOnAction(e -> {
disableTaskButtons();
dialog.show();
refresh();
});
showReportBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
try {
controller.loadZipEntry(entryList.getSelectionModel().getSelectedItem().getEntry());
if (currentlyLoadedEntry == -1) {
currentlyLoadedEntry = entryList.getSelectionModel().getSelectedIndex();
}
WriteReportDialog writeDialog = new WriteReportDialog(stage, controller, null);
writeDialog.show();
} catch (IOException ex) {
throw new RuntimeException(ex);
} finally {
controller.loadZipEntry(entryList.getItems().get(currentlyLoadedEntry).getEntry());
setEntryListLocked(false);
refresh();
}
});
showReportBtn.setDisable(true);
saveBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
try {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Export Zip file");
FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Zip File", "*.zip");
fileChooser.getExtensionFilters().add(zipFilter);
File f = fileChooser.showSaveDialog(stage.getOwner());
if (f != null) {
controller.saveZipArchiveReports(f);
}
} finally {
setEntryListLocked(false);
refresh();
}
});
saveBtn.setDisable(true);
cancelBtn.setOnAction(e -> stage.close());
}
private void applyLocalization() {
entriesPane.setText(Localization.getText("ZipEntryManager.entryListTitle"));
metadataPane.setText(Localization.getText("ZipEntryManager.metadata"));
subpathLbl.setText(Localization.getText("ZipEntryManager.subpathLbl"));
erroneousLbl.setText(Localization.getText("ZipEntryManager.erroneousLbl"));
filesizeLbl.setText(Localization.getText("ZipEntryManager.filesizeLbl"));
validatedLbl.setText(Localization.getText("ZipEntryManager.validatedLbl"));
objectCountLbl.setText(Localization.getText("ZipEntryManager.objectCountLbl"));
subpathValueTxt.setText(unknownValueText);
erroneousValue.setText(unknownValueText);
filesizeValue.setText(unknownValueText);
validatedValue.setText(unknownValueText);
objectCountValue.setText(unknownValueText);
loadBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.loadBtn")));
decompressBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.decompressBtn")));
decompressAllBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.decompressAllBtn")));
checkAllBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.checkAllBtn")));
showReportBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.showReportBtn")));
saveBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.saveBtn")));
cancelBtn.setText(Localization.getText("ZipEntryManager.cancelBtn"));
}
private void populateZipEntryList() {
populateZipEntryList(0);
}
private void populateZipEntryList(int selectionIndex) {
entryList.getItems().clear();
for (CityGmlZipEntry entry : archive.getEntries()) {
entryList.getItems().add(new ZipEntryNode(entry));
}
entryList.getSelectionModel().clearSelection();
entryList.getSelectionModel().select(selectionIndex);
showMetadata(entryList.getSelectionModel().getSelectedItem().getEntry());
decompressAllBtn.setDisable(entryList.getItems().stream().allMatch(entryDecompressed));
saveBtn.setDisable(entryList.getItems().stream().noneMatch(entryValidated));
}
private void showMetadata(CityGmlZipEntry entry) {
subpathValueTxt.setText(entry.getEntrySubPath());
if (entry.getFileSize() != -1L) {
long fileSize = entry.getFileSize();
long kb = 1024L;
long mb = kb * kb;
long gb = mb * kb;
if (fileSize < kb) {
filesizeValue.setText("< 1 KB");
} else if (fileSize < mb) {
filesizeValue.setText(String.format("%s KB", fileSize / kb));
} else if (fileSize < gb) {
filesizeValue.setText(String.format("%s MB", fileSize / mb));
} else {
double gigabytes = (double) fileSize / gb;
filesizeValue.setText(String.format("%.2f GB", gigabytes));
}
} else {
filesizeValue.setText(unknownValueText);
}
if (entry.getErrorType() != null) {
erroneousValue.setText(getErrorText(entry.getErrorType()));
validatedValue.setText(unknownValueText);
objectCountValue.setText(unknownValueText);
loadBtn.setDisable(true);
decompressBtn.setDisable(true);
showReportBtn.setDisable(true);
} else {
erroneousValue.setText(Localization.getText("ZipEntryManager.no"));
loadBtn.setDisable(!entry.isLoaded());
decompressBtn.setDisable(entry.isLoaded());
if (entry.getModel() == null) {
validatedValue.setText(unknownValueText);
objectCountValue.setText(unknownValueText);
return;
}
if (entry.getModel().isValidated()) {
validatedValue.setText(Localization.getText("ZipEntryManager.yes"));
showReportBtn.setDisable(false);
} else {
validatedValue.setText(Localization.getText("ZipEntryManager.no"));
showReportBtn.setDisable(true);
}
objectCountValue.setText(String.valueOf(entry.getModel().getNumberOfFeatures()));
}
}
private void disableTaskButtons() {
decompressBtn.setDisable(true);
loadBtn.setDisable(true);
decompressAllBtn.setDisable(true);
showReportBtn.setDisable(true);
saveBtn.setDisable(true);
}
public void refresh() {
populateZipEntryList(entryList.getSelectionModel().getSelectedIndex());
}
private String getErrorText(ZipEntryErrorType error) {
switch (error) {
case EXCESSIVE_FILESIZE -> {
return Localization.getText("ZipEntryManager.excessiveFileSize");
}
case INVALID_CITY_GML_FILE -> {
return Localization.getText("ZipEntryManager.invalidCityGml");
}
default -> {
return Localization.getText("ZipEntryManager.ioError");
}
}
}
private void setEntryListLocked(boolean locked) {
entryList.setMouseTransparent(locked);
entryList.setFocusTraversable(!locked);
}
public void show() {
Platform.runLater(() -> stage.showAndWait());
refresh();
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.gui.tree.node.ZipEntryNode;
import javafx.scene.control.ListCell;
public class ZipEntryListCell extends ListCell<ZipEntryNode> {
@Override
protected void updateItem(ZipEntryNode item, boolean empty) {
super.updateItem(item, empty);
if (!empty || item != null) {
setText(item.getText());
updateColor();
} else {
setText(null);
}
}
public void updateColor() {
setTextFill(getItem().getTextColor());
}
}
package de.hft.stuttgart.citydoctor2.gui.tree.node;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import javafx.scene.paint.Color;
public class ZipEntryNode {
private final CityGmlZipEntry entry;
public ZipEntryNode(CityGmlZipEntry entry) {
this.entry = entry;
}
public Color getTextColor() {
if (entry.getErrorType() != null) {
return Color.DARKRED;
} else if (entry.getModel() != null) {
if (entry.getModel().getNumberOfFeatures() == 0) {
return Color.GRAY;
}
if (entry.getModel().isValidated()) {
if (entry.getModel().collectErrors().isEmpty()) {
return Color.GREEN;
}
return Color.RED;
}
return Color.BLUE;
} else if (entry.isLoaded()) {
return Color.BLUE;
} else {
return Color.BLACK;
}
}
public String getText() {
return entry.getDisplayName();
}
public CityGmlZipEntry getEntry() {
return entry;
}
}
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?> <?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.Tab?> <?import javafx.scene.control.Tab?>
...@@ -52,78 +51,6 @@ ...@@ -52,78 +51,6 @@
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy> </columnResizePolicy>
</TableView> </TableView>
<VBox fx:id="zipArchiveOptionsVBox" prefHeight="176.0" prefWidth="485.0">
<children>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<CheckBox fx:id="streamCheckOption" mnemonicParsing="false"
text="Use low memory mode">
<font>
<Font size="14.0"/>
</font>
</CheckBox>
<Label fx:id="streamCheckLabel" text="(?)" underline="true">
<opaqueInsets>
<Insets/>
</opaqueInsets>
<padding>
<Insets left="3.0"/>
</padding>
<font>
<Font size="14.0"/>
</font>
</Label>
</children>
</HBox>
<VBox fx:id="streamCheckParametersVBox" disable="true" prefHeight="200.0"
prefWidth="100.0">
<children>
<Label fx:id="outputPathLabel" text="Output path:">
<font>
<Font size="14.0"/>
</font>
</Label>
<HBox prefWidth="485.0">
<children>
<TextField fx:id="outputPathTextField" prefHeight="25.0"
prefWidth="291.0">
<font>
<Font size="14.0"/>
</font>
</TextField>
<Button fx:id="outputPathBtn" mnemonicParsing="false" prefHeight="30.0"
prefWidth="86.0" text="Select">
<font>
<Font size="14.0"/>
</font>
</Button>
</children>
</HBox>
<CheckBox fx:id="pdfReportsOption" mnemonicParsing="false"
text="Create PDF reports">
<padding>
<Insets top="10.0"/>
</padding>
<font>
<Font size="14.0"/>
</font>
</CheckBox>
<CheckBox layoutX="10.0" layoutY="60.0" mnemonicParsing="false"
text="Create XML reports" fx:id="xmlReportsOption">
<padding>
<Insets top="10.0"/>
</padding>
<font>
<Font size="14.0"/>
</font>
</CheckBox>
</children>
</VBox>
</children>
<HBox.margin>
<Insets left="30.0"/>
</HBox.margin>
</VBox>
</children> </children>
</HBox> </HBox>
<HBox spacing="5.0" VBox.vgrow="NEVER"> <HBox spacing="5.0" VBox.vgrow="NEVER">
......
...@@ -16,13 +16,7 @@ ...@@ -16,13 +16,7 @@
<ImageView fx:id="openImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="openImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" />
</graphic> </graphic>
</Button> </Button>
<Button id="loadBtn" fx:id="zipManagerBtn" disable="true" mnemonicParsing="false"> <Separator layoutX="381.0" layoutY="10.0" orientation="VERTICAL" />
<graphic>
<ImageView fx:id="zipManagerView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true"
preserveRatio="true"/>
</graphic>
</Button>
<Separator layoutX="381.0" layoutY="10.0" orientation="VERTICAL"/>
<Button fx:id="checkBtn" mnemonicParsing="false"> <Button fx:id="checkBtn" mnemonicParsing="false">
<graphic> <graphic>
<ImageView fx:id="checkImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="checkImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" />
...@@ -33,7 +27,7 @@ ...@@ -33,7 +27,7 @@
<ImageView fx:id="reportImageView" disable="true" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="reportImageView" disable="true" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" />
</graphic> </graphic>
</Button> </Button>
<Separator layoutX="116.0" layoutY="10.0" orientation="VERTICAL"/> <Separator layoutX="116.0" layoutY="10.0" orientation="VERTICAL" />
<ToggleButton fx:id="gridButton" disable="true" mnemonicParsing="false"> <ToggleButton fx:id="gridButton" disable="true" mnemonicParsing="false">
<graphic> <graphic>
<ImageView fx:id="gridImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="gridImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" />
...@@ -86,7 +80,7 @@ ...@@ -86,7 +80,7 @@
</HBox> </HBox>
<HBox fx:id="spacer" alignment="TOP_RIGHT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" spacing="5.0" HBox.hgrow="ALWAYS"> <HBox fx:id="spacer" alignment="TOP_RIGHT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" spacing="5.0" HBox.hgrow="ALWAYS">
<children> <children>
<Separator orientation="VERTICAL"/> <Separator orientation="VERTICAL" />
<Button id="loadBtn" fx:id="saveBtn" disable="true" mnemonicParsing="false"> <Button id="loadBtn" fx:id="saveBtn" disable="true" mnemonicParsing="false">
<graphic> <graphic>
<ImageView fx:id="saveView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="saveView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true" preserveRatio="true" />
......
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane minHeight="32.0">
<children>
<HBox spacing="5.0" AnchorPane.leftAnchor="0.0">
<children>
<Button fx:id="loadBtn" alignment="CENTER" maxWidth="1.7976931348623157E308"
mnemonicParsing="false">
<font>
<Font size="14.0"/>
</font>
<graphic>
<ImageView fx:id="loadImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true"
preserveRatio="true"/>
</graphic>
</Button>
<Button fx:id="decompressBtn" alignment="CENTER" maxWidth="1.7976931348623157E308"
mnemonicParsing="false">
<font>
<Font size="14.0"/>
</font>
<graphic>
<ImageView fx:id="decompressImageView" fitHeight="32.0" fitWidth="32.0"
pickOnBounds="true" preserveRatio="true"/>
</graphic>
</Button>
<Button fx:id="showReportBtn" alignment="CENTER" maxWidth="1.7976931348623157E308"
mnemonicParsing="false">
<font>
<Font size="14.0"/>
</font>
<graphic>
<ImageView fx:id="showReportImageView" fitHeight="32.0" fitWidth="32.0"
pickOnBounds="true" preserveRatio="true"/>
</graphic>
</Button>
<Separator orientation="VERTICAL"/>
<Button fx:id="decompressAllBtn" alignment="CENTER" maxWidth="1.7976931348623157E308"
mnemonicParsing="false">
<font>
<Font size="14.0"/>
</font>
<graphic>
<ImageView fx:id="decompressAllImageView" fitHeight="32.0" fitWidth="32.0"
pickOnBounds="true" preserveRatio="true"/>
</graphic>
</Button>
<Button fx:id="checkAllBtn" alignment="CENTER" maxWidth="1.7976931348623157E308"
mnemonicParsing="false">
<font>
<Font size="14.0"/>
</font>
<graphic>
<ImageView fx:id="checkAllImageView" fitHeight="32.0" fitWidth="32.0"
pickOnBounds="true" preserveRatio="true"/>
</graphic>
</Button>
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
</HBox>
<HBox alignment="TOP_RIGHT" layoutX="296.0" prefHeight="52.0" AnchorPane.rightAnchor="0.0">
<children>
<Button fx:id="saveBtn" alignment="CENTER" maxWidth="1.7976931348623157E308"
mnemonicParsing="false">
<font>
<Font size="14.0"/>
</font>
<graphic>
<ImageView fx:id="saveImageView" fitHeight="32.0" fitWidth="32.0" pickOnBounds="true"
preserveRatio="true"/>
</graphic>
</Button>
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
</HBox>
</children>
</AnchorPane>
<HBox fillHeight="false" prefHeight="200.0" prefWidth="600.0" VBox.vgrow="ALWAYS">
<children>
<TitledPane fx:id="entriesPane" collapsible="false" text="Zip-entries" HBox.hgrow="ALWAYS">
<font>
<Font size="14.0"/>
</font>
<content>
<ListView fx:id="entryList" prefWidth="300.0"/>
</content>
</TitledPane>
<TitledPane fx:id="metadataPane" collapsible="false" layoutX="10.0" layoutY="10.0" prefWidth="300.0"
text="Metadata" HBox.hgrow="ALWAYS">
<font>
<Font size="14.0"/>
</font>
<content>
<HBox>
<children>
<VBox spacing="5.0">
<children>
<Label fx:id="subpathLbl" alignment="CENTER" text="Subpath:">
<font>
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="erroneousLbl" text="Erroneous:">
<font>
<Font size="14.0"/>
</font>
<padding>
<Insets top="7.0"/>
</padding>
</Label>
<Label fx:id="filesizeLbl" text="Filesize:">
<font>
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="validatedLbl" layoutX="10.0" layoutY="67.0" text="Validated:">
<font>
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="objectCountLbl" layoutX="10.0" layoutY="67.0"
text="Object count:">
<font>
<Font size="14.0"/>
</font>
</Label>
</children>
</VBox>
<VBox prefHeight="147.0" prefWidth="189.0" spacing="5.0">
<children>
<TextField fx:id="subpathValueTxt" editable="false" prefHeight="27.0"
prefWidth="184.0" text="N/A"/>
<Label fx:id="erroneousValue" text="N/A">
<font>
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="filesizeValue" text="N/A">
<font>
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="validatedValue" layoutX="15.0" layoutY="67.0" text="N/A">
<font>
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="objectCountValue" layoutX="15.0" layoutY="92.0" text="N/A">
<font>
<Font size="14.0"/>
</font>
</Label>
</children>
<padding>
<Insets left="5.0"/>
</padding>
</VBox>
</children>
</HBox>
</content>
</TitledPane>
</children>
</HBox>
<HBox spacing="5.0">
<children>
<StackPane HBox.hgrow="ALWAYS">
<children>
<ProgressBar fx:id="progress" maxWidth="1.7976931348623157E308" minHeight="40.0"
prefHeight="40.0" progress="0.0">
<padding>
<Insets bottom="5.0" right="5.0" top="5.0"/>
</padding>
</ProgressBar>
<ProgressBar fx:id="subProgress" prefHeight="11.0" prefWidth="520.0" progress="0.0"
StackPane.alignment="CENTER_LEFT"/>
</children>
</StackPane>
<Button fx:id="cancelBtn" alignment="CENTER" mnemonicParsing="false" text="Cancel">
<font>
<Font size="14.0"/>
</font>
<HBox.margin>
<Insets top="4.0"/>
</HBox.margin>
</Button>
</children>
<padding>
<Insets left="5.0" right="5.0"/>
</padding>
</HBox>
</children>
</VBox>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment