Implement additions pane pasting via ctrl-v
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user