Merge remote-tracking branch 'origin/development' into release/v2.5.0

This commit is contained in:
blitzmann
2018-10-08 12:40:23 -04:00
181 changed files with 6606 additions and 2836 deletions

View File

@@ -100,8 +100,8 @@ def DBInMemory():
import eos.db
# Output debug info to help us troubleshoot Travis
print((eos.db.saveddata_engine))
print((eos.db.gamedata_engine))
print(eos.db.saveddata_engine)
print(eos.db.gamedata_engine)
helper = {
'config': eos.config,

View File

@@ -1,7 +1,6 @@
import pytest
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
# noinspection PyShadowingNames

View File

@@ -1,7 +1,6 @@
import pytest
# noinspection PyPackageRequirements
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
# noinspection PyShadowingNames

View File

@@ -24,7 +24,7 @@ saveInRoot = False
# Version data
version = "2.4.0"
version = "2.5.0b1"
tag = "Stable"
expansionName = "YC120.8"
expansionVersion = "1.0"
@@ -229,20 +229,6 @@ def defLogging():
)
])
with logging_setup.threadbound():
# Output all stdout (print) messages as warnings
try:
sys.stdout = LoggerWriter(pyfalog.warning)
except:
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")
# Output all stderr (stacktrace) messages as critical
try:
sys.stderr = LoggerWriter(pyfalog.critical)
except:
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")
class LoggerWriter(object):
def __init__(self, level):

View File

@@ -38,7 +38,7 @@ call([
iscc,
os.path.join(os.getcwd(), "dist_assets", "win", "pyfa-setup.iss"),
"/dMyAppVersion=%s" % (config['version']),
"/dMyAppExpansion=%s" % (expansion),
"/dMyAppExpansion=%s" % expansion,
"/dMyAppDir=%s" % source,
"/dMyOutputDir=%s" % os.path.join(os.getcwd(), "dist"),
"/dMyOutputFile=%s" % fileName]) # stdout=devnull, stderr=devnull

View File

@@ -17,8 +17,8 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
from sqlalchemy.orm import relation, mapper, synonym, deferred
from sqlalchemy import Boolean, Column, Integer, String, Table
from sqlalchemy.orm import deferred, mapper, synonym
from eos.db import gamedata_meta
from eos.gamedata import Category

View File

@@ -17,15 +17,15 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table, Float
from sqlalchemy import Boolean, Column, Float, ForeignKey, Integer, String, Table
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import relation, mapper, synonym, deferred, backref
from sqlalchemy.orm import backref, deferred, mapper, relation, synonym
from sqlalchemy.orm.collections import attribute_mapped_collection
from eos.db.gamedata.effect import typeeffects_table
from eos.db import gamedata_meta
from eos.gamedata import Attribute, Effect, Group, Item, MetaType, Traits, DynamicItemItem, DynamicItem
from eos.db.gamedata.dynamicAttributes import dynamicApplicable_table, dynamic_table
from eos.db.gamedata.dynamicAttributes import dynamicApplicable_table
from eos.db.gamedata.effect import typeeffects_table
from eos.gamedata import Attribute, DynamicItem, Effect, Group, Item, MetaType, Traits
items_table = Table("invtypes", gamedata_meta,
Column("typeID", Integer, primary_key=True),

View File

@@ -17,16 +17,16 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy.orm import join, exc, aliased, joinedload, subqueryload
from sqlalchemy.sql import and_, or_, select
from sqlalchemy.inspection import inspect
from sqlalchemy.orm import aliased, exc, join
from sqlalchemy.sql import and_, or_, select
import eos.config
from eos.db import gamedata_session
from eos.db.gamedata.metaGroup import metatypes_table, items_table
from eos.db.gamedata.group import groups_table
from eos.db.gamedata.metaGroup import items_table, metatypes_table
from eos.db.util import processEager, processWhere
from eos.gamedata import AlphaClone, Attribute, Category, Group, Item, MarketGroup, MetaGroup, AttributeInfo, MetaData, DynamicItem
from eos.gamedata import AlphaClone, Attribute, AttributeInfo, Category, DynamicItem, Group, Item, MarketGroup, MetaData, MetaGroup
cache = {}
configVal = getattr(eos.config, "gamedataCache", None)
@@ -396,6 +396,21 @@ def getAbyssalTypes():
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
@cachedQuery(1, "itemID")
def getDynamicItem(itemID, eager=None):
try:
if isinstance(itemID, int):
if eager is None:
result = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == itemID).one()
else:
result = gamedata_session.query(DynamicItem).options(*processEager(eager)).filter(DynamicItem.ID == itemID).one()
else:
raise TypeError("Need integer as argument")
except exc.NoResultFound:
result = None
return result
def getRequiredFor(itemID, attrMapping):
Attribute1 = aliased(Attribute)
Attribute2 = aliased(Attribute)

View File

@@ -17,33 +17,32 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.sql import and_
from sqlalchemy.orm import relation, reconstructor, mapper, relationship
from sqlalchemy import ForeignKey, Column, Integer, String, Table, Boolean, DateTime
import datetime
from eos.db import saveddata_meta
from eos.db import saveddata_session
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Table
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import mapper, reconstructor, relation, relationship
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.sql import and_
from eos.db import saveddata_meta, saveddata_session
from eos.db.saveddata.cargo import cargo_table
from eos.db.saveddata.drone import drones_table
from eos.db.saveddata.fighter import fighters_table
from eos.db.saveddata.implant import fitImplants_table
from eos.db.saveddata.module import modules_table
from eos.effectHandlerHelpers import HandledModuleList, HandledImplantBoosterList, HandledProjectedModList, \
HandledDroneCargoList, HandledProjectedDroneList
from eos.saveddata.implant import Implant
from eos.saveddata.character import Character
from eos.saveddata.user import User
from eos.saveddata.fighter import Fighter
from eos.saveddata.fit import Fit as es_Fit, ImplantLocation
from eos.saveddata.drone import Drone
from eos.effectHandlerHelpers import HandledDroneCargoList, HandledImplantBoosterList, HandledModuleList, HandledProjectedDroneList, HandledProjectedModList
from eos.saveddata.booster import Booster
from eos.saveddata.module import Module
from eos.saveddata.cargo import Cargo
from eos.saveddata.character import Character
from eos.saveddata.damagePattern import DamagePattern
from eos.saveddata.drone import Drone
from eos.saveddata.fighter import Fighter
from eos.saveddata.fit import Fit as es_Fit
from eos.saveddata.implant import Implant
from eos.saveddata.module import Module
from eos.saveddata.targetResists import TargetResists
from eos.saveddata.user import User
fits_table = Table("fits", saveddata_meta,
Column("ID", Integer, primary_key=True),
@@ -132,13 +131,13 @@ class CommandFit(object):
)
es_Fit._Fit__projectedFits = association_proxy(
es_Fit.projectedFitDict = association_proxy(
"victimOf", # look at the victimOf association...
"source_fit", # .. and return the source fits
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
)
es_Fit._Fit__commandFits = association_proxy(
es_Fit.commandFitDict = association_proxy(
"boostedOf", # look at the boostedOf association...
"booster_fit", # .. and return the booster fit
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)

View File

@@ -17,10 +17,11 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime, Float
from sqlalchemy.orm import mapper
import datetime
from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, Table
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.saveddata.mutator import Mutator

View File

@@ -18,6 +18,7 @@
# ===============================================================================
from logbook import Logger
from utils.deprecated import deprecated
pyfalog = Logger(__name__)
@@ -113,6 +114,7 @@ class HandledList(list):
class HandledModuleList(HandledList):
def append(self, mod):
emptyPosition = float("Inf")
for i in range(len(self)):
@@ -130,6 +132,9 @@ class HandledModuleList(HandledList):
self.remove(mod)
return
self.appendIgnoreEmpty(mod)
def appendIgnoreEmpty(self, mod):
mod.position = len(self)
HandledList.append(self, mod)
if mod.isInvalid:
@@ -163,6 +168,7 @@ class HandledModuleList(HandledList):
mod.position = index
self[index] = mod
@deprecated
def freeSlot(self, slot):
for i in range(len(self)):
mod = self[i]
@@ -195,14 +201,20 @@ class HandledImplantBoosterList(HandledList):
self.remove(thing)
return
self.makeRoom(thing)
HandledList.append(self, thing)
def makeRoom(self, thing):
# if needed, remove booster that was occupying slot
oldObj = next((m for m in self if m.slot == thing.slot), None)
if oldObj:
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name, thing.item.name)
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name,
thing.item.name)
itemID = oldObj.itemID
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
self.remove(oldObj)
HandledList.append(self, thing)
return itemID
return None
class HandledSsoCharacterList(list):
@@ -228,12 +240,7 @@ class HandledProjectedModList(HandledList):
isSystemEffect = proj.item.group.name == "Effect Beacon"
if isSystemEffect:
# remove other system effects - only 1 per fit plz
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
if oldEffect:
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
self.remove(oldEffect)
self.makeRoom(proj)
HandledList.append(self, proj)
@@ -241,6 +248,16 @@ class HandledProjectedModList(HandledList):
if not proj.item.isType("projected") and not isSystemEffect:
self.remove(proj)
def makeRoom(self, proj):
# remove other system effects - only 1 per fit plz
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
if oldEffect:
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
self.remove(oldEffect)
return oldEffect.itemID
return None
class HandledProjectedDroneList(HandledDroneCargoList):
def append(self, proj):

View File

