Skip to content

Commit

Permalink
Improve propellant importing
Browse files Browse the repository at this point in the history
There were a couple of cases that weren't handled very well in the function that processes the propellant in a motor that is being loaded. First, if the loaded motor had a propellant with the same name as one in the library but different properties, it would correctly append a number to the end. However, it wouldn't check if there was already a numbered copy of the propellant with properties that match, and always just increment the number until it didn't overlap any existing propellant. This commit makes it check if the propellant matches any of the numbered copies. It also checks if there is a propellant in the library with the same properties and a different name, and asks if you'd like to merge them.
  • Loading branch information
reilleya committed Jan 11, 2025
1 parent 1d55ddf commit 730fa05
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 14 deletions.
12 changes: 12 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ def outputMessage(self, content, title='openMotor'):
msg.setWindowTitle(title)
msg.exec()

def promptYesNo(self, content, title='openMotor'):
if self.headless:
return input('{} (y/n): '.format(content)) == 'y'
else:
logger.log(content)
msg = QMessageBox()
msg.setWindowIcon(self.icon)
msg.setText(content)
msg.setWindowTitle(title)
msg.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
return msg.exec() == QMessageBox.StandardButton.Yes

def outputException(self, exception, text, title='openMotor - Error'):
if self.headless:
print(text + " " + str(exception))
Expand Down
2 changes: 1 addition & 1 deletion uilib/converters/burnsimImporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def importPropellant(node):

class BurnSimImporter(Importer):
def __init__(self, manager):
super().__init__(manager, 'BurnSim Motor', 'Loads motor files for BurnSim 3.0', {'.bsx': 'BurnSim Files'})
super().__init__(manager, 'BurnSim File', 'Loads motor files for BurnSim 3.0', {'.bsx': 'BurnSim Files'})

def doConversion(self, path):
motor = motorlib.motor.Motor()
Expand Down
45 changes: 32 additions & 13 deletions uilib/fileManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import motorlib

from .fileIO import saveFile, loadFile, fileTypes
from .helpers import FLAGS_NO_ICON
from .helpers import FLAGS_NO_ICON, excludeKeys
from .logger import logger

class FileManager(QObject):
Expand Down Expand Up @@ -189,27 +189,46 @@ def checkPropellant(self, motor):
if motor.propellant is None:
return motor

propManager = self.app.propellantManager
originalName = motor.propellant.getProperty('name')
# If the motor has a propellant that we don't have, add it to our library
if originalName not in self.app.propellantManager.getNames():
if originalName not in propManager.getNames():
# Check if any propellants in the library have the same properties and offer to dedupe
for libraryPropellantName in propManager.getNames():
libraryProperties = excludeKeys(propManager.getPropellantByName(libraryPropellantName).getProperties(), ['name'])
motorProperties = excludeKeys(motor.propellant.getProperties(), ['name'])
if libraryProperties == motorProperties:
message = 'The propellant from the loaded motor ("{}") was not in the library, but the properties match "{}" from the library. Should the loaded motor be updated to use this propellant?'
shouldDeDupe = self.app.promptYesNo(message.format(motor.propellant.getProperty('name'), libraryPropellantName))
if shouldDeDupe:
motor.propellant.setProperty('name', libraryPropellantName)
return motor

self.app.outputMessage('The propellant from the loaded motor was not in the library, so it was added as "{}"'.format(originalName),
'New propellant added')
self.app.propellantManager.propellants.append(motor.propellant)
self.app.propellantManager.savePropellants()
propManager.propellants.append(motor.propellant)
propManager.savePropellants()
logger.log('Propellant from loaded motor added to library under original name "{}"'.format(originalName))

return motor

# If a propellant by the name already exists, we need to check if they are the same and change the name if not
if motor.propellant.getProperties() == self.app.propellantManager.getPropellantByName(originalName).getProperties():
return motor

addedNumber = 1
while motor.propellant.getProperty('name') + ' (' + str(addedNumber) + ')' in self.app.propellantManager.getNames():
addedNumber = 0
name = originalName
while name in propManager.getNames():
existingProps = excludeKeys(propManager.getPropellantByName(name).getProperties(), ['name'])
motorProps = excludeKeys(motor.propellant.getProperties(), ['name'])
if existingProps == motorProps:
# If this isn't the first loop, we need to change the name to add the number
if addedNumber != 0:
motor.propellant.setProperty('name', name)
message = 'Propellant from loaded motor has the same name as one in the library ("{}"), but their properties do not match. It does match "{}", so it has been updated to that propellant.'.format(originalName, name)
self.app.outputMessage(message)
return motor
addedNumber += 1
motor.propellant.setProperty('name', originalName + ' (' + str(addedNumber) + ')')
self.app.propellantManager.propellants.append(motor.propellant)
self.app.propellantManager.savePropellants()
name = '{} ({})'.format(originalName, addedNumber)
motor.propellant.setProperty('name', '{} ({})'.format(originalName, addedNumber))
propManager.propellants.append(motor.propellant)
propManager.savePropellants()
self.app.outputMessage('The propellant from the loaded motor matches an existing item in the library, but they have different properties. The propellant from the motor has been added to the library as "{}"'.format(motor.propellant.getProperty('name')),
'New propellant added')

Expand Down
3 changes: 3 additions & 0 deletions uilib/helpers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from PyQt6.QtCore import Qt

FLAGS_NO_ICON = Qt.WindowType.Dialog | Qt.WindowType.CustomizeWindowHint | Qt.WindowType.WindowTitleHint | Qt.WindowType.WindowCloseButtonHint

def excludeKeys(d, keys):
return {k:v for k,v in d.items() if k not in keys}

0 comments on commit 730fa05

Please sign in to comment.