Implement additions pane pasting via ctrl-v

This commit is contained in:
DarkPhoenix
2019-08-21 17:39:06 +03:00
parent 9605efe643
commit 160c2f0942
3 changed files with 139 additions and 22 deletions

View File

@@ -739,11 +739,30 @@ class MainFrame(wx.Frame):
activeFit = self.getActiveFit()
try:
importType, importData = Port().importFitFromBuffer(clipboard, activeFit)
# If it's mutated item - make sure there's at least base item specified
if importType == "MutatedItem":
# we've imported an Abyssal module, need to fire off the command to add it to the fit
self.command.Submit(cmd.GuiImportLocalMutatedModuleCommand(activeFit, *importData[0]))
return # no need to do anything else
return
if importType == "AdditionsDrones":
if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, importData[0])):
self.additionsPane.select("Drones")
return
if importType == "AdditionsFighters":
if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, importData[0])):
self.additionsPane.select("Fighters")
return
if importType == "AdditionsImplants":
if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, importData[0])):
self.additionsPane.select("Implants")
return
if importType == "AdditionsBoosters":
if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, importData[0])):
self.additionsPane.select("Boosters")
return
if importType == "AdditionsCargo":
if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, importData[0])):
self.additionsPane.select("Cargo")
return
except:
pyfalog.error("Attempt to import failed:\n{0}", clipboard)
else:

View File