@@ -3,14 +3,14 @@
# Used by:
# Variations of module: Armor Command Burst I (2 of 2)
'''
"""
Some documentation:
When the fit is calculated, we gather up all the gang effects and stick them onto the fit. We don't run the actual
effect yet, only give the fit details so that it can run the effect at a later time. We need to do this so that we can
only run the strongest effect. When we are done, one of the last things that we do with the fit is to loop through those
bonuses and actually run the effect. To do this, we have a special argument passed into the effect handler that tells it
which warfareBuffID to run (shouldn't need this right now, but better safe than sorry)
'''
"""
type = "active", "gang"

View File

@@ -166,14 +166,14 @@ class Effect(EqBase):
t = t if isinstance(t, tuple) or t is None else (t,)
self.__type = t
except (ImportError) as e:
except ImportError as e:
# Effect probably doesn't exist, so create a dummy effect and flag it with a warning.
self.__handler = effectDummy
self.__runTime = "normal"
self.__activeByDefault = True
self.__type = None
pyfalog.debug("ImportError generating handler: {0}", e)
except (AttributeError) as e:
except AttributeError as e:
# Effect probably exists but there is an issue with it. Turn it into a dummy effect so we can continue, but flag it with an error.
self.__handler = effectDummy
self.__runTime = "normal"
@@ -476,6 +476,10 @@ class Item(EqBase):
def getAbyssalYypes(cls):
cls.ABYSSAL_TYPES = eos.db.getAbyssalTypes()
@property
def isCharge(self):
return self.category.name == "Charge"
def __repr__(self):
return "Item(ID={}, name={}) at {}".format(
self.ID, self.name, hex(id(self))
@@ -626,8 +630,8 @@ class Unit(EqBase):
def attributeIDCallback(v):
v = int(v)
if not v: # some attributes come through with a value of 0? See #1387
return "%d" % (v)
attribute = eos.db.getAttributeInfo(v, eager=("unit"))
return "%d" % v
attribute = eos.db.getAttributeInfo(v, eager="unit")
return "%s (%d)" % (attribute.name.capitalize(), v)
def TranslateValue(self, value):

View File

@@ -34,10 +34,10 @@ class ItemAttrShortcut(object):
return return_value or default
def getBaseAttrValue(self, key, default=0):
'''
"""
Gets base value in this order:
Mutated value > override value > attribute value
'''
"""
return_value = self.itemModifiedAttributes.getOriginal(key)
return return_value or default
@@ -382,7 +382,7 @@ class ModifiedAttributeDict(collections.MutableMapping):
if resist:
afflictPenal += "r"
self.__afflict(attributeName, "%s*" % (afflictPenal), multiplier, multiplier != 1)
self.__afflict(attributeName, "%s*" % afflictPenal, multiplier, multiplier != 1)
def boost(self, attributeName, boostFactor, skill=None, *args, **kwargs):
"""Boost value by some percentage"""

View File

@@ -53,6 +53,20 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
self.build()
standardAttackActive = False
for ability in self.abilities:
if ability.effect.isImplemented and ability.effect.handlerName == 'fighterabilityattackm':
# Activate "standard attack" if available
ability.active = True
standardAttackActive = True
else:
# Activate all other abilities (Neut, Web, etc) except propmods if no standard attack is active
if ability.effect.isImplemented and \
standardAttackActive is False and \
ability.effect.handlerName != 'fighterabilitymicrowarpdrive' and \
ability.effect.handlerName != 'fighterabilityevasivemaneuvers':
ability.active = True
@reconstructor
def init(self):
"""Initialize a fighter from the database and validate"""

View File

@@ -35,7 +35,6 @@ from eos.saveddata.character import Character
from eos.saveddata.citadel import Citadel
from eos.saveddata.module import Module, State, Slot, Hardpoint
from logbook import Logger
pyfalog = Logger(__name__)
@@ -258,11 +257,11 @@ class Fit(object):
def projectedFits(self):
# only in extreme edge cases will the fit be invalid, but to be sure do
# not return them.
return [fit for fit in list(self.__projectedFits.values()) if not fit.isInvalid]
return [fit for fit in list(self.projectedFitDict.values()) if not fit.isInvalid]
@property
def commandFits(self):
return [fit for fit in list(self.__commandFits.values()) if not fit.isInvalid]
return [fit for fit in list(self.commandFitDict.values()) if not fit.isInvalid]
def getProjectionInfo(self, fitID):
return self.projectedOnto.get(fitID, None)
@@ -911,6 +910,9 @@ class Fit(object):
Fill this fit's module slots with enough dummy slots so that all slots are used.
This is mostly for making the life of gui's easier.
GUI's can call fill() and then stop caring about empty slots completely.
todo: want to get rid of using this from the gui/commands, and instead make it a more built-in feature within
recalc. Figure out a way to keep track of any changes to slot layout and call this automatically
"""
if self.ship is None:
return
@@ -1603,7 +1605,7 @@ class Fit(object):
eos.db.saveddata_session.refresh(fit)
for fit in self.commandFits:
copy_ship.__commandFits[fit.ID] = fit
copy_ship.commandFitDict[fit.ID] = fit
forceUpdateSavedata(fit)
copyCommandInfo = fit.getCommandInfo(copy_ship.ID)
originalCommandInfo = fit.getCommandInfo(self.ID)
@@ -1611,7 +1613,7 @@ class Fit(object):
forceUpdateSavedata(fit)
for fit in self.projectedFits:
copy_ship.__projectedFits[fit.ID] = fit
copy_ship.projectedFitDict[fit.ID] = fit
forceUpdateSavedata(fit)
copyProjectionInfo = fit.getProjectionInfo(copy_ship.ID)
originalProjectionInfo = fit.getProjectionInfo(self.ID)

View File

@@ -17,16 +17,15 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from logbook import Logger
from copy import deepcopy
from sqlalchemy.orm import validates, reconstructor
from math import floor
from logbook import Logger
from sqlalchemy.orm import reconstructor, validates
import eos.db
from eos.effectHandlerHelpers import HandledItem, HandledCharge
from eos.effectHandlerHelpers import HandledCharge, HandledItem
from eos.enum import Enum
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
from eos.modifiedAttributeDict import ChargeAttrShortcut, ItemAttrShortcut, ModifiedAttributeDict
from eos.saveddata.citadel import Citadel
from eos.saveddata.mutator import Mutator
@@ -64,6 +63,30 @@ class Slot(Enum):
FS_HEAVY = 15
ProjectedMap = {
State.OVERHEATED: State.ACTIVE,
State.ACTIVE: State.OFFLINE,
State.OFFLINE: State.ACTIVE,
State.ONLINE: State.ACTIVE # Just in case
}
# Old state : New State
LocalMap = {
State.OVERHEATED: State.ACTIVE,
State.ACTIVE: State.ONLINE,
State.OFFLINE: State.ONLINE,
State.ONLINE: State.ACTIVE
}
# For system effects. They should only ever be online or offline
ProjectedSystem = {
State.OFFLINE: State.ONLINE,
State.ONLINE: State.OFFLINE
}
class Hardpoint(Enum):
NONE = 0
MISSILE = 1
@@ -626,7 +649,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
for i in range(5):
itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i), None)
if itemChargeGroup is not None:
g = eos.db.getGroup(int(itemChargeGroup), eager=("items.attributes"))
g = eos.db.getGroup(int(itemChargeGroup), eager="items.attributes")
if g is None:
continue
for singleItem in g.items:
@@ -832,6 +855,36 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
else:
return 0
@staticmethod
def getProposedState(mod, click, proposedState=None):
# todo: instead of passing in module, make this a instanced function.
pyfalog.debug("Get proposed state for module.")
if mod.slot == Slot.SUBSYSTEM or mod.isEmpty:
return State.ONLINE
if mod.slot == Slot.SYSTEM:
transitionMap = ProjectedSystem
else:
transitionMap = ProjectedMap if mod.projected else LocalMap
currState = mod.state
if proposedState is not None:
state = proposedState
elif click == "right":
state = State.OVERHEATED
elif click == "ctrl":
state = State.OFFLINE
else:
state = transitionMap[currState]
if not mod.isValidState(state):
state = -1
if mod.isValidState(state):
return state
else:
return currState
def __deepcopy__(self, memo):
item = self.item
if item is None:

View File

@@ -131,7 +131,7 @@ class Ship(ItemAttrShortcut, HandledItem):
return None
items = []
g = eos.db.getGroup("Ship Modifiers", eager=("items.attributes"))
g = eos.db.getGroup("Ship Modifiers", eager="items.attributes")
for item in g.items:
# Rely on name detection because race is not reliable
if item.name.lower().startswith(self.item.name.lower()):

View File

@@ -1,10 +1,13 @@
import copy
import wx
import math
from gui.utils import color as color_utils
from gui.utils import draw, anim_effects
from service.fit import Fit
from gui.utils import anim_effects
import math
import wx
from gui.utils import anim_effects
# todo: clean class up. Took from pyfa gauge, has a bunch of extra shit we don't need

View File

@@ -19,15 +19,14 @@
import io
import os.path
import zipfile
from collections import OrderedDict
# noinspection PyPackageRequirements
import wx
from logbook import Logger
import config
from logbook import Logger
logging = Logger(__name__)

View File

@@ -26,6 +26,7 @@ from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
import gui.fitCommands as cmd
class BoosterViewDrop(wx.DropTarget):
@@ -134,9 +135,7 @@ class BoosterView(d.Display):
event.Skip()
return
trigger = sFit.addBooster(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
if self.mainFrame.command.Submit(cmd.GuiAddBoosterCommand(fitID, event.itemID)):
self.mainFrame.additionsPane.select("Boosters")
event.Skip()
@@ -150,9 +149,7 @@ class BoosterView(d.Display):
def removeBooster(self, booster):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.removeBooster(fitID, self.origional.index(booster))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand(fitID, self.origional.index(booster)))
def click(self, event):
event.Skip()
@@ -161,9 +158,7 @@ class BoosterView(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.toggleBooster(fitID, row)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiToggleBoosterCommand(fitID, row))
def scheduleMenu(self, event):
event.Skip()

View File

@@ -26,6 +26,7 @@ import gui.globalEvents as GE
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
from service.market import Market
import gui.fitCommands as cmd
class CargoViewDrop(wx.DropTarget):
@@ -80,9 +81,7 @@ class CargoView(d.Display):
if data[0] == "fitting":
self.swapModule(x, y, int(data[1]))
elif data[0] == "market":
sFit = Fit.getInstance()
sFit.addCargo(self.mainFrame.getActiveFit(), int(data[1]), 1)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(self.mainFrame.getActiveFit(), int(data[1])))
def startDrag(self, event):
row = event.GetIndex()
@@ -127,18 +126,14 @@ class CargoView(d.Display):
if not result:
return
if dstRow != -1: # we're swapping with cargo
if mstate.cmdDown: # if copying, append to cargo
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID if not module.item.isAbyssal else module.baseItemID)
else: # else, move / swap
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.position, dstRow)
else: # dragging to blank spot, append
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID if not module.item.isAbyssal else module.baseItemID)
cargoPos = dstRow if dstRow > -1 else None
if not mstate.cmdDown: # if not copying, remove module
sFit.removeModule(self.mainFrame.getActiveFit(), module.position)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="moddel", typeID=module.item.ID))
self.mainFrame.command.Submit(cmd.GuiModuleToCargoCommand(
self.mainFrame.getActiveFit(),
module.modPosition,
cargoPos,
mstate.cmdDown
))
def fitChanged(self, event):
sFit = Fit.getInstance()

View File

@@ -30,6 +30,7 @@ from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
import gui.fitCommands as cmd
class DummyItem(object):
@@ -100,21 +101,16 @@ class CommandView(d.Display):
keycode = event.GetKeyCode()
if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE:
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
row = self.GetFirstSelected()
if row != -1:
sFit.removeCommand(fitID, self.get(row))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveCommandCommand(fitID, self.get(row).ID))
def handleDrag(self, type, fitID):
# Those are drags coming from pyfa sources, NOT builtin wx drags
if type == "fit":
activeFit = self.mainFrame.getActiveFit()
if activeFit:
sFit = Fit.getInstance()
draggedFit = sFit.getFit(fitID)
sFit.addCommandFit(activeFit, draggedFit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
self.mainFrame.command.Submit(cmd.GuiAddCommandCommand(activeFit, fitID))
def startDrag(self, event):
row = event.GetIndex()
@@ -190,9 +186,7 @@ class CommandView(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.toggleCommandFit(fitID, item)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiToggleCommandCommand(fitID, item.ID))
def scheduleMenu(self, event):
event.Skip()
@@ -224,8 +218,6 @@ class CommandView(d.Display):
col = self.getColumn(event.Position)
if col != self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
thing = self.get(row)
if thing: # thing doesn't exist if it's the dummy value
sFit.removeCommand(fitID, thing)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveCommandCommand(fitID, thing.ID))

View File

@@ -29,6 +29,7 @@ from gui.contextMenu import ContextMenu
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
from service.market import Market
import gui.fitCommands as cmd
class DroneViewDrop(wx.DropTarget):
@@ -144,10 +145,12 @@ class DroneView(Display):
data[1] is typeID or index of data we want to manipulate
"""
if data[0] == "drone": # we want to merge drones
srcRow = int(data[1])
dstRow, _ = self.HitTest((x, y))
if srcRow != -1 and dstRow != -1:
self._merge(srcRow, dstRow)
pass
# remove merge functionality, if people complain in the next while, can add it back
# srcRow = int(data[1])
# dstRow, _ = self.HitTest((x, y))
# if srcRow != -1 and dstRow != -1:
# self._merge(srcRow, dstRow)
elif data[0] == "market":
wx.PostEvent(self.mainFrame, ItemSelected(itemID=int(data[1])))
@@ -213,9 +216,7 @@ class DroneView(Display):
event.Skip()
return
trigger = sFit.addDrone(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
if self.mainFrame.command.Submit(cmd.GuiAddDroneCommand(fitID, event.itemID)):
self.mainFrame.additionsPane.select("Drones")
event.Skip()
@@ -230,9 +231,7 @@ class DroneView(Display):
def removeDrone(self, drone):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.removeDrone(fitID, self.original.index(drone))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveDroneCommand(fitID, self.original.index(drone)))
def click(self, event):
event.Skip()
@@ -241,10 +240,8 @@ class DroneView(Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
drone = self.drones[row]
sFit.toggleDrone(fitID, self.original.index(drone))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiToggleDroneCommand(fitID, self.original.index(drone)))
def scheduleMenu(self, event):
event.Skip()

View File

@@ -30,6 +30,7 @@ from gui.contextMenu import ContextMenu
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
from service.market import Market
import gui.fitCommands as cmd
class FighterViewDrop(wx.DropTarget):
@@ -269,11 +270,9 @@ class FighterDisplay(d.Display):
event.Skip()
def addItem(self, event):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
trigger = sFit.addFighter(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
if self.mainFrame.command.Submit(cmd.GuiAddFighterCommand(fitID, event.itemID)):
self.mainFrame.additionsPane.select("Fighters")
event.Skip()
@@ -288,9 +287,7 @@ class FighterDisplay(d.Display):
def removeFighter(self, fighter):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.removeFighter(fitID, self.original.index(fighter))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveFighterCommand(fitID, self.original.index(fighter)))
def click(self, event):
event.Skip()
@@ -299,10 +296,8 @@ class FighterDisplay(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
fighter = self.fighters[row]
sFit.toggleFighter(fitID, self.original.index(fighter))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiToggleFighterCommand(fitID, self.original.index(fighter)))
def scheduleMenu(self, event):
event.Skip()

View File

@@ -28,6 +28,7 @@ import gui.globalEvents as GE
from eos.saveddata.fit import ImplantLocation
from service.fit import Fit
from service.market import Market
import gui.fitCommands as cmd
class ImplantView(wx.Panel):
@@ -155,9 +156,7 @@ class ImplantDisplay(d.Display):
event.Skip()
return
trigger = sFit.addImplant(fitID, event.itemID)
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
if self.mainFrame.command.Submit(cmd.GuiAddImplantCommand(fitID, event.itemID)):
self.mainFrame.additionsPane.select("Implants")
event.Skip()
@@ -175,10 +174,7 @@ class ImplantDisplay(d.Display):
def removeImplant(self, implant):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.removeImplant(fitID, self.original.index(implant))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand(fitID, self.original.index(implant)))
def click(self, event):
event.Skip()
@@ -192,9 +188,7 @@ class ImplantDisplay(d.Display):
col = self.getColumn(event.Position)
if col == self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
sFit.toggleImplant(fitID, row)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiToggleImplantCommand(fitID, row))
def scheduleMenu(self, event):
event.Skip()

View File

@@ -32,6 +32,7 @@ from gui.contextMenu import ContextMenu
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
from service.market import Market
import gui.fitCommands as cmd
pyfalog = Logger(__name__)
@@ -100,21 +101,26 @@ class ProjectedView(d.Display):
data[1] is typeID or index of data we want to manipulate
"""
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(self.mainFrame.getActiveFit())
if data[0] == "projected":
# if source is coming from projected, we are trying to combine drones.
self.mergeDrones(x, y, int(data[1]))
pass
# removing merge functionality - if people complain about it, can add it back as a command
# self.mergeDrones(x, y, int(data[1]))
elif data[0] == "fitting":
dstRow, _ = self.HitTest((x, y))
# Gather module information to get position
module = fit.modules[int(data[1])]
sFit.project(fit.ID, module)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(fitID, module.itemID, 'item'))
# sFit.project(fit.ID, module)
# wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
elif data[0] == "market":
sFit = Fit.getInstance()
sFit.project(fit.ID, int(data[1]))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
# sFit = Fit.getInstance()
self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(fitID, int(data[1]), 'item'))
# sFit.project(fit.ID, int(data[1]))
# wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
def kbEvent(self, event):
keycode = event.GetKeyCode()
@@ -131,10 +137,7 @@ class ProjectedView(d.Display):
if type == "fit":
activeFit = self.mainFrame.getActiveFit()
if activeFit:
sFit = Fit.getInstance()
draggedFit = sFit.getFit(fitID)
sFit.project(activeFit, draggedFit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(activeFit, fitID, 'fit'))
def startDrag(self, event):
row = event.GetIndex()
@@ -319,8 +322,6 @@ class ProjectedView(d.Display):
col = self.getColumn(event.Position)
if col != self.getColIndex(State):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
thing = self.get(row)
if thing: # thing doesn't exist if it's the dummy value
sFit.removeProjected(fitID, thing)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveProjectedCommand(fitID, thing))

View File

@@ -6,9 +6,11 @@ import gui.globalEvents as GE
import wx
import re
from service.fit import Fit
from eos.saveddata.drone import Drone
from eos.saveddata.cargo import Cargo as es_Cargo
from eos.saveddata.fighter import Fighter as es_Fighter
from service.settings import ContextMenuSettings
import gui.fitCommands as cmd
class ChangeAmount(ContextMenu):
@@ -20,7 +22,7 @@ class ChangeAmount(ContextMenu):
if not self.settings.get('amount'):
return False
return srcContext in ("cargoItem", "projectedFit", "fighterItem", "projectedFighter")
return srcContext in ("droneItem", "projectedDrone", "cargoItem", "projectedFit", "fighterItem", "projectedFighter")
def getText(self, itmContext, selection):
return u"Change {0} Quantity".format(itmContext)
@@ -29,7 +31,7 @@ class ChangeAmount(ContextMenu):
thing = selection[0]
mainFrame = gui.mainFrame.MainFrame.getInstance()
fitID = mainFrame.getActiveFit()
srcContext = fullContext[0]
if isinstance(thing, es_Fit):
value = thing.getProjectionInfo(fitID).amount
else:
@@ -42,14 +44,23 @@ class ChangeAmount(ContextMenu):
return
sFit = Fit.getInstance()
fit = sFit.getFit(fitID)
cleanInput = re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip())
if isinstance(thing, es_Cargo):
sFit.addCargo(fitID, thing.item.ID, int(float(cleanInput)), replace=True)
self.mainFrame.command.Submit(cmd.GuiChangeCargoQty(fitID, fit.cargo.index(thing), int(float(cleanInput))))
return # no need for post event here
elif isinstance(thing, Drone):
if srcContext == "droneItem":
self.mainFrame.command.Submit(cmd.GuiChangeDroneQty(fitID, fit.drones.index(thing), int(float(cleanInput))))
else:
self.mainFrame.command.Submit(cmd.GuiChangeProjectedDroneQty(fitID, fit.projectedDrones.index(thing), int(float(cleanInput))))
elif isinstance(thing, es_Fit):
sFit.changeAmount(fitID, thing, int(float(cleanInput)))
self.mainFrame.command.Submit(cmd.GuiChangeProjectedFitQty(fitID, thing.ID, int(float(cleanInput))))
return
elif isinstance(thing, es_Fighter):
sFit.changeActiveFighters(fitID, thing, int(float(cleanInput)))
self.mainFrame.command.Submit(cmd.GuiChangeFighterQty(fitID, fit.fighters.index(thing), int(float(cleanInput))))
return
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))

View File

@@ -16,7 +16,7 @@ class BoosterSideEffect(ContextMenu):
# if not self.settings.get('fighterAbilities'):
# return False
if self.mainFrame.getActiveFit() is None or srcContext not in ("boosterItem"):
if self.mainFrame.getActiveFit() is None or srcContext not in "boosterItem":
return False
self.booster = selection[0]
@@ -50,7 +50,7 @@ class BoosterSideEffect(ContextMenu):
if not effect.effect.isImplemented:
continue
menuItem = self.addEffect(rootMenu if msw else sub, effect)
sub.AppendItem(menuItem)
sub.Append(menuItem)
menuItem.Check(effect.active)
return sub

View File

@@ -1,8 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.fitCommands as cmd
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
from service.settings import ContextMenuSettings
@@ -32,13 +31,12 @@ class Cargo(ContextMenu):
return "Add {0} to Cargo".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
typeID = int(selection[0].ID)
sFit.addCargo(fitID, typeID)
self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(fitID, typeID))
self.mainFrame.additionsPane.select("Cargo")
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
Cargo.register()

View File

@@ -1,9 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.fitCommands as cmd
import gui.mainFrame
import gui.globalEvents as GE
import wx
from gui.contextMenu import ContextMenu
from service.settings import ContextMenuSettings
from service.fit import Fit
class CargoAmmo(ContextMenu):
@@ -28,13 +26,10 @@ class CargoAmmo(ContextMenu):
return "Add {0} to Cargo (x1000)".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
typeID = int(selection[0].ID)
sFit.addCargo(fitID, typeID, 1000)
self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(fitID, typeID, 1000))
self.mainFrame.additionsPane.select("Cargo")
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
CargoAmmo.register()

View File

@@ -1,11 +1,11 @@
# noinspection PyPackageRequirements
import wx
import gui.fitCommands as cmd
import gui.mainFrame
from gui.contextMenu import ContextMenu
from service.fit import Fit
from service.market import Market
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
from service.settings import ContextMenuSettings
@@ -25,7 +25,7 @@ class CommandFits(ContextMenu):
if evt is not None:
ids = getattr(evt, 'typeID')
if not isinstance(ids, set):
ids = set([ids])
ids = {ids}
if evt is None or not ids.isdisjoint(cls.commandTypeIDs):
# we are adding or removing an item that defines a command fit. Need to refresh fit list
@@ -97,11 +97,8 @@ class CommandFits(ContextMenu):
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.addCommandFit(fitID, fit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiAddCommandCommand(fitID, fit.ID))
CommandFits.populateFits(None)

View File

@@ -1,8 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.fitCommands as cmd
import gui.mainFrame
from gui.contextMenu import ContextMenu
# noinspection PyPackageRequirements
import wx
import gui.globalEvents as GE
from service.fit import Fit
from service.settings import ContextMenuSettings
@@ -27,9 +26,7 @@ class ItemRemove(ContextMenu):
fit = sFit.getFit(fitID)
idx = fit.drones.index(selection[0])
sFit.removeDrone(fitID, idx, numDronesToRemove=fit.drones[idx].amount)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiRemoveDroneCommand(fitID, idx, fit.drones[idx].amount))
ItemRemove.register()

View File

@@ -5,6 +5,7 @@ from service.fit import Fit
# noinspection PyPackageRequirements
import wx
from service.settings import ContextMenuSettings
import re
class DroneSplit(ContextMenu):
@@ -23,14 +24,93 @@ class DroneSplit(ContextMenu):
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
dlg = DroneSpinner(self.mainFrame, selection[0], srcContext)
dlg.ShowModal()
dlg.Destroy()
drone = selection[0]
dlg = DroneStackSplit(self.mainFrame, drone.amount)
if dlg.ShowModal() == wx.ID_OK:
if dlg.input.GetLineText(0).strip() == '':
return
sFit = Fit.getInstance()
cleanInput = re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip())
fitID = self.mainFrame.getActiveFit()
if srcContext == "droneItem":
sFit.splitDroneStack(fitID, drone, int(float(cleanInput)))
else:
sFit.splitProjectedDroneStack(fitID, drone, int(float(cleanInput)))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
# if isinstance(thing, es_Cargo):
# self.mainFrame.command.Submit(
# cmd.GuiAddCargoCommand(fitID, thing.item.ID, int(float(cleanInput)), replace=True))
# return # no need for post event here
# elif isinstance(thing, es_Fit):
# sFit.changeAmount(fitID, thing, int(float(cleanInput)))
# elif isinstance(thing, es_Fighter):
# sFit.changeActiveFighters(fitID, thing, int(float(cleanInput)))
#
# wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
#
# dlg = DroneSpinner(self.mainFrame, selection[0], srcContext)
# dlg.ShowModal()
# dlg.Destroy()
DroneSplit.register()
class DroneStackSplit(wx.Dialog):
def __init__(self, parent, value):
wx.Dialog.__init__(self, parent, title="Split Drone Stack")
self.SetMinSize((346, 156))
bSizer1 = wx.BoxSizer(wx.VERTICAL)
bSizer2 = wx.BoxSizer(wx.VERTICAL)
text = wx.StaticText(self, wx.ID_ANY, "New Amount:")
bSizer2.Add(text, 0)
bSizer1.Add(bSizer2, 0, wx.ALL, 10)
self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
self.input.SetValue(str(value))
self.input.SelectAll()
bSizer1.Add(self.input, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 15)
bSizer3 = wx.BoxSizer(wx.VERTICAL)
bSizer3.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.BOTTOM | wx.EXPAND, 15)
bSizer3.Add(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND)
bSizer1.Add(bSizer3, 0, wx.ALL | wx.EXPAND, 10)
self.input.SetFocus()
self.input.Bind(wx.EVT_CHAR, self.onChar)
self.input.Bind(wx.EVT_TEXT_ENTER, self.processEnter)
self.SetSizer(bSizer1)
self.CenterOnParent()
self.Fit()
def processEnter(self, evt):
self.EndModal(wx.ID_OK)
# checks to make sure it's valid number
@staticmethod
def onChar(event):
key = event.GetKeyCode()
acceptable_characters = "1234567890"
acceptable_keycode = [3, 22, 13, 8, 127] # modifiers like delete, copy, paste
if key in acceptable_keycode or key >= 255 or (key < 255 and chr(key) in acceptable_characters):
event.Skip()
return
else:
return False
class DroneSpinner(wx.Dialog):
def __init__(self, parent, drone, context):
wx.Dialog.__init__(self, parent, title="Select Amount", size=wx.Size(220, 60))

View File

@@ -5,6 +5,7 @@ import wx
import gui.globalEvents as GE
from service.fit import Fit
from service.settings import ContextMenuSettings
import gui.fitCommands as cmd
class ItemRemove(ContextMenu):
@@ -35,26 +36,33 @@ class ItemRemove(ContextMenu):
fit = sFit.getFit(fitID)
if srcContext == "fittingModule":
for module in selection:
if module is not None:
sFit.removeModule(fitID, fit.modules.index(module))
modules = [module for module in selection if module is not None]
self.mainFrame.command.Submit(cmd.GuiModuleRemoveCommand(fitID, modules))
return # the command takes care of the PostEvent
elif srcContext in ("fittingCharge", "projectedCharge"):
sFit.setAmmo(fitID, None, selection)
self.mainFrame.command.Submit(cmd.GuiModuleAddChargeCommand(fitID, None, selection))
return
elif srcContext == "droneItem":
sFit.removeDrone(fitID, fit.drones.index(selection[0]))
self.mainFrame.command.Submit(cmd.GuiRemoveDroneCommand(fitID, fit.drones.index(selection[0])))
return
elif srcContext == "fighterItem":
sFit.removeFighter(fitID, fit.fighters.index(selection[0]))
self.mainFrame.command.Submit(cmd.GuiRemoveFighterCommand(fitID, fit.fighters.index(selection[0])))
return # the command takes care of the PostEvent
elif srcContext == "implantItem":
sFit.removeImplant(fitID, fit.implants.index(selection[0]))
self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand(fitID, fit.implants.index(selection[0])))
return # the command takes care of the PostEvent
elif srcContext == "boosterItem":
sFit.removeBooster(fitID, fit.boosters.index(selection[0]))
self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand(fitID, fit.boosters.index(selection[0])))
return # the command takes care of the PostEvent
elif srcContext == "cargoItem":
sFit.removeCargo(fitID, fit.cargo.index(selection[0]))
self.mainFrame.command.Submit(cmd.GuiRemoveCargoCommand(fitID, selection[0].itemID))
return # the command takes care of the PostEvent
elif srcContext in ("projectedFit", "projectedModule", "projectedDrone", "projectedFighter"):
sFit.removeProjected(fitID, selection[0])
self.mainFrame.command.Submit(cmd.GuiRemoveProjectedCommand(fitID, selection[0]))
return # the command takes care of the PostEvent
elif srcContext == "commandFit":
sFit.removeCommand(fitID, selection[0])
self.mainFrame.command.Submit(cmd.GuiRemoveCommandCommand(fitID, selection[0].ID))
return # the command takes care of the PostEvent
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))

View File

@@ -3,18 +3,11 @@
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
from service.market import Market
import gui.fitCommands as cmd
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
from service.market import Market
from service.settings import ContextMenuSettings
from eos.saveddata.booster import Booster
from eos.saveddata.module import Module
from eos.saveddata.drone import Drone
from eos.saveddata.fighter import Fighter
from eos.saveddata.implant import Implant
from eos.saveddata.cargo import Cargo
class MetaSwap(ContextMenu):
@@ -91,7 +84,7 @@ class MetaSwap(ContextMenu):
# Sort items by metalevel, and group within that metalevel
items = list(self.variations)
print(context)
if "implantItem" in context:
# sort implants based on name
items.sort(key=lambda x: x.name)
@@ -122,79 +115,35 @@ class MetaSwap(ContextMenu):
id = ContextMenu.nextID()
mitem = wx.MenuItem(rootMenu, id, item.name)
bindmenu.Bind(wx.EVT_MENU, self.handleModule, mitem)
self.moduleLookup[id] = item
self.moduleLookup[id] = item, context
m.Append(mitem)
return m
def handleModule(self, event):
item = self.moduleLookup.get(event.Id, None)
item, context = self.moduleLookup.get(event.Id, None)
if item is None:
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
for selected_item in self.selection:
if isinstance(selected_item, Module):
pos = fit.modules.index(selected_item)
sFit.changeModule(fitID, pos, item.ID)
self.mainFrame.command.Submit(cmd.GuiMetaSwapCommand(fitID, context, item.ID, self.selection))
elif isinstance(selected_item, Drone):
drone_count = None
# for selected_item in self.selection:
for idx, drone_stack in enumerate(fit.drones):
if drone_stack is selected_item:
drone_count = drone_stack.amount
sFit.removeDrone(fitID, idx, drone_count, False)
break
if drone_count:
sFit.addDrone(fitID, item.ID, drone_count, True)
elif isinstance(selected_item, Fighter):
fighter_count = None
for idx, fighter_stack in enumerate(fit.fighters):
# Right now fighters always will have max stack size.
# Including this for future improvement, so if adjustable
# fighter stacks get added we're ready for it.
if fighter_stack is selected_item:
if fighter_stack.amount > 0:
fighter_count = fighter_stack.amount
elif fighter_stack.amount == -1:
fighter_count = fighter_stack.amountActive
else:
fighter_count.amount = 0
sFit.removeFighter(fitID, idx, False)
break
sFit.addFighter(fitID, item.ID, True)
elif isinstance(selected_item, Booster):
for idx, booster_stack in enumerate(fit.boosters):
if booster_stack is selected_item:
sFit.removeBooster(fitID, idx, False)
sFit.addBooster(fitID, item.ID, True)
break
elif isinstance(selected_item, Implant):
for idx, implant_stack in enumerate(fit.implants):
if implant_stack is selected_item:
sFit.removeImplant(fitID, idx, False)
sFit.addImplant(fitID, item.ID, True)
break
elif isinstance(selected_item, Cargo):
for idx, cargo_stack in enumerate(fit.cargo):
if cargo_stack is selected_item:
sFit.removeCargo(fitID, idx)
sFit.addCargo(fitID, item.ID, cargo_stack.amount, True)
break
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
#
# elif isinstance(selected_item, Drone):
# drone_count = None
#
# for idx, drone_stack in enumerate(fit.drones):
# if drone_stack is selected_item:
# drone_count = drone_stack.amount
# sFit.removeDrone(fitID, idx, drone_count, False)
# break
#
# if drone_count:
# sFit.addDrone(fitID, item.ID, drone_count, True)
MetaSwap.register()

View File

@@ -3,13 +3,12 @@
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
from service.market import Market
from eos.saveddata.module import Hardpoint
import gui.fitCommands as cmd
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
from eos.saveddata.module import Hardpoint
from gui.bitmap_loader import BitmapLoader
from gui.contextMenu import ContextMenu
from service.market import Market
from service.settings import ContextMenuSettings
@@ -228,11 +227,8 @@ class ModuleAmmoPicker(ContextMenu):
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setAmmo(fitID, charge.ID if charge is not None else None, self.modules)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiModuleAddChargeCommand(fitID, charge.ID if charge is not None else None, self.modules))
ModuleAmmoPicker.register()

View File

@@ -1,11 +1,9 @@
# -*- coding: utf-8 -*-
import gui.fitCommands as cmd
import gui.mainFrame
# noinspection PyPackageRequirements
import wx
import gui.globalEvents as GE
from gui.builtinContextMenus.moduleAmmoPicker import ModuleAmmoPicker
from eos.db.saveddata.queries import getFit as db_getFit
from service.fit import Fit
# noinspection PyPackageRequirements
from gui.builtinContextMenus.moduleAmmoPicker import ModuleAmmoPicker
from service.settings import ContextMenuSettings
@@ -28,7 +26,6 @@ class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = db_getFit(fitID)
@@ -40,8 +37,7 @@ class ModuleGlobalAmmoPicker(ModuleAmmoPicker):
if mod.itemID == selectedModule.itemID:
allModules.append(mod)
sFit.setAmmo(fitID, charge.ID if charge is not None else None, allModules)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiModuleAddChargeCommand(fitID, charge.ID if charge is not None else None, allModules))
def display(self, srcContext, selection):
if not self.settings.get('moduleGlobalAmmoPicker'):

View File

@@ -18,7 +18,7 @@ class MutaplasmidCM(ContextMenu):
# if not self.settings.get('ammoPattern'):
# return False
if srcContext not in ("fittingModule") or self.mainFrame.getActiveFit() is None:
if srcContext not in "fittingModule" or self.mainFrame.getActiveFit() is None:
return False
mod = selection[0]

View File

@@ -1,8 +1,7 @@
from gui.contextMenu import ContextMenu
import gui.fitCommands as cmd
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
from service.settings import ContextMenuSettings
@@ -33,12 +32,13 @@ class Project(ContextMenu):
return "Project {0} onto Fit".format(itmContext)
def activate(self, fullContext, selection, i):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
trigger = sFit.project(fitID, selection[0])
if trigger:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.additionsPane.select("Projected")
self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(fitID, selection[0].ID, 'item'))
# trigger = sFit.project(fitID, selection[0])
# if trigger:
# wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
# self.mainFrame.additionsPane.select("Projected")
Project.register()

View File

@@ -3,11 +3,11 @@
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
import gui.fitCommands as cmd
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
from gui.builtinViews.emptyView import BlankPage
from gui.contextMenu import ContextMenu
from service.fit import Fit
class TabbedFits(ContextMenu):
@@ -51,17 +51,14 @@ class TabbedFits(ContextMenu):
return m
def handleSelection(self, event):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = self.fitLookup[event.Id]
if self.context == 'commandView':
sFit.addCommandFit(fitID, fit)
self.mainFrame.command.Submit(cmd.GuiAddCommandCommand(fitID, fit.ID))
elif self.context == 'projected':
sFit.project(fitID, fit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(fitID, fit.ID, 'fit'))
TabbedFits.register()

View File

@@ -1,9 +1,9 @@
# noinspection PyPackageRequirements
import wx
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
import gui.fitCommands as cmd
import gui.mainFrame
from gui.contextMenu import ContextMenu
from service.fit import Fit
from service.settings import ContextMenuSettings
@@ -60,10 +60,8 @@ class TacticalMode(ContextMenu):
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.setMode(fitID, self.modeIds[event.Id])
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiSetModeCommand(fitID, self.modeIds[event.Id]))
TacticalMode.register()

View File

@@ -1,13 +1,14 @@
from gui.contextMenu import ContextMenu
import gui.mainFrame
import gui.globalEvents as GE
import re
from itertools import chain
# noinspection PyPackageRequirements
import wx
import gui.fitCommands as cmd
import gui.mainFrame
from gui.contextMenu import ContextMenu
from service.market import Market
from service.fit import Fit
from service.settings import ContextMenuSettings
from itertools import chain
import re
class WhProjector(ContextMenu):
@@ -87,10 +88,8 @@ class WhProjector(ContextMenu):
event.Skip()
return
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.project(fitID, swObj)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(fitID, swObj.ID, 'item'))
def buildMenu(self, data, local_menu, rootMenu, msw):
for swType in sorted(data):

View File

@@ -1,9 +1,7 @@
import wx
import wx.lib.newevent
from gui.attribute_gauge import AttributeGauge
import eos
import eos.db
from gui.attribute_gauge import AttributeGauge
_ValueChanged, EVT_VALUE_CHANGED = wx.lib.newevent.NewEvent()

View File

@@ -1,18 +1,16 @@
# noinspection PyPackageRequirements
import wx
from service.fit import Fit
from .attributeSlider import AttributeSlider, EVT_VALUE_CHANGED
import gui.mainFrame
from gui.contextMenu import ContextMenu
from .itemAttributes import ItemParams
from gui.bitmap_loader import BitmapLoader
import gui.globalEvents as GE
import random
import wx
from logbook import Logger
import gui.globalEvents as GE
import gui.mainFrame
from gui.bitmap_loader import BitmapLoader
from service.fit import Fit
from .attributeSlider import AttributeSlider, EVT_VALUE_CHANGED
from .itemAttributes import ItemParams
pyfalog = Logger(__name__)

View File

@@ -1,16 +1,13 @@
import wx
import config
import gui.builtinMarketBrowser.pfSearchBox as SBox
from gui.contextMenu import ContextMenu
from gui.display import Display
from service.attribute import Attribute
from service.fit import Fit
from gui.utils.staticHelpers import DragDropHelper
from logbook import Logger
from gui.builtinMarketBrowser.events import RECENTLY_USED_MODULES, MAX_RECENTLY_USED_MODULES, ItemSelected
import gui.builtinMarketBrowser.pfSearchBox as SBox
from gui.builtinMarketBrowser.events import ItemSelected, MAX_RECENTLY_USED_MODULES, RECENTLY_USED_MODULES
from gui.contextMenu import ContextMenu
from gui.display import Display
from gui.utils.staticHelpers import DragDropHelper
from service.attribute import Attribute
from service.fit import Fit
pyfalog = Logger(__name__)

View File

@@ -1,17 +1,13 @@
# noinspection PyPackageRequirements
import wx
from gui.preferenceView import PreferenceView
from gui.bitmap_loader import BitmapLoader
import gui.mainFrame
from gui.bitmap_loader import BitmapLoader
from gui.preferenceView import PreferenceView
from service.settings import EsiSettings
# noinspection PyPackageRequirements
from wx.lib.intctrl import IntCtrl
from service.esi import Esi
# noinspection PyPackageRequirements
class PFEsiPref(PreferenceView):

View File

@@ -3,12 +3,9 @@
# noinspection PyPackageRequirements
import wx
import copy
from gui.preferenceView import PreferenceView
from gui.bitmap_loader import BitmapLoader
from gui.utils.color import CalculateTransition
import gui.utils.draw as drawUtils
from gui.preferenceView import PreferenceView
###########################################################################

View File

@@ -2,21 +2,21 @@
import re
import time
import config
import wx
from logbook import Logger
import config
import gui.builtinShipBrowser.sfBrowserItem as SFItem
import gui.globalEvents as GE
import gui.fitCommands as cmd
import gui.mainFrame
import gui.utils.color as colorUtils
import gui.utils.draw as drawUtils
import gui.utils.fonts as fonts
from .events import ImportSelected, SearchSelected, FitSelected, BoosterListUpdated, Stage3Selected, FitRenamed, FitRemoved
from gui.bitmap_loader import BitmapLoader
from gui.builtinShipBrowser.pfBitmapFrame import PFBitmapFrame
from service.fit import Fit
from .events import BoosterListUpdated, FitRemoved, FitSelected, ImportSelected, SearchSelected, Stage3Selected
pyfalog = Logger(__name__)
@@ -183,18 +183,14 @@ class FitItem(SFItem.SFBrowserItem):
if activeFit:
sFit = Fit.getInstance()
projectedFit = sFit.getFit(self.fitID)
sFit.project(activeFit, projectedFit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
self.mainFrame.additionsPane.select("Projected")
if self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(activeFit, projectedFit.ID, 'fit')):
self.mainFrame.additionsPane.select("Projected")
def OnAddCommandFit(self, event):
activeFit = self.mainFrame.getActiveFit()
if activeFit:
sFit = Fit.getInstance()
commandFit = sFit.getFit(self.fitID)
sFit.addCommandFit(activeFit, commandFit)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
self.mainFrame.additionsPane.select("Command")
if self.mainFrame.command.Submit(cmd.GuiAddCommandCommand(activeFit, self.fitID)):
self.mainFrame.additionsPane.select("Command")
def OnMouseCaptureLost(self, event):
""" Destroy drag information (GH issue #479)"""
@@ -325,14 +321,12 @@ class FitItem(SFItem.SFBrowserItem):
self.Refresh()
def renameFit(self, event=None):
sFit = Fit.getInstance()
self.tcFitName.Show(False)
self.editWasShown = 0
fitName = self.tcFitName.GetValue()
if fitName:
self.fitName = fitName
sFit.renameFit(self.fitID, self.fitName)
wx.PostEvent(self.mainFrame, FitRenamed(fitID=self.fitID))
self.mainFrame.command.Submit(cmd.GuiFitRenameCommand(self.fitID, self.fitName))
else:
self.tcFitName.SetValue(self.fitName)

View File

@@ -8,11 +8,11 @@ import gui.mainFrame
import gui.utils.color as colorUtils
import gui.utils.draw as drawUtils
import gui.utils.fonts as fonts
from .events import Stage3Selected, Stage2Selected, Stage1Selected, FitSelected
from gui.bitmap_loader import BitmapLoader
from gui.contextMenu import ContextMenu
from service.fit import Fit
from service.market import Market
from .events import FitSelected, Stage3Selected
pyfalog = Logger(__name__)

View File

@@ -129,15 +129,15 @@ class PriceViewFull(StatsView):
total_price = 0
if (self.settings.get("ship")):
if self.settings.get("ship"):
total_price += ship_price
if (self.settings.get("modules")):
if self.settings.get("modules"):
total_price += module_price
if (self.settings.get("drones")):
if self.settings.get("drones"):
total_price += drone_price + fighter_price
if (self.settings.get("cargo")):
if self.settings.get("cargo"):
total_price += cargo_price
if (self.settings.get("character")):
if self.settings.get("character"):
total_price += booster_price + implant_price
self.labelPriceShip.SetLabel("%s ISK" % formatAmount(ship_price, 3, 3, 9, currency=True))

View File

@@ -125,15 +125,15 @@ class PriceViewMinimal(StatsView):
total_price = 0
if (self.settings.get("ship")):
if self.settings.get("ship"):
total_price += ship_price
if (self.settings.get("modules")):
if self.settings.get("modules"):
total_price += module_price
if (self.settings.get("drones")):
if self.settings.get("drones"):
total_price += drone_price + fighter_price
if (self.settings.get("cargo")):
if self.settings.get("cargo"):
total_price += cargo_price
if (self.settings.get("character")):
if self.settings.get("character"):
total_price += booster_price + implant_price
self.labelPriceShip.SetLabel("%s ISK" % formatAmount(ship_price, 3, 3, 9, currency=True))

View File

@@ -50,10 +50,13 @@ class Price(ViewColumn):
if not price or not price.isValid:
return False
if isinstance(stuff, Drone) or isinstance(stuff, Cargo):
price.price *= stuff.amount
# Fetch actual price as float to not modify its value on Price object
price = price.price
return formatAmount(price.price, 3, 3, 9, currency=True)
if isinstance(stuff, Drone) or isinstance(stuff, Cargo):
price *= stuff.amount
return formatAmount(price, 3, 3, 9, currency=True)
def delayedText(self, mod, display, colItem):
sPrice = ServicePrice.getInstance()

View File

@@ -21,28 +21,26 @@
import wx
# noinspection PyPackageRequirements
import wx.lib.newevent
import gui.mainFrame
from gui.builtinMarketBrowser.events import ItemSelected, ITEM_SELECTED
from logbook import Logger
import gui.builtinViews.emptyView
import gui.display as d
from gui.contextMenu import ContextMenu
from gui.builtinShipBrowser.events import EVT_FIT_RENAMED, EVT_FIT_REMOVED, FitSelected, EVT_FIT_SELECTED
import gui.fitCommands as cmd
import gui.globalEvents as GE
import gui.mainFrame
import gui.multiSwitch
from eos.saveddata.mode import Mode
from eos.saveddata.module import Module, Slot, Rack
from gui.builtinViewColumns.state import State
from eos.saveddata.module import Module, Rack, Slot
from gui.bitmap_loader import BitmapLoader
import gui.builtinViews.emptyView
from logbook import Logger
from gui.builtinMarketBrowser.events import ITEM_SELECTED
from gui.builtinShipBrowser.events import EVT_FIT_REMOVED, EVT_FIT_RENAMED, EVT_FIT_SELECTED, FitSelected
from gui.builtinViewColumns.state import State
from gui.chrome_tabs import EVT_NOTEBOOK_PAGE_CHANGED
from gui.contextMenu import ContextMenu
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
from service.market import Market
from gui.utils.staticHelpers import DragDropHelper
import gui.utils.fonts as fonts
import gui.globalEvents as GE
pyfalog = Logger(__name__)
@@ -265,7 +263,9 @@ class FittingView(d.Display):
sel = []
row = self.GetFirstSelected()
while row != -1:
sel.append(self.mods[self.GetItemData(row)])
mod = self.mods[self.GetItemData(row)]
if mod and not isinstance(mod, Rack):
sel.append(mod)
row = self.GetNextSelected(row)
return sel
@@ -358,6 +358,9 @@ class FittingView(d.Display):
self.parent.SetPageTextIcon(pageIndex, text, bitmap)
def appendItem(self, event):
"""
Adds items that are double clicks from the market browser. We handle both modules and ammo
"""
if not self:
event.Skip()
return
@@ -367,6 +370,7 @@ class FittingView(d.Display):
if fitID is not None:
sFit = Fit.getInstance()
if sFit.isAmmo(itemID):
# If we've selected ammo, then apply to the selected module(s)
modules = []
sel = self.GetFirstSelected()
while sel != -1 and sel not in self.blanks:
@@ -376,17 +380,14 @@ class FittingView(d.Display):
sel = self.GetNextSelected(sel)
if len(modules) > 0:
sFit.setAmmo(fitID, itemID, modules)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.mainFrame.command.Submit(cmd.GuiModuleAddChargeCommand(fitID, itemID, modules))
else:
populate = sFit.appendModule(fitID, itemID)
if populate is not None:
self.slotsChanged()
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID, action="modadd", typeID=itemID))
self.mainFrame.command.Submit(cmd.GuiModuleAddCommand(fitID, itemID))
event.Skip()
def removeItem(self, event):
"""Double Left Click - remove module"""
if event.CmdDown():
return
row, _ = self.HitTest(event.Position)
@@ -400,36 +401,22 @@ class FittingView(d.Display):
def removeModule(self, modules):
"""Removes a list of modules from the fit"""
sFit = Fit.getInstance()
if not isinstance(modules, list):
modules = [modules]
positions = [mod.modPosition for mod in modules]
result = sFit.removeModule(self.activeFitID, positions)
self.mainFrame.command.Submit(cmd.GuiModuleRemoveCommand(self.activeFitID, modules))
if result is not None:
self.slotsChanged()
ids = {mod.item.ID for mod in modules}
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID, action="moddel", typeID=ids))
def addModule(self, x, y, srcIdx):
"""Add a module from the market browser"""
def addModule(self, x, y, itemID):
"""Add a module from the market browser (from dragging it)"""
dstRow, _ = self.HitTest((x, y))
if dstRow != -1 and dstRow not in self.blanks:
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
mod = self.mods[dstRow]
if not isinstance(mod, Module): # make sure we're not adding something to a T3D Mode
return
moduleChanged = sFit.changeModule(fitID, self.mods[dstRow].modPosition, srcIdx)
if moduleChanged is None:
# the new module doesn't fit in specified slot, try to simply append it
wx.PostEvent(self.mainFrame, ItemSelected(itemID=srcIdx))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="modadd", typeID=srcIdx))
self.mainFrame.command.Submit(cmd.GuiModuleAddCommand(fitID, itemID, self.mods[dstRow].modPosition))
def swapCargo(self, x, y, srcIdx):
"""Swap a module from cargo to fitting window"""
@@ -442,14 +429,11 @@ class FittingView(d.Display):
if not isinstance(module, Module):
return
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
typeID = fit.cargo[srcIdx].item.ID
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.modPosition, srcIdx,
mstate.CmdDown() and module.isEmpty)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="modadd", typeID=typeID))
self.mainFrame.command.Submit(cmd.GuiCargoToModuleCommand(
self.mainFrame.getActiveFit(),
module.modPosition,
srcIdx,
mstate.CmdDown() and module.isEmpty))
def swapItems(self, x, y, srcIdx):
"""Swap two modules in fitting window"""
@@ -457,15 +441,9 @@ class FittingView(d.Display):
sFit = Fit.getInstance()
fit = sFit.getFit(self.activeFitID)
if mstate.CmdDown():
clone = True
else:
clone = False
dstRow, _ = self.HitTest((x, y))
if dstRow != -1 and dstRow not in self.blanks:
mod1 = fit.modules[srcIdx]
mod2 = self.mods[dstRow]
@@ -476,13 +454,11 @@ class FittingView(d.Display):
if mod1.slot != mod2.slot:
return
if getattr(mod2, "modPosition") is not None:
if clone and mod2.isEmpty and mod1.getModifiedItemAttr("maxGroupFitted", 0) < 1.0:
sFit.cloneModule(self.mainFrame.getActiveFit(), srcIdx, mod2.modPosition)
else:
sFit.swapModules(self.mainFrame.getActiveFit(), srcIdx, mod2.modPosition)
clone = mstate.CmdDown() and mod2.isEmpty
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
fitID = self.mainFrame.getActiveFit()
if getattr(mod2, "modPosition") is not None:
self.mainFrame.command.Submit(cmd.GuiModuleSwapOrCloneCommand(fitID, srcIdx, mod2.modPosition, clone))
else:
pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown")))
@@ -638,18 +614,18 @@ class FittingView(d.Display):
else:
mods = self.getSelectedMods()
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
ctrl = event.cmdDown or event.middleIsDown
click = "ctrl" if ctrl is True else "right" if event.GetButton() == 3 else "left"
sFit.toggleModulesState(fitID, self.mods[self.GetItemData(row)], mods, click)
self.mainFrame.command.Submit(cmd.GuiModuleStateChangeCommand(
fitID, self.mods[self.GetItemData(row)].modPosition, [mod.modPosition for mod in mods], click))
# update state tooltip
tooltip = self.activeColumns[col].getToolTip(self.mods[self.GetItemData(row)])
if tooltip:
self.SetToolTip(tooltip)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
else:
event.Skip()

View File

@@ -17,35 +17,30 @@
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# =============================================================================
import re
import roman
# noinspection PyPackageRequirements
import wx
import wx.dataview
import wx.lib.agw.hyperlink
# noinspection PyPackageRequirements
import wx.lib.newevent
from logbook import Logger
# noinspection PyPackageRequirements
from wx.dataview import TreeListCtrl
from gui.bitmap_loader import BitmapLoader
from gui.contextMenu import ContextMenu
import gui.globalEvents as GE
from gui.builtinViews.implantEditor import BaseImplantEditorView
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator, TextEntryValidatedDialog
from service.fit import Fit
from service.character import Character
from service.esi import Esi
from service.network import AuthenticationError, TimeoutError
from service.market import Market
from logbook import Logger
from wx.lib.agw.floatspin import FloatSpin
from gui.utils.clipboard import toClipboard, fromClipboard
import roman
import re
import webbrowser
import gui.globalEvents as GE
from gui.bitmap_loader import BitmapLoader
from gui.builtinViews.entityEditor import BaseValidator, EntityEditor, TextEntryValidatedDialog
from gui.builtinViews.implantEditor import BaseImplantEditorView
from gui.contextMenu import ContextMenu
from gui.utils.clipboard import fromClipboard, toClipboard
from service.character import Character
from service.esi import Esi
from service.fit import Fit
from service.market import Market
pyfalog = Logger(__name__)

View File

@@ -30,7 +30,7 @@ PageAdded, EVT_NOTEBOOK_PAGE_ADDED = wx.lib.newevent.NewEvent()
PageClosed, EVT_NOTEBOOK_PAGE_CLOSED = wx.lib.newevent.NewEvent()
class VetoAble():
class VetoAble:
def __init__(self):
self.__vetoed = False
@@ -41,7 +41,7 @@ class VetoAble():
return self.__vetoed
class NotebookTabChangeEvent():
class NotebookTabChangeEvent:
def __init__(self, old, new):
self.__old = old
self.__new = new

View File

@@ -186,7 +186,7 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
itemStats,
damagePattern,
marketJump,
droneSplit,
# droneSplit,
itemRemove,
droneRemoveStack,
ammoPattern,
@@ -202,7 +202,7 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
priceOptions,
amount,
cargoAmmo,
droneStack,
# droneStack,
metaSwap,
implantSets,
fighterAbilities,

View File

@@ -20,51 +20,84 @@
# noinspection PyPackageRequirements
import wx
from service.port.eft import EFT_OPTIONS
from service.settings import SettingsProvider
class CopySelectDialog(wx.Dialog):
copyFormatEft = 0
copyFormatEftImps = 1
copyFormatXml = 2
copyFormatDna = 3
copyFormatEsi = 4
copyFormatMultiBuy = 5
copyFormatEfs = 6
copyFormatXml = 1
copyFormatDna = 2
copyFormatEsi = 3
copyFormatMultiBuy = 4
copyFormatEfs = 5
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Select a format", size=(-1, -1),
style=wx.DEFAULT_DIALOG_STYLE)
mainSizer = wx.BoxSizer(wx.VERTICAL)
copyFormats = ["EFT", "EFT (Implants)", "XML", "DNA", "ESI", "MultiBuy", "EFS"]
copyFormatTooltips = {CopySelectDialog.copyFormatEft: "EFT text format",
CopySelectDialog.copyFormatEftImps: "EFT text format",
CopySelectDialog.copyFormatXml: "EVE native XML format",
CopySelectDialog.copyFormatDna: "A one-line text format",
CopySelectDialog.copyFormatEsi: "A JSON format used for ESI",
CopySelectDialog.copyFormatMultiBuy: "MultiBuy text format",
CopySelectDialog.copyFormatEfs: "JSON data format used by EFS"}
selector = wx.RadioBox(self, wx.ID_ANY, label="Copy to the clipboard using:", choices=copyFormats,
style=wx.RA_SPECIFY_ROWS)
selector.Bind(wx.EVT_RADIOBOX, self.Selected)
for format, tooltip in copyFormatTooltips.items():
selector.SetItemToolTip(format, tooltip)
self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": 0})
self.copyFormat = CopySelectDialog.copyFormatEft
selector.SetSelection(self.copyFormat)
self.copyFormats = {
"EFT": CopySelectDialog.copyFormatEft,
"XML": CopySelectDialog.copyFormatXml,
"DNA": CopySelectDialog.copyFormatDna,
"ESI": CopySelectDialog.copyFormatEsi,
"MultiBuy": CopySelectDialog.copyFormatMultiBuy,
"EFS": CopySelectDialog.copyFormatEfs
}
mainSizer.Add(selector, 0, wx.EXPAND | wx.ALL, 5)
self.options = {}
for i, format in enumerate(self.copyFormats.keys()):
if i == 0:
rdo = wx.RadioButton(self, wx.ID_ANY, format, style=wx.RB_GROUP)
else:
rdo = wx.RadioButton(self, wx.ID_ANY, format)
rdo.Bind(wx.EVT_RADIOBUTTON, self.Selected)
if self.settings['format'] == self.copyFormats[format]:
rdo.SetValue(True)
self.copyFormat = self.copyFormats[format]
mainSizer.Add(rdo, 0, wx.EXPAND | wx.ALL, 5)
if format == "EFT":
bsizer = wx.BoxSizer(wx.VERTICAL)
for x, v in EFT_OPTIONS.items():
ch = wx.CheckBox(self, -1, v['name'])
self.options[x] = ch
if self.settings['options'] & x:
ch.SetValue(True)
bsizer.Add(ch, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3)
mainSizer.Add(bsizer, 1, wx.EXPAND | wx.LEFT, 20)
buttonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)
if buttonSizer:
mainSizer.Add(buttonSizer, 0, wx.EXPAND | wx.ALL, 5)
self.toggleOptions()
self.SetSizer(mainSizer)
self.Fit()
self.Center()
def Selected(self, event):
self.copyFormat = event.GetSelection()
obj = event.GetEventObject()
format = obj.GetLabel()
self.copyFormat = self.copyFormats[format]
self.toggleOptions()
self.Fit()
def toggleOptions(self):
for ch in self.options.values():
ch.Enable(self.GetSelected() == CopySelectDialog.copyFormatEft)
def GetSelected(self):
return self.copyFormat
def GetOptions(self):
i = 0
for x, v in self.options.items():
if v.IsChecked():
i = i ^ x
return i

View File

@@ -35,7 +35,7 @@ class DevTools(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Damage Pattern Editor", size=wx.Size(400, 240))
self.mainFrame = parent
self.block = False
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
@@ -56,13 +56,19 @@ class DevTools(wx.Dialog):
self.fitTest = wx.Button(self, wx.ID_ANY, "Test fits", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.fitTest, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.fitTest .Bind(wx.EVT_BUTTON, self.fit_test)
self.fitTest.Bind(wx.EVT_BUTTON, self.fit_test)
self.cmdPrint = wx.Button(self, wx.ID_ANY, "Command Print", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cmdPrint, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
self.cmdPrint.Bind(wx.EVT_BUTTON, self.cmd_print)
self.SetSizer(mainSizer)
self.Layout()
self.CenterOnParent()
self.Show()
print(parent)
def objects_by_id(self, evt):
input = self.id_get.GetValue()
@@ -81,6 +87,11 @@ class DevTools(wx.Dialog):
else:
print(None)
def cmd_print(self, evt):
print("=" * 20)
for x in self.mainFrame.command.GetCommands():
print("{}{} {}".format("==> " if x == self.mainFrame.command.GetCurrentCommand() else "", x.GetName(), x))
def gc_collect(self, evt):
print(gc.collect())
print(gc.get_debug())

View File

@@ -15,7 +15,7 @@ import gui.globalEvents as GE
from logbook import Logger
from service.esi import Esi
from service.esiAccess import APIException
from service.port import ESIExportException
from service.port.esi import ESIExportException
pyfalog = Logger(__name__)
@@ -319,7 +319,7 @@ class SsoCharacterMgmt(wx.Dialog):
self.Centre(wx.BOTH)
def ssoLogin(self, event):
if (self):
if self:
# todo: these events don't unbind properly when window is closed (?), hence the `if`. Figure out better way of doing this.
self.popCharList()
event.Skip()
@@ -384,7 +384,7 @@ class FittingsTreeView(wx.Panel):
dict = {}
fits = data
for fit in fits:
if (fit['fitting_id'] in sEsi.fittings_deleted):
if fit['fitting_id'] in sEsi.fittings_deleted:
continue
ship = getItem(fit['ship_type_id'])
if ship is None:

View File

@@ -0,0 +1,34 @@
from .guiToggleModuleState import GuiModuleStateChangeCommand
from .guiAddModule import GuiModuleAddCommand
from .guiRemoveModule import GuiModuleRemoveCommand
from .guiAddCharge import GuiModuleAddChargeCommand
from .guiSwapCloneModule import GuiModuleSwapOrCloneCommand
from .guiRemoveCargo import GuiRemoveCargoCommand
from .guiAddCargo import GuiAddCargoCommand
from .guiRemoveImplant import GuiRemoveImplantCommand
from .guiAddImplant import GuiAddImplantCommand
from .guiAddBooster import GuiAddBoosterCommand
from .guiRemoveBooster import GuiRemoveBoosterCommand
from .guiAddCommand import GuiAddCommandCommand
from .guiRemoveCommand import GuiRemoveCommandCommand
from .guiSetMode import GuiSetModeCommand
from .guiToggleCommand import GuiToggleCommandCommand
from .guiAddProjected import GuiAddProjectedCommand
from .guiRemoveProjected import GuiRemoveProjectedCommand
from .guiCargoToModule import GuiCargoToModuleCommand
from .guiModuleToCargo import GuiModuleToCargoCommand
from .guiAddFighter import GuiAddFighterCommand
from .guiRemoveFighter import GuiRemoveFighterCommand
from .guiMetaSwap import GuiMetaSwapCommand
from .guiToggleFighter import GuiToggleFighterCommand
from .guiToggleImplant import GuiToggleImplantCommand
from .guiToggleBooster import GuiToggleBoosterCommand
from .guiAddDrone import GuiAddDroneCommand
from .guiRemoveDrone import GuiRemoveDroneCommand
from .guiChangeFighterQty import GuiChangeFighterQty
from .guiChangeCargoQty import GuiChangeCargoQty
from .guiChangeProjectedFitQty import GuiChangeProjectedFitQty
from .guiChangeDroneQty import GuiChangeDroneQty
from .guiChangeProjectedDroneQty import GuiChangeProjectedDroneQty
from .guiToggleDrone import GuiToggleDroneCommand
from .guiFitRename import GuiFitRenameCommand

View File

View File

@@ -0,0 +1,49 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.booster import Booster
pyfalog = Logger(__name__)
class FitAddBoosterCommand(wx.Command):
""""
from sFit.addBooster
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.new_index = None
self.old_item = None
def Do(self):
pyfalog.debug("Adding booster ({0}) to fit ID: {1}", self.itemID, self.fitID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager="attributes")
if next((x for x in fit.boosters if x.itemID == self.itemID), None):
return False # already have item in list of boosters
try:
booster = Booster(item)
except ValueError:
pyfalog.warning("Invalid item: {0}", self.itemID)
return False
self.old_item = fit.boosters.makeRoom(booster)
fit.boosters.append(booster)
self.new_index = fit.boosters.index(booster)
return True
def Undo(self):
if self.old_item:
# If we had an item in the slot previously, add it back.
cmd = FitAddBoosterCommand(self.fitID, self.old_item)
cmd.Do()
return True
from .fitRemoveBooster import FitRemoveBoosterCommand # Avoid circular import
cmd = FitRemoveBoosterCommand(self.fitID, self.new_index)
cmd.Do()
return True

View File

@@ -0,0 +1,43 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.cargo import Cargo
pyfalog = Logger(__name__)
class FitAddCargoCommand(wx.Command):
""""
from sFit.addCargo
"""
def __init__(self, fitID, itemID, amount=1, replace=False):
wx.Command.__init__(self, True, "Cargo add")
self.fitID = fitID
self.itemID = itemID
self.amount = amount # add x amount. If this goes over amount, removes stack
self.replace = replace # if this is false, we increment.
def Do(self):
pyfalog.debug("Adding cargo {0} (x{1}) for fit {2}", self.itemID, self.amount, self.fitID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID)
cargo = next((x for x in fit.cargo if x.itemID == self.itemID), None)
if cargo is None:
cargo = Cargo(item)
fit.cargo.append(cargo)
if self.replace:
cargo.amount = self.amount
else:
cargo.amount += self.amount
eos.db.commit()
return True
def Undo(self):
from .fitRemoveCargo import FitRemoveCargoCommand # Avoid circular import
cmd = FitRemoveCargoCommand(self.fitID, self.itemID, self.amount)
cmd.Do()
return True

View File

@@ -0,0 +1,47 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitAddCommandCommand(wx.Command): # well that's an unfrtunate name
""""
from sFit.addCommand
"""
def __init__(self, fitID, commandFitID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.commandFitID = commandFitID
def Do(self):
pyfalog.debug("Projecting command fit ({0}) onto: {1}", self.fitID, self.commandFitID)
fit = eos.db.getFit(self.fitID)
command = eos.db.getFit(self.commandFitID)
if not command:
# if redoing when the command fit has been deleted, simply fail this command
return False
if command in fit.commandFits:
return
fit.commandFitDict[command.ID] = command
# this bit is required -- see GH issue # 83
eos.db.saveddata_session.flush()
eos.db.saveddata_session.refresh(command)
eos.db.commit()
return True
def Undo(self):
command = eos.db.getFit(self.commandFitID)
if not command:
# can't find the command fit, it must have been deleted. Just skip this undo
return True
from .fitRemoveCommand import FitRemoveCommandCommand
cmd = FitRemoveCommandCommand(self.fitID, self.commandFitID)
cmd.Do()
return True

View File

@@ -0,0 +1,49 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.drone import Drone
pyfalog = Logger(__name__)
class FitAddDroneCommand(wx.Command):
""""
from sFit.addDrone
"""
def __init__(self, fitID, itemID, amount=1, replace=False):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.itemID = itemID
self.amount = amount # add x amount. If this goes over amount, removes stack
self.replace = replace # if this is false, we increment.
self.index = None
def Do(self):
pyfalog.debug("Adding {0} drones ({1}) to fit ID: {2}", self.amount, self.itemID, self.fitID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager=("attributes", "group.category"))
for d in fit.drones.find(item):
if d is not None and d.amountActive == 0 and d.amount < max(5, fit.extraAttributes["maxActiveDrones"]):
drone = d
break
else:
try:
drone = Drone(item)
except ValueError:
pyfalog.warning("Invalid drone: {}", item)
return False
if not drone.fits(fit):
return False
fit.drones.append(drone)
drone.amount += self.amount
eos.db.commit()
self.index = fit.drones.index(drone)
return True
def Undo(self):
from .fitRemoveDrone import FitRemoveDroneCommand # Avoid circular import
cmd = FitRemoveDroneCommand(self.fitID, self.index, self.amount)
return cmd.Do()

View File

@@ -0,0 +1,48 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.fighter import Fighter
pyfalog = Logger(__name__)
class FitAddFighterCommand(wx.Command):
""""
from sFit.addFighter
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True, "Cargo add")
self.fitID = fitID
self.itemID = itemID
self.new_index = None
def Do(self):
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager=("attributes", "group.category"))
try:
fighter = Fighter(item)
except ValueError:
pyfalog.warning("Invalid fighter: {}", item)
return False
if not fighter.fits(fit):
return False
used = fit.getSlotsUsed(fighter.slot)
total = fit.getNumSlots(fighter.slot)
if used >= total:
fighter.active = False
fit.fighters.append(fighter)
self.new_index = fit.fighters.index(fighter)
eos.db.commit()
return True
def Undo(self):
from .fitRemoveFighter import FitRemoveFighterCommand # Avoid circular import
cmd = FitRemoveFighterCommand(self.fitID, self.new_index)
cmd.Do()
return True

View File

@@ -0,0 +1,48 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.implant import Implant
pyfalog = Logger(__name__)
class FitAddImplantCommand(wx.Command):
""""
from sFit.addImplant
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True, "Cargo add")
self.fitID = fitID
self.itemID = itemID
self.old_item = None
def Do(self):
pyfalog.debug("Adding implant to fit ({0}) for item ID: {1}", self.fitID, self.itemID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager="attributes")
if next((x for x in fit.implants if x.itemID == self.itemID), None):
return False # already have item in list of implants
try:
implant = Implant(item)
except ValueError:
pyfalog.warning("Invalid item: {0}", self.itemID)
return False
self.old_item = fit.implants.makeRoom(implant)
fit.implants.append(implant)
self.new_index = fit.implants.index(implant)
return True
def Undo(self):
if self.old_item:
# If we had an item in the slot previously, add it back.
cmd = FitAddImplantCommand(self.fitID, self.old_item)
cmd.Do()
return True
from .fitRemoveImplant import FitRemoveImplantCommand # Avoid circular import
cmd = FitRemoveImplantCommand(self.fitID, self.new_index)
cmd.Do()
return True

View File

@@ -0,0 +1,81 @@
import wx
from eos.saveddata.module import Module, State
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitAddModuleCommand(wx.Command):
""""
Fitting command that appends a module to a fit using the first available slot. In the case of a Subsystem, it checks
if there is already a subsystem with the same slot, and runs the replace command instead.
from sFit.appendModule
"""
def __init__(self, fitID, itemID, mutaplasmidID=None, baseID=None):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.mutaplasmidID = mutaplasmidID
self.baseID = baseID
self.new_position = None
self.change = None
self.replace_cmd = None
def Do(self):
fitID = self.fitID
itemID = self.itemID
fit = eos.db.getFit(fitID)
item = eos.db.getItem(itemID, eager=("attributes", "group.category"))
bItem = eos.db.getItem(self.baseID) if self.baseID else None
mItem = next((x for x in bItem.mutaplasmids if x.ID == self.mutaplasmidID)) if self.mutaplasmidID else None
try:
self.module = Module(item, bItem, mItem)
except ValueError:
pyfalog.warning("Invalid module: {}", item)
return False
# If subsystem and we need to replace, run the replace command instead and bypass the rest of this command
if self.module.item.category.name == "Subsystem":
for mod in fit.modules:
if mod.getModifiedItemAttr("subSystemSlot") == self.module.getModifiedItemAttr("subSystemSlot"):
from .fitReplaceModule import FitReplaceModuleCommand
self.replace_cmd = FitReplaceModuleCommand(self.fitID, mod.modPosition, itemID)
return self.replace_cmd.Do()
if self.module.fits(fit):
pyfalog.debug("Adding {} as module for fit {}", self.module, fit)
self.module.owner = fit
numSlots = len(fit.modules)
fit.modules.append(self.module)
if self.module.isValidState(State.ACTIVE):
self.module.state = State.ACTIVE
# todo: fix these
# As some items may affect state-limiting attributes of the ship, calculate new attributes first
# self.recalc(fit)
# Then, check states of all modules and change where needed. This will recalc if needed
# self.checkStates(fit, m)
# fit.fill()
eos.db.commit()
self.change = numSlots != len(fit.modules)
self.new_position = self.module.modPosition
else:
return False
return True
def Undo(self):
# We added a subsystem module, which actually ran the replace command. Run the undo for that guy instead
if self.replace_cmd:
return self.replace_cmd.Undo()
from .fitRemoveModule import FitRemoveModuleCommand # Avoid circular import
if self.new_position:
cmd = FitRemoveModuleCommand(self.fitID, [self.new_position])
cmd.Do()
return True

View File

@@ -0,0 +1,45 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.drone import Drone
pyfalog = Logger(__name__)
class FitAddProjectedDroneCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.index = None
def Do(self):
pyfalog.debug("Projecting fit ({0}) onto: {1}", self.fitID, self.itemID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID)
drone = None
for d in fit.projectedDrones.find(item):
if d is None or d.amountActive == d.amount or d.amount >= 5:
drone = d
break
if drone is None:
drone = Drone(item)
if not drone.item.isType("projected"):
return False
fit.projectedDrones.append(drone)
self.index = fit.projectedDrones.index(drone)
drone.amount += 1
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitRemoveProjectedDrone import FitRemoveProjectedDroneCommand # avoids circular import
cmd = FitRemoveProjectedDroneCommand(self.fitID, self.index)
cmd.Do()
return True

View File

@@ -0,0 +1,50 @@
import wx
from eos.saveddata.module import Module, State
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitAddProjectedEnvCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.new_index = None
self.old_item = None
def Do(self):
pyfalog.debug("Projecting fit ({0}) onto: {1}", self.fitID, self.itemID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager=("attributes", "group.category"))
try:
module = Module(item)
except ValueError:
return False
# todo: thing to check for existing environmental effects
self.old_item = fit.projectedModules.makeRoom(module)
module.state = State.ONLINE
fit.projectedModules.append(module)
eos.db.commit()
self.new_index = fit.projectedModules.index(module)
return True
def Undo(self):
if self.old_item:
# If we had an item in the slot previously, add it back.
cmd = FitAddProjectedEnvCommand(self.fitID, self.old_item)
cmd.Do()
return True
from gui.fitCommands.calc.fitRemoveProjectedEnv import FitRemoveProjectedEnvCommand # avoids circular import
cmd = FitRemoveProjectedEnvCommand(self.fitID, self.itemID)
cmd.Do()
return True

View File

@@ -0,0 +1,40 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.fighter import Fighter
pyfalog = Logger(__name__)
class FitAddProjectedFighterCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.new_index = None
def Do(self):
pyfalog.debug("Projecting fit ({0}) onto: {1}", self.fitID, self.itemID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager=("attributes", "group.category"))
try:
fighter = Fighter(item)
except ValueError:
return False
fit.projectedFighters.append(fighter)
# sometimes fighters aren't added because they aren't valid projectionable ones. todo: move that logic into here
if fighter in fit.projectedFighters:
eos.db.commit()
self.new_index = fit.projectedFighters.index(fighter)
return True
return False
def Undo(self):
from gui.fitCommands.calc.fitRemoveProjectedFighter import FitRemoveProjectedFighterCommand # avoids circular import
cmd = FitRemoveProjectedFighterCommand(self.fitID, self.new_index)
cmd.Do()
return True

View File

@@ -0,0 +1,39 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitAddProjectedFitCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, projectedFitID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.projectedFitID = projectedFitID
self.new_index = None
self.old_item = None
def Do(self):
pyfalog.debug("Projecting fit ({0}) onto: {1}", self.fitID, self.projectedFitID)
fit = eos.db.getFit(self.fitID)
projectedFit = eos.db.getFit(self.projectedFitID)
if projectedFit is None or projectedFit in fit.projectedFits:
return False
fit.projectedFitDict[projectedFit.ID] = projectedFit
# this bit is required -- see GH issue # 83
eos.db.saveddata_session.flush()
eos.db.saveddata_session.refresh(projectedFit)
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitRemoveProjectedFit import FitRemoveProjectedFitCommand # avoids circular import
cmd = FitRemoveProjectedFitCommand(self.fitID, self.projectedFitID)
cmd.Do()
return True

View File

@@ -0,0 +1,43 @@
import wx
import eos.db
from logbook import Logger
from eos.saveddata.module import Module, State
pyfalog = Logger(__name__)
class FitAddProjectedModuleCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.new_index = None
def Do(self):
pyfalog.debug("Projecting fit ({0}) onto: {1}", self.fitID, self.itemID)
fit = eos.db.getFit(self.fitID)
item = eos.db.getItem(self.itemID, eager=("attributes", "group.category"))
try:
module = Module(item)
if not module.item.isType("projected"):
return False
except ValueError:
return False
module.state = State.ACTIVE
if not module.canHaveState(module.state, fit):
module.state = State.OFFLINE
fit.projectedModules.append(module)
eos.db.commit()
self.new_index = fit.projectedModules.index(module)
return True
def Undo(self):
from gui.fitCommands.calc.fitRemoveProjectedModule import FitRemoveProjectedModuleCommand # avoids circular import
cmd = FitRemoveProjectedModuleCommand(self.fitID, self.new_index)
cmd.Do()
return True

View File

@@ -0,0 +1,27 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitChangeCargoQty(wx.Command):
def __init__(self, fitID, position, amount=1):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.position = position
self.amount = amount # add x amount. If this goes over amount, removes stack
self.old_amount = None
def Do(self):
pyfalog.debug("Changing cargo ({0}) for fit ({1}) to amount: {2}", self.position, self.fitID, self.amount)
fit = eos.db.getFit(self.fitID)
cargo = fit.cargo[self.position]
self.old_amount = cargo.amount
cargo.amount = self.amount
eos.db.commit()
return True
def Undo(self):
cmd = FitChangeCargoQty(self.fitID, self.position, self.old_amount)
return cmd.Do()

View File

@@ -0,0 +1,27 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitChangeDroneQty(wx.Command):
def __init__(self, fitID, position, amount=1):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.position = position
self.amount = amount # add x amount. If this goes over amount, removes stack
self.old_amount = None
def Do(self):
pyfalog.debug("Changing active fighters ({0}) for fit ({1}) to amount: {2}", self.position, self.fitID, self.amount)
fit = eos.db.getFit(self.fitID)
drone = fit.drones[self.position]
self.old_amount = drone.amount
drone.amount = self.amount
eos.db.commit()
return True
def Undo(self):
cmd = FitChangeDroneQty(self.fitID, self.position, self.old_amount)
return cmd.Do()

View File

@@ -0,0 +1,30 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitChangeFighterQty(wx.Command):
""""
from sFit.changeActiveFighters
"""
def __init__(self, fitID, position, amount=1):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.position = position
self.amount = amount # add x amount. If this goes over amount, removes stack
self.old_amount = None
def Do(self):
pyfalog.debug("Changing active fighters ({0}) for fit ({1}) to amount: {2}", self.position, self.fitID, self.amount)
fit = eos.db.getFit(self.fitID)
fighter = fit.fighters[self.position]
self.old_amount = fighter.amountActive
fighter.amountActive = self.amount
eos.db.commit()
return True
def Undo(self):
cmd = FitChangeFighterQty(self.fitID, self.position, self.old_amount)
return cmd.Do()

View File

@@ -0,0 +1,27 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitChangeProjectedDroneQty(wx.Command):
def __init__(self, fitID, position, amount=1):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.position = position
self.amount = amount # add x amount. If this goes over amount, removes stack
self.old_amount = None
def Do(self):
pyfalog.debug("Changing active fighters ({0}) for fit ({1}) to amount: {2}", self.position, self.fitID, self.amount)
fit = eos.db.getFit(self.fitID)
drone = fit.projectedDrones[self.position]
self.old_amount = drone.amount
drone.amount = self.amount
eos.db.commit()
return True
def Undo(self):
cmd = FitChangeProjectedDroneQty(self.fitID, self.position, self.old_amount)
return cmd.Do()

View File

@@ -0,0 +1,36 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitChangeProjectedFitQty(wx.Command):
""""
from sFit.changeAmount
"""
def __init__(self, fitID, pfitID, amount=1):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.pfitID = pfitID
self.amount = amount
self.old_amount = None
def Do(self):
pfit = eos.db.getFit(self.pfitID)
if not pfit: # fit was deleted
return False
amount = min(20, max(1, self.amount)) # 1 <= a <= 20
projectionInfo = pfit.getProjectionInfo(self.fitID)
if projectionInfo:
self.old_amount = projectionInfo.amount
projectionInfo.amount = amount
eos.db.commit()
return True
def Undo(self):
cmd = FitChangeProjectedFitQty(self.fitID, self.pfitID, self.old_amount)
return cmd.Do()

View File

@@ -0,0 +1,75 @@
import wx
from logbook import Logger
import gui.mainFrame
from eos.saveddata.module import Module
from service.fit import Fit
import eos.db
pyfalog = Logger(__name__)
class FitChangeStatesCommand(wx.Command):
"""
Fitting command that trys to change the state of modules in [positions]. We use the base module to determine the
state that we will try to apply for all modules.
"""
def __init__(self, fitID, baseModPos, positions, click):
# todo: instead of modules, needs to be positions. Dead objects are a thing
wx.Command.__init__(self, True, "Module State Change")
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.sFit = Fit.getInstance()
self.fitID = fitID
self.baseModPos = baseModPos
self.positions = positions
self.click = click
self.changed = None
self.old_states = {}
def Do(self):
fit = eos.db.getFit(self.fitID)
baseMod = fit.modules[self.baseModPos]
# make sure positions only include non-empty positions
self.positions = [x for x in self.positions if not fit.modules[x].isEmpty]
for x in self.positions:
self.old_states[x] = fit.modules[x].state
proposedState = Module.getProposedState(baseMod, self.click)
pyfalog.debug("Attempting to change modules to {}", proposedState)
if proposedState != baseMod.state:
pyfalog.debug("Toggle {} state: {} for fit ID: {}", baseMod, proposedState, self.fitID)
self.changed = True
baseMod.state = proposedState
for i in [x for x in self.positions if x != self.baseModPos]: # dont consider base module position
mod = fit.modules[i]
p = Module.getProposedState(mod, self.click, proposedState)
mod.state = p
if p != mod.state:
pyfalog.debug("Toggle {} state: {} for fit ID: {}", mod, p, self.fitID)
self.changed = True
# if we haven't change the state (eg, overheat -> overheat), simply fail the command
if self.changed:
eos.db.commit()
# As some items may affect state-limiting attributes of the ship, calculate new attributes first
# self.recalc(fit)
# # Then, check states of all modules and change where needed. This will recalc if needed
# self.checkStates(fit, base)
return True
return False
def Undo(self):
# todo: some sanity checking to make sure that we are applying state back to the same modules?
fit = self.sFit.getFit(self.fitID)
for k, v in self.old_states.items():
mod = fit.modules[k]
pyfalog.debug("Reverting {} to state {} for fit ID", mod, v, self.fitID)
mod.state = v
return True

View File

@@ -0,0 +1,44 @@
import wx
import eos.db
from logbook import Logger
import copy
pyfalog = Logger(__name__)
class FitCloneModuleCommand(wx.Command):
"""
Clone a module from src to dst
This will overwrite dst! Checking for empty module must be
done at a higher level
from sFit.cloneModule
"""
def __init__(self, fitID, src, dst):
wx.Command.__init__(self, True, "Module Clone")
self.fitID = fitID
self.src = src
self.dst = dst
def Do(self):
fit = eos.db.getFit(self.fitID)
# Gather modules
srcMod = fit.modules[self.src]
dstMod = fit.modules[self.dst] # should be a placeholder module
new = copy.deepcopy(srcMod)
new.owner = fit
if new.fits(fit):
pyfalog.debug("Cloning {} from source {} to destination {} for fit ID {}", srcMod, self.src, self.dst, self.fitID)
# insert copy if module meets hardpoint restrictions
fit.modules.remove(dstMod)
fit.modules.insert(self.dst, new)
eos.db.commit()
return True
return False
def Undo(self):
from .fitRemoveModule import FitRemoveModuleCommand # Avoid circular import
cmd = FitRemoveModuleCommand(self.fitID, [self.dst])
cmd.Do()
return True

View File

@@ -0,0 +1,30 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveBoosterCommand(wx.Command):
""""
from sFit.removeBooster
"""
def __init__(self, fitID, position):
wx.Command.__init__(self, True, "Implant remove")
self.fitID = fitID
self.position = position
self.old = None
def Do(self):
pyfalog.debug("Removing booster from position ({0}) for fit ID: {1}", self.position, self.fitID)
fit = eos.db.getFit(self.fitID)
booster = fit.boosters[self.position]
self.old = booster.itemID
fit.boosters.remove(booster)
return True
def Undo(self):
from .fitAddBooster import FitAddBoosterCommand # Avoid circular import
cmd = FitAddBoosterCommand(self.fitID, self.old)
cmd.Do()
return True

View File

@@ -0,0 +1,47 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveCargoCommand(wx.Command):
""""
Fitting command that sets the amount for an item within the cargo.
from sFit.removeCargo
"""
def __init__(self, fitID, itemID, amount=1, stack=False):
wx.Command.__init__(self, True, "Cargo remove")
self.fitID = fitID
self.itemID = itemID
self.stack = stack # remove entire stack
self.amount = amount # remove x amount. If this goes over amount, removes stack
self.old_amount = None
def Do(self):
pyfalog.debug("Removing cargo {0} (x{1}) for fit {2}", self.itemID, self.amount, self.fitID)
fit = eos.db.getFit(self.fitID)
cargo = next((x for x in fit.cargo if x.itemID == self.itemID), None)
if cargo is None:
return False
self.old_amount = cargo.amount
if self.amount >= cargo.amount:
self.stack = True # set to full stack, this allows easier logic in the Undo function
if self.stack or self.amount >= cargo.amount:
fit.cargo.remove(cargo)
eos.db.commit()
return True
cargo.amount -= self.amount
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitAddCargo import FitAddCargoCommand # Avoid circular import
cmd = FitAddCargoCommand(self.fitID, self.itemID, self.old_amount, True)
cmd.Do()
return True

View File

@@ -0,0 +1,37 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveCommandCommand(wx.Command): # well that's an unfortunate name
""""
from sFit.removeCommand
"""
def __init__(self, fitID, commandFitID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.commandFitID = commandFitID
def Do(self):
pyfalog.debug("Removing command projection from fit ({0}) for: {1}", self.fitID, self.commandFitID)
fit = eos.db.getFit(self.fitID)
command = eos.db.getFit(self.commandFitID)
if not command:
return False
del fit.commandFitDict[command.ID]
eos.db.commit()
return True
def Undo(self):
command = eos.db.getFit(self.commandFitID)
if not command:
# can't find the command fit, it must have been deleted. Just skip this undo
return True
from .fitAddCommand import FitAddCommandCommand
cmd = FitAddCommandCommand(self.fitID, self.commandFitID)
cmd.Do()
return True

View File

@@ -0,0 +1,43 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveDroneCommand(wx.Command):
""""
from sFit.addDrone
"""
def __init__(self, fitID, position, amount=1):
wx.Command.__init__(self, True, "Drone add")
self.fitID = fitID
self.position = position
self.amount = amount # add x amount. If this goes over amount, removes stack
self.removed_item = None
def Do(self):
pyfalog.debug("Removing {0} drones for fit ID: {1}", self.amount, self.fitID)
fit = eos.db.getFit(self.fitID)
d = fit.drones[self.position]
d.amount -= self.amount
if d.amountActive > 0:
d.amountActive -= self.amount
if d.amount == 0:
self.removed_item = d.itemID
del fit.drones[self.position]
eos.db.commit()
return True
def Undo(self):
if self.removed_item:
from .fitAddDrone import FitAddDroneCommand # Avoid circular import
cmd = FitAddDroneCommand(self.fitID, self.removed_item, self.amount)
return cmd.Do()
else:
fit = eos.db.getFit(self.fitID)
d = fit.drones[self.position]
d.amount += self.amount
eos.db.commit()
return True

View File

@@ -0,0 +1,34 @@
import wx
from logbook import Logger
import eos.db
pyfalog = Logger(__name__)
class FitRemoveFighterCommand(wx.Command):
""""
Fitting command that removes a module at a specified positions
from sFit.removeFighter
"""
def __init__(self, fitID: int, position: int):
wx.Command.__init__(self, True)
self.fitID = fitID
self.position = position
self.change = None
self.removed_item = None
def Do(self):
fitID = self.fitID
fit = eos.db.getFit(fitID)
f = fit.fighters[self.position]
fit.fighters.remove(f)
self.removed_item = f.itemID
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitAddFighter import FitAddFighterCommand # avoids circular import
cmd = FitAddFighterCommand(self.fitID, self.removed_item)
return cmd.Do()

View File

@@ -0,0 +1,32 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveImplantCommand(wx.Command):
""""
Fitting command that sets the amount for an item within the cargo.
from sFit.removeImplant
"""
def __init__(self, fitID, position):
wx.Command.__init__(self, True, "Implant remove")
self.fitID = fitID
self.position = position
self.old_implant = None
def Do(self):
pyfalog.debug("Removing implant from position ({0}) for fit ID: {1}", self.position, self.fitID)
fit = eos.db.getFit(self.fitID)
implant = fit.implants[self.position]
self.old_implant = implant.itemID
fit.implants.remove(implant)
return True
def Undo(self):
from gui.fitCommands.calc.fitAddImplant import FitAddImplantCommand # Avoid circular import
cmd = FitAddImplantCommand(self.fitID, self.old_implant)
cmd.Do()
return True

View File

@@ -0,0 +1,59 @@
import wx
from gui.fitCommands.helpers import ModuleInfoCache
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveModuleCommand(wx.Command):
""""
Fitting command that removes a module at a specified positions
from sFit.removeModule
"""
def __init__(self, fitID: int, positions: list = None):
wx.Command.__init__(self, True)
self.fitID = fitID
self.positions = positions
self.modCache = []
self.change = None
def Do(self):
fitID = self.fitID
fit = eos.db.getFit(fitID)
pyfalog.debug("Removing module from position ({0}) for fit ID: {1}", self.positions, fitID)
for x in self.positions:
mod = fit.modules[x]
if not mod.isEmpty:
pyfalog.debug(" -- Removing {}", mod)
self.modCache.append(ModuleInfoCache(mod.modPosition, mod.item.ID, mod.state, mod.charge, mod.baseItemID, mod.mutaplasmidID))
fit.modules.toDummy(x)
# if no modules have changes, skip command
if not len(self.modCache) > 0:
return False
numSlots = len(fit.modules)
# todo: determine if we need to do this still
# self.recalc(fit)
# self.checkStates(fit, None)
# fit.fill()
eos.db.commit()
self.slotsChanged = numSlots != len(fit.modules)
return True
def Undo(self):
pyfalog.debug("Reapplying {} removed module(s) for {}", len(self.modCache), self.fitID)
from gui.fitCommands.calc.fitReplaceModule import FitReplaceModuleCommand # avoids circular import
for mod in self.modCache:
pyfalog.debug(" -- {}", mod)
# todo, send the state and charge?
cmd = FitReplaceModuleCommand(self.fitID, mod.modPosition, mod.itemID)
cmd.Do()
cmd.module.state = mod.state
cmd.module.charge = mod.charge
return True

View File

@@ -0,0 +1,42 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
# this has the same exact definition that regular projected modules, besides the undo
class FitRemoveProjectedDroneCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, position, stack=False):
wx.Command.__init__(self, True)
self.fitID = fitID
self.position = position
self.removed_item = None
self.stack = stack
def Do(self):
pyfalog.debug("Removing ({0}) onto: {1}", self.fitID, self.position)
fit = eos.db.getFit(self.fitID)
drone = fit.projectedDrones[self.position]
if self.stack:
fit.projectedDrones.remove(drone)
else:
if drone.amount > 1:
drone.amount -= 1
else:
fit.projectedDrones.remove(drone)
self.drone_item = drone.itemID
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitAddProjectedDrone import FitAddProjectedDroneCommand
cmd = FitAddProjectedDroneCommand(self.fitID, self.drone_item)
cmd.Do()
return True

View File

@@ -0,0 +1,35 @@
import wx
import eos.db
from logbook import Logger
from .fitRemoveProjectedModule import FitRemoveProjectedModuleCommand
pyfalog = Logger(__name__)
# this has the same exact definition that regular rpojected modules, besides the undo
class FitRemoveProjectedEnvCommand(FitRemoveProjectedModuleCommand):
""""
from sFit.project
"""
def __init__(self, fitID, itemID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.itemID = itemID
self.removed_item = None
def Do(self):
pyfalog.debug("Removing ({0}) onto: {1}", self.fitID, self.itemID)
fit = eos.db.getFit(self.fitID)
item = next((x for x in fit.projectedModules if x.itemID == self.itemID), None)
self.removed_item = item.itemID
fit.projectedModules.remove(item)
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitAddProjectedEnv import FitAddProjectedEnvCommand
cmd = FitAddProjectedEnvCommand(self.fitID, self.removed_item)
cmd.Do()
return True

View File

@@ -0,0 +1,34 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
# this has the same exact definition that regular rpojected modules, besides the undo
class FitRemoveProjectedFighterCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, position):
wx.Command.__init__(self, True)
self.fitID = fitID
self.position = position
self.removed_item = None
def Do(self):
pyfalog.debug("Removing ({0}) onto: {1}", self.fitID, self.position)
fit = eos.db.getFit(self.fitID)
fighter = fit.projectedFighters[self.position]
fit.projectedFighters.remove(fighter)
self.removed_item = fighter.itemID
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitAddProjectedFighter import FitAddProjectedFighterCommand
cmd = FitAddProjectedFighterCommand(self.fitID, self.removed_item)
cmd.Do()
return True

View File

@@ -0,0 +1,37 @@
import wx
import eos.db
from logbook import Logger
from .fitRemoveProjectedModule import FitRemoveProjectedModuleCommand
pyfalog = Logger(__name__)
# this has the same exact definition that regular rpojected modules, besides the undo
class FitRemoveProjectedFitCommand(FitRemoveProjectedModuleCommand):
""""
from sFit.project
"""
def __init__(self, fitID, projectedFitID):
wx.Command.__init__(self, True)
self.fitID = fitID
self.projectedFitID = projectedFitID
def Do(self):
pyfalog.debug("Removing ({0}) onto: {1}", self.fitID, self.projectedFitID)
fit = eos.db.getFit(self.fitID)
projectedFit = eos.db.getFit(self.projectedFitID)
if projectedFit is None:
return False
del fit.projectedFitDict[projectedFit.ID]
eos.db.commit()
return True
def Undo(self):
# todo: figure out if I need to return false here if the fit doesn't return true (means it was deleted)
from gui.fitCommands.calc.fitAddProjectedFit import FitAddProjectedFitCommand
cmd = FitAddProjectedFitCommand(self.fitID, self.projectedFitID)
cmd.Do()
return True

View File

@@ -0,0 +1,30 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitRemoveProjectedModuleCommand(wx.Command):
""""
from sFit.project
"""
def __init__(self, fitID, position):
wx.Command.__init__(self, True)
self.fitID = fitID
self.position = position
self.removed_item = None
def Do(self):
pyfalog.debug("Removing ({0}) onto: {1}", self.fitID, self.position)
fit = eos.db.getFit(self.fitID)
self.removed_item = fit.projectedModules[self.position].itemID
del fit.projectedModules[self.position]
eos.db.commit()
return True
def Undo(self):
from gui.fitCommands.calc.fitAddProjectedModule import FitAddProjectedModuleCommand
cmd = FitAddProjectedModuleCommand(self.fitID, self.removed_item)
cmd.Do()
return True

View File

@@ -0,0 +1,26 @@
import wx
from logbook import Logger
import eos.db
pyfalog = Logger(__name__)
class FitRenameCommand(wx.Command):
def __init__(self, fitID, newName):
wx.Command.__init__(self, True, "FitRename")
self.fitID = fitID
self.newName = newName
self.oldName = None
def Do(self):
pyfalog.debug("Renaming fit ({0}) to: {1}", self.fitID, self.newName)
fit = eos.db.getFit(self.fitID)
self.oldName = fit.name
fit.name = self.newName
eos.db.commit()
return True
def Undo(self):
cmd = FitRenameCommand(self.fitID, self.oldName)
return cmd.Do()

View File

@@ -0,0 +1,84 @@
import wx
from logbook import Logger
import eos.db
from eos.saveddata.module import Module, State
from gui.fitCommands.helpers import ModuleInfoCache
pyfalog = Logger(__name__)
class FitReplaceModuleCommand(wx.Command):
""""
Fitting command that changes an existing module into another.
from sFit.changeModule
"""
def __init__(self, fitID, position, itemID):
wx.Command.__init__(self, True, "Change Module")
self.fitID = fitID
self.itemID = itemID
self.position = position
self.module = None # the module version of itemID
self.old_module = None
def Do(self):
return self.change_module(self.fitID, self.position, self.itemID)
def Undo(self):
if self.old_module is None:
fit = eos.db.getFit(self.fitID)
fit.modules.toDummy(self.position)
return True
self.change_module(self.fitID, self.position, self.old_module.itemID)
self.module.state = self.old_module.state
self.module.charge = self.old_module.charge
return True
def change_module(self, fitID, position, itemID):
fit = eos.db.getFit(fitID)
# We're trying to add a charge to a slot, which won't work. Instead, try to add the charge to the module in that slot.
# todo: evaluate if this is still a thing
# actually, this seems like it should be handled higher up...
#
# if self.isAmmo(itemID):
# module = fit.modules[self.position]
# if not module.isEmpty:
# self.setAmmo(fitID, itemID, [module])
# return True
pyfalog.debug("Changing position of module from position ({0}) for fit ID: {1}", self.position, fitID)
item = eos.db.getItem(itemID, eager=("attributes", "group.category"))
mod = fit.modules[self.position]
if not mod.isEmpty:
self.old_module = ModuleInfoCache(mod.modPosition, mod.item.ID, mod.state, mod.charge, mod.baseItemID, mod.mutaplasmidID)
try:
self.module = Module(item)
except ValueError:
pyfalog.warning("Invalid item: {0}", itemID)
return False
if self.module.slot != mod.slot:
return False
# Dummy it out in case the next bit fails
fit.modules.toDummy(self.position)
if self.module.fits(fit):
self.module.owner = fit
fit.modules.toModule(self.position, self.module)
if self.module.isValidState(State.ACTIVE):
self.module.state = State.ACTIVE
# Then, check states of all modules and change where needed. This will recalc if needed
# self.checkStates(fit, m)
# fit.fill()
eos.db.commit()
return True
return False

View File

@@ -0,0 +1,46 @@
import wx
from logbook import Logger
import eos.db
import gui.mainFrame
from service.fit import Fit
pyfalog = Logger(__name__)
class FitSetChargeCommand(wx.Command):
def __init__(self, fitID, positions, chargeID=None):
# todo: determine if this command really should be used with a group of modules, or a simple per module basis
wx.Command.__init__(self, True, "Module Charge Add")
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.sFit = Fit.getInstance()
self.fitID = fitID
self.chargeID = chargeID
self.positions = positions
self.cache = None
def Do(self):
return self.__setAmmo(self.positions, self.chargeID)
def Undo(self):
for position, chargeID in self.cache.items():
self.__setAmmo([position], chargeID)
return True
def __setAmmo(self, positions, chargeID):
fit = eos.db.getFit(self.fitID)
self.cache = {fit.modules[i].modPosition: fit.modules[i].chargeID for i in positions}
ammo = eos.db.getItem(chargeID) if chargeID else None
if ammo is not None and not ammo.isCharge:
return False
result = False
for pos in positions:
mod = fit.modules[pos]
if not mod.isEmpty and mod.isValidCharge(ammo):
pyfalog.debug("Set ammo {} for {} on fit {}", ammo, mod, self.fitID)
result = True
mod.charge = ammo
eos.db.commit()
return result

View File

@@ -0,0 +1,28 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitSetModeCommand(wx.Command):
""""
from sFit.setMode
"""
def __init__(self, fitID, mode):
wx.Command.__init__(self, True, "Cargo add")
self.fitID = fitID
self.mode = mode
self.old_mode = None
def Do(self):
pyfalog.debug("Set mode for fit ID: {0}", self.fitID)
fit = eos.db.getFit(self.fitID)
self.old_mode = fit.mode
fit.mode = self.mode
eos.db.commit()
return True
def Undo(self):
cmd = FitSetModeCommand(self.fitID, self.old_mode)
cmd.Do()
return True

View File

@@ -0,0 +1,38 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitSwapModuleCommand(wx.Command):
""""
from sFit.swapModules
"""
def __init__(self, fitID, src, dst):
wx.Command.__init__(self, True, "Module Swap")
self.fitID = fitID
self.src = src
self.dst = dst
def Do(self):
self.__swap(self.fitID, self.src, self.dst)
return True
def Undo(self):
self.__swap(self.fitID, self.dst, self.src)
return True
def __swap(self, fitID, src, dst):
pyfalog.debug("Swapping modules from source ({0}) to destination ({1}) for fit ID: {1}", src, dst, fitID)
fit = eos.db.getFit(fitID)
# Gather modules
srcMod = fit.modules[src]
dstMod = fit.modules[dst]
# To swap, we simply remove mod and insert at destination.
fit.modules.remove(srcMod)
fit.modules.insert(dst, srcMod)
fit.modules.remove(dstMod)
fit.modules.insert(src, dstMod)
eos.db.commit()

View File

@@ -0,0 +1,27 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitToggleBoosterCommand(wx.Command):
""""
from sFit.toggleBooster
"""
def __init__(self, fitID, position):
wx.Command.__init__(self, True, "Cargo add")
self.fitID = fitID
self.position = position
def Do(self):
pyfalog.debug("Toggling booster for fit ID: {0}", self.fitID)
fit = eos.db.getFit(self.fitID)
booster = fit.boosters[self.position]
booster.active = not booster.active
eos.db.commit()
return True
def Undo(self):
cmd = FitToggleBoosterCommand(self.fitID, self.position)
return cmd.Do()

View File

@@ -0,0 +1,36 @@
import wx
import eos.db
from logbook import Logger
pyfalog = Logger(__name__)
class FitToggleCommandCommand(wx.Command):
""""
from sFit.toggleCommandFit
"""
def __init__(self, fitID, commandFitId):
wx.Command.__init__(self, True, "Cargo add")
self.fitID = fitID
self.commandFitID = commandFitId
def Do(self):
pyfalog.debug("Toggle command fit ({0}) for: {1}", self.commandFitID, self.fitID)
commandFit = eos.db.getFit(self.commandFitID)
if not commandFit:
pyfalog.debug(" -- Command fit not found, deleted?")
return False
commandInfo = commandFit.getCommandInfo(self.fitID)
if not commandInfo:
pyfalog.debug(" -- Command fit info not found, deleted?")
return False
commandInfo.active = not commandInfo.active
eos.db.commit()
return True
def Undo(self):
cmd = FitToggleCommandCommand(self.fitID, self.commandFitID)
return cmd.Do()

Some files were not shown because too many files have changed in this diff Show More