Check when a material to be removed is in use by a component

This commit is contained in:
SiboVG 2024-08-08 22:43:21 +02:00
parent e63e521e90
commit 9f0b7c9b15
2 changed files with 83 additions and 4 deletions

View File

@ -278,6 +278,10 @@ matedtpan.but.ttip.revertall = Delete all user-defined materials
matedtpan.title.Deletealluser-defined = Delete all user-defined materials?
matedtpan.title.Revertall = Revert all?
matedtpan.lbl.edtmaterials = Editing materials will not affect existing rocket designs.
matedtpan.dlg.RemoveUsedMaterial.Application.title = Material used by component(s)
matedtpan.dlg.RemoveUsedMaterial.Application.msg = <html>The material is currently used in the following designs and components:<br>%s<br>The material will be converted from an Application material to a Document material.</html>
matedtpan.dlg.RemoveUsedMaterial.Document.title = Cannot remove material
matedtpan.dlg.RemoveUsedMaterial.Document.msg = <html>The material cannot be removed because it is used in the following designs and components:<br>%s</html>
!MaterialModel
MaterialModel.title.Material = Material

View File

@ -6,7 +6,12 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JLabel;
@ -20,6 +25,8 @@ import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.swing.gui.main.BasicFrame;
import net.miginfocom.swing.MigLayout;
import info.openrocket.core.database.Databases;
@ -200,7 +207,7 @@ public class MaterialEditPanel extends JPanel {
return;
}
// Remove the original material
removeMaterial(m);
removeMaterial(m, false);
// Add the edited material
Material mat = dialog.getMaterial();
@ -227,7 +234,7 @@ public class MaterialEditPanel extends JPanel {
Material m = getMaterial(sel);
if (!m.isUserDefined())
return;
removeMaterial(m);
removeMaterial(m, true);
model.fireTableDataChanged();
setButtonStates();
}
@ -324,14 +331,82 @@ public class MaterialEditPanel extends JPanel {
}
}
private void removeMaterial(Material m) {
// TODO: what if a component is currently using the material?
private void removeMaterial(Material m, boolean checkForComponentsInUse) {
Map<OpenRocketDocument, List<RocketComponent>> components = getComponentsThatUseMaterial(m);
if (m.isDocumentMaterial()) {
if (checkForComponentsInUse && !components.isEmpty()) {
String componentsTxt = formatDocumentComponentsMap(components);
JOptionPane.showMessageDialog(MaterialEditPanel.this,
String.format(trans.get("matedtpan.dlg.RemoveUsedMaterial.Document.msg"), componentsTxt),
trans.get("matedtpan.dlg.RemoveUsedMaterial.Document.title"), JOptionPane.WARNING_MESSAGE);
return;
}
document.getDocumentPreferences().removeMaterial(m);
} else {
if (checkForComponentsInUse && !components.isEmpty()) {
String componentsTxt = formatDocumentComponentsMap(components);
JOptionPane.showMessageDialog(MaterialEditPanel.this,
String.format(trans.get("matedtpan.dlg.RemoveUsedMaterial.Application.msg"), componentsTxt),
trans.get("matedtpan.dlg.RemoveUsedMaterial.Application.title"), JOptionPane.WARNING_MESSAGE);
Databases.removeMaterial(m);
m.setDocumentMaterial(true);
document.getDocumentPreferences().addMaterial(m);
return;
}
Databases.removeMaterial(m);
}
}
private String formatDocumentComponentsMap(Map<OpenRocketDocument, List<RocketComponent>> components) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<OpenRocketDocument, List<RocketComponent>> entry: components.entrySet()) {
OpenRocketDocument doc = entry.getKey();
List<RocketComponent> comps = entry.getValue();
File file = doc.getFile();
String fileName = file == null ? "&lt;" + "Unsaved" + "&gt;" : file.getName();
sb.append(fileName);
sb.append(": ");
for (RocketComponent comp: comps) {
sb.append(comp.getName());
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
sb.append("<br>");
}
return sb.toString();
}
/**
* Parse all open documents and return a map of documents and components that use the material.
* @param m The material to search for
* @return A map of documents and components that use the material.
*/
private Map<OpenRocketDocument, List<RocketComponent>> getComponentsThatUseMaterial(Material m) {
Map<OpenRocketDocument, List<RocketComponent>> result = new HashMap<>();
for (BasicFrame frame: BasicFrame.getAllFrames()) {
OpenRocketDocument doc = frame.getRocketPanel().getDocument();
List<RocketComponent> components = new ArrayList<>();
for (RocketComponent component: doc.getRocket()) {
// Parse the materials of the component
List<Material> materials = component.getAllMaterials();
if (materials == null) {
continue;
}
for (Material componentMaterial: materials) {
if (m.equals(componentMaterial)) {
components.add(component);
break;
}
}
}
if (!components.isEmpty()) {
result.put(doc, components);
}
}
return result;
}
private void setButtonStates() {