@@ -54,6 +54,7 @@ EFT_OPTIONS = (
MODULE_CATS = ('Module', 'Subsystem', 'Structure Module')
SLOT_ORDER = (FittingSlot.LOW, FittingSlot.MED, FittingSlot.HIGH, FittingSlot.RIG, FittingSlot.SUBSYSTEM, FittingSlot.SERVICE)
OFFLINE_SUFFIX = '/OFFLINE'
NAME_CHARS = '[^,/\[\]]' # Characters which are allowed to be used in name
def exportEft(fit, options, callback):
@@ -193,10 +194,9 @@ def importEft(lines):
aFit = AbstractFit()
aFit.mutations = _importGetMutationData(lines)
nameChars = '[^,/\[\]]' # Characters which are allowed to be used in name
stubPattern = '^\[.+?\]$'
modulePattern = '^(?P<typeName>{0}+?)(,\s*(?P<chargeName>{0}+?))?(?P<offline>\s*{1})?(\s*\[(?P<mutation>\d+?)\])?$'.format(nameChars, OFFLINE_SUFFIX)
droneCargoPattern = '^(?P<typeName>{}+?) x(?P<amount>\d+?)$'.format(nameChars)
modulePattern = '^(?P<typeName>{0}+?)(,\s*(?P<chargeName>{0}+?))?(?P<offline>\s*{1})?(\s*\[(?P<mutation>\d+?)\])?$'.format(NAME_CHARS, OFFLINE_SUFFIX)
droneCargoPattern = '^(?P<typeName>{}+?) x(?P<amount>\d+?)$'.format(NAME_CHARS)
sections = []
for section in _importSectionIter(lines):
@@ -864,12 +864,20 @@ class AbstractFit:
self.cargo[itemSpec.item].amount += itemSpec.amount
def _lineIter(text):
"""Iterate over non-blank lines."""
for line in text.splitlines():
line = line.strip()
if line:
yield line
def parseAdditions(text):
items = []
sMkt = Market.getInstance()
pattern = '^(?P<typeName>[^,/\[\]]+?)( x(?P<amount>\d+?))?$'
for line in text.splitlines():
line = line.strip()
pattern = '^(?P<typeName>{}+?)( x(?P<amount>\d+?))?$'.format(NAME_CHARS)
for line in _lineIter(text):
m = re.match(pattern, line)
if not m:
continue
@@ -880,3 +888,73 @@ def parseAdditions(text):
amount = 1 if amount is None else int(amount)
items.append((item, amount))
return items
def isValidDroneImport(text):
pattern = 'x\d+$'
for line in _lineIter(text):
if not re.search(pattern, line):
return False, ()
itemData = parseAdditions(text)
if not itemData:
return False, ()
for item, amount in itemData:
if not item.isDrone:
return False, ()
return True, itemData
def isValidFighterImport(text):
pattern = 'x\d+$'
for line in _lineIter(text):
if not re.search(pattern, line):
return False, ()
itemData = parseAdditions(text)
if not itemData:
return False, ()
for item, amount in itemData:
if not item.isFighter:
return False, ()
return True, itemData
def isValidCargoImport(text):
pattern = 'x\d+$'
for line in _lineIter(text):
if not re.search(pattern, line):
return False, ()
itemData = parseAdditions(text)
if not itemData:
return False, ()
for item, amount in itemData:
if item.isAbyssal:
return False, ()
return True, itemData
def isValidImplantImport(text):
pattern = 'x\d+$'
for line in _lineIter(text):
if re.search(pattern, line):
return False, ()
itemData = parseAdditions(text)
if not itemData:
return False, ()
for item, amount in itemData:
if not item.isImplant:
return False, ()
return True, itemData
def isValidBoosterImport(text):
pattern = 'x\d+$'
for line in _lineIter(text):
if re.search(pattern, line):
return False, ()
itemData = parseAdditions(text)
if not itemData:
return False, ()
for item, amount in itemData:
if not item.isBooster:
return False, ()
return True, itemData

View File

@@ -32,7 +32,10 @@ from eos import db
from eos.const import ImplantLocation
from service.fit import Fit as svcFit
from service.port.dna import exportDna, importDna
from service.port.eft import exportEft, importEft, importEftCfg
from service.port.eft import (
exportEft, importEft, importEftCfg,
isValidDroneImport, isValidFighterImport, isValidCargoImport,
isValidImplantImport, isValidBoosterImport)
from service.port.esi import exportESI, importESI
from service.port.multibuy import exportMultiBuy
from service.port.shared import IPortUser, UserCancelException, processing_notify
@@ -144,7 +147,7 @@ class Port:
continue
try:
_, fitsImport = Port.importAuto(srcString, path, iportuser=iportuser)
importType, makesNewFits, fitsImport = Port.importAuto(srcString, path, iportuser=iportuser)
fit_list += fitsImport
except xml.parsers.expat.ExpatError:
pyfalog.warning("Malformed XML in:\n{0}", path)
@@ -188,9 +191,9 @@ class Port:
# TODO: catch the exception?
# activeFit is reserved?, bufferStr is unicode? (assume only clipboard string?
sFit = svcFit.getInstance()
importType, importData = Port.importAuto(bufferStr, activeFit=activeFit)
importType, makesNewFits, importData = Port.importAuto(bufferStr, activeFit=activeFit)
if importType != "MutatedItem":
if makesNewFits:
for fit in importData:
fit.character = sFit.character
fit.damagePattern = sFit.pattern
@@ -217,41 +220,58 @@ class Port:
# If XML-style start of tag encountered, detect as XML
if re.search(RE_XML_START, firstLine):
return "XML", cls.importXml(string, iportuser)
return "XML", True, cls.importXml(string, iportuser)
# If JSON-style start, parse as CREST/JSON
if firstLine[0] == '{':
return "JSON", (cls.importESI(string),)
return "JSON", True, (cls.importESI(string),)
# If we've got source file name which is used to describe ship name
# and first line contains something like [setup name], detect as eft config file
if re.match("\[.*\]", firstLine) and path is not None:
filename = os.path.split(path)[1]
shipName = filename.rsplit('.')[0]
return "EFT Config", cls.importEftCfg(shipName, lines, iportuser)
return "EFT Config", True, cls.importEftCfg(shipName, lines, iportuser)
# If no file is specified and there's comma between brackets,
# consider that we have [ship, setup name] and detect like eft export format
if re.match("\[.*,.*\]", firstLine):
return "EFT", (cls.importEft(lines),)
return "EFT", True, (cls.importEft(lines),)
# Check if string is in DNA format
dnaPattern = "\d+(:\d+(;\d+))*::"
if re.match(dnaPattern, firstLine):
return "DNA", (cls.importDna(string),)
return "DNA", True, (cls.importDna(string),)
dnaChatPattern = "<url=fitting:(?P<dna>{})>(?P<fitName>[^<>]+)</url>".format(dnaPattern)
m = re.search(dnaChatPattern, firstLine)
if m:
return "DNA", (cls.importDna(m.group("dna"), fitName=m.group("fitName")),)
return "DNA", True, (cls.importDna(m.group("dna"), fitName=m.group("fitName")),)
# Assume that we import stand-alone abyssal module if all else fails
if activeFit is not None:
# Try to import mutated module
try:
return "MutatedItem", (parseMutant(lines),)
baseItem, mutaplasmidItem, mutations = parseMutant(lines)
except:
pass
else:
if baseItem is not None and mutaplasmidItem is not None:
return "MutatedItem", False, ((baseItem, mutaplasmidItem, mutations),)
# Try to import into one of additions panels
isDrone, droneData = isValidDroneImport(string)
if isDrone:
return "AdditionsDrones", False, (droneData,)
isFighter, fighterData = isValidFighterImport(string)
if isFighter:
return "AdditionsFighters", False, (fighterData,)
isImplant, implantData = isValidImplantImport(string)
if isImplant:
return "AdditionsImplants", False, (implantData,)
isBooster, boosterData = isValidBoosterImport(string)
if isBooster:
return "AdditionsBoosters", False, (boosterData,)
isCargo, cargoData = isValidCargoImport(string)
if isCargo:
return "AdditionsCargo", False, (cargoData,)
# EFT-related methods
@staticmethod