Commit initial work for effect DPS / Target resists
This commit is contained in:
@@ -66,7 +66,7 @@ from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithS
|
||||
getCharacterList, getPrice, getDamagePatternList, getDamagePattern, \
|
||||
getFitList, getFleetList, getFleet, save, remove, commit, add, \
|
||||
getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \
|
||||
getSquad, getBoosterFits, getProjectedFits
|
||||
getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists
|
||||
|
||||
#If using in memory saveddata, you'll want to reflect it so the data structure is good.
|
||||
if config.saveddata_connectionstring == "sqlite:///:memory:":
|
||||
|
||||
@@ -4,6 +4,7 @@ def update(saveddata_engine):
|
||||
checkPriceFailures(saveddata_engine)
|
||||
checkApiDefaultChar(saveddata_engine)
|
||||
checkFitBooster(saveddata_engine)
|
||||
checktargetResists(saveddata_engine)
|
||||
|
||||
def checkPriceFailures(saveddata_engine):
|
||||
# Check if we have 'failed' column
|
||||
@@ -57,3 +58,19 @@ def checkFitBooster(saveddata_engine):
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN booster BOOLEAN;")
|
||||
# Set NULL data to 0 (needed in case of downgrade, see GH issue #62
|
||||
saveddata_engine.execute("UPDATE fits SET booster = 0 WHERE booster IS NULL;")
|
||||
|
||||
def checktargetResists(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT * FROM fits LIMIT 1")
|
||||
# If table doesn't exist, it means we're doing everything from scratch
|
||||
# and sqlalchemy will process everything as needed
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
pass
|
||||
# If not, we're running on top of existing DB
|
||||
else:
|
||||
# Check that we have columns
|
||||
try:
|
||||
saveddata_engine.execute("SELECT targetResistsID FROM fits LIMIT 1")
|
||||
# If we don't, create them
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN targetResistsID INTEGER;")
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
__all__ = ["character", "fit", "module", "user", "skill", "price",
|
||||
"booster", "drone", "implant", "fleet", "damagePattern",
|
||||
"miscData"]
|
||||
"miscData", "targetResists"]
|
||||
|
||||
@@ -26,10 +26,11 @@ from eos.db.saveddata.module import modules_table
|
||||
from eos.db.saveddata.drone import drones_table
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.implant import fitImplants_table
|
||||
from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern
|
||||
from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern, TargetResists
|
||||
from eos.effectHandlerHelpers import HandledModuleList, HandledDroneList, \
|
||||
HandledImplantBoosterList, HandledProjectedModList, HandledProjectedDroneList, \
|
||||
HandledProjectedFitList, HandledCargoList
|
||||
|
||||
fits_table = Table("fits", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True),
|
||||
@@ -38,7 +39,8 @@ fits_table = Table("fits", saveddata_meta,
|
||||
Column("timestamp", Integer, nullable = False),
|
||||
Column("characterID", ForeignKey("characters.ID"), nullable = True),
|
||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||
Column("booster", Boolean, nullable = False, index = True, default = 0))
|
||||
Column("booster", Boolean, nullable = False, index = True, default = 0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True))
|
||||
|
||||
projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||
Column("sourceID", ForeignKey("fits.ID"), primary_key = True),
|
||||
@@ -64,6 +66,7 @@ mapper(Fit, fits_table,
|
||||
secondary = fitImplants_table),
|
||||
"_Fit__character" : relation(Character, backref = "fits"),
|
||||
"_Fit__damagePattern" : relation(DamagePattern),
|
||||
"_Fit__targetResists" : relation(TargetResists),
|
||||
"_Fit__projectedFits" : relation(Fit,
|
||||
primaryjoin = projectedFits_table.c.victimID == fits_table.c.ID,
|
||||
secondaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.db import saveddata_session, sd_lock
|
||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad
|
||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists
|
||||
from eos.db.saveddata.fleet import squadmembers_table
|
||||
from eos.db.saveddata.fit import projectedFits_table
|
||||
from sqlalchemy.sql import and_
|
||||
@@ -322,6 +322,12 @@ def getDamagePatternList(eager=None):
|
||||
patterns = saveddata_session.query(DamagePattern).options(*eager).all()
|
||||
return patterns
|
||||
|
||||
def getTargetResistsList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
patterns = saveddata_session.query(TargetResists).options(*eager).all()
|
||||
return patterns
|
||||
|
||||
@cachedQuery(DamagePattern, 1, "lookfor")
|
||||
def getDamagePattern(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -340,6 +346,24 @@ def getDamagePattern(lookfor, eager=None):
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return pattern
|
||||
|
||||
@cachedQuery(TargetResists, 1, "lookfor")
|
||||
def getTargetResists(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).get(lookfor)
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.name == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return pattern
|
||||
|
||||
def searchFits(nameLike, where=None, eager=None):
|
||||
if not isinstance(nameLike, basestring):
|
||||
raise TypeError("Need string as argument")
|
||||
@@ -361,7 +385,7 @@ def getSquadsIDsWithFitID(fitID):
|
||||
return squads
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
|
||||
def getProjectedFits(fitID):
|
||||
if isinstance(fitID, int):
|
||||
with sd_lock:
|
||||
@@ -369,7 +393,7 @@ def getProjectedFits(fitID):
|
||||
fits = saveddata_session.query(Fit).filter(filter).all()
|
||||
return fits
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def add(stuff):
|
||||
with sd_lock:
|
||||
|
||||
35
eos/db/saveddata/targetResists.py
Normal file
35
eos/db/saveddata/targetResists.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, String
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import TargetResists
|
||||
|
||||
targetResists_table = Table("targetResists", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String),
|
||||
Column("emAmount", Float),
|
||||
Column("thermalAmount", Float),
|
||||
Column("kineticAmount", Float),
|
||||
Column("explosiveAmount", Float),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True))
|
||||
|
||||
mapper(TargetResists, targetResists_table)
|
||||
@@ -99,6 +99,17 @@ class Fit(object):
|
||||
self.extraAttributes.original = self.EXTRA_ATTRIBUTES
|
||||
self.ship = Ship(db.getItem(self.shipID)) if self.shipID is not None else None
|
||||
|
||||
@property
|
||||
def targetResists(self):
|
||||
return self.__targetResists
|
||||
|
||||
@targetResists.setter
|
||||
def targetResists(self, targetResists):
|
||||
self.__targetResists = targetResists
|
||||
self.__weaponDPS = None
|
||||
self.__weaponVolley = None
|
||||
self.__droneDPS = None
|
||||
|
||||
@property
|
||||
def damagePattern(self):
|
||||
return self.__damagePattern
|
||||
@@ -809,9 +820,9 @@ class Fit(object):
|
||||
weaponDPS = 0
|
||||
droneDPS = 0
|
||||
weaponVolley = 0
|
||||
|
||||
print "calc weapons with: %s"%self.targetResists
|
||||
for mod in self.modules:
|
||||
dps, volley = mod.damageStats
|
||||
dps, volley = mod.damageStats(self.targetResists)
|
||||
weaponDPS += dps
|
||||
weaponVolley += volley
|
||||
|
||||
@@ -838,6 +849,7 @@ class Fit(object):
|
||||
copy.ship = deepcopy(self.ship, memo)
|
||||
copy.name = "%s copy" % self.name
|
||||
copy.damagePattern = self.damagePattern
|
||||
copy.targetResists = self.targetResists
|
||||
|
||||
toCopy = ("modules", "drones", "implants", "boosters", "projectedModules", "projectedDrones")
|
||||
for name in toCopy:
|
||||
|
||||
@@ -44,7 +44,7 @@ class Hardpoint(Enum):
|
||||
|
||||
class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
"""An instance of this class represents a module together with its charge and modified attributes"""
|
||||
DAMAGE_ATTRIBUTES = ("emDamage", "kineticDamage", "explosiveDamage", "thermalDamage")
|
||||
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
|
||||
MINING_ATTRIBUTES = ("miningAmount", )
|
||||
|
||||
def __init__(self, item):
|
||||
@@ -308,8 +308,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
self.__itemModifiedAttributes.clear()
|
||||
|
||||
@property
|
||||
def damageStats(self):
|
||||
def damageStats(self, targetResists):
|
||||
if self.__dps == None:
|
||||
if self.isEmpty:
|
||||
self.__dps = 0
|
||||
@@ -317,9 +316,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
if self.state >= State.ACTIVE:
|
||||
if self.charge:
|
||||
volley = sum(map(lambda attr: self.getModifiedChargeAttr(attr) or 0, self.DAMAGE_ATTRIBUTES))
|
||||
func = self.getModifiedChargeAttr
|
||||
else:
|
||||
volley = sum(map(lambda attr: self.getModifiedItemAttr(attr) or 0, self.DAMAGE_ATTRIBUTES))
|
||||
func = self.getModifiedItemAttr
|
||||
|
||||
volley = sum(map(lambda attr: (func("%sDamage"%attr) or 0) * (1-getattr(targetResists, "%sAmount"%attr, 0)), self.DAMAGE_TYPES))
|
||||
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
|
||||
if volley:
|
||||
cycleTime = self.cycleTime
|
||||
|
||||
82
eos/saveddata/targetResists.py
Normal file
82
eos/saveddata/targetResists.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
import re
|
||||
|
||||
class TargetResists(object):
|
||||
# also determined import/export order - VERY IMPORTANT
|
||||
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
|
||||
|
||||
def __init__(self, emAmount = 0, thermalAmount = 0, kineticAmount = 0, explosiveAmount = 0):
|
||||
print "new"
|
||||
self.emAmount = emAmount
|
||||
self.thermalAmount = thermalAmount
|
||||
self.kineticAmount = kineticAmount
|
||||
self.explosiveAmount = explosiveAmount
|
||||
|
||||
@classmethod
|
||||
def importPatterns(cls, text):
|
||||
lines = re.split('[\n\r]+', text)
|
||||
patterns = []
|
||||
|
||||
for line in lines:
|
||||
if line.strip()[0] == "#": # comments
|
||||
continue
|
||||
line = line.split('#',1)[0] # allows for comments
|
||||
type, data = line.rsplit('=',1)
|
||||
type, data = type.strip(), data.split(',')
|
||||
|
||||
#if type != "TargetResists":
|
||||
#continue
|
||||
|
||||
name, data = data[0], data[1:5]
|
||||
#print name, data
|
||||
fields = {}
|
||||
|
||||
for index, val in enumerate(data):
|
||||
val = float(val)
|
||||
try:
|
||||
assert 0 <= val <= 100
|
||||
fields["%sAmount" % cls.DAMAGE_TYPES[index]] = val/100
|
||||
except:
|
||||
continue
|
||||
|
||||
if len(fields) == 4: # Avoid possible blank lines
|
||||
print name, fields
|
||||
pattern = TargetResists(**fields)
|
||||
pattern.name = name.strip()
|
||||
patterns.append(pattern)
|
||||
|
||||
return patterns
|
||||
|
||||
EXPORT_FORMAT = "TargetResists = %s,%.1f,%.1f,%.1f,%.1f\n"
|
||||
@classmethod
|
||||
def exportPatterns(cls, *patterns):
|
||||
out = "# Exported from pyfa\n#\n"
|
||||
out += "# Values are in following format:\n"
|
||||
out += "# TargetResists = [name],[EM %],[Thermal %],[Kinetic %],[Explosive %]\n\n"
|
||||
for dp in patterns:
|
||||
out += cls.EXPORT_FORMAT % (dp.name, dp.emAmount*100, dp.thermalAmount*100, dp.kineticAmount*100, dp.explosiveAmount*100)
|
||||
|
||||
return out.strip()
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
p = TargetResists(self.emAmount, self.thermalAmount, self.kineticAmount, self.explosiveAmount)
|
||||
p.name = "%s copy" % self.name
|
||||
return p
|
||||
@@ -22,6 +22,7 @@ MetaGroup, AttributeInfo, Unit, EffectInfo, MetaType, MetaData, Traits
|
||||
from eos.saveddata.price import Price
|
||||
from eos.saveddata.user import User
|
||||
from eos.saveddata.damagePattern import DamagePattern
|
||||
from eos.saveddata.targetResists import TargetResists
|
||||
from eos.saveddata.character import Character, Skill
|
||||
from eos.saveddata.module import Module, State, Slot, Hardpoint, Rack
|
||||
from eos.saveddata.drone import Drone
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
__all__ = ["moduleAmmoPicker", "itemStats", "damagePattern", "marketJump", "droneSplit", "itemRemove",
|
||||
"droneRemoveStack", "ammoPattern", "project", "factorReload", "whProjector", "cargo", "shipJump"]
|
||||
"droneRemoveStack", "ammoPattern", "project", "factorReload", "whProjector", "cargo", "shipJump",
|
||||
"targetResists"]
|
||||
|
||||
98
gui/builtinContextMenus/targetResists.py
Normal file
98
gui/builtinContextMenus/targetResists.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import wx
|
||||
from gui import bitmapLoader
|
||||
|
||||
class TargetResists(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if self.mainFrame.getActiveFit() is None or srcContext not in ("firepowerViewFull",):
|
||||
return False
|
||||
|
||||
sTR = service.TargetResists.getInstance()
|
||||
self.patterns = sTR.getTargetResistsList()
|
||||
self.patterns.sort( key=lambda p: (p.name in ["None"], p.name) )
|
||||
return len(self.patterns) > 0
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return "Target Resists"
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
pass
|
||||
|
||||
def handleResistSwitch(self, event):
|
||||
pattern = self.patternIds.get(event.Id, False)
|
||||
if pattern is False:
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
sFit = service.Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
sFit.setTargetResists(fitID, pattern)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
def addPattern(self, menu, pattern, currBase = None):
|
||||
id = wx.NewId()
|
||||
name = pattern.name if pattern is not None else "No Profile"
|
||||
self.patternIds[id] = pattern
|
||||
if currBase:
|
||||
item = wx.MenuItem(menu, id, currBase)
|
||||
else:
|
||||
item = wx.MenuItem(menu, id, name)
|
||||
|
||||
item.pattern = pattern
|
||||
return item
|
||||
|
||||
def addSeperator(self, m, text):
|
||||
id = wx.NewId()
|
||||
m.Append(id, u'─ %s ─' % text)
|
||||
m.Enable(id, False)
|
||||
|
||||
def getSubMenu(self, context, selection, menu, i):
|
||||
self.context = context
|
||||
menu.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
m = wx.Menu()
|
||||
m.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
self.patternIds = {}
|
||||
|
||||
# @todo: this whole thing is a mess, please fix
|
||||
# Maybe look into processing resists into a dict and iterating through
|
||||
# dict to make submenus instead of this shitty logic
|
||||
items = []
|
||||
nameBase = None
|
||||
sub = None
|
||||
|
||||
m.AppendItem(self.addPattern(m, None)) # Add reset
|
||||
m.AppendSeparator()
|
||||
for pattern in self.patterns:
|
||||
start, end = pattern.name.find('['), pattern.name.find(']')
|
||||
if start is not -1 and end is not -1:
|
||||
currBase = pattern.name[start+1:end]
|
||||
else:
|
||||
currBase = None
|
||||
|
||||
if nameBase is None or nameBase != currBase:
|
||||
sub = None
|
||||
base = pattern
|
||||
nameBase = currBase
|
||||
item = self.addPattern(m, pattern, currBase)
|
||||
items.append(item)
|
||||
else:
|
||||
if sub is None:
|
||||
sub = wx.Menu()
|
||||
sub.Bind(wx.EVT_MENU, self.handleResistSwitch)
|
||||
item.SetSubMenu(sub)
|
||||
sub.AppendItem(self.addPattern(sub, base))
|
||||
|
||||
sub.AppendItem(self.addPattern(sub, pattern))
|
||||
for item in items:
|
||||
m.AppendItem(item)
|
||||
return m
|
||||
|
||||
TargetResists.register()
|
||||
@@ -40,13 +40,20 @@ class FirepowerViewFull(StatsView):
|
||||
def populatePanel(self, contentPanel, headerPanel):
|
||||
contentSizer = contentPanel.GetSizer()
|
||||
parent = self.panel = contentPanel
|
||||
|
||||
self.headerPanel = headerPanel
|
||||
headerContentSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
hsizer = headerPanel.GetSizer()
|
||||
hsizer.Add(headerContentSizer,0,0,0)
|
||||
self.stEff = wx.StaticText(headerPanel, wx.ID_ANY, "( Effective )")
|
||||
headerContentSizer.Add(self.stEff)
|
||||
headerPanel.GetParent().AddToggleItem(self.stEff)
|
||||
|
||||
panel = "full"
|
||||
|
||||
sizerFirepower = wx.FlexGridSizer(1, 4)
|
||||
sizerFirepower.AddGrowableCol(1)
|
||||
|
||||
|
||||
contentSizer.Add( sizerFirepower, 0, wx.EXPAND, 0)
|
||||
|
||||
counter = 0
|
||||
@@ -129,6 +136,10 @@ class FirepowerViewFull(StatsView):
|
||||
|
||||
def refreshPanel(self, fit):
|
||||
#If we did anything intresting, we'd update our labels to reflect the new fit's stats here
|
||||
if fit is not None and fit.targetResists is not None:
|
||||
self.stEff.Show()
|
||||
else:
|
||||
self.stEff.Hide()
|
||||
|
||||
stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS",None),
|
||||
("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None),
|
||||
|
||||
@@ -46,6 +46,7 @@ from gui.shipBrowser import ShipBrowser, FitSelected
|
||||
from gui.characterEditor import CharacterEditor
|
||||
from gui.characterSelection import CharacterSelection
|
||||
from gui.patternEditor import DmgPatternEditorDlg
|
||||
from gui.resistsEditor import ResistsEditorDlg
|
||||
from gui.preferenceDialog import PreferenceDialog
|
||||
from gui.graphFrame import GraphFrame
|
||||
from gui.copySelectDialog import CopySelectDialog
|
||||
@@ -311,6 +312,11 @@ class MainFrame(wx.Frame):
|
||||
dlg=CharacterEditor(self)
|
||||
dlg.Show()
|
||||
|
||||
def showTargetResistsEditor(self, event):
|
||||
dlg=ResistsEditorDlg(self)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
def showDamagePatternEditor(self, event):
|
||||
dlg=DmgPatternEditorDlg(self)
|
||||
dlg.ShowModal()
|
||||
@@ -392,6 +398,8 @@ class MainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.showCharacterEditor, id=menuBar.characterEditorId)
|
||||
# Damage pattern editor
|
||||
self.Bind(wx.EVT_MENU, self.showDamagePatternEditor, id=menuBar.damagePatternEditorId)
|
||||
# Target Resists editor
|
||||
self.Bind(wx.EVT_MENU, self.showTargetResistsEditor, id=menuBar.targetResistsEditorId)
|
||||
# Import dialog
|
||||
self.Bind(wx.EVT_MENU, self.showImportDialog, id=wx.ID_OPEN)
|
||||
# Export dialog
|
||||
|
||||
@@ -28,6 +28,7 @@ class MainMenuBar(wx.MenuBar):
|
||||
def __init__(self):
|
||||
self.characterEditorId = wx.NewId()
|
||||
self.damagePatternEditorId = wx.NewId()
|
||||
self.targetResistsEditorId = wx.NewId()
|
||||
self.graphFrameId = wx.NewId()
|
||||
self.backupFitsId = wx.NewId()
|
||||
self.exportSkillsNeededId = wx.NewId()
|
||||
@@ -82,6 +83,10 @@ class MainMenuBar(wx.MenuBar):
|
||||
damagePatternEditItem.SetBitmap(bitmapLoader.getBitmap("damagePattern_small", "icons"))
|
||||
windowMenu.AppendItem(damagePatternEditItem)
|
||||
|
||||
targetResistsEditItem = wx.MenuItem(windowMenu, self.targetResistsEditorId, "Target Resists Editor\tCTRL+R")
|
||||
targetResistsEditItem.SetBitmap(bitmapLoader.getBitmap("explosive_big", "icons"))
|
||||
windowMenu.AppendItem(targetResistsEditItem)
|
||||
|
||||
graphFrameItem = wx.MenuItem(windowMenu, self.graphFrameId, "Graphs\tCTRL+G")
|
||||
graphFrameItem.SetBitmap(bitmapLoader.getBitmap("graphs_small", "icons"))
|
||||
windowMenu.AppendItem(graphFrameItem)
|
||||
|
||||
353
gui/resistsEditor.py
Normal file
353
gui/resistsEditor.py
Normal file
@@ -0,0 +1,353 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
#
|
||||
# pyfa is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyfa is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
import wx
|
||||
import bitmapLoader
|
||||
import service
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
|
||||
class ResistsEditorDlg (wx.Dialog):
|
||||
|
||||
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
|
||||
|
||||
def __init__(self, parent):
|
||||
wx.Dialog.__init__ (self, parent, id = wx.ID_ANY, title = u"Target Resists Editor", size = wx.Size( 350,240 ))
|
||||
|
||||
self.block = False
|
||||
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.headerSizer = headerSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
sTR = service.TargetResists.getInstance()
|
||||
|
||||
self.choices = sTR.getTargetResistsList()
|
||||
|
||||
# Sort the remaining list and continue on
|
||||
self.choices.sort(key=lambda p: p.name)
|
||||
self.ccResists = wx.Choice(self, choices=map(lambda p: p.name, self.choices))
|
||||
self.ccResists.Bind(wx.EVT_CHOICE, self.patternChanged)
|
||||
self.ccResists.SetSelection(0)
|
||||
|
||||
self.namePicker = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER)
|
||||
self.namePicker.Bind(wx.EVT_TEXT_ENTER, self.processRename)
|
||||
self.namePicker.Hide()
|
||||
|
||||
self.btnSave = wx.Button(self, wx.ID_SAVE)
|
||||
self.btnSave.Hide()
|
||||
self.btnSave.Bind(wx.EVT_BUTTON, self.processRename)
|
||||
|
||||
size = None
|
||||
headerSizer.Add(self.ccResists, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT|wx.LEFT, 3)
|
||||
|
||||
buttons = (("new", wx.ART_NEW),
|
||||
("rename", bitmapLoader.getBitmap("rename", "icons")),
|
||||
("copy", wx.ART_COPY),
|
||||
("delete", wx.ART_DELETE))
|
||||
for name, art in buttons:
|
||||
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON) if name != "rename" else art
|
||||
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
|
||||
if size is None:
|
||||
size = btn.GetSize()
|
||||
|
||||
btn.SetMinSize(size)
|
||||
btn.SetMaxSize(size)
|
||||
|
||||
btn.Layout()
|
||||
setattr(self, name, btn)
|
||||
btn.Enable(True)
|
||||
btn.SetToolTipString("%s resist profile" % name.capitalize())
|
||||
headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
|
||||
mainSizer.Add(headerSizer, 0, wx.EXPAND | wx.ALL, 2)
|
||||
|
||||
self.sl = wx.StaticLine(self)
|
||||
mainSizer.Add(self.sl, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
resistEditSizer = wx.FlexGridSizer(2, 6, 0, 2)
|
||||
resistEditSizer.AddGrowableCol(0)
|
||||
resistEditSizer.AddGrowableCol(5)
|
||||
resistEditSizer.SetFlexibleDirection(wx.BOTH)
|
||||
resistEditSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
|
||||
|
||||
width = -1
|
||||
defSize = wx.Size(50,-1)
|
||||
|
||||
for i, type in enumerate(self.DAMAGE_TYPES):
|
||||
if i%2:
|
||||
style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx. LEFT
|
||||
border = 25
|
||||
else:
|
||||
style = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT
|
||||
border = 5
|
||||
|
||||
bmp = wx.StaticBitmap(self, wx.ID_ANY, bitmapLoader.getBitmap("%s_big"%type, "icons"))
|
||||
resistEditSizer.Add(bmp, 0, style, border)
|
||||
# set text edit
|
||||
setattr(self, "%sEdit"%type, wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, defSize))
|
||||
editObj = getattr(self, "%sEdit"%type)
|
||||
resistEditSizer.Add(editObj, 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||
resistEditSizer.Add(wx.StaticText( self, wx.ID_ANY, u"%", wx.DefaultPosition, wx.DefaultSize, 0 ), 0, wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 5)
|
||||
editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated)
|
||||
|
||||
contentSizer.Add(resistEditSizer, 1, wx.EXPAND | wx.ALL, 5)
|
||||
self.slfooter = wx.StaticLine(self)
|
||||
contentSizer.Add(self.slfooter, 0, wx.EXPAND | wx.TOP, 5)
|
||||
|
||||
footerSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
perSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.stNotice = wx.StaticText(self, wx.ID_ANY, u"")
|
||||
self.stNotice.Wrap(-1)
|
||||
perSizer.Add(self.stNotice, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5)
|
||||
|
||||
footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5)
|
||||
|
||||
self.totSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
contentSizer.Add(footerSizer, 0, wx.EXPAND, 5)
|
||||
|
||||
mainSizer.Add(contentSizer, 1, wx.EXPAND, 0)
|
||||
|
||||
if "wxGTK" in wx.PlatformInfo:
|
||||
self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 )
|
||||
self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent)
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
importExport = (("Import", wx.ART_FILE_OPEN, "from"),
|
||||
("Export", wx.ART_FILE_SAVE_AS, "to"))
|
||||
|
||||
for name, art, direction in importExport:
|
||||
bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON)
|
||||
btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
|
||||
|
||||
btn.SetMinSize( btn.GetSize() )
|
||||
btn.SetMaxSize( btn.GetSize() )
|
||||
|
||||
btn.Layout()
|
||||
setattr(self, name, btn)
|
||||
btn.Enable(True)
|
||||
btn.SetToolTipString("%s patterns %s clipboard" % (name, direction) )
|
||||
footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT)
|
||||
|
||||
self.Layout()
|
||||
bsize = self.GetBestSize()
|
||||
self.SetSize((-1,bsize.height))
|
||||
|
||||
self.new.Bind(wx.EVT_BUTTON, self.newPattern)
|
||||
self.rename.Bind(wx.EVT_BUTTON, self.renamePattern)
|
||||
self.copy.Bind(wx.EVT_BUTTON, self.copyPattern)
|
||||
self.delete.Bind(wx.EVT_BUTTON, self.deletePattern)
|
||||
self.Import.Bind(wx.EVT_BUTTON, self.importPatterns)
|
||||
self.Export.Bind(wx.EVT_BUTTON, self.exportPatterns)
|
||||
|
||||
self.patternChanged()
|
||||
|
||||
def closeEvent(self, event):
|
||||
self.Destroy()
|
||||
|
||||
def ValuesUpdated(self, event=None):
|
||||
if self.block:
|
||||
return
|
||||
if event is not None:
|
||||
print event.GetString()
|
||||
|
||||
try:
|
||||
p = self.getActivePattern()
|
||||
|
||||
for type in self.DAMAGE_TYPES:
|
||||
editObj = getattr(self, "%sEdit"%type)
|
||||
|
||||
if editObj.GetValue() == "":
|
||||
# if we are blank, overwrite with 0
|
||||
editObj.ChangeValue("0")
|
||||
editObj.SetInsertionPointEnd()
|
||||
|
||||
value = float(editObj.GetValue())
|
||||
|
||||
# assertion, because they're easy
|
||||
assert 0 <= value <= 100
|
||||
|
||||
# if everything checks out, set resist attribute
|
||||
setattr(p, "%sAmount"%type, value/100)
|
||||
|
||||
self.stNotice.SetLabel("")
|
||||
self.totSizer.Layout()
|
||||
|
||||
if event is not None:
|
||||
# If we get here, everything is normal. Reset color
|
||||
event.EventObject.SetForegroundColour(wx.NullColor)
|
||||
event.Skip()
|
||||
|
||||
service.TargetResists.getInstance().saveChanges(p)
|
||||
|
||||
except ValueError:
|
||||
event.EventObject.SetForegroundColour(wx.RED)
|
||||
self.stNotice.SetLabel("Incorrect Formatting (decimals only)")
|
||||
except AssertionError:
|
||||
event.EventObject.SetForegroundColour(wx.RED)
|
||||
self.stNotice.SetLabel("Incorrect Range (must be 0-100)")
|
||||
finally:
|
||||
self.Refresh() # Refresh for color changes to take effect immediately
|
||||
|
||||
def restrict(self):
|
||||
for type in self.DAMAGE_TYPES:
|
||||
editObj = getattr(self, "%sEdit"%type)
|
||||
editObj.Enable(False)
|
||||
self.rename.Enable(False)
|
||||
self.delete.Enable(False)
|
||||
|
||||
def unrestrict(self):
|
||||
for type in self.DAMAGE_TYPES:
|
||||
editObj = getattr(self, "%sEdit"%type)
|
||||
editObj.Enable()
|
||||
self.rename.Enable()
|
||||
self.delete.Enable()
|
||||
|
||||
def getActivePattern(self):
|
||||
if len(self.choices) == 0:
|
||||
return None
|
||||
|
||||
return self.choices[self.ccResists.GetSelection()]
|
||||
|
||||
def patternChanged(self, event=None):
|
||||
p = self.getActivePattern()
|
||||
if p is None:
|
||||
return
|
||||
|
||||
self.block = True
|
||||
for field in self.DAMAGE_TYPES:
|
||||
edit = getattr(self, "%sEdit" % field)
|
||||
amount = getattr(p, "%sAmount" % field)*100
|
||||
edit.ChangeValue(str(amount))
|
||||
|
||||
self.block = False
|
||||
self.ValuesUpdated()
|
||||
|
||||
def newPattern(self,event):
|
||||
sTR = service.TargetResists.getInstance()
|
||||
p = sTR.newPattern()
|
||||
self.choices.append(p)
|
||||
id = self.ccResists.Append(p.name)
|
||||
self.ccResists.SetSelection(id)
|
||||
self.btnSave.SetLabel("Create")
|
||||
|
||||
# reset values
|
||||
for type in self.DAMAGE_TYPES:
|
||||
editObj = getattr(self, "%sEdit"%type)
|
||||
editObj.ChangeValue("0")
|
||||
editObj.SetForegroundColour(wx.NullColor)
|
||||
|
||||
self.Refresh()
|
||||
self.renamePattern()
|
||||
|
||||
def renamePattern(self,event=None):
|
||||
if event is not None:
|
||||
self.btnSave.SetLabel("Rename")
|
||||
|
||||
self.ccResists.Hide()
|
||||
self.namePicker.Show()
|
||||
self.headerSizer.Replace(self.ccResists, self.namePicker)
|
||||
self.namePicker.SetFocus()
|
||||
self.namePicker.SetValue(self.getActivePattern().name)
|
||||
|
||||
for btn in (self.new, self.rename, self.delete, self.copy):
|
||||
btn.Hide()
|
||||
self.headerSizer.Remove(btn)
|
||||
|
||||
self.headerSizer.Add(self.btnSave, 0, wx.ALIGN_CENTER)
|
||||
self.btnSave.Show()
|
||||
self.headerSizer.Layout()
|
||||
if event is not None:
|
||||
event.Skip()
|
||||
|
||||
def processRename(self, event):
|
||||
newName = self.namePicker.GetLineText(0)
|
||||
self.stNotice.SetLabel("")
|
||||
|
||||
p = self.getActivePattern()
|
||||
for pattern in self.choices:
|
||||
if pattern.name == newName and p != pattern:
|
||||
self.stNotice.SetLabel("Name already used, please pick another")
|
||||
return
|
||||
|
||||
if newName == "":
|
||||
self.stNotice.SetLabel("Invalid name")
|
||||
return
|
||||
|
||||
sTR = service.TargetResists.getInstance()
|
||||
sTR.renamePattern(p, newName)
|
||||
|
||||
self.headerSizer.Replace(self.namePicker, self.ccResists)
|
||||
self.ccResists.Show()
|
||||
self.namePicker.Hide()
|
||||
self.btnSave.Hide()
|
||||
self.headerSizer.Remove(self.btnSave)
|
||||
for btn in (self.new, self.rename, self.delete, self.copy):
|
||||
self.headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
btn.Show()
|
||||
|
||||
sel = self.ccResists.GetSelection()
|
||||
self.ccResists.Delete(sel)
|
||||
self.ccResists.Insert(newName, sel)
|
||||
self.ccResists.SetSelection(sel)
|
||||
self.ValuesUpdated()
|
||||
self.unrestrict()
|
||||
|
||||
def copyPattern(self,event):
|
||||
sTR = service.TargetResists.getInstance()
|
||||
p = sTR.copyPattern(self.getActivePattern())
|
||||
self.choices.append(p)
|
||||
id = self.ccResists.Append(p.name)
|
||||
self.ccResists.SetSelection(id)
|
||||
self.btnSave.SetLabel("Copy")
|
||||
self.renamePattern()
|
||||
self.patternChanged()
|
||||
|
||||
def deletePattern(self,event):
|
||||
sTR = service.TargetResists.getInstance()
|
||||
sel = self.ccResists.GetSelection()
|
||||
sTR.deletePattern(self.getActivePattern())
|
||||
self.ccResists.Delete(sel)
|
||||
self.ccResists.SetSelection(max(0, sel - 1))
|
||||
del self.choices[sel]
|
||||
self.patternChanged()
|
||||
|
||||
def __del__( self ):
|
||||
pass
|
||||
|
||||
def importPatterns(self, event):
|
||||
text = fromClipboard()
|
||||
if text:
|
||||
sTR = service.TargetResists.getInstance()
|
||||
# @todo: fix return value and use that to determine label
|
||||
sTR.importPatterns(text)
|
||||
self.stNotice.SetLabel("Patterns imported from clipboard")
|
||||
else:
|
||||
self.stNotice.SetLabel("Could not import from clipboard")
|
||||
|
||||
def exportPatterns(self, event):
|
||||
sTR = service.TargetResists.getInstance()
|
||||
toClipboard( sTR.exportPatterns() )
|
||||
self.stNotice.SetLabel("Patterns exported to clipboard")
|
||||
@@ -3,6 +3,7 @@ from service.fit import Fit
|
||||
from service.attribute import Attribute
|
||||
from service.character import Character
|
||||
from service.damagePattern import DamagePattern
|
||||
from service.targetResists import TargetResists
|
||||
from service.settings import SettingsProvider
|
||||
from service.fleet import Fleet
|
||||
from service.update import Update
|
||||
|
||||
@@ -83,6 +83,7 @@ class Fit(object):
|
||||
|
||||
def __init__(self):
|
||||
self.pattern = DamagePattern.getInstance().getDamagePattern("Uniform")
|
||||
self.targetResists = None
|
||||
self.character = Character.getInstance().all5()
|
||||
self.booster = False
|
||||
self.dirtyFitIDs = set()
|
||||
@@ -148,6 +149,7 @@ class Fit(object):
|
||||
fit.ship = eos.types.Ship(eos.db.getItem(shipID))
|
||||
fit.name = name if name is not None else "New %s" % fit.ship.item.name
|
||||
fit.damagePattern = self.pattern
|
||||
fit.targetResists = self.targetResists
|
||||
fit.character = self.character
|
||||
fit.booster = self.booster
|
||||
eos.db.save(fit)
|
||||
@@ -683,6 +685,23 @@ class Fit(object):
|
||||
|
||||
self.recalc(fit)
|
||||
|
||||
def getTargetResists(self, fitID):
|
||||
if fitID is None:
|
||||
return
|
||||
|
||||
fit = eos.db.getFit(fitID)
|
||||
return fit.targetResists
|
||||
|
||||
def setTargetResists(self, fitID, pattern):
|
||||
if fitID is None:
|
||||
return
|
||||
print "Set target resists: %s"%pattern
|
||||
fit = eos.db.getFit(fitID)
|
||||
fit.targetResists = pattern
|
||||
eos.db.commit()
|
||||
|
||||
self.recalc(fit)
|
||||
|
||||
def getDamagePattern(self, fitID):
|
||||
if fitID is None:
|
||||
return
|
||||
@@ -760,6 +779,7 @@ class Fit(object):
|
||||
for fit in fits:
|
||||
fit.character = self.character
|
||||
fit.damagePattern = self.pattern
|
||||
fit.targetResists = self.targetResists
|
||||
return fits
|
||||
|
||||
def importFitFromBuffer(self, bufferStr, activeFit=None):
|
||||
@@ -767,6 +787,7 @@ class Fit(object):
|
||||
for fit in fits:
|
||||
fit.character = self.character
|
||||
fit.damagePattern = self.pattern
|
||||
fit.targetResists = self.targetResists
|
||||
return fits
|
||||
|
||||
def saveImportedFits(self, fits):
|
||||
|
||||
92
service/targetResists.py
Normal file
92
service/targetResists.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
#
|
||||
# pyfa is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyfa is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
import eos.db
|
||||
import eos.types
|
||||
import copy
|
||||
|
||||
class TargetResists():
|
||||
instance = None
|
||||
@classmethod
|
||||
def getInstance(cls):
|
||||
if cls.instance is None:
|
||||
cls.instance = TargetResists()
|
||||
|
||||
return cls.instance
|
||||
|
||||
def __init__(self):
|
||||
uniform = eos.db.getTargetResists("None")
|
||||
if uniform is None:
|
||||
uniform = eos.types.TargetResists(0,0,0,0)
|
||||
uniform.name = "None"
|
||||
eos.db.save(uniform)
|
||||
|
||||
def getTargetResistsList(self):
|
||||
return eos.db.getTargetResistsList()
|
||||
|
||||
def getTargetResists(self, name):
|
||||
print "Getting Target Resists: %s"%name
|
||||
return eos.db.getTargetResists(name)
|
||||
|
||||
def newPattern(self):
|
||||
p = eos.types.TargetResists(0, 0, 0, 0)
|
||||
p.name = ""
|
||||
return p
|
||||
|
||||
def renamePattern(self, p, newName):
|
||||
p.name = newName
|
||||
eos.db.save(p)
|
||||
|
||||
def deletePattern(self, p):
|
||||
eos.db.remove(p)
|
||||
|
||||
def copyPattern(self, p):
|
||||
newP = copy.deepcopy(p)
|
||||
eos.db.save(newP)
|
||||
return newP
|
||||
|
||||
def saveChanges(self, p):
|
||||
eos.db.save(p)
|
||||
|
||||
def importPatterns(self, text):
|
||||
lookup = {}
|
||||
current = self.getTargetResistsList()
|
||||
for pattern in current:
|
||||
lookup[pattern.name] = pattern
|
||||
try:
|
||||
imports = eos.types.TargetResists.importPatterns(text)
|
||||
for pattern in imports:
|
||||
if pattern.name in lookup:
|
||||
match = lookup[pattern.name]
|
||||
match.__dict__.update(pattern.__dict__)
|
||||
else:
|
||||
eos.db.save(pattern)
|
||||
eos.db.commit()
|
||||
except:
|
||||
pass
|
||||
|
||||
def exportPatterns(self):
|
||||
patterns = self.getTargetResistsList()
|
||||
for i in xrange(len(patterns) - 1, -1, -1):
|
||||
if patterns[i].name in ("None"):
|
||||
del patterns[i]
|
||||
|
||||
patterns.sort(key=lambda p: p.name)
|
||||
return eos.types.TargetResists.exportPatterns(*patterns)
|
||||
|
||||
Reference in New Issue
Block a user