From 68f45706ab7dc9c2e68a3f9d868b37b1ce56decc Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Thu, 15 Sep 2016 15:07:59 -0700 Subject: [PATCH 01/13] Purging fleet bonuses from code base --- eos/db/saveddata/fleet.py | 48 +--- eos/db/saveddata/queries.py | 58 ----- eos/types.py | 1 - gui/additionsPane.py | 7 +- gui/builtinViews/fleetView.py | 141 +---------- gui/fleetBrowser.py | 457 +--------------------------------- gui/gangView.py | 394 +---------------------------- gui/mainFrame.py | 7 - service/__init__.py | 1 - service/fit.py | 13 +- service/fleet.py | 197 +-------------- 11 files changed, 7 insertions(+), 1317 deletions(-) diff --git a/eos/db/saveddata/fleet.py b/eos/db/saveddata/fleet.py index 8f0e6736b..0583b43b0 100644 --- a/eos/db/saveddata/fleet.py +++ b/eos/db/saveddata/fleet.py @@ -17,50 +17,4 @@ # along with eos. If not, see . #=============================================================================== -from sqlalchemy import Table, Column, Integer, ForeignKey, String -from sqlalchemy.orm import mapper, relation - -from eos.db import saveddata_meta -from eos.types import Fleet, Wing, Squad, Fit -from eos.db.saveddata.fit import fits_table - -gangs_table = Table("gangs", saveddata_meta, - Column("ID", Integer, primary_key = True), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("name", String)) - -wings_table = Table("wings", saveddata_meta, - Column("ID", Integer, primary_key = True), - Column("gangID", ForeignKey("gangs.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("leaderID", ForeignKey("fits.ID"))) - -squads_table = Table("squads", saveddata_meta, - Column("ID", Integer, primary_key = True), - Column("wingID", ForeignKey("wings.ID")), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID"))) - -squadmembers_table = Table("squadmembers", saveddata_meta, - Column("squadID", ForeignKey("squads.ID"), primary_key = True), - Column("memberID", ForeignKey("fits.ID"), primary_key = True)) - -mapper(Fleet, gangs_table, - properties = {"wings" : relation(Wing, backref="gang"), - "leader" : relation(Fit, primaryjoin = gangs_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin = gangs_table.c.boosterID == fits_table.c.ID)}) - -mapper(Wing, wings_table, - properties = {"squads" : relation(Squad, backref="wing"), - "leader" : relation(Fit, primaryjoin = wings_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin = wings_table.c.boosterID == fits_table.c.ID)}) - -mapper(Squad, squads_table, - properties = {"leader" : relation(Fit, primaryjoin = squads_table.c.leaderID == fits_table.c.ID), - "booster" : relation(Fit, primaryjoin = squads_table.c.boosterID == fits_table.c.ID), - "members" : relation(Fit, - primaryjoin = squads_table.c.ID == squadmembers_table.c.squadID, - secondaryjoin = squadmembers_table.c.memberID == fits_table.c.ID, - secondary = squadmembers_table)}) - +#Purging fleet \ No newline at end of file diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index 5a6dd1bfc..cb3033cc1 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -21,7 +21,6 @@ from eos.db.util import processEager, processWhere from eos.db import saveddata_session, sd_lock from eos.types import * -from eos.db.saveddata.fleet import squadmembers_table from eos.db.saveddata.fit import projectedFits_table from sqlalchemy.sql import and_ import eos.config @@ -194,48 +193,6 @@ def getFit(lookfor, eager=None): return fit -@cachedQuery(Fleet, 1, "fleetID") -def getFleet(fleetID, eager=None): - if isinstance(fleetID, int): - if eager is None: - with sd_lock: - fleet = saveddata_session.query(Fleet).get(fleetID) - else: - eager = processEager(eager) - with sd_lock: - fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first() - else: - raise TypeError("Need integer as argument") - return fleet - -@cachedQuery(Wing, 1, "wingID") -def getWing(wingID, eager=None): - if isinstance(wingID, int): - if eager is None: - with sd_lock: - wing = saveddata_session.query(Wing).get(wingID) - else: - eager = processEager(eager) - with sd_lock: - wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first() - else: - raise TypeError("Need integer as argument") - return wing - -@cachedQuery(Squad, 1, "squadID") -def getSquad(squadID, eager=None): - if isinstance(squadID, int): - if eager is None: - with sd_lock: - squad = saveddata_session.query(Squad).get(squadID) - else: - eager = processEager(eager) - with sd_lock: - squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first() - else: - raise TypeError("Need integer as argument") - return squad - def getFitsWithShip(shipID, ownerID=None, where=None, eager=None): """ Get all the fits using a certain ship. @@ -308,12 +265,6 @@ def getFitList(eager=None): return fits -def getFleetList(eager=None): - eager = processEager(eager) - with sd_lock: - fleets = saveddata_session.query(Fleet).options(*eager).all() - return fleets - @cachedQuery(Price, 1, "typeID") def getPrice(typeID): if isinstance(typeID, int): @@ -423,15 +374,6 @@ def searchFits(nameLike, where=None, eager=None): return fits -def getSquadsIDsWithFitID(fitID): - if isinstance(fitID, int): - with sd_lock: - squads = saveddata_session.query(squadmembers_table.c.squadID).filter(squadmembers_table.c.memberID == fitID).all() - squads = tuple(entry[0] for entry in squads) - return squads - else: - raise TypeError("Need integer as argument") - def getProjectedFits(fitID): if isinstance(fitID, int): with sd_lock: diff --git a/eos/types.py b/eos/types.py index 12e7eb281..f2550ad31 100644 --- a/eos/types.py +++ b/eos/types.py @@ -38,7 +38,6 @@ from eos.saveddata.booster import SideEffect from eos.saveddata.booster import Booster from eos.saveddata.fit import Fit, ImplantLocation from eos.saveddata.mode import Mode -from eos.saveddata.fleet import Fleet, Wing, Squad from eos.saveddata.miscData import MiscData from eos.saveddata.override import Override diff --git a/gui/additionsPane.py b/gui/additionsPane.py index 8c855dc95..f1ca44be4 100644 --- a/gui/additionsPane.py +++ b/gui/additionsPane.py @@ -26,7 +26,6 @@ from gui.cargoView import CargoView from gui.implantView import ImplantView from gui.projectedView import ProjectedView from gui.pyfatogglepanel import TogglePanel -from gui.gangView import GangView from gui.bitmapLoader import BitmapLoader import gui.chromeTabs @@ -55,7 +54,6 @@ class AdditionsPane(TogglePanel): implantImg = BitmapLoader.getImage("implant_small", "gui") boosterImg = BitmapLoader.getImage("booster_small", "gui") projectedImg = BitmapLoader.getImage("projected_small", "gui") - gangImg = BitmapLoader.getImage("fleet_fc_small", "gui") cargoImg = BitmapLoader.getImage("cargo_small", "gui") self.drone = DroneView(self.notebook) @@ -76,12 +74,9 @@ class AdditionsPane(TogglePanel): self.projectedPage = ProjectedView(self.notebook) self.notebook.AddPage(self.projectedPage, "Projected", tabImage = projectedImg, showClose = False) - self.gangPage = GangView(self.notebook) - self.notebook.AddPage(self.gangPage, "Fleet", tabImage = gangImg, showClose = False) - self.notebook.SetSelection(0) - PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected", "Fleet"] + PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected"] def select(self, name): self.notebook.SetSelection(self.PANES.index(name)) diff --git a/gui/builtinViews/fleetView.py b/gui/builtinViews/fleetView.py index bc6eef9a2..9058bc35f 100644 --- a/gui/builtinViews/fleetView.py +++ b/gui/builtinViews/fleetView.py @@ -1,140 +1 @@ -import wx.gizmos -import gui.fleetBrowser -import service -from gui.bitmapLoader import BitmapLoader - -#Tab spawning handler -class FleetSpawner(gui.multiSwitch.TabSpawner): - def __init__(self, multiSwitch): - self.multiSwitch = multiSwitch - mainFrame = gui.mainFrame.MainFrame.getInstance() - mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_SELECTED, self.fleetSelected) - - def fleetSelected(self, event): - if self.multiSwitch.GetPageCount() == 0: - self.multiSwitch.AddPage(wx.Panel(self.multiSwitch, size = (0,0)), "Empty Tab") - - view = FleetView(self.multiSwitch) - self.multiSwitch.ReplaceActivePage(view) - view.populate(event.fleetID) - view.Show() - -FleetSpawner.register() - -class FleetView(wx.gizmos.TreeListCtrl): - def __init__(self, parent, size = (0,0)): - wx.gizmos.TreeListCtrl.__init__(self, parent, size = size) - - self.tabManager = parent - - self.fleetId = None - self.fleetImg = BitmapLoader.getImage("53_16", "icons") - - self.imageList = wx.ImageList(16, 16) - self.SetImageList(self.imageList) - - for col in ("", "Fit", "Shiptype", "Character", "Bonusses"): - self.AddColumn(col) - - self.SetMainColumn(1) - self.icons = {} - self.addImage = self.imageList.Add(BitmapLoader.getBitmap("add_small", "gui")) - for icon in ("fb", "fc", "sb", "sc", "wb", "wc"): - self.icons[icon] = self.imageList.Add(BitmapLoader.getBitmap("fleet_%s_small" % icon, "gui")) - - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.checkNew) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_RENAMED, self.fleetRenamed) - self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_REMOVED, self.fleetRemoved) - - def Destroy(self): - self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_REMOVED, handler = self.fleetRemoved) - self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_RENAMED, handler = self.fleetRenamed) - wx.gizmos.TreeListCtrl.Destroy(self) - - def fleetRenamed(self, event): - if event.fleetID == self.fleetId: - sFleet = service.Fleet.getInstance() - f = sFleet.getFleetByID(event.fleetID) - self.UpdateTab(f.name, self.fleetImg) - - event.Skip() - - def fleetRemoved(self, event): - if event.fleetID == self.fleetId: - self.tabManager.DeletePage(self.tabManager.GetPageIndex(self)) - - event.Skip() - - def checkNew(self, event): - data = self.GetPyData(event.Item) - if data and isinstance(data, tuple) and data[0] == "add": - layer = data[1] - - - def UpdateTab(self, name, img): - self.tabManager.SetPageTextIcon(self.tabManager.GetSelection(), name, img) - - def populate(self, fleetID): - sFleet = service.Fleet.getInstance() - f = sFleet.getFleetByID(fleetID) - self.fleetId = fleetID - - self.UpdateTab( f.name, self.fleetImg) - self.fleet = f - self.DeleteAllItems() - root = self.AddRoot("") - - self.setEntry(root, f.leader, "fleet", f) - for wing in f.wings: - wingId = self.AppendItem(root, "") - self.setEntry(wingId, wing.leader, "wing", wing) - for squad in wing.squads: - for member in squad.members: - memberId = self.AppendItem(wingId, "") - self.setEntry(memberId, member, "squad", squad) - - self.addAdder(wingId, "squad") - - self.addAdder(root, "wing") - - self.ExpandAll(root) - self.SetColumnWidth(0, 16) - for i in xrange(1, 5): - self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) - headerWidth = self.GetColumnWidth(i) + 5 - self.SetColumnWidth(i, wx.LIST_AUTOSIZE) - baseWidth = self.GetColumnWidth(i) - if baseWidth < headerWidth: - self.SetColumnWidth(i, headerWidth) - else: - self.SetColumnWidth(i, baseWidth) - - - def addAdder(self, treeItemId, layer): - id = self.AppendItem(treeItemId, "Add new %s" % layer.capitalize()) - self.SetPyData(id, ("add", layer)) - self.SetItemImage(id, self.addImage, 1) - - def setEntry(self, treeItemId, fit, layer, info): - self.SetPyData(treeItemId, info) - if fit is None: - self.SetItemText(treeItemId, "%s Commander" % layer.capitalize(), 1) - else: - fleet = self.fleet - if fit == info.booster: - self.SetItemImage(treeItemId, self.icons["%sb" % layer[0]], 0) - elif fit == info.leader: - self.SetItemImage(treeItemId, self.icons["%sc" % layer[0]], 1) - - self.SetItemText(treeItemId, fit.name, 1) - self.SetItemText(treeItemId, fit.ship.item.name, 2) - self.SetItemText(treeItemId, fit.character.name, 3) - boosts = fleet.store.getBoosts(fit) - if boosts: - bonusses = [] - for name, info in boosts.iteritems(): - bonusses.append("%s: %.2g" % (name, info[0])) - - self.SetItemText(treeItemId, ", ".join(bonusses), 3) +#Purge fleet boosts \ No newline at end of file diff --git a/gui/fleetBrowser.py b/gui/fleetBrowser.py index 7476d7d7f..bb28be251 100644 --- a/gui/fleetBrowser.py +++ b/gui/fleetBrowser.py @@ -1,456 +1 @@ -import wx -import copy -from gui.bitmapLoader import BitmapLoader -import gui.mainFrame -from gui.PFListPane import PFListPane -import service.fleet -from gui.utils.drawUtils import GetPartialText - -from wx.lib.buttons import GenBitmapButton - -import gui.utils.colorUtils as colorUtils -import gui.utils.drawUtils as drawUtils - -import gui.sfBrowserItem as SFItem - -FleetSelected, EVT_FLEET_SELECTED = wx.lib.newevent.NewEvent() -FleetRenamed, EVT_FLEET_RENAMED = wx.lib.newevent.NewEvent() -FleetRemoved, EVT_FLEET_REMOVED = wx.lib.newevent.NewEvent() - - -FleetItemSelect, EVT_FLEET_ITEM_SELECT = wx.lib.newevent.NewEvent() -FleetItemDelete, EVT_FLEET_ITEM_DELETE = wx.lib.newevent.NewEvent() -FleetItemNew, EVT_FLEET_ITEM_NEW = wx.lib.newevent.NewEvent() -FleetItemCopy, EVT_FLEET_ITEM_COPY = wx.lib.newevent.NewEvent() -FleetItemRename, EVT_FLEET_ITEM_RENAME = wx.lib.newevent.NewEvent() - - - -class FleetBrowser(wx.Panel): - def __init__(self, parent): - wx.Panel.__init__(self, parent) - - self.sFleet = service.fleet.Fleet.getInstance() - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - mainSizer = wx.BoxSizer(wx.VERTICAL) - - self.hpane = FleetBrowserHeader(self) - mainSizer.Add(self.hpane, 0, wx.EXPAND) - - self.m_sl2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - mainSizer.Add( self.m_sl2, 0, wx.EXPAND, 0 ) - - self.fleetItemContainer = PFFleetItemContainer(self) - - mainSizer.Add(self.fleetItemContainer, 1, wx.EXPAND) - - self.SetSizer(mainSizer) - self.Layout() - - self.filter = "" - self.fleetIDMustEditName = -1 - - self.Bind(wx.EVT_SIZE, self.SizeRefreshList) - - self.Bind(EVT_FLEET_ITEM_NEW, self.AddNewFleetItem) - self.Bind(EVT_FLEET_ITEM_SELECT, self.SelectFleetItem) - self.Bind(EVT_FLEET_ITEM_DELETE, self.DeleteFleetItem) - self.Bind(EVT_FLEET_ITEM_COPY, self.CopyFleetItem) - self.Bind(EVT_FLEET_ITEM_RENAME, self.RenameFleetItem) - - self.PopulateFleetList() - - def AddNewFleetItem(self, event): - fleetName = event.fleetName - newFleet = self.sFleet.addFleet() - self.sFleet.renameFleet(newFleet, fleetName) - - self.fleetIDMustEditName = newFleet.ID - self.AddItem(newFleet.ID, newFleet.name, newFleet.count()) - - def SelectFleetItem(self, event): - fleetID = event.fleetID - self.fleetItemContainer.SelectWidgetByFleetID(fleetID) - wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleetID)) - - def CopyFleetItem(self, event): - fleetID = event.fleetID - fleet = self.sFleet.copyFleetByID(fleetID) - - fleetName = fleet.name + " Copy" - self.sFleet.renameFleet(fleet,fleetName) - - self.fleetIDMustEditName = fleet.ID - self.AddItem(fleet.ID, fleet.name, fleet.count()) - - self.fleetItemContainer.SelectWidgetByFleetID(fleet.ID) - wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleet.ID)) - - def RenameFleetItem(self, event): - fleetID = event.fleetID - fleet = self.sFleet.getFleetByID(fleetID) - - newFleetName = event.fleetName - - self.sFleet.renameFleet(fleet, newFleetName) - wx.PostEvent(self.mainFrame, FleetRenamed(fleetID = fleet.ID)) - - def DeleteFleetItem(self, event): - self.sFleet.deleteFleetByID(event.fleetID) - self.PopulateFleetList() - wx.PostEvent(self.mainFrame, FleetRemoved(fleetID = event.fleetID)) - - def AddItem (self, ID, name, count): - self.fleetItemContainer.AddWidget(FleetItem(self, ID, name, count)) - widget = self.fleetItemContainer.GetWidgetByFleetID(ID) - self.fleetItemContainer.RefreshList(True) - self.fleetItemContainer.ScrollChildIntoView(widget) - wx.PostEvent(self, FleetItemSelect(fleetID = ID)) - - def PopulateFleetList(self): - self.Freeze() - filter = self.filter - self.fleetItemContainer.RemoveAllChildren() - fleetList = self.sFleet.getFleetList() - for fleetID, fleetName, fleetCount in fleetList: - if fleetName.lower().find(filter.lower()) != -1: - self.fleetItemContainer.AddWidget(FleetItem(self, fleetID, fleetName, fleetCount)) - self.fleetItemContainer.RefreshList() - self.Thaw() - - def SetFilter(self, filter): - self.filter = filter - - def SizeRefreshList(self, event): - ewidth, eheight = event.GetSize() - self.Layout() - self.fleetItemContainer.Layout() - self.fleetItemContainer.RefreshList(True) - event.Skip() - - -class FleetBrowserHeader (wx.Panel): - def __init__(self, parent): - wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 24), style=wx.TAB_TRAVERSAL) - self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) ) - - self.newBmp = BitmapLoader.getBitmap("fit_add_small","gui") - bmpSize = (16,16) - - mainSizer = wx.BoxSizer(wx.HORIZONTAL) - - if 'wxMac' in wx.PlatformInfo: - bgcolour = wx.Colour(0, 0, 0, 0) - else: - bgcolour = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) - - self.fbNewFleet = PFGenBitmapButton( self, wx.ID_ANY, self.newBmp, wx.DefaultPosition, bmpSize, wx.BORDER_NONE ) - mainSizer.Add(self.fbNewFleet, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL , 5) - self.fbNewFleet.SetBackgroundColour( bgcolour ) - - self.sl1 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_VERTICAL ) - mainSizer.Add( self.sl1, 0, wx.EXPAND |wx.LEFT, 5 ) - - self.tcFilter = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) - mainSizer.Add( self.tcFilter, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.stStatus = wx.StaticText( self, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stStatus.Wrap( -1 ) - mainSizer.Add( self.stStatus, 1, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.SetSizer(mainSizer) - self.Layout() - - self.fbNewFleet.Bind(wx.EVT_ENTER_WINDOW, self.fbNewEnterWindow) - self.fbNewFleet.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) - self.fbNewFleet.Bind(wx.EVT_BUTTON, self.OnNewFleetItem) - - self.tcFilter.Bind(wx.EVT_TEXT, self.OnFilterText) - - self.tcFilter.Bind(wx.EVT_ENTER_WINDOW, self.fbFilterEnterWindow) - self.tcFilter.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) - - def OnFilterText(self, event): - filter = self.tcFilter.GetValue() - self.Parent.SetFilter(filter) - self.Parent.PopulateFleetList() - event.Skip() - - def OnNewFleetItem(self, event): - wx.PostEvent(self.Parent, FleetItemNew(fleetName = "New Fleet")) - - def fbNewEnterWindow(self, event): - self.stStatus.SetLabel("New fleet") - self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - event.Skip() - - def fbHItemLeaveWindow(self, event): - self.stStatus.SetLabel("") - self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - event.Skip() - - def fbFilterEnterWindow(self, event): - self.stStatus.SetLabel("Filter list") - event.Skip() - - - -class PFFleetItemContainer(PFListPane): - def __init__(self,parent): - PFListPane.__init__(self,parent) - self.selectedWidget = -1 - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - - def IsWidgetSelectedByContext(self, widget): - if self.GetWidgetList()[widget].IsSelected(): - return True - return False - - def GetWidgetIndex(self, widgetWnd): - return self.GetWidgetList().index(widgetWnd) - - def GetWidgetByFleetID(self, fleetID): - for widget in self.GetWidgetList(): - if widget.fleetID == fleetID: - return widget - return None - - def SelectWidget(self, widgetWnd): - wlist = self.GetWidgetList() - if self.selectedWidget != -1: - wlist[self.selectedWidget].SetSelected(False) - wlist[self.selectedWidget].Refresh() - windex = self.GetWidgetIndex(widgetWnd) - wlist[windex].SetSelected(True) - wlist[windex].Refresh() - self.selectedWidget = windex - - def SelectWidgetByFleetID(self, fleetID): - widgetWnd = self.GetWidgetByFleetID(fleetID) - if widgetWnd: - self.SelectWidget(widgetWnd) - - def RemoveWidget(self, child): - child.Destroy() - self.selectedWidget = -1 - self._wList.remove(child) - - - def RemoveAllChildren(self): - for widget in self._wList: - widget.Destroy() - - self.selectedWidget = -1 - self._wList = [] - - def OnLeftUp(self, event): - event.Skip() - -class FleetItem(SFItem.SFBrowserItem): - def __init__(self, parent, fleetID, fleetName, fleetCount, - id=wx.ID_ANY, pos=wx.DefaultPosition, - size=(0,40), style=0): - SFItem.SFBrowserItem.__init__(self, parent, size = size) - - self.fleetBrowser = self.Parent - self.fleetID = fleetID - self.fleetName = fleetName - self.fleetCount = fleetCount - - self.padding = 4 - - self.fontBig = wx.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.BOLD, False) - self.fontNormal = wx.FontFromPixelSize((0,14),wx.SWISS, wx.NORMAL, wx.NORMAL, False) - self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False) - - self.copyBmp = BitmapLoader.getBitmap("fit_add_small", "gui") - self.renameBmp = BitmapLoader.getBitmap("fit_rename_small", "gui") - self.deleteBmp = BitmapLoader.getBitmap("fit_delete_small","gui") - self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui") - self.fleetBmp = BitmapLoader.getBitmap("fleet_item_big", "gui") - - fleetImg = self.fleetBmp.ConvertToImage() - fleetImg = fleetImg.Blur(2) - - if not fleetImg.HasAlpha(): - fleetImg.InitAlpha() - - fleetImg = fleetImg.AdjustChannels(1, 1, 1, 0.5) - self.fleetEffBmp = wx.BitmapFromImage(fleetImg) - - self.toolbar.AddButton(self.copyBmp, "Copy", self.CopyFleetCB) - self.renameBtn = self.toolbar.AddButton(self.renameBmp, "Rename", self.RenameFleetCB) - self.toolbar.AddButton(self.deleteBmp, "Delete", self.DeleteFleetCB) - - self.editWidth = 150 - self.tcFleetName = wx.TextCtrl(self, wx.ID_ANY, "%s" % self.fleetName, wx.DefaultPosition, (self.editWidth,-1), wx.TE_PROCESS_ENTER) - - if self.fleetBrowser.fleetIDMustEditName != self.fleetID: - self.tcFleetName.Show(False) - else: - self.tcFleetName.SetFocus() - self.tcFleetName.SelectAll() - self.fleetBrowser.fleetIDMustEditName = -1 - self.renameBtn.SetBitmap(self.acceptBmp) - self.selected = True - - self.tcFleetName.Bind(wx.EVT_KILL_FOCUS, self.OnEditLostFocus) - self.tcFleetName.Bind(wx.EVT_TEXT_ENTER, self.RenameFleet) - self.tcFleetName.Bind(wx.EVT_KEY_DOWN, self.EditCheckEsc) - - - self.animCount = 0 - - def MouseLeftUp(self, event): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - else: - wx.PostEvent(self.fleetBrowser, FleetItemSelect(fleetID = self.fleetID)) - - def CopyFleetCB(self): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - return - - wx.PostEvent(self.fleetBrowser, FleetItemCopy(fleetID = self.fleetID)) - - def RenameFleetCB(self): - - if self.tcFleetName.IsShown(): - - self.RenameFleet(None) - self.RestoreEditButton() - - else: - self.tcFleetName.SetValue(self.fleetName) - self.tcFleetName.Show() - - self.renameBtn.SetBitmap(self.acceptBmp) - self.Refresh() - - self.tcFleetName.SetFocus() - self.tcFleetName.SelectAll() - - self.Refresh() - - def RenameFleet(self, event): - - newFleetName = self.tcFleetName.GetValue() - self.fleetName = newFleetName - - self.tcFleetName.Show(False) - - wx.PostEvent(self.fleetBrowser, FleetItemRename(fleetID = self.fleetID, fleetName = self.fleetName)) - self.Refresh() - - def DeleteFleetCB(self): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - return - wx.PostEvent(self.fleetBrowser, FleetItemDelete(fleetID = self.fleetID)) - - def RestoreEditButton(self): - self.tcFleetName.Show(False) - self.renameBtn.SetBitmap(self.renameBmp) - self.Refresh() - - def OnEditLostFocus(self, event): - self.RestoreEditButton() - self.Refresh() - - def EditCheckEsc(self, event): - if event.GetKeyCode() == wx.WXK_ESCAPE: - self.RestoreEditButton() - else: - event.Skip() - - def IsSelected(self): - return self.selected - - def UpdateElementsPos(self, mdc): - rect = self.GetRect() - - self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding - self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2 - - self.toolbarx = self.toolbarx + self.animCount - - self.fleetBmpx = self.padding + (rect.height - self.fleetBmp.GetWidth()) / 2 - self.fleetBmpy = (rect.height - self.fleetBmp.GetHeight()) / 2 - - self.fleetBmpx -= self.animCount - - self.textStartx = self.fleetBmpx + self.fleetBmp.GetWidth() + self.padding - - self.fleetNamey = (rect.height - self.fleetBmp.GetHeight()) / 2 - - mdc.SetFont(self.fontBig) - wtext, htext = mdc.GetTextExtent(self.fleetName) - - self.fleetCounty = self.fleetNamey + htext - - mdc.SetFont(self.fontSmall) - - wlabel,hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel) - - self.thoverx = self.toolbarx - self.padding - wlabel - self.thovery = (rect.height - hlabel)/2 - self.thoverw = wlabel - - def DrawItem(self, mdc): - rect = self.GetRect() - - windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW) - textColor = colorUtils.GetSuitableColor(windowColor, 1) - - mdc.SetTextForeground(textColor) - - self.UpdateElementsPos(mdc) - - self.toolbar.SetPosition((self.toolbarx, self.toolbary)) - mdc.DrawBitmap(self.fleetEffBmp, self.fleetBmpx + 3, self.fleetBmpy + 2) - mdc.DrawBitmap(self.fleetBmp, self.fleetBmpx,self.fleetBmpy) - - mdc.SetFont(self.fontNormal) - - suffix = "%d ships" % self.fleetCount if self.fleetCount >1 else "%d ship" % self.fleetCount if self.fleetCount == 1 else "No ships" - fleetCount = "Fleet size: %s" % suffix - fleetCount = drawUtils.GetPartialText(mdc, fleetCount, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) - - mdc.DrawText(fleetCount, self.textStartx, self.fleetCounty) - - mdc.SetFont(self.fontSmall) - mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery) - - mdc.SetFont(self.fontBig) - - pfname = drawUtils.GetPartialText(mdc, self.fleetName, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) - mdc.DrawText(pfname, self.textStartx, self.fleetNamey) - - if self.tcFleetName.IsShown(): - self.AdjustControlSizePos(self.tcFleetName, self.textStartx, self.toolbarx - self.editWidth - self.padding) - - def AdjustControlSizePos(self, editCtl, start, end): - fnEditSize = editCtl.GetSize() - wSize = self.GetSize() - fnEditPosX = end - fnEditPosY = (wSize.height - fnEditSize.height)/2 - if fnEditPosX < start: - editCtl.SetSize((self.editWidth + fnEditPosX - start,-1)) - editCtl.SetPosition((start,fnEditPosY)) - else: - editCtl.SetSize((self.editWidth,-1)) - editCtl.SetPosition((fnEditPosX,fnEditPosY)) - - -class PFGenBitmapButton(GenBitmapButton): - def __init__(self, parent, id, bitmap, pos, size, style): - GenBitmapButton.__init__(self, parent, id, bitmap, pos, size, style) - self.bgcolor = wx.Brush(wx.WHITE) - - def SetBackgroundColour(self, color): - self.bgcolor = wx.Brush(color) - - def GetBackgroundBrush(self, dc): - return self.bgcolor +# purging fleet \ No newline at end of file diff --git a/gui/gangView.py b/gui/gangView.py index 106f14f98..d5f8e43cb 100644 --- a/gui/gangView.py +++ b/gui/gangView.py @@ -16,397 +16,5 @@ # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . #=============================================================================== -import wx -from wx.lib.scrolledpanel import ScrolledPanel -import service -import gui.mainFrame -import gui.shipBrowser -import gui.globalEvents as GE - -from gui import characterEditor as CharEditor - -class GangView ( ScrolledPanel ): - - def __init__( self, parent ): - ScrolledPanel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 100,20 ), style = wx.TAB_TRAVERSAL | wx.HSCROLL | wx.VSCROLL ) - mainSizer = wx.BoxSizer( wx.VERTICAL ) - - self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - self.draggedFitID = None - - help = '''Set fit as booster to display in dropdown, or drag fitting from\nship browser to this window, or right click fit and select booster role.''' - helpSizer = wx.BoxSizer( wx.HORIZONTAL ) - self.helpText = wx.StaticText( self, wx.ID_ANY, help, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE ) - helpSizer.Add( self.helpText, 1, wx.ALL, 5 ) - - self.options = ["Fleet", "Wing", "Squad"] - - self.fleet = {} - for id, option in enumerate(self.options): - - # set content for each commander - self.fleet[id] = {} - self.fleet[id]['stLabel'] = wx.StaticText( self, wx.ID_ANY, self.options[id]+':', wx.DefaultPosition, wx.DefaultSize, 0 ) - self.fleet[id]['stText'] = wx.StaticText( self, wx.ID_ANY, 'None', wx.DefaultPosition, wx.DefaultSize, 0 ) - self.fleet[id]['chFit'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) - self.fleet[id]['chChar'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) - self.fleet[id]['fitSizer'] = wx.BoxSizer( wx.VERTICAL ) - - self.FitDNDPopupMenu = self.buildBoostermenu() - - contentFGSizer = wx.FlexGridSizer( 5, 3, 0, 0 ) - contentFGSizer.AddGrowableCol( 1 ) - contentFGSizer.SetFlexibleDirection( wx.BOTH ) - contentFGSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED ) - - ### Header - self.stBooster = wx.StaticText( self, wx.ID_ANY, u"Booster", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stBooster.Wrap( -1 ) - self.stBooster.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stBooster, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.stFits = wx.StaticText( self, wx.ID_ANY, u"Fits", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stFits.Wrap( -1 ) - self.stFits.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stFits, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.stCharacters = wx.StaticText( self, wx.ID_ANY, u"Characters", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stCharacters.Wrap( -1 ) - self.stCharacters.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stCharacters, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.m_staticline2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline2, 0, wx.EXPAND, 5 ) - - self.m_staticline3 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline3, 0, wx.EXPAND, 5 ) - - self.m_staticline4 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline4, 0, wx.EXPAND, 5 ) - - ### Content - for id in self.fleet: - # set various properties - self.fleet[id]['stLabel'].Wrap( -1 ) - self.fleet[id]['stLabel'].SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - self.fleet[id]['stText'].Wrap( -1 ) - - # bind text and choice events - self.fleet[id]['stText'].Bind(wx.EVT_LEFT_DCLICK, self.RemoveBooster) - self.fleet[id]['stText'].Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) - self.fleet[id]['stText'].Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) - self.fleet[id]['stText'].SetToolTip(wx.ToolTip("Double click to remove booster")) - self.fleet[id]['chChar'].Bind(wx.EVT_CHOICE, self.CharChanged) - self.fleet[id]['chFit'].Bind(wx.EVT_CHOICE, self.OnFitChoiceSelected) - - # add fit text and choice to the fit sizer - self.fleet[id]['fitSizer'].Add( self.fleet[id]['stText'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - self.fleet[id]['fitSizer'].Add( self.fleet[id]['chFit'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 1 ) - - # add everything to the content sizer - contentFGSizer.Add( self.fleet[id]['stLabel'], 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - contentFGSizer.Add( self.fleet[id]['fitSizer'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 5 ) - contentFGSizer.Add( self.fleet[id]['chChar'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - - mainSizer.Add( contentFGSizer, 1, wx.EXPAND, 0 ) - mainSizer.Add( helpSizer, 0, wx.EXPAND, 0 ) - - self.SetSizer( mainSizer ) - self.SetAutoLayout(True) - self.SetupScrolling() - - self.mainFrame.Bind(GE.CHAR_LIST_UPDATED, self.RefreshCharacterList) - self.mainFrame.Bind(GE.FIT_CHANGED, self.fitSelected) - self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_RENAMED, self.fitRenamed) - self.mainFrame.Bind(gui.shipBrowser.BOOSTER_LIST_UPDATED, self.RefreshBoosterFits) - - self.RefreshBoosterFits() - self.RefreshCharacterList() - - def buildBoostermenu(self): - menu = wx.Menu() - - for id, option in enumerate(self.options): - item = menu.Append(-1, option) - # We bind it to the mainFrame because it may be called from either this class or from FitItem via shipBrowser - self.mainFrame.Bind(wx.EVT_MENU, self.OnPopupItemSelected, item) - return menu - - def OnEnterWindow(self, event): - obj = event.GetEventObject() - obj.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - event.Skip() - - def OnLeaveWindow(self, event): - obj = event.GetEventObject() - obj.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) - event.Skip() - - def CharChanged(self, event): - ''' Change booster character ''' - chBooster = event.GetEventObject() - - type = -1 - for id in self.fleet: - if chBooster == self.fleet[id]['chChar']: type = id - - if type == -1: - event.Skip() - return - - sFit = service.Fit.getInstance() - - fleetSrv = service.Fleet.getInstance() - - activeFitID = self.mainFrame.getActiveFit() - fit = sFit.getFit(activeFitID) - - sChar = service.Character.getInstance() - charList = sChar.getCharacterList() - - if activeFitID: - commanders = fleetSrv.loadLinearFleet(fit) - if commanders is None: - fleetCom, wingCom, squadCom = (None, None, None) - else: - fleetCom, wingCom, squadCom = commanders - - if type == 0: - if fleetCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(fleetCom.ID, charID) - else: - chBooster.SetSelection(0) - - if type == 1: - if wingCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(wingCom.ID, charID) - else: - chBooster.SetSelection(0) - - if type == 2: - if squadCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(squadCom.ID, charID) - else: - chBooster.SetSelection(0) - - sFit.recalc(fit, withBoosters=True) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - else: - chBooster.SetSelection(0) - - def RemoveBooster(self, event): - activeFitID = self.mainFrame.getActiveFit() - if not activeFitID: - return - - location = event.GetEventObject() - - for id in self.fleet: - if location == self.fleet[id]['stText']: type = id - - sFit = service.Fit.getInstance() - boostee = sFit.getFit(activeFitID) - booster = None - - fleetSrv = service.Fleet.getInstance() - - if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) - if type == 1: fleetSrv.setLinearWingCom(boostee, booster) - if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) - - # Hide stText and, default fit selection, and enable it - location.Hide() - choice = self.fleet[type]['chFit'] - choice.SetSelection(0) - choice.Show() - - sFit.recalc(boostee, withBoosters=True) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - def fitRenamed(self, event): - fleetSrv = service.Fleet.getInstance() - activeFitID = self.mainFrame.getActiveFit() - - if activeFitID: - ev = event - ev.fitID = activeFitID - self.fitSelected(ev) - - def fitSelected(self, event): - ''' Fires when active fit is selected and when booster is saved to fit. Update the UI to reflect changes ''' - fleetSrv = service.Fleet.getInstance() - - activeFitID = self.mainFrame.getActiveFit() - sFit = service.Fit.getInstance() - fit = sFit.getFit(event.fitID or activeFitID) - - self.Parent.Parent.DisablePage(self, not fit or fit.isStructure) - - commanders = (None, None, None) - - if activeFitID: - commanders = fleetSrv.loadLinearFleet(fit) - - for id in self.fleet: - # try...except here as we're trying 2 different criteria and want to fall back on the same code - try: - commander = commanders[id] - - if not activeFitID or commander is None: - raise Exception() - - self.fleet[id]['stText'].SetLabel(commander.ship.item.name + ": " + commander.name) - self.fleet[id]['chChar'].SetStringSelection(commander.character.name if commander.character is not None else "All 0") - self.fleet[id]['chChar'].Enable() - self.fleet[id]['chFit'].Hide() - self.fleet[id]['stText'].Show() - except: - #set defaults, disable char selection, and enable fit selection - self.fleet[id]['stText'].SetLabel("None") - self.fleet[id]['chChar'].SetStringSelection("All 0") - self.fleet[id]['chChar'].Disable() - self.fleet[id]['chFit'].SetSelection(0) - self.fleet[id]['chFit'].Show() - self.fleet[id]['stText'].Hide() - - if activeFitID: - self.Enable() - else: - self.Disable() - - self.Layout() - self.SendSizeEvent() - - def AddCommander(self, fitID, type = None): - ''' Adds booster to a fit, then recalculates active fit ''' - if type is None: - return - - activeFitID = self.mainFrame.getActiveFit() - if activeFitID: - sFit = service.Fit.getInstance() - - boostee = sFit.getFit(activeFitID) - booster = sFit.getFit(fitID) - - fleetSrv = service.Fleet.getInstance() - - if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) - if type == 1: fleetSrv.setLinearWingCom(boostee, booster) - if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) - - sFit.recalc(boostee) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - def RefreshBoosterFits(self, event = None): - sFit = service.Fit.getInstance() - sMkt = service.Market.getInstance() - fitList = sFit.getBoosterFits() - - for id in self.fleet: - choice = self.fleet[id]['chFit'] - chCurrSelection = choice.GetSelection() - chCurrData = -1 - if chCurrSelection != -1: - chCurrData = choice.GetClientData(chCurrSelection) - chCurrSelString = choice.GetString(chCurrSelection) - choice.Clear() - currSelFound = False - choice.Append("None", -1) - for fit in fitList: - id,name,type = fit - ship = sMkt.getItem(type) - choice.Append(ship.name+': '+name, id) - if chCurrData == id: - currSelFound = True - - if chCurrSelection == -1: - choice.SetSelection(0) - else: - if currSelFound: - choice.SetStringSelection(chCurrSelString) - else: - choice.SetSelection(0) - - def RefreshCharacterList(self, event = None): - sChar = service.Character.getInstance() - charList = sChar.getCharacterList() - for id in self.fleet: - choice = self.fleet[id]['chChar'] - chCurrSelection = choice.GetSelection() - chCurrData = -1 - if chCurrSelection != -1: - chCurrData = choice.GetClientData(chCurrSelection) - chCurrSelString = choice.GetString(chCurrSelection) - choice.Clear() - currSelFound = False - for char in charList: - choice.Append(char.name, char.ID) - if chCurrData == char.ID: - currSelFound = True - - if chCurrSelection == -1: - choice.SetSelection(1) - else: - if currSelFound: - choice.SetStringSelection(chCurrSelString) - else: - choice.SetSelection(1) - - def handleDrag(self, type, fitID): - ''' Handle dragging of fit to fleet interface ''' - #Those are drags coming from pyfa sources, NOT builtin wx drags - self.draggedFitID = None - if type == "fit": - sFit = service.Fit.getInstance() - fit = sFit.getFit(self.mainFrame.getActiveFit()) - - if fit and not fit.isStructure: - self.draggedFitID = fitID - - pos = wx.GetMousePosition() - pos = self.ScreenToClient(pos) - - self.PopupMenu(self.FitDNDPopupMenu, pos) - - - def OnPopupItemSelected(self, event): - ''' Fired when booster popup item is selected ''' - # Get menu selection ID via self.options - menuItem = event.EventObject.FindItemById(event.GetId()) - type = self.options.index(menuItem.GetText()) - - if self.draggedFitID: - sFit = service.Fit.getInstance() - draggedFit = sFit.getFit(self.draggedFitID) - - self.AddCommander(draggedFit.ID, type) - self.mainFrame.additionsPane.select("Fleet") - - def OnFitChoiceSelected(self, event): - ''' Fired when booster choice is selected ''' - sFit = service.Fit.getInstance() - - # set type via choice box used - chFit = event.GetEventObject() - fitID = chFit.GetClientData(chFit.GetSelection()) - - type = -1 - for id in self.fleet: - if chFit == self.fleet[id]['chFit']: type = id - - if type == -1 or fitID == -1: - event.Skip() - return - - fit = sFit.getFit(fitID) - - self.AddCommander(fit.ID, type) - self.mainFrame.additionsPane.select("Fleet") +#Purging fleet boosts \ No newline at end of file diff --git a/gui/mainFrame.py b/gui/mainFrame.py index c209a0422..220a8f0ab 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -55,7 +55,6 @@ from gui.preferenceDialog import PreferenceDialog from gui.graphFrame import GraphFrame from gui.copySelectDialog import CopySelectDialog from gui.utils.clipboard import toClipboard, fromClipboard -from gui.fleetBrowser import FleetBrowser from gui.updateDialog import UpdateDialog from gui.builtinViews import * @@ -158,12 +157,6 @@ class MainFrame(wx.Frame): self.shipBrowser = ShipBrowser(self.notebookBrowsers) self.notebookBrowsers.AddPage(self.shipBrowser, "Fittings", tabImage = shipBrowserImg, showClose = False) - #======================================================================= - # DISABLED FOR RC2 RELEASE - #self.fleetBrowser = FleetBrowser(self.notebookBrowsers) - #self.notebookBrowsers.AddPage(self.fleetBrowser, "Fleets", showClose = False) - #======================================================================= - self.notebookBrowsers.SetSelection(1) self.browser_fitting_split.SplitVertically(self.notebookBrowsers, self.fitting_additions_split) diff --git a/service/__init__.py b/service/__init__.py index b19c6db17..91ed07d82 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -5,7 +5,6 @@ from service.character import Character from service.damagePattern import DamagePattern from service.targetResists import TargetResists from service.settings import SettingsProvider -from service.fleet import Fleet from service.update import Update from service.price import Price from service.network import Network diff --git a/service/fit.py b/service/fit.py index 455e76463..d05865514 100644 --- a/service/fit.py +++ b/service/fit.py @@ -34,7 +34,6 @@ from eos.types import State, Slot from service.market import Market from service.damagePattern import DamagePattern from service.character import Character -from service.fleet import Fleet from service.settings import SettingsProvider from service.port import Port @@ -184,8 +183,6 @@ class Fit(object): def deleteFit(self, fitID): fit = eos.db.getFit(fitID) - sFleet = Fleet.getInstance() - sFleet.removeAssociatedFleetData(fit) eos.db.remove(fit) @@ -236,7 +233,7 @@ class Fit(object): self.recalc(fit, withBoosters=True) def getFit(self, fitID, projected=False, basic=False): - ''' Gets fit from database, and populates fleet data. + ''' Gets fit from database. Projected is a recursion flag that is set to reduce recursions into projected fits Basic is a flag to simply return the fit without any other processing @@ -251,14 +248,6 @@ class Fit(object): inited = getattr(fit, "inited", None) if inited is None or inited is False: - sFleet = Fleet.getInstance() - f = sFleet.getLinearFleet(fit) - if f is None: - sFleet.removeAssociatedFleetData(fit) - fit.fleet = None - else: - fit.fleet = f - if not projected: for fitP in fit.projectedFits: self.getFit(fitP.ID, projected=True) diff --git a/service/fleet.py b/service/fleet.py index cfad7f04b..3a158cb2d 100644 --- a/service/fleet.py +++ b/service/fleet.py @@ -17,199 +17,4 @@ # along with pyfa. If not, see . #=============================================================================== -import eos.db -from eos.types import Fleet as Fleet_, Wing, Squad -import copy - -class Fleet(object): - instance = None - @classmethod - def getInstance(cls): - if cls.instance is None: - cls.instance = Fleet() - - return cls.instance - - def __init__(self): - pass - - def getFleetList(self): - fleetList = [] - fleets = eos.db.getFleetList() - for fleet in fleets: - fleetList.append((fleet.ID, fleet.name, fleet.count())) - - return fleetList - - def getFleetByID(self, ID): - f = eos.db.getFleet(ID) - return f - - def addFleet(self): - f = Fleet_() - eos.db.save(f) - return f - - def renameFleet(self, fleet, newName): - fleet.name = newName - eos.db.commit() - - def copyFleet(self, fleet): - newFleet = copy.deepcopy(fleet) - eos.db.save(newFleet) - return newFleet - - def copyFleetByID(self, ID): - fleet = self.getFleetByID(ID) - return self.copyFleet(fleet) - - def deleteFleet(self, fleet): - eos.db.remove(fleet) - - def deleteFleetByID(self, ID): - fleet = self.getFleetByID(ID) - self.deleteFleet(fleet) - - def makeLinearFleet(self, fit): - f = Fleet_() - w = Wing() - f.wings.append(w) - s = Squad() - w.squads.append(s) - s.members.append(fit) - fit.fleet = f - eos.db.save(f) - - def setLinearFleetCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.wing.gang.leader is not None and booster is None: - try: - squad.wing.gang.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.wing.gang.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - def setLinearWingCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.wing.leader is not None and booster is None: - try: - squad.wing.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.wing.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - def setLinearSquadCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.leader is not None and booster is None: - try: - squad.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - - def getLinearFleet(self, fit): - sqIDs = eos.db.getSquadsIDsWithFitID(fit.ID) - if len(sqIDs) != 1: - return None - s = eos.db.getSquad(sqIDs[0]) - if len(s.members) != 1: - return None - w = s.wing - if len(w.squads) != 1: - return None - f = w.gang - if len(f.wings) != 1: - return None - return f - - def removeAssociatedFleetData(self, fit): - squadIDs = set(eos.db.getSquadsIDsWithFitID(fit.ID)) - if len(squadIDs) == 0: - return - squads = list(eos.db.getSquad(sqID) for sqID in squadIDs) - wingIDs = set(squad.wing.ID for squad in squads) - fleetIDs = set(squad.wing.gang.ID for squad in squads) - for fleetID in fleetIDs: - fleet = eos.db.getFleet(fleetID) - for wing in fleet.wings: - wingIDs.add(wing.ID) - for wingID in wingIDs: - wing = eos.db.getWing(wingID) - for squad in wing.squads: - squadIDs.add(squad.ID) - for squadID in squadIDs: - squad = eos.db.getSquad(squadID) - if squad.leader is not None: - try: - squad.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(squad) - for wingID in wingIDs: - wing = eos.db.getWing(wingID) - if wing.leader is not None: - try: - wing.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(wing) - for fleetID in fleetIDs: - fleet = eos.db.getFleet(fleetID) - if fleet.leader is not None: - try: - fleet.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(fleet) - fit.fleet = None - return - - def anyBoosters(self, squad): - wing = squad.wing - fleet = wing.gang - if squad.leader is None and wing.leader is None and fleet.leader is None: - return False - return True - - def loadLinearFleet(self, fit): - if self.getLinearFleet(fit) is None: - return None - squadID = eos.db.getSquadsIDsWithFitID(fit.ID)[0] - s = eos.db.getSquad(squadID) - w = s.wing - f = w.gang - return (f.leader, w.leader, s.leader) +#Purge fleet boosts From 6e54d6788cd4784c5d6b76c26a2ec243e4c87cad Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Thu, 15 Sep 2016 15:27:10 -0700 Subject: [PATCH 02/13] Revert "Purging fleet bonuses from code base" This reverts commit 68f45706ab7dc9c2e68a3f9d868b37b1ce56decc. --- eos/db/saveddata/fleet.py | 48 +++- eos/db/saveddata/queries.py | 58 +++++ eos/types.py | 1 + gui/additionsPane.py | 7 +- gui/builtinViews/fleetView.py | 141 ++++++++++- gui/fleetBrowser.py | 457 +++++++++++++++++++++++++++++++++- gui/gangView.py | 394 ++++++++++++++++++++++++++++- gui/mainFrame.py | 7 + service/__init__.py | 1 + service/fit.py | 13 +- service/fleet.py | 197 ++++++++++++++- 11 files changed, 1317 insertions(+), 7 deletions(-) diff --git a/eos/db/saveddata/fleet.py b/eos/db/saveddata/fleet.py index 0583b43b0..8f0e6736b 100644 --- a/eos/db/saveddata/fleet.py +++ b/eos/db/saveddata/fleet.py @@ -17,4 +17,50 @@ # along with eos. If not, see . #=============================================================================== -#Purging fleet \ No newline at end of file +from sqlalchemy import Table, Column, Integer, ForeignKey, String +from sqlalchemy.orm import mapper, relation + +from eos.db import saveddata_meta +from eos.types import Fleet, Wing, Squad, Fit +from eos.db.saveddata.fit import fits_table + +gangs_table = Table("gangs", saveddata_meta, + Column("ID", Integer, primary_key = True), + Column("leaderID", ForeignKey("fits.ID")), + Column("boosterID", ForeignKey("fits.ID")), + Column("name", String)) + +wings_table = Table("wings", saveddata_meta, + Column("ID", Integer, primary_key = True), + Column("gangID", ForeignKey("gangs.ID")), + Column("boosterID", ForeignKey("fits.ID")), + Column("leaderID", ForeignKey("fits.ID"))) + +squads_table = Table("squads", saveddata_meta, + Column("ID", Integer, primary_key = True), + Column("wingID", ForeignKey("wings.ID")), + Column("leaderID", ForeignKey("fits.ID")), + Column("boosterID", ForeignKey("fits.ID"))) + +squadmembers_table = Table("squadmembers", saveddata_meta, + Column("squadID", ForeignKey("squads.ID"), primary_key = True), + Column("memberID", ForeignKey("fits.ID"), primary_key = True)) + +mapper(Fleet, gangs_table, + properties = {"wings" : relation(Wing, backref="gang"), + "leader" : relation(Fit, primaryjoin = gangs_table.c.leaderID == fits_table.c.ID), + "booster": relation(Fit, primaryjoin = gangs_table.c.boosterID == fits_table.c.ID)}) + +mapper(Wing, wings_table, + properties = {"squads" : relation(Squad, backref="wing"), + "leader" : relation(Fit, primaryjoin = wings_table.c.leaderID == fits_table.c.ID), + "booster": relation(Fit, primaryjoin = wings_table.c.boosterID == fits_table.c.ID)}) + +mapper(Squad, squads_table, + properties = {"leader" : relation(Fit, primaryjoin = squads_table.c.leaderID == fits_table.c.ID), + "booster" : relation(Fit, primaryjoin = squads_table.c.boosterID == fits_table.c.ID), + "members" : relation(Fit, + primaryjoin = squads_table.c.ID == squadmembers_table.c.squadID, + secondaryjoin = squadmembers_table.c.memberID == fits_table.c.ID, + secondary = squadmembers_table)}) + diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index cb3033cc1..5a6dd1bfc 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -21,6 +21,7 @@ from eos.db.util import processEager, processWhere from eos.db import saveddata_session, sd_lock from eos.types import * +from eos.db.saveddata.fleet import squadmembers_table from eos.db.saveddata.fit import projectedFits_table from sqlalchemy.sql import and_ import eos.config @@ -193,6 +194,48 @@ def getFit(lookfor, eager=None): return fit +@cachedQuery(Fleet, 1, "fleetID") +def getFleet(fleetID, eager=None): + if isinstance(fleetID, int): + if eager is None: + with sd_lock: + fleet = saveddata_session.query(Fleet).get(fleetID) + else: + eager = processEager(eager) + with sd_lock: + fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first() + else: + raise TypeError("Need integer as argument") + return fleet + +@cachedQuery(Wing, 1, "wingID") +def getWing(wingID, eager=None): + if isinstance(wingID, int): + if eager is None: + with sd_lock: + wing = saveddata_session.query(Wing).get(wingID) + else: + eager = processEager(eager) + with sd_lock: + wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first() + else: + raise TypeError("Need integer as argument") + return wing + +@cachedQuery(Squad, 1, "squadID") +def getSquad(squadID, eager=None): + if isinstance(squadID, int): + if eager is None: + with sd_lock: + squad = saveddata_session.query(Squad).get(squadID) + else: + eager = processEager(eager) + with sd_lock: + squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first() + else: + raise TypeError("Need integer as argument") + return squad + def getFitsWithShip(shipID, ownerID=None, where=None, eager=None): """ Get all the fits using a certain ship. @@ -265,6 +308,12 @@ def getFitList(eager=None): return fits +def getFleetList(eager=None): + eager = processEager(eager) + with sd_lock: + fleets = saveddata_session.query(Fleet).options(*eager).all() + return fleets + @cachedQuery(Price, 1, "typeID") def getPrice(typeID): if isinstance(typeID, int): @@ -374,6 +423,15 @@ def searchFits(nameLike, where=None, eager=None): return fits +def getSquadsIDsWithFitID(fitID): + if isinstance(fitID, int): + with sd_lock: + squads = saveddata_session.query(squadmembers_table.c.squadID).filter(squadmembers_table.c.memberID == fitID).all() + squads = tuple(entry[0] for entry in squads) + return squads + else: + raise TypeError("Need integer as argument") + def getProjectedFits(fitID): if isinstance(fitID, int): with sd_lock: diff --git a/eos/types.py b/eos/types.py index f2550ad31..12e7eb281 100644 --- a/eos/types.py +++ b/eos/types.py @@ -38,6 +38,7 @@ from eos.saveddata.booster import SideEffect from eos.saveddata.booster import Booster from eos.saveddata.fit import Fit, ImplantLocation from eos.saveddata.mode import Mode +from eos.saveddata.fleet import Fleet, Wing, Squad from eos.saveddata.miscData import MiscData from eos.saveddata.override import Override diff --git a/gui/additionsPane.py b/gui/additionsPane.py index f1ca44be4..8c855dc95 100644 --- a/gui/additionsPane.py +++ b/gui/additionsPane.py @@ -26,6 +26,7 @@ from gui.cargoView import CargoView from gui.implantView import ImplantView from gui.projectedView import ProjectedView from gui.pyfatogglepanel import TogglePanel +from gui.gangView import GangView from gui.bitmapLoader import BitmapLoader import gui.chromeTabs @@ -54,6 +55,7 @@ class AdditionsPane(TogglePanel): implantImg = BitmapLoader.getImage("implant_small", "gui") boosterImg = BitmapLoader.getImage("booster_small", "gui") projectedImg = BitmapLoader.getImage("projected_small", "gui") + gangImg = BitmapLoader.getImage("fleet_fc_small", "gui") cargoImg = BitmapLoader.getImage("cargo_small", "gui") self.drone = DroneView(self.notebook) @@ -74,9 +76,12 @@ class AdditionsPane(TogglePanel): self.projectedPage = ProjectedView(self.notebook) self.notebook.AddPage(self.projectedPage, "Projected", tabImage = projectedImg, showClose = False) + self.gangPage = GangView(self.notebook) + self.notebook.AddPage(self.gangPage, "Fleet", tabImage = gangImg, showClose = False) + self.notebook.SetSelection(0) - PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected"] + PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected", "Fleet"] def select(self, name): self.notebook.SetSelection(self.PANES.index(name)) diff --git a/gui/builtinViews/fleetView.py b/gui/builtinViews/fleetView.py index 9058bc35f..bc6eef9a2 100644 --- a/gui/builtinViews/fleetView.py +++ b/gui/builtinViews/fleetView.py @@ -1 +1,140 @@ -#Purge fleet boosts \ No newline at end of file +import wx.gizmos +import gui.fleetBrowser +import service +from gui.bitmapLoader import BitmapLoader + +#Tab spawning handler +class FleetSpawner(gui.multiSwitch.TabSpawner): + def __init__(self, multiSwitch): + self.multiSwitch = multiSwitch + mainFrame = gui.mainFrame.MainFrame.getInstance() + mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_SELECTED, self.fleetSelected) + + def fleetSelected(self, event): + if self.multiSwitch.GetPageCount() == 0: + self.multiSwitch.AddPage(wx.Panel(self.multiSwitch, size = (0,0)), "Empty Tab") + + view = FleetView(self.multiSwitch) + self.multiSwitch.ReplaceActivePage(view) + view.populate(event.fleetID) + view.Show() + +FleetSpawner.register() + +class FleetView(wx.gizmos.TreeListCtrl): + def __init__(self, parent, size = (0,0)): + wx.gizmos.TreeListCtrl.__init__(self, parent, size = size) + + self.tabManager = parent + + self.fleetId = None + self.fleetImg = BitmapLoader.getImage("53_16", "icons") + + self.imageList = wx.ImageList(16, 16) + self.SetImageList(self.imageList) + + for col in ("", "Fit", "Shiptype", "Character", "Bonusses"): + self.AddColumn(col) + + self.SetMainColumn(1) + self.icons = {} + self.addImage = self.imageList.Add(BitmapLoader.getBitmap("add_small", "gui")) + for icon in ("fb", "fc", "sb", "sc", "wb", "wc"): + self.icons[icon] = self.imageList.Add(BitmapLoader.getBitmap("fleet_%s_small" % icon, "gui")) + + self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.checkNew) + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_RENAMED, self.fleetRenamed) + self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_REMOVED, self.fleetRemoved) + + def Destroy(self): + self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_REMOVED, handler = self.fleetRemoved) + self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_RENAMED, handler = self.fleetRenamed) + wx.gizmos.TreeListCtrl.Destroy(self) + + def fleetRenamed(self, event): + if event.fleetID == self.fleetId: + sFleet = service.Fleet.getInstance() + f = sFleet.getFleetByID(event.fleetID) + self.UpdateTab(f.name, self.fleetImg) + + event.Skip() + + def fleetRemoved(self, event): + if event.fleetID == self.fleetId: + self.tabManager.DeletePage(self.tabManager.GetPageIndex(self)) + + event.Skip() + + def checkNew(self, event): + data = self.GetPyData(event.Item) + if data and isinstance(data, tuple) and data[0] == "add": + layer = data[1] + + + def UpdateTab(self, name, img): + self.tabManager.SetPageTextIcon(self.tabManager.GetSelection(), name, img) + + def populate(self, fleetID): + sFleet = service.Fleet.getInstance() + f = sFleet.getFleetByID(fleetID) + self.fleetId = fleetID + + self.UpdateTab( f.name, self.fleetImg) + self.fleet = f + self.DeleteAllItems() + root = self.AddRoot("") + + self.setEntry(root, f.leader, "fleet", f) + for wing in f.wings: + wingId = self.AppendItem(root, "") + self.setEntry(wingId, wing.leader, "wing", wing) + for squad in wing.squads: + for member in squad.members: + memberId = self.AppendItem(wingId, "") + self.setEntry(memberId, member, "squad", squad) + + self.addAdder(wingId, "squad") + + self.addAdder(root, "wing") + + self.ExpandAll(root) + self.SetColumnWidth(0, 16) + for i in xrange(1, 5): + self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) + headerWidth = self.GetColumnWidth(i) + 5 + self.SetColumnWidth(i, wx.LIST_AUTOSIZE) + baseWidth = self.GetColumnWidth(i) + if baseWidth < headerWidth: + self.SetColumnWidth(i, headerWidth) + else: + self.SetColumnWidth(i, baseWidth) + + + def addAdder(self, treeItemId, layer): + id = self.AppendItem(treeItemId, "Add new %s" % layer.capitalize()) + self.SetPyData(id, ("add", layer)) + self.SetItemImage(id, self.addImage, 1) + + def setEntry(self, treeItemId, fit, layer, info): + self.SetPyData(treeItemId, info) + if fit is None: + self.SetItemText(treeItemId, "%s Commander" % layer.capitalize(), 1) + else: + fleet = self.fleet + if fit == info.booster: + self.SetItemImage(treeItemId, self.icons["%sb" % layer[0]], 0) + elif fit == info.leader: + self.SetItemImage(treeItemId, self.icons["%sc" % layer[0]], 1) + + self.SetItemText(treeItemId, fit.name, 1) + self.SetItemText(treeItemId, fit.ship.item.name, 2) + self.SetItemText(treeItemId, fit.character.name, 3) + boosts = fleet.store.getBoosts(fit) + if boosts: + bonusses = [] + for name, info in boosts.iteritems(): + bonusses.append("%s: %.2g" % (name, info[0])) + + self.SetItemText(treeItemId, ", ".join(bonusses), 3) diff --git a/gui/fleetBrowser.py b/gui/fleetBrowser.py index bb28be251..7476d7d7f 100644 --- a/gui/fleetBrowser.py +++ b/gui/fleetBrowser.py @@ -1 +1,456 @@ -# purging fleet \ No newline at end of file +import wx +import copy +from gui.bitmapLoader import BitmapLoader +import gui.mainFrame +from gui.PFListPane import PFListPane +import service.fleet +from gui.utils.drawUtils import GetPartialText + +from wx.lib.buttons import GenBitmapButton + +import gui.utils.colorUtils as colorUtils +import gui.utils.drawUtils as drawUtils + +import gui.sfBrowserItem as SFItem + +FleetSelected, EVT_FLEET_SELECTED = wx.lib.newevent.NewEvent() +FleetRenamed, EVT_FLEET_RENAMED = wx.lib.newevent.NewEvent() +FleetRemoved, EVT_FLEET_REMOVED = wx.lib.newevent.NewEvent() + + +FleetItemSelect, EVT_FLEET_ITEM_SELECT = wx.lib.newevent.NewEvent() +FleetItemDelete, EVT_FLEET_ITEM_DELETE = wx.lib.newevent.NewEvent() +FleetItemNew, EVT_FLEET_ITEM_NEW = wx.lib.newevent.NewEvent() +FleetItemCopy, EVT_FLEET_ITEM_COPY = wx.lib.newevent.NewEvent() +FleetItemRename, EVT_FLEET_ITEM_RENAME = wx.lib.newevent.NewEvent() + + + +class FleetBrowser(wx.Panel): + def __init__(self, parent): + wx.Panel.__init__(self, parent) + + self.sFleet = service.fleet.Fleet.getInstance() + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + mainSizer = wx.BoxSizer(wx.VERTICAL) + + self.hpane = FleetBrowserHeader(self) + mainSizer.Add(self.hpane, 0, wx.EXPAND) + + self.m_sl2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + mainSizer.Add( self.m_sl2, 0, wx.EXPAND, 0 ) + + self.fleetItemContainer = PFFleetItemContainer(self) + + mainSizer.Add(self.fleetItemContainer, 1, wx.EXPAND) + + self.SetSizer(mainSizer) + self.Layout() + + self.filter = "" + self.fleetIDMustEditName = -1 + + self.Bind(wx.EVT_SIZE, self.SizeRefreshList) + + self.Bind(EVT_FLEET_ITEM_NEW, self.AddNewFleetItem) + self.Bind(EVT_FLEET_ITEM_SELECT, self.SelectFleetItem) + self.Bind(EVT_FLEET_ITEM_DELETE, self.DeleteFleetItem) + self.Bind(EVT_FLEET_ITEM_COPY, self.CopyFleetItem) + self.Bind(EVT_FLEET_ITEM_RENAME, self.RenameFleetItem) + + self.PopulateFleetList() + + def AddNewFleetItem(self, event): + fleetName = event.fleetName + newFleet = self.sFleet.addFleet() + self.sFleet.renameFleet(newFleet, fleetName) + + self.fleetIDMustEditName = newFleet.ID + self.AddItem(newFleet.ID, newFleet.name, newFleet.count()) + + def SelectFleetItem(self, event): + fleetID = event.fleetID + self.fleetItemContainer.SelectWidgetByFleetID(fleetID) + wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleetID)) + + def CopyFleetItem(self, event): + fleetID = event.fleetID + fleet = self.sFleet.copyFleetByID(fleetID) + + fleetName = fleet.name + " Copy" + self.sFleet.renameFleet(fleet,fleetName) + + self.fleetIDMustEditName = fleet.ID + self.AddItem(fleet.ID, fleet.name, fleet.count()) + + self.fleetItemContainer.SelectWidgetByFleetID(fleet.ID) + wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleet.ID)) + + def RenameFleetItem(self, event): + fleetID = event.fleetID + fleet = self.sFleet.getFleetByID(fleetID) + + newFleetName = event.fleetName + + self.sFleet.renameFleet(fleet, newFleetName) + wx.PostEvent(self.mainFrame, FleetRenamed(fleetID = fleet.ID)) + + def DeleteFleetItem(self, event): + self.sFleet.deleteFleetByID(event.fleetID) + self.PopulateFleetList() + wx.PostEvent(self.mainFrame, FleetRemoved(fleetID = event.fleetID)) + + def AddItem (self, ID, name, count): + self.fleetItemContainer.AddWidget(FleetItem(self, ID, name, count)) + widget = self.fleetItemContainer.GetWidgetByFleetID(ID) + self.fleetItemContainer.RefreshList(True) + self.fleetItemContainer.ScrollChildIntoView(widget) + wx.PostEvent(self, FleetItemSelect(fleetID = ID)) + + def PopulateFleetList(self): + self.Freeze() + filter = self.filter + self.fleetItemContainer.RemoveAllChildren() + fleetList = self.sFleet.getFleetList() + for fleetID, fleetName, fleetCount in fleetList: + if fleetName.lower().find(filter.lower()) != -1: + self.fleetItemContainer.AddWidget(FleetItem(self, fleetID, fleetName, fleetCount)) + self.fleetItemContainer.RefreshList() + self.Thaw() + + def SetFilter(self, filter): + self.filter = filter + + def SizeRefreshList(self, event): + ewidth, eheight = event.GetSize() + self.Layout() + self.fleetItemContainer.Layout() + self.fleetItemContainer.RefreshList(True) + event.Skip() + + +class FleetBrowserHeader (wx.Panel): + def __init__(self, parent): + wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 24), style=wx.TAB_TRAVERSAL) + self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) ) + + self.newBmp = BitmapLoader.getBitmap("fit_add_small","gui") + bmpSize = (16,16) + + mainSizer = wx.BoxSizer(wx.HORIZONTAL) + + if 'wxMac' in wx.PlatformInfo: + bgcolour = wx.Colour(0, 0, 0, 0) + else: + bgcolour = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) + + self.fbNewFleet = PFGenBitmapButton( self, wx.ID_ANY, self.newBmp, wx.DefaultPosition, bmpSize, wx.BORDER_NONE ) + mainSizer.Add(self.fbNewFleet, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL , 5) + self.fbNewFleet.SetBackgroundColour( bgcolour ) + + self.sl1 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_VERTICAL ) + mainSizer.Add( self.sl1, 0, wx.EXPAND |wx.LEFT, 5 ) + + self.tcFilter = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.tcFilter, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.stStatus = wx.StaticText( self, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stStatus.Wrap( -1 ) + mainSizer.Add( self.stStatus, 1, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.SetSizer(mainSizer) + self.Layout() + + self.fbNewFleet.Bind(wx.EVT_ENTER_WINDOW, self.fbNewEnterWindow) + self.fbNewFleet.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) + self.fbNewFleet.Bind(wx.EVT_BUTTON, self.OnNewFleetItem) + + self.tcFilter.Bind(wx.EVT_TEXT, self.OnFilterText) + + self.tcFilter.Bind(wx.EVT_ENTER_WINDOW, self.fbFilterEnterWindow) + self.tcFilter.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) + + def OnFilterText(self, event): + filter = self.tcFilter.GetValue() + self.Parent.SetFilter(filter) + self.Parent.PopulateFleetList() + event.Skip() + + def OnNewFleetItem(self, event): + wx.PostEvent(self.Parent, FleetItemNew(fleetName = "New Fleet")) + + def fbNewEnterWindow(self, event): + self.stStatus.SetLabel("New fleet") + self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) + event.Skip() + + def fbHItemLeaveWindow(self, event): + self.stStatus.SetLabel("") + self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) + event.Skip() + + def fbFilterEnterWindow(self, event): + self.stStatus.SetLabel("Filter list") + event.Skip() + + + +class PFFleetItemContainer(PFListPane): + def __init__(self,parent): + PFListPane.__init__(self,parent) + self.selectedWidget = -1 + self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) + + def IsWidgetSelectedByContext(self, widget): + if self.GetWidgetList()[widget].IsSelected(): + return True + return False + + def GetWidgetIndex(self, widgetWnd): + return self.GetWidgetList().index(widgetWnd) + + def GetWidgetByFleetID(self, fleetID): + for widget in self.GetWidgetList(): + if widget.fleetID == fleetID: + return widget + return None + + def SelectWidget(self, widgetWnd): + wlist = self.GetWidgetList() + if self.selectedWidget != -1: + wlist[self.selectedWidget].SetSelected(False) + wlist[self.selectedWidget].Refresh() + windex = self.GetWidgetIndex(widgetWnd) + wlist[windex].SetSelected(True) + wlist[windex].Refresh() + self.selectedWidget = windex + + def SelectWidgetByFleetID(self, fleetID): + widgetWnd = self.GetWidgetByFleetID(fleetID) + if widgetWnd: + self.SelectWidget(widgetWnd) + + def RemoveWidget(self, child): + child.Destroy() + self.selectedWidget = -1 + self._wList.remove(child) + + + def RemoveAllChildren(self): + for widget in self._wList: + widget.Destroy() + + self.selectedWidget = -1 + self._wList = [] + + def OnLeftUp(self, event): + event.Skip() + +class FleetItem(SFItem.SFBrowserItem): + def __init__(self, parent, fleetID, fleetName, fleetCount, + id=wx.ID_ANY, pos=wx.DefaultPosition, + size=(0,40), style=0): + SFItem.SFBrowserItem.__init__(self, parent, size = size) + + self.fleetBrowser = self.Parent + self.fleetID = fleetID + self.fleetName = fleetName + self.fleetCount = fleetCount + + self.padding = 4 + + self.fontBig = wx.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.BOLD, False) + self.fontNormal = wx.FontFromPixelSize((0,14),wx.SWISS, wx.NORMAL, wx.NORMAL, False) + self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False) + + self.copyBmp = BitmapLoader.getBitmap("fit_add_small", "gui") + self.renameBmp = BitmapLoader.getBitmap("fit_rename_small", "gui") + self.deleteBmp = BitmapLoader.getBitmap("fit_delete_small","gui") + self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui") + self.fleetBmp = BitmapLoader.getBitmap("fleet_item_big", "gui") + + fleetImg = self.fleetBmp.ConvertToImage() + fleetImg = fleetImg.Blur(2) + + if not fleetImg.HasAlpha(): + fleetImg.InitAlpha() + + fleetImg = fleetImg.AdjustChannels(1, 1, 1, 0.5) + self.fleetEffBmp = wx.BitmapFromImage(fleetImg) + + self.toolbar.AddButton(self.copyBmp, "Copy", self.CopyFleetCB) + self.renameBtn = self.toolbar.AddButton(self.renameBmp, "Rename", self.RenameFleetCB) + self.toolbar.AddButton(self.deleteBmp, "Delete", self.DeleteFleetCB) + + self.editWidth = 150 + self.tcFleetName = wx.TextCtrl(self, wx.ID_ANY, "%s" % self.fleetName, wx.DefaultPosition, (self.editWidth,-1), wx.TE_PROCESS_ENTER) + + if self.fleetBrowser.fleetIDMustEditName != self.fleetID: + self.tcFleetName.Show(False) + else: + self.tcFleetName.SetFocus() + self.tcFleetName.SelectAll() + self.fleetBrowser.fleetIDMustEditName = -1 + self.renameBtn.SetBitmap(self.acceptBmp) + self.selected = True + + self.tcFleetName.Bind(wx.EVT_KILL_FOCUS, self.OnEditLostFocus) + self.tcFleetName.Bind(wx.EVT_TEXT_ENTER, self.RenameFleet) + self.tcFleetName.Bind(wx.EVT_KEY_DOWN, self.EditCheckEsc) + + + self.animCount = 0 + + def MouseLeftUp(self, event): + if self.tcFleetName.IsShown(): + self.RestoreEditButton() + else: + wx.PostEvent(self.fleetBrowser, FleetItemSelect(fleetID = self.fleetID)) + + def CopyFleetCB(self): + if self.tcFleetName.IsShown(): + self.RestoreEditButton() + return + + wx.PostEvent(self.fleetBrowser, FleetItemCopy(fleetID = self.fleetID)) + + def RenameFleetCB(self): + + if self.tcFleetName.IsShown(): + + self.RenameFleet(None) + self.RestoreEditButton() + + else: + self.tcFleetName.SetValue(self.fleetName) + self.tcFleetName.Show() + + self.renameBtn.SetBitmap(self.acceptBmp) + self.Refresh() + + self.tcFleetName.SetFocus() + self.tcFleetName.SelectAll() + + self.Refresh() + + def RenameFleet(self, event): + + newFleetName = self.tcFleetName.GetValue() + self.fleetName = newFleetName + + self.tcFleetName.Show(False) + + wx.PostEvent(self.fleetBrowser, FleetItemRename(fleetID = self.fleetID, fleetName = self.fleetName)) + self.Refresh() + + def DeleteFleetCB(self): + if self.tcFleetName.IsShown(): + self.RestoreEditButton() + return + wx.PostEvent(self.fleetBrowser, FleetItemDelete(fleetID = self.fleetID)) + + def RestoreEditButton(self): + self.tcFleetName.Show(False) + self.renameBtn.SetBitmap(self.renameBmp) + self.Refresh() + + def OnEditLostFocus(self, event): + self.RestoreEditButton() + self.Refresh() + + def EditCheckEsc(self, event): + if event.GetKeyCode() == wx.WXK_ESCAPE: + self.RestoreEditButton() + else: + event.Skip() + + def IsSelected(self): + return self.selected + + def UpdateElementsPos(self, mdc): + rect = self.GetRect() + + self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding + self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2 + + self.toolbarx = self.toolbarx + self.animCount + + self.fleetBmpx = self.padding + (rect.height - self.fleetBmp.GetWidth()) / 2 + self.fleetBmpy = (rect.height - self.fleetBmp.GetHeight()) / 2 + + self.fleetBmpx -= self.animCount + + self.textStartx = self.fleetBmpx + self.fleetBmp.GetWidth() + self.padding + + self.fleetNamey = (rect.height - self.fleetBmp.GetHeight()) / 2 + + mdc.SetFont(self.fontBig) + wtext, htext = mdc.GetTextExtent(self.fleetName) + + self.fleetCounty = self.fleetNamey + htext + + mdc.SetFont(self.fontSmall) + + wlabel,hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel) + + self.thoverx = self.toolbarx - self.padding - wlabel + self.thovery = (rect.height - hlabel)/2 + self.thoverw = wlabel + + def DrawItem(self, mdc): + rect = self.GetRect() + + windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW) + textColor = colorUtils.GetSuitableColor(windowColor, 1) + + mdc.SetTextForeground(textColor) + + self.UpdateElementsPos(mdc) + + self.toolbar.SetPosition((self.toolbarx, self.toolbary)) + mdc.DrawBitmap(self.fleetEffBmp, self.fleetBmpx + 3, self.fleetBmpy + 2) + mdc.DrawBitmap(self.fleetBmp, self.fleetBmpx,self.fleetBmpy) + + mdc.SetFont(self.fontNormal) + + suffix = "%d ships" % self.fleetCount if self.fleetCount >1 else "%d ship" % self.fleetCount if self.fleetCount == 1 else "No ships" + fleetCount = "Fleet size: %s" % suffix + fleetCount = drawUtils.GetPartialText(mdc, fleetCount, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) + + mdc.DrawText(fleetCount, self.textStartx, self.fleetCounty) + + mdc.SetFont(self.fontSmall) + mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery) + + mdc.SetFont(self.fontBig) + + pfname = drawUtils.GetPartialText(mdc, self.fleetName, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) + mdc.DrawText(pfname, self.textStartx, self.fleetNamey) + + if self.tcFleetName.IsShown(): + self.AdjustControlSizePos(self.tcFleetName, self.textStartx, self.toolbarx - self.editWidth - self.padding) + + def AdjustControlSizePos(self, editCtl, start, end): + fnEditSize = editCtl.GetSize() + wSize = self.GetSize() + fnEditPosX = end + fnEditPosY = (wSize.height - fnEditSize.height)/2 + if fnEditPosX < start: + editCtl.SetSize((self.editWidth + fnEditPosX - start,-1)) + editCtl.SetPosition((start,fnEditPosY)) + else: + editCtl.SetSize((self.editWidth,-1)) + editCtl.SetPosition((fnEditPosX,fnEditPosY)) + + +class PFGenBitmapButton(GenBitmapButton): + def __init__(self, parent, id, bitmap, pos, size, style): + GenBitmapButton.__init__(self, parent, id, bitmap, pos, size, style) + self.bgcolor = wx.Brush(wx.WHITE) + + def SetBackgroundColour(self, color): + self.bgcolor = wx.Brush(color) + + def GetBackgroundBrush(self, dc): + return self.bgcolor diff --git a/gui/gangView.py b/gui/gangView.py index d5f8e43cb..106f14f98 100644 --- a/gui/gangView.py +++ b/gui/gangView.py @@ -16,5 +16,397 @@ # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . #=============================================================================== +import wx +from wx.lib.scrolledpanel import ScrolledPanel -#Purging fleet boosts \ No newline at end of file +import service +import gui.mainFrame +import gui.shipBrowser +import gui.globalEvents as GE + +from gui import characterEditor as CharEditor + +class GangView ( ScrolledPanel ): + + def __init__( self, parent ): + ScrolledPanel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 100,20 ), style = wx.TAB_TRAVERSAL | wx.HSCROLL | wx.VSCROLL ) + mainSizer = wx.BoxSizer( wx.VERTICAL ) + + self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + self.draggedFitID = None + + help = '''Set fit as booster to display in dropdown, or drag fitting from\nship browser to this window, or right click fit and select booster role.''' + helpSizer = wx.BoxSizer( wx.HORIZONTAL ) + self.helpText = wx.StaticText( self, wx.ID_ANY, help, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE ) + helpSizer.Add( self.helpText, 1, wx.ALL, 5 ) + + self.options = ["Fleet", "Wing", "Squad"] + + self.fleet = {} + for id, option in enumerate(self.options): + + # set content for each commander + self.fleet[id] = {} + self.fleet[id]['stLabel'] = wx.StaticText( self, wx.ID_ANY, self.options[id]+':', wx.DefaultPosition, wx.DefaultSize, 0 ) + self.fleet[id]['stText'] = wx.StaticText( self, wx.ID_ANY, 'None', wx.DefaultPosition, wx.DefaultSize, 0 ) + self.fleet[id]['chFit'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) + self.fleet[id]['chChar'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) + self.fleet[id]['fitSizer'] = wx.BoxSizer( wx.VERTICAL ) + + self.FitDNDPopupMenu = self.buildBoostermenu() + + contentFGSizer = wx.FlexGridSizer( 5, 3, 0, 0 ) + contentFGSizer.AddGrowableCol( 1 ) + contentFGSizer.SetFlexibleDirection( wx.BOTH ) + contentFGSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED ) + + ### Header + self.stBooster = wx.StaticText( self, wx.ID_ANY, u"Booster", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stBooster.Wrap( -1 ) + self.stBooster.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) + contentFGSizer.Add( self.stBooster, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.stFits = wx.StaticText( self, wx.ID_ANY, u"Fits", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stFits.Wrap( -1 ) + self.stFits.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) + contentFGSizer.Add( self.stFits, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.stCharacters = wx.StaticText( self, wx.ID_ANY, u"Characters", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stCharacters.Wrap( -1 ) + self.stCharacters.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) + contentFGSizer.Add( self.stCharacters, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.m_staticline2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + contentFGSizer.Add( self.m_staticline2, 0, wx.EXPAND, 5 ) + + self.m_staticline3 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + contentFGSizer.Add( self.m_staticline3, 0, wx.EXPAND, 5 ) + + self.m_staticline4 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + contentFGSizer.Add( self.m_staticline4, 0, wx.EXPAND, 5 ) + + ### Content + for id in self.fleet: + # set various properties + self.fleet[id]['stLabel'].Wrap( -1 ) + self.fleet[id]['stLabel'].SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) + self.fleet[id]['stText'].Wrap( -1 ) + + # bind text and choice events + self.fleet[id]['stText'].Bind(wx.EVT_LEFT_DCLICK, self.RemoveBooster) + self.fleet[id]['stText'].Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) + self.fleet[id]['stText'].Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) + self.fleet[id]['stText'].SetToolTip(wx.ToolTip("Double click to remove booster")) + self.fleet[id]['chChar'].Bind(wx.EVT_CHOICE, self.CharChanged) + self.fleet[id]['chFit'].Bind(wx.EVT_CHOICE, self.OnFitChoiceSelected) + + # add fit text and choice to the fit sizer + self.fleet[id]['fitSizer'].Add( self.fleet[id]['stText'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) + self.fleet[id]['fitSizer'].Add( self.fleet[id]['chFit'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 1 ) + + # add everything to the content sizer + contentFGSizer.Add( self.fleet[id]['stLabel'], 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) + contentFGSizer.Add( self.fleet[id]['fitSizer'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 5 ) + contentFGSizer.Add( self.fleet[id]['chChar'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) + + mainSizer.Add( contentFGSizer, 1, wx.EXPAND, 0 ) + mainSizer.Add( helpSizer, 0, wx.EXPAND, 0 ) + + self.SetSizer( mainSizer ) + self.SetAutoLayout(True) + self.SetupScrolling() + + self.mainFrame.Bind(GE.CHAR_LIST_UPDATED, self.RefreshCharacterList) + self.mainFrame.Bind(GE.FIT_CHANGED, self.fitSelected) + self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_RENAMED, self.fitRenamed) + self.mainFrame.Bind(gui.shipBrowser.BOOSTER_LIST_UPDATED, self.RefreshBoosterFits) + + self.RefreshBoosterFits() + self.RefreshCharacterList() + + def buildBoostermenu(self): + menu = wx.Menu() + + for id, option in enumerate(self.options): + item = menu.Append(-1, option) + # We bind it to the mainFrame because it may be called from either this class or from FitItem via shipBrowser + self.mainFrame.Bind(wx.EVT_MENU, self.OnPopupItemSelected, item) + return menu + + def OnEnterWindow(self, event): + obj = event.GetEventObject() + obj.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) + event.Skip() + + def OnLeaveWindow(self, event): + obj = event.GetEventObject() + obj.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) + event.Skip() + + def CharChanged(self, event): + ''' Change booster character ''' + chBooster = event.GetEventObject() + + type = -1 + for id in self.fleet: + if chBooster == self.fleet[id]['chChar']: type = id + + if type == -1: + event.Skip() + return + + sFit = service.Fit.getInstance() + + fleetSrv = service.Fleet.getInstance() + + activeFitID = self.mainFrame.getActiveFit() + fit = sFit.getFit(activeFitID) + + sChar = service.Character.getInstance() + charList = sChar.getCharacterList() + + if activeFitID: + commanders = fleetSrv.loadLinearFleet(fit) + if commanders is None: + fleetCom, wingCom, squadCom = (None, None, None) + else: + fleetCom, wingCom, squadCom = commanders + + if type == 0: + if fleetCom: + charID = chBooster.GetClientData(chBooster.GetSelection()) + sFit.changeChar(fleetCom.ID, charID) + else: + chBooster.SetSelection(0) + + if type == 1: + if wingCom: + charID = chBooster.GetClientData(chBooster.GetSelection()) + sFit.changeChar(wingCom.ID, charID) + else: + chBooster.SetSelection(0) + + if type == 2: + if squadCom: + charID = chBooster.GetClientData(chBooster.GetSelection()) + sFit.changeChar(squadCom.ID, charID) + else: + chBooster.SetSelection(0) + + sFit.recalc(fit, withBoosters=True) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) + + else: + chBooster.SetSelection(0) + + def RemoveBooster(self, event): + activeFitID = self.mainFrame.getActiveFit() + if not activeFitID: + return + + location = event.GetEventObject() + + for id in self.fleet: + if location == self.fleet[id]['stText']: type = id + + sFit = service.Fit.getInstance() + boostee = sFit.getFit(activeFitID) + booster = None + + fleetSrv = service.Fleet.getInstance() + + if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) + if type == 1: fleetSrv.setLinearWingCom(boostee, booster) + if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) + + # Hide stText and, default fit selection, and enable it + location.Hide() + choice = self.fleet[type]['chFit'] + choice.SetSelection(0) + choice.Show() + + sFit.recalc(boostee, withBoosters=True) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) + + def fitRenamed(self, event): + fleetSrv = service.Fleet.getInstance() + activeFitID = self.mainFrame.getActiveFit() + + if activeFitID: + ev = event + ev.fitID = activeFitID + self.fitSelected(ev) + + def fitSelected(self, event): + ''' Fires when active fit is selected and when booster is saved to fit. Update the UI to reflect changes ''' + fleetSrv = service.Fleet.getInstance() + + activeFitID = self.mainFrame.getActiveFit() + sFit = service.Fit.getInstance() + fit = sFit.getFit(event.fitID or activeFitID) + + self.Parent.Parent.DisablePage(self, not fit or fit.isStructure) + + commanders = (None, None, None) + + if activeFitID: + commanders = fleetSrv.loadLinearFleet(fit) + + for id in self.fleet: + # try...except here as we're trying 2 different criteria and want to fall back on the same code + try: + commander = commanders[id] + + if not activeFitID or commander is None: + raise Exception() + + self.fleet[id]['stText'].SetLabel(commander.ship.item.name + ": " + commander.name) + self.fleet[id]['chChar'].SetStringSelection(commander.character.name if commander.character is not None else "All 0") + self.fleet[id]['chChar'].Enable() + self.fleet[id]['chFit'].Hide() + self.fleet[id]['stText'].Show() + except: + #set defaults, disable char selection, and enable fit selection + self.fleet[id]['stText'].SetLabel("None") + self.fleet[id]['chChar'].SetStringSelection("All 0") + self.fleet[id]['chChar'].Disable() + self.fleet[id]['chFit'].SetSelection(0) + self.fleet[id]['chFit'].Show() + self.fleet[id]['stText'].Hide() + + if activeFitID: + self.Enable() + else: + self.Disable() + + self.Layout() + self.SendSizeEvent() + + def AddCommander(self, fitID, type = None): + ''' Adds booster to a fit, then recalculates active fit ''' + if type is None: + return + + activeFitID = self.mainFrame.getActiveFit() + if activeFitID: + sFit = service.Fit.getInstance() + + boostee = sFit.getFit(activeFitID) + booster = sFit.getFit(fitID) + + fleetSrv = service.Fleet.getInstance() + + if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) + if type == 1: fleetSrv.setLinearWingCom(boostee, booster) + if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) + + sFit.recalc(boostee) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) + + def RefreshBoosterFits(self, event = None): + sFit = service.Fit.getInstance() + sMkt = service.Market.getInstance() + fitList = sFit.getBoosterFits() + + for id in self.fleet: + choice = self.fleet[id]['chFit'] + chCurrSelection = choice.GetSelection() + chCurrData = -1 + if chCurrSelection != -1: + chCurrData = choice.GetClientData(chCurrSelection) + chCurrSelString = choice.GetString(chCurrSelection) + choice.Clear() + currSelFound = False + choice.Append("None", -1) + for fit in fitList: + id,name,type = fit + ship = sMkt.getItem(type) + choice.Append(ship.name+': '+name, id) + if chCurrData == id: + currSelFound = True + + if chCurrSelection == -1: + choice.SetSelection(0) + else: + if currSelFound: + choice.SetStringSelection(chCurrSelString) + else: + choice.SetSelection(0) + + def RefreshCharacterList(self, event = None): + sChar = service.Character.getInstance() + charList = sChar.getCharacterList() + for id in self.fleet: + choice = self.fleet[id]['chChar'] + chCurrSelection = choice.GetSelection() + chCurrData = -1 + if chCurrSelection != -1: + chCurrData = choice.GetClientData(chCurrSelection) + chCurrSelString = choice.GetString(chCurrSelection) + choice.Clear() + currSelFound = False + for char in charList: + choice.Append(char.name, char.ID) + if chCurrData == char.ID: + currSelFound = True + + if chCurrSelection == -1: + choice.SetSelection(1) + else: + if currSelFound: + choice.SetStringSelection(chCurrSelString) + else: + choice.SetSelection(1) + + def handleDrag(self, type, fitID): + ''' Handle dragging of fit to fleet interface ''' + #Those are drags coming from pyfa sources, NOT builtin wx drags + self.draggedFitID = None + if type == "fit": + sFit = service.Fit.getInstance() + fit = sFit.getFit(self.mainFrame.getActiveFit()) + + if fit and not fit.isStructure: + self.draggedFitID = fitID + + pos = wx.GetMousePosition() + pos = self.ScreenToClient(pos) + + self.PopupMenu(self.FitDNDPopupMenu, pos) + + + def OnPopupItemSelected(self, event): + ''' Fired when booster popup item is selected ''' + # Get menu selection ID via self.options + menuItem = event.EventObject.FindItemById(event.GetId()) + type = self.options.index(menuItem.GetText()) + + if self.draggedFitID: + sFit = service.Fit.getInstance() + draggedFit = sFit.getFit(self.draggedFitID) + + self.AddCommander(draggedFit.ID, type) + self.mainFrame.additionsPane.select("Fleet") + + def OnFitChoiceSelected(self, event): + ''' Fired when booster choice is selected ''' + sFit = service.Fit.getInstance() + + # set type via choice box used + chFit = event.GetEventObject() + fitID = chFit.GetClientData(chFit.GetSelection()) + + type = -1 + for id in self.fleet: + if chFit == self.fleet[id]['chFit']: type = id + + if type == -1 or fitID == -1: + event.Skip() + return + + fit = sFit.getFit(fitID) + + self.AddCommander(fit.ID, type) + self.mainFrame.additionsPane.select("Fleet") diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 220a8f0ab..c209a0422 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -55,6 +55,7 @@ from gui.preferenceDialog import PreferenceDialog from gui.graphFrame import GraphFrame from gui.copySelectDialog import CopySelectDialog from gui.utils.clipboard import toClipboard, fromClipboard +from gui.fleetBrowser import FleetBrowser from gui.updateDialog import UpdateDialog from gui.builtinViews import * @@ -157,6 +158,12 @@ class MainFrame(wx.Frame): self.shipBrowser = ShipBrowser(self.notebookBrowsers) self.notebookBrowsers.AddPage(self.shipBrowser, "Fittings", tabImage = shipBrowserImg, showClose = False) + #======================================================================= + # DISABLED FOR RC2 RELEASE + #self.fleetBrowser = FleetBrowser(self.notebookBrowsers) + #self.notebookBrowsers.AddPage(self.fleetBrowser, "Fleets", showClose = False) + #======================================================================= + self.notebookBrowsers.SetSelection(1) self.browser_fitting_split.SplitVertically(self.notebookBrowsers, self.fitting_additions_split) diff --git a/service/__init__.py b/service/__init__.py index 91ed07d82..b19c6db17 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -5,6 +5,7 @@ from service.character import Character from service.damagePattern import DamagePattern from service.targetResists import TargetResists from service.settings import SettingsProvider +from service.fleet import Fleet from service.update import Update from service.price import Price from service.network import Network diff --git a/service/fit.py b/service/fit.py index d05865514..455e76463 100644 --- a/service/fit.py +++ b/service/fit.py @@ -34,6 +34,7 @@ from eos.types import State, Slot from service.market import Market from service.damagePattern import DamagePattern from service.character import Character +from service.fleet import Fleet from service.settings import SettingsProvider from service.port import Port @@ -183,6 +184,8 @@ class Fit(object): def deleteFit(self, fitID): fit = eos.db.getFit(fitID) + sFleet = Fleet.getInstance() + sFleet.removeAssociatedFleetData(fit) eos.db.remove(fit) @@ -233,7 +236,7 @@ class Fit(object): self.recalc(fit, withBoosters=True) def getFit(self, fitID, projected=False, basic=False): - ''' Gets fit from database. + ''' Gets fit from database, and populates fleet data. Projected is a recursion flag that is set to reduce recursions into projected fits Basic is a flag to simply return the fit without any other processing @@ -248,6 +251,14 @@ class Fit(object): inited = getattr(fit, "inited", None) if inited is None or inited is False: + sFleet = Fleet.getInstance() + f = sFleet.getLinearFleet(fit) + if f is None: + sFleet.removeAssociatedFleetData(fit) + fit.fleet = None + else: + fit.fleet = f + if not projected: for fitP in fit.projectedFits: self.getFit(fitP.ID, projected=True) diff --git a/service/fleet.py b/service/fleet.py index 3a158cb2d..cfad7f04b 100644 --- a/service/fleet.py +++ b/service/fleet.py @@ -17,4 +17,199 @@ # along with pyfa. If not, see . #=============================================================================== -#Purge fleet boosts +import eos.db +from eos.types import Fleet as Fleet_, Wing, Squad +import copy + +class Fleet(object): + instance = None + @classmethod + def getInstance(cls): + if cls.instance is None: + cls.instance = Fleet() + + return cls.instance + + def __init__(self): + pass + + def getFleetList(self): + fleetList = [] + fleets = eos.db.getFleetList() + for fleet in fleets: + fleetList.append((fleet.ID, fleet.name, fleet.count())) + + return fleetList + + def getFleetByID(self, ID): + f = eos.db.getFleet(ID) + return f + + def addFleet(self): + f = Fleet_() + eos.db.save(f) + return f + + def renameFleet(self, fleet, newName): + fleet.name = newName + eos.db.commit() + + def copyFleet(self, fleet): + newFleet = copy.deepcopy(fleet) + eos.db.save(newFleet) + return newFleet + + def copyFleetByID(self, ID): + fleet = self.getFleetByID(ID) + return self.copyFleet(fleet) + + def deleteFleet(self, fleet): + eos.db.remove(fleet) + + def deleteFleetByID(self, ID): + fleet = self.getFleetByID(ID) + self.deleteFleet(fleet) + + def makeLinearFleet(self, fit): + f = Fleet_() + w = Wing() + f.wings.append(w) + s = Squad() + w.squads.append(s) + s.members.append(fit) + fit.fleet = f + eos.db.save(f) + + def setLinearFleetCom(self, boostee, booster): + #if boostee == booster: + # return + if self.getLinearFleet(boostee) is None: + self.removeAssociatedFleetData(boostee) + self.makeLinearFleet(boostee) + squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) + squad = eos.db.getSquad(squadIDs.pop()) + if squad.wing.gang.leader is not None and booster is None: + try: + squad.wing.gang.leader.boostsFits.remove(boostee.ID) + except KeyError: + pass + squad.wing.gang.leader = booster + if self.anyBoosters(squad) is False: + self.removeAssociatedFleetData(boostee) + from service.fit import Fit + sFit = Fit.getInstance() + sFit.recalc(boostee, withBoosters=True) + + def setLinearWingCom(self, boostee, booster): + #if boostee == booster: + # return + if self.getLinearFleet(boostee) is None: + self.removeAssociatedFleetData(boostee) + self.makeLinearFleet(boostee) + squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) + squad = eos.db.getSquad(squadIDs.pop()) + if squad.wing.leader is not None and booster is None: + try: + squad.wing.leader.boostsFits.remove(boostee.ID) + except KeyError: + pass + squad.wing.leader = booster + if self.anyBoosters(squad) is False: + self.removeAssociatedFleetData(boostee) + from service.fit import Fit + sFit = Fit.getInstance() + sFit.recalc(boostee, withBoosters=True) + + def setLinearSquadCom(self, boostee, booster): + #if boostee == booster: + # return + if self.getLinearFleet(boostee) is None: + self.removeAssociatedFleetData(boostee) + self.makeLinearFleet(boostee) + squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) + squad = eos.db.getSquad(squadIDs.pop()) + if squad.leader is not None and booster is None: + try: + squad.leader.boostsFits.remove(boostee.ID) + except KeyError: + pass + squad.leader = booster + if self.anyBoosters(squad) is False: + self.removeAssociatedFleetData(boostee) + from service.fit import Fit + sFit = Fit.getInstance() + sFit.recalc(boostee, withBoosters=True) + + + def getLinearFleet(self, fit): + sqIDs = eos.db.getSquadsIDsWithFitID(fit.ID) + if len(sqIDs) != 1: + return None + s = eos.db.getSquad(sqIDs[0]) + if len(s.members) != 1: + return None + w = s.wing + if len(w.squads) != 1: + return None + f = w.gang + if len(f.wings) != 1: + return None + return f + + def removeAssociatedFleetData(self, fit): + squadIDs = set(eos.db.getSquadsIDsWithFitID(fit.ID)) + if len(squadIDs) == 0: + return + squads = list(eos.db.getSquad(sqID) for sqID in squadIDs) + wingIDs = set(squad.wing.ID for squad in squads) + fleetIDs = set(squad.wing.gang.ID for squad in squads) + for fleetID in fleetIDs: + fleet = eos.db.getFleet(fleetID) + for wing in fleet.wings: + wingIDs.add(wing.ID) + for wingID in wingIDs: + wing = eos.db.getWing(wingID) + for squad in wing.squads: + squadIDs.add(squad.ID) + for squadID in squadIDs: + squad = eos.db.getSquad(squadID) + if squad.leader is not None: + try: + squad.leader.boostsFits.remove(fit.ID) + except KeyError: + pass + eos.db.remove(squad) + for wingID in wingIDs: + wing = eos.db.getWing(wingID) + if wing.leader is not None: + try: + wing.leader.boostsFits.remove(fit.ID) + except KeyError: + pass + eos.db.remove(wing) + for fleetID in fleetIDs: + fleet = eos.db.getFleet(fleetID) + if fleet.leader is not None: + try: + fleet.leader.boostsFits.remove(fit.ID) + except KeyError: + pass + eos.db.remove(fleet) + fit.fleet = None + return + + def anyBoosters(self, squad): + wing = squad.wing + fleet = wing.gang + if squad.leader is None and wing.leader is None and fleet.leader is None: + return False + return True + + def loadLinearFleet(self, fit): + if self.getLinearFleet(fit) is None: + return None + squadID = eos.db.getSquadsIDsWithFitID(fit.ID)[0] + s = eos.db.getSquad(squadID) + w = s.wing + f = w.gang + return (f.leader, w.leader, s.leader) From c30190f63e29f315cd26251ecd40931d46a6de57 Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Thu, 15 Sep 2016 15:27:30 -0700 Subject: [PATCH 03/13] Revert "Revert "Purging fleet bonuses from code base"" This reverts commit 6e54d6788cd4784c5d6b76c26a2ec243e4c87cad. --- eos/db/saveddata/fleet.py | 48 +--- eos/db/saveddata/queries.py | 58 ----- eos/types.py | 1 - gui/additionsPane.py | 7 +- gui/builtinViews/fleetView.py | 141 +---------- gui/fleetBrowser.py | 457 +--------------------------------- gui/gangView.py | 394 +---------------------------- gui/mainFrame.py | 7 - service/__init__.py | 1 - service/fit.py | 13 +- service/fleet.py | 197 +-------------- 11 files changed, 7 insertions(+), 1317 deletions(-) diff --git a/eos/db/saveddata/fleet.py b/eos/db/saveddata/fleet.py index 8f0e6736b..0583b43b0 100644 --- a/eos/db/saveddata/fleet.py +++ b/eos/db/saveddata/fleet.py @@ -17,50 +17,4 @@ # along with eos. If not, see . #=============================================================================== -from sqlalchemy import Table, Column, Integer, ForeignKey, String -from sqlalchemy.orm import mapper, relation - -from eos.db import saveddata_meta -from eos.types import Fleet, Wing, Squad, Fit -from eos.db.saveddata.fit import fits_table - -gangs_table = Table("gangs", saveddata_meta, - Column("ID", Integer, primary_key = True), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("name", String)) - -wings_table = Table("wings", saveddata_meta, - Column("ID", Integer, primary_key = True), - Column("gangID", ForeignKey("gangs.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("leaderID", ForeignKey("fits.ID"))) - -squads_table = Table("squads", saveddata_meta, - Column("ID", Integer, primary_key = True), - Column("wingID", ForeignKey("wings.ID")), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID"))) - -squadmembers_table = Table("squadmembers", saveddata_meta, - Column("squadID", ForeignKey("squads.ID"), primary_key = True), - Column("memberID", ForeignKey("fits.ID"), primary_key = True)) - -mapper(Fleet, gangs_table, - properties = {"wings" : relation(Wing, backref="gang"), - "leader" : relation(Fit, primaryjoin = gangs_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin = gangs_table.c.boosterID == fits_table.c.ID)}) - -mapper(Wing, wings_table, - properties = {"squads" : relation(Squad, backref="wing"), - "leader" : relation(Fit, primaryjoin = wings_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin = wings_table.c.boosterID == fits_table.c.ID)}) - -mapper(Squad, squads_table, - properties = {"leader" : relation(Fit, primaryjoin = squads_table.c.leaderID == fits_table.c.ID), - "booster" : relation(Fit, primaryjoin = squads_table.c.boosterID == fits_table.c.ID), - "members" : relation(Fit, - primaryjoin = squads_table.c.ID == squadmembers_table.c.squadID, - secondaryjoin = squadmembers_table.c.memberID == fits_table.c.ID, - secondary = squadmembers_table)}) - +#Purging fleet \ No newline at end of file diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index 5a6dd1bfc..cb3033cc1 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -21,7 +21,6 @@ from eos.db.util import processEager, processWhere from eos.db import saveddata_session, sd_lock from eos.types import * -from eos.db.saveddata.fleet import squadmembers_table from eos.db.saveddata.fit import projectedFits_table from sqlalchemy.sql import and_ import eos.config @@ -194,48 +193,6 @@ def getFit(lookfor, eager=None): return fit -@cachedQuery(Fleet, 1, "fleetID") -def getFleet(fleetID, eager=None): - if isinstance(fleetID, int): - if eager is None: - with sd_lock: - fleet = saveddata_session.query(Fleet).get(fleetID) - else: - eager = processEager(eager) - with sd_lock: - fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first() - else: - raise TypeError("Need integer as argument") - return fleet - -@cachedQuery(Wing, 1, "wingID") -def getWing(wingID, eager=None): - if isinstance(wingID, int): - if eager is None: - with sd_lock: - wing = saveddata_session.query(Wing).get(wingID) - else: - eager = processEager(eager) - with sd_lock: - wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first() - else: - raise TypeError("Need integer as argument") - return wing - -@cachedQuery(Squad, 1, "squadID") -def getSquad(squadID, eager=None): - if isinstance(squadID, int): - if eager is None: - with sd_lock: - squad = saveddata_session.query(Squad).get(squadID) - else: - eager = processEager(eager) - with sd_lock: - squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first() - else: - raise TypeError("Need integer as argument") - return squad - def getFitsWithShip(shipID, ownerID=None, where=None, eager=None): """ Get all the fits using a certain ship. @@ -308,12 +265,6 @@ def getFitList(eager=None): return fits -def getFleetList(eager=None): - eager = processEager(eager) - with sd_lock: - fleets = saveddata_session.query(Fleet).options(*eager).all() - return fleets - @cachedQuery(Price, 1, "typeID") def getPrice(typeID): if isinstance(typeID, int): @@ -423,15 +374,6 @@ def searchFits(nameLike, where=None, eager=None): return fits -def getSquadsIDsWithFitID(fitID): - if isinstance(fitID, int): - with sd_lock: - squads = saveddata_session.query(squadmembers_table.c.squadID).filter(squadmembers_table.c.memberID == fitID).all() - squads = tuple(entry[0] for entry in squads) - return squads - else: - raise TypeError("Need integer as argument") - def getProjectedFits(fitID): if isinstance(fitID, int): with sd_lock: diff --git a/eos/types.py b/eos/types.py index 12e7eb281..f2550ad31 100644 --- a/eos/types.py +++ b/eos/types.py @@ -38,7 +38,6 @@ from eos.saveddata.booster import SideEffect from eos.saveddata.booster import Booster from eos.saveddata.fit import Fit, ImplantLocation from eos.saveddata.mode import Mode -from eos.saveddata.fleet import Fleet, Wing, Squad from eos.saveddata.miscData import MiscData from eos.saveddata.override import Override diff --git a/gui/additionsPane.py b/gui/additionsPane.py index 8c855dc95..f1ca44be4 100644 --- a/gui/additionsPane.py +++ b/gui/additionsPane.py @@ -26,7 +26,6 @@ from gui.cargoView import CargoView from gui.implantView import ImplantView from gui.projectedView import ProjectedView from gui.pyfatogglepanel import TogglePanel -from gui.gangView import GangView from gui.bitmapLoader import BitmapLoader import gui.chromeTabs @@ -55,7 +54,6 @@ class AdditionsPane(TogglePanel): implantImg = BitmapLoader.getImage("implant_small", "gui") boosterImg = BitmapLoader.getImage("booster_small", "gui") projectedImg = BitmapLoader.getImage("projected_small", "gui") - gangImg = BitmapLoader.getImage("fleet_fc_small", "gui") cargoImg = BitmapLoader.getImage("cargo_small", "gui") self.drone = DroneView(self.notebook) @@ -76,12 +74,9 @@ class AdditionsPane(TogglePanel): self.projectedPage = ProjectedView(self.notebook) self.notebook.AddPage(self.projectedPage, "Projected", tabImage = projectedImg, showClose = False) - self.gangPage = GangView(self.notebook) - self.notebook.AddPage(self.gangPage, "Fleet", tabImage = gangImg, showClose = False) - self.notebook.SetSelection(0) - PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected", "Fleet"] + PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected"] def select(self, name): self.notebook.SetSelection(self.PANES.index(name)) diff --git a/gui/builtinViews/fleetView.py b/gui/builtinViews/fleetView.py index bc6eef9a2..9058bc35f 100644 --- a/gui/builtinViews/fleetView.py +++ b/gui/builtinViews/fleetView.py @@ -1,140 +1 @@ -import wx.gizmos -import gui.fleetBrowser -import service -from gui.bitmapLoader import BitmapLoader - -#Tab spawning handler -class FleetSpawner(gui.multiSwitch.TabSpawner): - def __init__(self, multiSwitch): - self.multiSwitch = multiSwitch - mainFrame = gui.mainFrame.MainFrame.getInstance() - mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_SELECTED, self.fleetSelected) - - def fleetSelected(self, event): - if self.multiSwitch.GetPageCount() == 0: - self.multiSwitch.AddPage(wx.Panel(self.multiSwitch, size = (0,0)), "Empty Tab") - - view = FleetView(self.multiSwitch) - self.multiSwitch.ReplaceActivePage(view) - view.populate(event.fleetID) - view.Show() - -FleetSpawner.register() - -class FleetView(wx.gizmos.TreeListCtrl): - def __init__(self, parent, size = (0,0)): - wx.gizmos.TreeListCtrl.__init__(self, parent, size = size) - - self.tabManager = parent - - self.fleetId = None - self.fleetImg = BitmapLoader.getImage("53_16", "icons") - - self.imageList = wx.ImageList(16, 16) - self.SetImageList(self.imageList) - - for col in ("", "Fit", "Shiptype", "Character", "Bonusses"): - self.AddColumn(col) - - self.SetMainColumn(1) - self.icons = {} - self.addImage = self.imageList.Add(BitmapLoader.getBitmap("add_small", "gui")) - for icon in ("fb", "fc", "sb", "sc", "wb", "wc"): - self.icons[icon] = self.imageList.Add(BitmapLoader.getBitmap("fleet_%s_small" % icon, "gui")) - - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.checkNew) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_RENAMED, self.fleetRenamed) - self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_REMOVED, self.fleetRemoved) - - def Destroy(self): - self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_REMOVED, handler = self.fleetRemoved) - self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_RENAMED, handler = self.fleetRenamed) - wx.gizmos.TreeListCtrl.Destroy(self) - - def fleetRenamed(self, event): - if event.fleetID == self.fleetId: - sFleet = service.Fleet.getInstance() - f = sFleet.getFleetByID(event.fleetID) - self.UpdateTab(f.name, self.fleetImg) - - event.Skip() - - def fleetRemoved(self, event): - if event.fleetID == self.fleetId: - self.tabManager.DeletePage(self.tabManager.GetPageIndex(self)) - - event.Skip() - - def checkNew(self, event): - data = self.GetPyData(event.Item) - if data and isinstance(data, tuple) and data[0] == "add": - layer = data[1] - - - def UpdateTab(self, name, img): - self.tabManager.SetPageTextIcon(self.tabManager.GetSelection(), name, img) - - def populate(self, fleetID): - sFleet = service.Fleet.getInstance() - f = sFleet.getFleetByID(fleetID) - self.fleetId = fleetID - - self.UpdateTab( f.name, self.fleetImg) - self.fleet = f - self.DeleteAllItems() - root = self.AddRoot("") - - self.setEntry(root, f.leader, "fleet", f) - for wing in f.wings: - wingId = self.AppendItem(root, "") - self.setEntry(wingId, wing.leader, "wing", wing) - for squad in wing.squads: - for member in squad.members: - memberId = self.AppendItem(wingId, "") - self.setEntry(memberId, member, "squad", squad) - - self.addAdder(wingId, "squad") - - self.addAdder(root, "wing") - - self.ExpandAll(root) - self.SetColumnWidth(0, 16) - for i in xrange(1, 5): - self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) - headerWidth = self.GetColumnWidth(i) + 5 - self.SetColumnWidth(i, wx.LIST_AUTOSIZE) - baseWidth = self.GetColumnWidth(i) - if baseWidth < headerWidth: - self.SetColumnWidth(i, headerWidth) - else: - self.SetColumnWidth(i, baseWidth) - - - def addAdder(self, treeItemId, layer): - id = self.AppendItem(treeItemId, "Add new %s" % layer.capitalize()) - self.SetPyData(id, ("add", layer)) - self.SetItemImage(id, self.addImage, 1) - - def setEntry(self, treeItemId, fit, layer, info): - self.SetPyData(treeItemId, info) - if fit is None: - self.SetItemText(treeItemId, "%s Commander" % layer.capitalize(), 1) - else: - fleet = self.fleet - if fit == info.booster: - self.SetItemImage(treeItemId, self.icons["%sb" % layer[0]], 0) - elif fit == info.leader: - self.SetItemImage(treeItemId, self.icons["%sc" % layer[0]], 1) - - self.SetItemText(treeItemId, fit.name, 1) - self.SetItemText(treeItemId, fit.ship.item.name, 2) - self.SetItemText(treeItemId, fit.character.name, 3) - boosts = fleet.store.getBoosts(fit) - if boosts: - bonusses = [] - for name, info in boosts.iteritems(): - bonusses.append("%s: %.2g" % (name, info[0])) - - self.SetItemText(treeItemId, ", ".join(bonusses), 3) +#Purge fleet boosts \ No newline at end of file diff --git a/gui/fleetBrowser.py b/gui/fleetBrowser.py index 7476d7d7f..bb28be251 100644 --- a/gui/fleetBrowser.py +++ b/gui/fleetBrowser.py @@ -1,456 +1 @@ -import wx -import copy -from gui.bitmapLoader import BitmapLoader -import gui.mainFrame -from gui.PFListPane import PFListPane -import service.fleet -from gui.utils.drawUtils import GetPartialText - -from wx.lib.buttons import GenBitmapButton - -import gui.utils.colorUtils as colorUtils -import gui.utils.drawUtils as drawUtils - -import gui.sfBrowserItem as SFItem - -FleetSelected, EVT_FLEET_SELECTED = wx.lib.newevent.NewEvent() -FleetRenamed, EVT_FLEET_RENAMED = wx.lib.newevent.NewEvent() -FleetRemoved, EVT_FLEET_REMOVED = wx.lib.newevent.NewEvent() - - -FleetItemSelect, EVT_FLEET_ITEM_SELECT = wx.lib.newevent.NewEvent() -FleetItemDelete, EVT_FLEET_ITEM_DELETE = wx.lib.newevent.NewEvent() -FleetItemNew, EVT_FLEET_ITEM_NEW = wx.lib.newevent.NewEvent() -FleetItemCopy, EVT_FLEET_ITEM_COPY = wx.lib.newevent.NewEvent() -FleetItemRename, EVT_FLEET_ITEM_RENAME = wx.lib.newevent.NewEvent() - - - -class FleetBrowser(wx.Panel): - def __init__(self, parent): - wx.Panel.__init__(self, parent) - - self.sFleet = service.fleet.Fleet.getInstance() - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - mainSizer = wx.BoxSizer(wx.VERTICAL) - - self.hpane = FleetBrowserHeader(self) - mainSizer.Add(self.hpane, 0, wx.EXPAND) - - self.m_sl2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - mainSizer.Add( self.m_sl2, 0, wx.EXPAND, 0 ) - - self.fleetItemContainer = PFFleetItemContainer(self) - - mainSizer.Add(self.fleetItemContainer, 1, wx.EXPAND) - - self.SetSizer(mainSizer) - self.Layout() - - self.filter = "" - self.fleetIDMustEditName = -1 - - self.Bind(wx.EVT_SIZE, self.SizeRefreshList) - - self.Bind(EVT_FLEET_ITEM_NEW, self.AddNewFleetItem) - self.Bind(EVT_FLEET_ITEM_SELECT, self.SelectFleetItem) - self.Bind(EVT_FLEET_ITEM_DELETE, self.DeleteFleetItem) - self.Bind(EVT_FLEET_ITEM_COPY, self.CopyFleetItem) - self.Bind(EVT_FLEET_ITEM_RENAME, self.RenameFleetItem) - - self.PopulateFleetList() - - def AddNewFleetItem(self, event): - fleetName = event.fleetName - newFleet = self.sFleet.addFleet() - self.sFleet.renameFleet(newFleet, fleetName) - - self.fleetIDMustEditName = newFleet.ID - self.AddItem(newFleet.ID, newFleet.name, newFleet.count()) - - def SelectFleetItem(self, event): - fleetID = event.fleetID - self.fleetItemContainer.SelectWidgetByFleetID(fleetID) - wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleetID)) - - def CopyFleetItem(self, event): - fleetID = event.fleetID - fleet = self.sFleet.copyFleetByID(fleetID) - - fleetName = fleet.name + " Copy" - self.sFleet.renameFleet(fleet,fleetName) - - self.fleetIDMustEditName = fleet.ID - self.AddItem(fleet.ID, fleet.name, fleet.count()) - - self.fleetItemContainer.SelectWidgetByFleetID(fleet.ID) - wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleet.ID)) - - def RenameFleetItem(self, event): - fleetID = event.fleetID - fleet = self.sFleet.getFleetByID(fleetID) - - newFleetName = event.fleetName - - self.sFleet.renameFleet(fleet, newFleetName) - wx.PostEvent(self.mainFrame, FleetRenamed(fleetID = fleet.ID)) - - def DeleteFleetItem(self, event): - self.sFleet.deleteFleetByID(event.fleetID) - self.PopulateFleetList() - wx.PostEvent(self.mainFrame, FleetRemoved(fleetID = event.fleetID)) - - def AddItem (self, ID, name, count): - self.fleetItemContainer.AddWidget(FleetItem(self, ID, name, count)) - widget = self.fleetItemContainer.GetWidgetByFleetID(ID) - self.fleetItemContainer.RefreshList(True) - self.fleetItemContainer.ScrollChildIntoView(widget) - wx.PostEvent(self, FleetItemSelect(fleetID = ID)) - - def PopulateFleetList(self): - self.Freeze() - filter = self.filter - self.fleetItemContainer.RemoveAllChildren() - fleetList = self.sFleet.getFleetList() - for fleetID, fleetName, fleetCount in fleetList: - if fleetName.lower().find(filter.lower()) != -1: - self.fleetItemContainer.AddWidget(FleetItem(self, fleetID, fleetName, fleetCount)) - self.fleetItemContainer.RefreshList() - self.Thaw() - - def SetFilter(self, filter): - self.filter = filter - - def SizeRefreshList(self, event): - ewidth, eheight = event.GetSize() - self.Layout() - self.fleetItemContainer.Layout() - self.fleetItemContainer.RefreshList(True) - event.Skip() - - -class FleetBrowserHeader (wx.Panel): - def __init__(self, parent): - wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 24), style=wx.TAB_TRAVERSAL) - self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) ) - - self.newBmp = BitmapLoader.getBitmap("fit_add_small","gui") - bmpSize = (16,16) - - mainSizer = wx.BoxSizer(wx.HORIZONTAL) - - if 'wxMac' in wx.PlatformInfo: - bgcolour = wx.Colour(0, 0, 0, 0) - else: - bgcolour = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) - - self.fbNewFleet = PFGenBitmapButton( self, wx.ID_ANY, self.newBmp, wx.DefaultPosition, bmpSize, wx.BORDER_NONE ) - mainSizer.Add(self.fbNewFleet, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL , 5) - self.fbNewFleet.SetBackgroundColour( bgcolour ) - - self.sl1 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_VERTICAL ) - mainSizer.Add( self.sl1, 0, wx.EXPAND |wx.LEFT, 5 ) - - self.tcFilter = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) - mainSizer.Add( self.tcFilter, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.stStatus = wx.StaticText( self, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stStatus.Wrap( -1 ) - mainSizer.Add( self.stStatus, 1, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.SetSizer(mainSizer) - self.Layout() - - self.fbNewFleet.Bind(wx.EVT_ENTER_WINDOW, self.fbNewEnterWindow) - self.fbNewFleet.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) - self.fbNewFleet.Bind(wx.EVT_BUTTON, self.OnNewFleetItem) - - self.tcFilter.Bind(wx.EVT_TEXT, self.OnFilterText) - - self.tcFilter.Bind(wx.EVT_ENTER_WINDOW, self.fbFilterEnterWindow) - self.tcFilter.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) - - def OnFilterText(self, event): - filter = self.tcFilter.GetValue() - self.Parent.SetFilter(filter) - self.Parent.PopulateFleetList() - event.Skip() - - def OnNewFleetItem(self, event): - wx.PostEvent(self.Parent, FleetItemNew(fleetName = "New Fleet")) - - def fbNewEnterWindow(self, event): - self.stStatus.SetLabel("New fleet") - self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - event.Skip() - - def fbHItemLeaveWindow(self, event): - self.stStatus.SetLabel("") - self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - event.Skip() - - def fbFilterEnterWindow(self, event): - self.stStatus.SetLabel("Filter list") - event.Skip() - - - -class PFFleetItemContainer(PFListPane): - def __init__(self,parent): - PFListPane.__init__(self,parent) - self.selectedWidget = -1 - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - - def IsWidgetSelectedByContext(self, widget): - if self.GetWidgetList()[widget].IsSelected(): - return True - return False - - def GetWidgetIndex(self, widgetWnd): - return self.GetWidgetList().index(widgetWnd) - - def GetWidgetByFleetID(self, fleetID): - for widget in self.GetWidgetList(): - if widget.fleetID == fleetID: - return widget - return None - - def SelectWidget(self, widgetWnd): - wlist = self.GetWidgetList() - if self.selectedWidget != -1: - wlist[self.selectedWidget].SetSelected(False) - wlist[self.selectedWidget].Refresh() - windex = self.GetWidgetIndex(widgetWnd) - wlist[windex].SetSelected(True) - wlist[windex].Refresh() - self.selectedWidget = windex - - def SelectWidgetByFleetID(self, fleetID): - widgetWnd = self.GetWidgetByFleetID(fleetID) - if widgetWnd: - self.SelectWidget(widgetWnd) - - def RemoveWidget(self, child): - child.Destroy() - self.selectedWidget = -1 - self._wList.remove(child) - - - def RemoveAllChildren(self): - for widget in self._wList: - widget.Destroy() - - self.selectedWidget = -1 - self._wList = [] - - def OnLeftUp(self, event): - event.Skip() - -class FleetItem(SFItem.SFBrowserItem): - def __init__(self, parent, fleetID, fleetName, fleetCount, - id=wx.ID_ANY, pos=wx.DefaultPosition, - size=(0,40), style=0): - SFItem.SFBrowserItem.__init__(self, parent, size = size) - - self.fleetBrowser = self.Parent - self.fleetID = fleetID - self.fleetName = fleetName - self.fleetCount = fleetCount - - self.padding = 4 - - self.fontBig = wx.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.BOLD, False) - self.fontNormal = wx.FontFromPixelSize((0,14),wx.SWISS, wx.NORMAL, wx.NORMAL, False) - self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False) - - self.copyBmp = BitmapLoader.getBitmap("fit_add_small", "gui") - self.renameBmp = BitmapLoader.getBitmap("fit_rename_small", "gui") - self.deleteBmp = BitmapLoader.getBitmap("fit_delete_small","gui") - self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui") - self.fleetBmp = BitmapLoader.getBitmap("fleet_item_big", "gui") - - fleetImg = self.fleetBmp.ConvertToImage() - fleetImg = fleetImg.Blur(2) - - if not fleetImg.HasAlpha(): - fleetImg.InitAlpha() - - fleetImg = fleetImg.AdjustChannels(1, 1, 1, 0.5) - self.fleetEffBmp = wx.BitmapFromImage(fleetImg) - - self.toolbar.AddButton(self.copyBmp, "Copy", self.CopyFleetCB) - self.renameBtn = self.toolbar.AddButton(self.renameBmp, "Rename", self.RenameFleetCB) - self.toolbar.AddButton(self.deleteBmp, "Delete", self.DeleteFleetCB) - - self.editWidth = 150 - self.tcFleetName = wx.TextCtrl(self, wx.ID_ANY, "%s" % self.fleetName, wx.DefaultPosition, (self.editWidth,-1), wx.TE_PROCESS_ENTER) - - if self.fleetBrowser.fleetIDMustEditName != self.fleetID: - self.tcFleetName.Show(False) - else: - self.tcFleetName.SetFocus() - self.tcFleetName.SelectAll() - self.fleetBrowser.fleetIDMustEditName = -1 - self.renameBtn.SetBitmap(self.acceptBmp) - self.selected = True - - self.tcFleetName.Bind(wx.EVT_KILL_FOCUS, self.OnEditLostFocus) - self.tcFleetName.Bind(wx.EVT_TEXT_ENTER, self.RenameFleet) - self.tcFleetName.Bind(wx.EVT_KEY_DOWN, self.EditCheckEsc) - - - self.animCount = 0 - - def MouseLeftUp(self, event): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - else: - wx.PostEvent(self.fleetBrowser, FleetItemSelect(fleetID = self.fleetID)) - - def CopyFleetCB(self): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - return - - wx.PostEvent(self.fleetBrowser, FleetItemCopy(fleetID = self.fleetID)) - - def RenameFleetCB(self): - - if self.tcFleetName.IsShown(): - - self.RenameFleet(None) - self.RestoreEditButton() - - else: - self.tcFleetName.SetValue(self.fleetName) - self.tcFleetName.Show() - - self.renameBtn.SetBitmap(self.acceptBmp) - self.Refresh() - - self.tcFleetName.SetFocus() - self.tcFleetName.SelectAll() - - self.Refresh() - - def RenameFleet(self, event): - - newFleetName = self.tcFleetName.GetValue() - self.fleetName = newFleetName - - self.tcFleetName.Show(False) - - wx.PostEvent(self.fleetBrowser, FleetItemRename(fleetID = self.fleetID, fleetName = self.fleetName)) - self.Refresh() - - def DeleteFleetCB(self): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - return - wx.PostEvent(self.fleetBrowser, FleetItemDelete(fleetID = self.fleetID)) - - def RestoreEditButton(self): - self.tcFleetName.Show(False) - self.renameBtn.SetBitmap(self.renameBmp) - self.Refresh() - - def OnEditLostFocus(self, event): - self.RestoreEditButton() - self.Refresh() - - def EditCheckEsc(self, event): - if event.GetKeyCode() == wx.WXK_ESCAPE: - self.RestoreEditButton() - else: - event.Skip() - - def IsSelected(self): - return self.selected - - def UpdateElementsPos(self, mdc): - rect = self.GetRect() - - self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding - self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2 - - self.toolbarx = self.toolbarx + self.animCount - - self.fleetBmpx = self.padding + (rect.height - self.fleetBmp.GetWidth()) / 2 - self.fleetBmpy = (rect.height - self.fleetBmp.GetHeight()) / 2 - - self.fleetBmpx -= self.animCount - - self.textStartx = self.fleetBmpx + self.fleetBmp.GetWidth() + self.padding - - self.fleetNamey = (rect.height - self.fleetBmp.GetHeight()) / 2 - - mdc.SetFont(self.fontBig) - wtext, htext = mdc.GetTextExtent(self.fleetName) - - self.fleetCounty = self.fleetNamey + htext - - mdc.SetFont(self.fontSmall) - - wlabel,hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel) - - self.thoverx = self.toolbarx - self.padding - wlabel - self.thovery = (rect.height - hlabel)/2 - self.thoverw = wlabel - - def DrawItem(self, mdc): - rect = self.GetRect() - - windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW) - textColor = colorUtils.GetSuitableColor(windowColor, 1) - - mdc.SetTextForeground(textColor) - - self.UpdateElementsPos(mdc) - - self.toolbar.SetPosition((self.toolbarx, self.toolbary)) - mdc.DrawBitmap(self.fleetEffBmp, self.fleetBmpx + 3, self.fleetBmpy + 2) - mdc.DrawBitmap(self.fleetBmp, self.fleetBmpx,self.fleetBmpy) - - mdc.SetFont(self.fontNormal) - - suffix = "%d ships" % self.fleetCount if self.fleetCount >1 else "%d ship" % self.fleetCount if self.fleetCount == 1 else "No ships" - fleetCount = "Fleet size: %s" % suffix - fleetCount = drawUtils.GetPartialText(mdc, fleetCount, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) - - mdc.DrawText(fleetCount, self.textStartx, self.fleetCounty) - - mdc.SetFont(self.fontSmall) - mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery) - - mdc.SetFont(self.fontBig) - - pfname = drawUtils.GetPartialText(mdc, self.fleetName, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) - mdc.DrawText(pfname, self.textStartx, self.fleetNamey) - - if self.tcFleetName.IsShown(): - self.AdjustControlSizePos(self.tcFleetName, self.textStartx, self.toolbarx - self.editWidth - self.padding) - - def AdjustControlSizePos(self, editCtl, start, end): - fnEditSize = editCtl.GetSize() - wSize = self.GetSize() - fnEditPosX = end - fnEditPosY = (wSize.height - fnEditSize.height)/2 - if fnEditPosX < start: - editCtl.SetSize((self.editWidth + fnEditPosX - start,-1)) - editCtl.SetPosition((start,fnEditPosY)) - else: - editCtl.SetSize((self.editWidth,-1)) - editCtl.SetPosition((fnEditPosX,fnEditPosY)) - - -class PFGenBitmapButton(GenBitmapButton): - def __init__(self, parent, id, bitmap, pos, size, style): - GenBitmapButton.__init__(self, parent, id, bitmap, pos, size, style) - self.bgcolor = wx.Brush(wx.WHITE) - - def SetBackgroundColour(self, color): - self.bgcolor = wx.Brush(color) - - def GetBackgroundBrush(self, dc): - return self.bgcolor +# purging fleet \ No newline at end of file diff --git a/gui/gangView.py b/gui/gangView.py index 106f14f98..d5f8e43cb 100644 --- a/gui/gangView.py +++ b/gui/gangView.py @@ -16,397 +16,5 @@ # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . #=============================================================================== -import wx -from wx.lib.scrolledpanel import ScrolledPanel -import service -import gui.mainFrame -import gui.shipBrowser -import gui.globalEvents as GE - -from gui import characterEditor as CharEditor - -class GangView ( ScrolledPanel ): - - def __init__( self, parent ): - ScrolledPanel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 100,20 ), style = wx.TAB_TRAVERSAL | wx.HSCROLL | wx.VSCROLL ) - mainSizer = wx.BoxSizer( wx.VERTICAL ) - - self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - self.draggedFitID = None - - help = '''Set fit as booster to display in dropdown, or drag fitting from\nship browser to this window, or right click fit and select booster role.''' - helpSizer = wx.BoxSizer( wx.HORIZONTAL ) - self.helpText = wx.StaticText( self, wx.ID_ANY, help, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE ) - helpSizer.Add( self.helpText, 1, wx.ALL, 5 ) - - self.options = ["Fleet", "Wing", "Squad"] - - self.fleet = {} - for id, option in enumerate(self.options): - - # set content for each commander - self.fleet[id] = {} - self.fleet[id]['stLabel'] = wx.StaticText( self, wx.ID_ANY, self.options[id]+':', wx.DefaultPosition, wx.DefaultSize, 0 ) - self.fleet[id]['stText'] = wx.StaticText( self, wx.ID_ANY, 'None', wx.DefaultPosition, wx.DefaultSize, 0 ) - self.fleet[id]['chFit'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) - self.fleet[id]['chChar'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) - self.fleet[id]['fitSizer'] = wx.BoxSizer( wx.VERTICAL ) - - self.FitDNDPopupMenu = self.buildBoostermenu() - - contentFGSizer = wx.FlexGridSizer( 5, 3, 0, 0 ) - contentFGSizer.AddGrowableCol( 1 ) - contentFGSizer.SetFlexibleDirection( wx.BOTH ) - contentFGSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED ) - - ### Header - self.stBooster = wx.StaticText( self, wx.ID_ANY, u"Booster", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stBooster.Wrap( -1 ) - self.stBooster.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stBooster, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.stFits = wx.StaticText( self, wx.ID_ANY, u"Fits", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stFits.Wrap( -1 ) - self.stFits.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stFits, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.stCharacters = wx.StaticText( self, wx.ID_ANY, u"Characters", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stCharacters.Wrap( -1 ) - self.stCharacters.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stCharacters, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.m_staticline2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline2, 0, wx.EXPAND, 5 ) - - self.m_staticline3 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline3, 0, wx.EXPAND, 5 ) - - self.m_staticline4 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline4, 0, wx.EXPAND, 5 ) - - ### Content - for id in self.fleet: - # set various properties - self.fleet[id]['stLabel'].Wrap( -1 ) - self.fleet[id]['stLabel'].SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - self.fleet[id]['stText'].Wrap( -1 ) - - # bind text and choice events - self.fleet[id]['stText'].Bind(wx.EVT_LEFT_DCLICK, self.RemoveBooster) - self.fleet[id]['stText'].Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) - self.fleet[id]['stText'].Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) - self.fleet[id]['stText'].SetToolTip(wx.ToolTip("Double click to remove booster")) - self.fleet[id]['chChar'].Bind(wx.EVT_CHOICE, self.CharChanged) - self.fleet[id]['chFit'].Bind(wx.EVT_CHOICE, self.OnFitChoiceSelected) - - # add fit text and choice to the fit sizer - self.fleet[id]['fitSizer'].Add( self.fleet[id]['stText'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - self.fleet[id]['fitSizer'].Add( self.fleet[id]['chFit'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 1 ) - - # add everything to the content sizer - contentFGSizer.Add( self.fleet[id]['stLabel'], 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - contentFGSizer.Add( self.fleet[id]['fitSizer'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 5 ) - contentFGSizer.Add( self.fleet[id]['chChar'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - - mainSizer.Add( contentFGSizer, 1, wx.EXPAND, 0 ) - mainSizer.Add( helpSizer, 0, wx.EXPAND, 0 ) - - self.SetSizer( mainSizer ) - self.SetAutoLayout(True) - self.SetupScrolling() - - self.mainFrame.Bind(GE.CHAR_LIST_UPDATED, self.RefreshCharacterList) - self.mainFrame.Bind(GE.FIT_CHANGED, self.fitSelected) - self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_RENAMED, self.fitRenamed) - self.mainFrame.Bind(gui.shipBrowser.BOOSTER_LIST_UPDATED, self.RefreshBoosterFits) - - self.RefreshBoosterFits() - self.RefreshCharacterList() - - def buildBoostermenu(self): - menu = wx.Menu() - - for id, option in enumerate(self.options): - item = menu.Append(-1, option) - # We bind it to the mainFrame because it may be called from either this class or from FitItem via shipBrowser - self.mainFrame.Bind(wx.EVT_MENU, self.OnPopupItemSelected, item) - return menu - - def OnEnterWindow(self, event): - obj = event.GetEventObject() - obj.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - event.Skip() - - def OnLeaveWindow(self, event): - obj = event.GetEventObject() - obj.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) - event.Skip() - - def CharChanged(self, event): - ''' Change booster character ''' - chBooster = event.GetEventObject() - - type = -1 - for id in self.fleet: - if chBooster == self.fleet[id]['chChar']: type = id - - if type == -1: - event.Skip() - return - - sFit = service.Fit.getInstance() - - fleetSrv = service.Fleet.getInstance() - - activeFitID = self.mainFrame.getActiveFit() - fit = sFit.getFit(activeFitID) - - sChar = service.Character.getInstance() - charList = sChar.getCharacterList() - - if activeFitID: - commanders = fleetSrv.loadLinearFleet(fit) - if commanders is None: - fleetCom, wingCom, squadCom = (None, None, None) - else: - fleetCom, wingCom, squadCom = commanders - - if type == 0: - if fleetCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(fleetCom.ID, charID) - else: - chBooster.SetSelection(0) - - if type == 1: - if wingCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(wingCom.ID, charID) - else: - chBooster.SetSelection(0) - - if type == 2: - if squadCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(squadCom.ID, charID) - else: - chBooster.SetSelection(0) - - sFit.recalc(fit, withBoosters=True) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - else: - chBooster.SetSelection(0) - - def RemoveBooster(self, event): - activeFitID = self.mainFrame.getActiveFit() - if not activeFitID: - return - - location = event.GetEventObject() - - for id in self.fleet: - if location == self.fleet[id]['stText']: type = id - - sFit = service.Fit.getInstance() - boostee = sFit.getFit(activeFitID) - booster = None - - fleetSrv = service.Fleet.getInstance() - - if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) - if type == 1: fleetSrv.setLinearWingCom(boostee, booster) - if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) - - # Hide stText and, default fit selection, and enable it - location.Hide() - choice = self.fleet[type]['chFit'] - choice.SetSelection(0) - choice.Show() - - sFit.recalc(boostee, withBoosters=True) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - def fitRenamed(self, event): - fleetSrv = service.Fleet.getInstance() - activeFitID = self.mainFrame.getActiveFit() - - if activeFitID: - ev = event - ev.fitID = activeFitID - self.fitSelected(ev) - - def fitSelected(self, event): - ''' Fires when active fit is selected and when booster is saved to fit. Update the UI to reflect changes ''' - fleetSrv = service.Fleet.getInstance() - - activeFitID = self.mainFrame.getActiveFit() - sFit = service.Fit.getInstance() - fit = sFit.getFit(event.fitID or activeFitID) - - self.Parent.Parent.DisablePage(self, not fit or fit.isStructure) - - commanders = (None, None, None) - - if activeFitID: - commanders = fleetSrv.loadLinearFleet(fit) - - for id in self.fleet: - # try...except here as we're trying 2 different criteria and want to fall back on the same code - try: - commander = commanders[id] - - if not activeFitID or commander is None: - raise Exception() - - self.fleet[id]['stText'].SetLabel(commander.ship.item.name + ": " + commander.name) - self.fleet[id]['chChar'].SetStringSelection(commander.character.name if commander.character is not None else "All 0") - self.fleet[id]['chChar'].Enable() - self.fleet[id]['chFit'].Hide() - self.fleet[id]['stText'].Show() - except: - #set defaults, disable char selection, and enable fit selection - self.fleet[id]['stText'].SetLabel("None") - self.fleet[id]['chChar'].SetStringSelection("All 0") - self.fleet[id]['chChar'].Disable() - self.fleet[id]['chFit'].SetSelection(0) - self.fleet[id]['chFit'].Show() - self.fleet[id]['stText'].Hide() - - if activeFitID: - self.Enable() - else: - self.Disable() - - self.Layout() - self.SendSizeEvent() - - def AddCommander(self, fitID, type = None): - ''' Adds booster to a fit, then recalculates active fit ''' - if type is None: - return - - activeFitID = self.mainFrame.getActiveFit() - if activeFitID: - sFit = service.Fit.getInstance() - - boostee = sFit.getFit(activeFitID) - booster = sFit.getFit(fitID) - - fleetSrv = service.Fleet.getInstance() - - if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) - if type == 1: fleetSrv.setLinearWingCom(boostee, booster) - if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) - - sFit.recalc(boostee) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - def RefreshBoosterFits(self, event = None): - sFit = service.Fit.getInstance() - sMkt = service.Market.getInstance() - fitList = sFit.getBoosterFits() - - for id in self.fleet: - choice = self.fleet[id]['chFit'] - chCurrSelection = choice.GetSelection() - chCurrData = -1 - if chCurrSelection != -1: - chCurrData = choice.GetClientData(chCurrSelection) - chCurrSelString = choice.GetString(chCurrSelection) - choice.Clear() - currSelFound = False - choice.Append("None", -1) - for fit in fitList: - id,name,type = fit - ship = sMkt.getItem(type) - choice.Append(ship.name+': '+name, id) - if chCurrData == id: - currSelFound = True - - if chCurrSelection == -1: - choice.SetSelection(0) - else: - if currSelFound: - choice.SetStringSelection(chCurrSelString) - else: - choice.SetSelection(0) - - def RefreshCharacterList(self, event = None): - sChar = service.Character.getInstance() - charList = sChar.getCharacterList() - for id in self.fleet: - choice = self.fleet[id]['chChar'] - chCurrSelection = choice.GetSelection() - chCurrData = -1 - if chCurrSelection != -1: - chCurrData = choice.GetClientData(chCurrSelection) - chCurrSelString = choice.GetString(chCurrSelection) - choice.Clear() - currSelFound = False - for char in charList: - choice.Append(char.name, char.ID) - if chCurrData == char.ID: - currSelFound = True - - if chCurrSelection == -1: - choice.SetSelection(1) - else: - if currSelFound: - choice.SetStringSelection(chCurrSelString) - else: - choice.SetSelection(1) - - def handleDrag(self, type, fitID): - ''' Handle dragging of fit to fleet interface ''' - #Those are drags coming from pyfa sources, NOT builtin wx drags - self.draggedFitID = None - if type == "fit": - sFit = service.Fit.getInstance() - fit = sFit.getFit(self.mainFrame.getActiveFit()) - - if fit and not fit.isStructure: - self.draggedFitID = fitID - - pos = wx.GetMousePosition() - pos = self.ScreenToClient(pos) - - self.PopupMenu(self.FitDNDPopupMenu, pos) - - - def OnPopupItemSelected(self, event): - ''' Fired when booster popup item is selected ''' - # Get menu selection ID via self.options - menuItem = event.EventObject.FindItemById(event.GetId()) - type = self.options.index(menuItem.GetText()) - - if self.draggedFitID: - sFit = service.Fit.getInstance() - draggedFit = sFit.getFit(self.draggedFitID) - - self.AddCommander(draggedFit.ID, type) - self.mainFrame.additionsPane.select("Fleet") - - def OnFitChoiceSelected(self, event): - ''' Fired when booster choice is selected ''' - sFit = service.Fit.getInstance() - - # set type via choice box used - chFit = event.GetEventObject() - fitID = chFit.GetClientData(chFit.GetSelection()) - - type = -1 - for id in self.fleet: - if chFit == self.fleet[id]['chFit']: type = id - - if type == -1 or fitID == -1: - event.Skip() - return - - fit = sFit.getFit(fitID) - - self.AddCommander(fit.ID, type) - self.mainFrame.additionsPane.select("Fleet") +#Purging fleet boosts \ No newline at end of file diff --git a/gui/mainFrame.py b/gui/mainFrame.py index c209a0422..220a8f0ab 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -55,7 +55,6 @@ from gui.preferenceDialog import PreferenceDialog from gui.graphFrame import GraphFrame from gui.copySelectDialog import CopySelectDialog from gui.utils.clipboard import toClipboard, fromClipboard -from gui.fleetBrowser import FleetBrowser from gui.updateDialog import UpdateDialog from gui.builtinViews import * @@ -158,12 +157,6 @@ class MainFrame(wx.Frame): self.shipBrowser = ShipBrowser(self.notebookBrowsers) self.notebookBrowsers.AddPage(self.shipBrowser, "Fittings", tabImage = shipBrowserImg, showClose = False) - #======================================================================= - # DISABLED FOR RC2 RELEASE - #self.fleetBrowser = FleetBrowser(self.notebookBrowsers) - #self.notebookBrowsers.AddPage(self.fleetBrowser, "Fleets", showClose = False) - #======================================================================= - self.notebookBrowsers.SetSelection(1) self.browser_fitting_split.SplitVertically(self.notebookBrowsers, self.fitting_additions_split) diff --git a/service/__init__.py b/service/__init__.py index b19c6db17..91ed07d82 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -5,7 +5,6 @@ from service.character import Character from service.damagePattern import DamagePattern from service.targetResists import TargetResists from service.settings import SettingsProvider -from service.fleet import Fleet from service.update import Update from service.price import Price from service.network import Network diff --git a/service/fit.py b/service/fit.py index 455e76463..d05865514 100644 --- a/service/fit.py +++ b/service/fit.py @@ -34,7 +34,6 @@ from eos.types import State, Slot from service.market import Market from service.damagePattern import DamagePattern from service.character import Character -from service.fleet import Fleet from service.settings import SettingsProvider from service.port import Port @@ -184,8 +183,6 @@ class Fit(object): def deleteFit(self, fitID): fit = eos.db.getFit(fitID) - sFleet = Fleet.getInstance() - sFleet.removeAssociatedFleetData(fit) eos.db.remove(fit) @@ -236,7 +233,7 @@ class Fit(object): self.recalc(fit, withBoosters=True) def getFit(self, fitID, projected=False, basic=False): - ''' Gets fit from database, and populates fleet data. + ''' Gets fit from database. Projected is a recursion flag that is set to reduce recursions into projected fits Basic is a flag to simply return the fit without any other processing @@ -251,14 +248,6 @@ class Fit(object): inited = getattr(fit, "inited", None) if inited is None or inited is False: - sFleet = Fleet.getInstance() - f = sFleet.getLinearFleet(fit) - if f is None: - sFleet.removeAssociatedFleetData(fit) - fit.fleet = None - else: - fit.fleet = f - if not projected: for fitP in fit.projectedFits: self.getFit(fitP.ID, projected=True) diff --git a/service/fleet.py b/service/fleet.py index cfad7f04b..3a158cb2d 100644 --- a/service/fleet.py +++ b/service/fleet.py @@ -17,199 +17,4 @@ # along with pyfa. If not, see . #=============================================================================== -import eos.db -from eos.types import Fleet as Fleet_, Wing, Squad -import copy - -class Fleet(object): - instance = None - @classmethod - def getInstance(cls): - if cls.instance is None: - cls.instance = Fleet() - - return cls.instance - - def __init__(self): - pass - - def getFleetList(self): - fleetList = [] - fleets = eos.db.getFleetList() - for fleet in fleets: - fleetList.append((fleet.ID, fleet.name, fleet.count())) - - return fleetList - - def getFleetByID(self, ID): - f = eos.db.getFleet(ID) - return f - - def addFleet(self): - f = Fleet_() - eos.db.save(f) - return f - - def renameFleet(self, fleet, newName): - fleet.name = newName - eos.db.commit() - - def copyFleet(self, fleet): - newFleet = copy.deepcopy(fleet) - eos.db.save(newFleet) - return newFleet - - def copyFleetByID(self, ID): - fleet = self.getFleetByID(ID) - return self.copyFleet(fleet) - - def deleteFleet(self, fleet): - eos.db.remove(fleet) - - def deleteFleetByID(self, ID): - fleet = self.getFleetByID(ID) - self.deleteFleet(fleet) - - def makeLinearFleet(self, fit): - f = Fleet_() - w = Wing() - f.wings.append(w) - s = Squad() - w.squads.append(s) - s.members.append(fit) - fit.fleet = f - eos.db.save(f) - - def setLinearFleetCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.wing.gang.leader is not None and booster is None: - try: - squad.wing.gang.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.wing.gang.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - def setLinearWingCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.wing.leader is not None and booster is None: - try: - squad.wing.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.wing.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - def setLinearSquadCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.leader is not None and booster is None: - try: - squad.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - - def getLinearFleet(self, fit): - sqIDs = eos.db.getSquadsIDsWithFitID(fit.ID) - if len(sqIDs) != 1: - return None - s = eos.db.getSquad(sqIDs[0]) - if len(s.members) != 1: - return None - w = s.wing - if len(w.squads) != 1: - return None - f = w.gang - if len(f.wings) != 1: - return None - return f - - def removeAssociatedFleetData(self, fit): - squadIDs = set(eos.db.getSquadsIDsWithFitID(fit.ID)) - if len(squadIDs) == 0: - return - squads = list(eos.db.getSquad(sqID) for sqID in squadIDs) - wingIDs = set(squad.wing.ID for squad in squads) - fleetIDs = set(squad.wing.gang.ID for squad in squads) - for fleetID in fleetIDs: - fleet = eos.db.getFleet(fleetID) - for wing in fleet.wings: - wingIDs.add(wing.ID) - for wingID in wingIDs: - wing = eos.db.getWing(wingID) - for squad in wing.squads: - squadIDs.add(squad.ID) - for squadID in squadIDs: - squad = eos.db.getSquad(squadID) - if squad.leader is not None: - try: - squad.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(squad) - for wingID in wingIDs: - wing = eos.db.getWing(wingID) - if wing.leader is not None: - try: - wing.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(wing) - for fleetID in fleetIDs: - fleet = eos.db.getFleet(fleetID) - if fleet.leader is not None: - try: - fleet.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(fleet) - fit.fleet = None - return - - def anyBoosters(self, squad): - wing = squad.wing - fleet = wing.gang - if squad.leader is None and wing.leader is None and fleet.leader is None: - return False - return True - - def loadLinearFleet(self, fit): - if self.getLinearFleet(fit) is None: - return None - squadID = eos.db.getSquadsIDsWithFitID(fit.ID)[0] - s = eos.db.getSquad(squadID) - w = s.wing - f = w.gang - return (f.leader, w.leader, s.leader) +#Purge fleet boosts From e5d65b97cee041b10c598590358762658a0f8658 Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Sun, 6 Nov 2016 16:33:28 -0800 Subject: [PATCH 04/13] Merged changes from Pyfa.org\Master to branch --- service/fit.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/service/fit.py b/service/fit.py index d05865514..1ef142266 100644 --- a/service/fit.py +++ b/service/fit.py @@ -105,7 +105,9 @@ class Fit(object): "showTooltip": True, "showMarketShortcuts": False, "enableGaugeAnimation": True, - "exportCharges": True} + "exportCharges": True, + "openFitInNew":False + } self.serviceFittingOptions = SettingsProvider.getInstance().getSettings( "pyfaServiceFittingOptions", serviceFittingDefaultOptions) @@ -233,8 +235,7 @@ class Fit(object): self.recalc(fit, withBoosters=True) def getFit(self, fitID, projected=False, basic=False): - ''' Gets fit from database. - + ''' Gets fit from database, and populates fleet data. Projected is a recursion flag that is set to reduce recursions into projected fits Basic is a flag to simply return the fit without any other processing ''' @@ -501,7 +502,6 @@ class Fit(object): """ Moves cargo to fitting window. Can either do a copy, move, or swap with current module If we try to copy/move into a spot with a non-empty module, we swap instead. - To avoid redundancy in converting Cargo item, this function does the sanity checks as opposed to the GUI View. This is different than how the normal .swapModules() does things, which is mostly a blind swap. @@ -567,7 +567,6 @@ class Fit(object): def cloneModule(self, fitID, src, dst): """ Clone a module from src to dst - This will overwrite dst! Checking for empty module must be done at a higher level """ @@ -914,6 +913,10 @@ class Fit(object): fits = map(lambda fitID: eos.db.getFit(fitID), fitIDs) return Port.exportXml(callback, *fits) + def exportMultiBuy(self, fitID): + fit = eos.db.getFit(fitID) + return Port.exportMultiBuy(fit) + def backupFits(self, path, callback): thread = FitBackupThread(path, callback) thread.start() @@ -927,7 +930,6 @@ class Fit(object): Imports fits from file(s). First processes all provided paths and stores assembled fits into a list. This allows us to call back to the GUI as fits are processed as well as when fits are being saved. - returns """ defcodepage = locale.getpreferredencoding() From b6c5183d400d45d1c778175a9127dbe7b5b15436 Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Sun, 6 Nov 2016 16:38:21 -0800 Subject: [PATCH 05/13] Removed actual fleet files. Cleaned up __init__.py that had references. --- eos/db/saveddata/__init__.py | 1 - eos/db/saveddata/fleet.py | 20 -------------------- gui/builtinViews/__init__.py | 2 +- gui/builtinViews/fleetView.py | 1 - gui/fleetBrowser.py | 1 - gui/gangView.py | 20 -------------------- service/fleet.py | 20 -------------------- 7 files changed, 1 insertion(+), 64 deletions(-) delete mode 100644 eos/db/saveddata/fleet.py delete mode 100644 gui/builtinViews/fleetView.py delete mode 100644 gui/fleetBrowser.py delete mode 100644 gui/gangView.py delete mode 100644 service/fleet.py diff --git a/eos/db/saveddata/__init__.py b/eos/db/saveddata/__init__.py index c97707f68..ad6b69ed7 100644 --- a/eos/db/saveddata/__init__.py +++ b/eos/db/saveddata/__init__.py @@ -8,7 +8,6 @@ __all__ = [ "booster", "drone", "implant", - "fleet", "damagePattern", "miscData", "targetResists", diff --git a/eos/db/saveddata/fleet.py b/eos/db/saveddata/fleet.py deleted file mode 100644 index 0583b43b0..000000000 --- a/eos/db/saveddata/fleet.py +++ /dev/null @@ -1,20 +0,0 @@ -#=============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of eos. -# -# eos is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# eos is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with eos. If not, see . -#=============================================================================== - -#Purging fleet \ No newline at end of file diff --git a/gui/builtinViews/__init__.py b/gui/builtinViews/__init__.py index 46a500f7b..d51fdbad6 100644 --- a/gui/builtinViews/__init__.py +++ b/gui/builtinViews/__init__.py @@ -1 +1 @@ -__all__ = ["fittingView", "fleetView", "implantEditor"] +__all__ = ["fittingView", "implantEditor"] diff --git a/gui/builtinViews/fleetView.py b/gui/builtinViews/fleetView.py deleted file mode 100644 index 9058bc35f..000000000 --- a/gui/builtinViews/fleetView.py +++ /dev/null @@ -1 +0,0 @@ -#Purge fleet boosts \ No newline at end of file diff --git a/gui/fleetBrowser.py b/gui/fleetBrowser.py deleted file mode 100644 index bb28be251..000000000 --- a/gui/fleetBrowser.py +++ /dev/null @@ -1 +0,0 @@ -# purging fleet \ No newline at end of file diff --git a/gui/gangView.py b/gui/gangView.py deleted file mode 100644 index d5f8e43cb..000000000 --- a/gui/gangView.py +++ /dev/null @@ -1,20 +0,0 @@ -#=============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of pyfa. -# -# pyfa is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# pyfa is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with pyfa. If not, see . -#=============================================================================== - -#Purging fleet boosts \ No newline at end of file diff --git a/service/fleet.py b/service/fleet.py deleted file mode 100644 index 3a158cb2d..000000000 --- a/service/fleet.py +++ /dev/null @@ -1,20 +0,0 @@ -#=============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of pyfa. -# -# pyfa is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# pyfa is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with pyfa. If not, see . -#=============================================================================== - -#Purge fleet boosts From 8a4fe1627e59cce17e236ae2c73b89ae97ea27be Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Mon, 14 Nov 2016 01:37:23 -0800 Subject: [PATCH 06/13] Requirements for Pyfa Caught most of the main ones, I think. (Yes I'm sneaking EVE-Gnosis in here, just so I don't have a conflict when I submit the cap/shield sim fix) --- requirements.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..e009d507a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +matplotlib +PyYAML +python-dateutil +urllib3 +requests +sqlalchemy +EVE-Gnosis From d3fdf9854d76a1d6b39c6ec3674cfbb6ff47dae3 Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Fri, 18 Nov 2016 01:01:08 -0800 Subject: [PATCH 07/13] Add versions Updated Gnosis to point to at least the current version. Pinned Requests as there's a bug in the most recent version. (Only applies to Python 3, but....) --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index e009d507a..548ada1d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,6 @@ matplotlib PyYAML python-dateutil urllib3 -requests +requests==2.11.1 sqlalchemy -EVE-Gnosis +EVE-Gnosis>=2016.11.17post2 From b9e5a47924ef756f87d653aba1f38eeb75ee5488 Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Tue, 6 Dec 2016 13:46:09 -0800 Subject: [PATCH 08/13] Remove gnosis --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 548ada1d7..f8e777507 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,3 @@ python-dateutil urllib3 requests==2.11.1 sqlalchemy -EVE-Gnosis>=2016.11.17post2 From 5b62419520a80de633d3fb6aa5d85bf02cf43a52 Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Thu, 8 Dec 2016 10:05:22 -0800 Subject: [PATCH 09/13] Add requirements for getting this to work on Travis-Ci --- requirements_test.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 requirements_test.txt diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 000000000..1bbef8b92 --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1,7 @@ +pytest==3.0.3 +pytest-mock==1.2 +pytest-cov==2.3.1 +pytest-capturelog==0.7 +coverage==4.2 +coveralls==1.1 +codecov From 7875c2acaa8770bfd9b5480b4bdd52759731f5a9 Mon Sep 17 00:00:00 2001 From: blitzman Date: Mon, 12 Dec 2016 00:24:50 -0500 Subject: [PATCH 10/13] Fix titan command effects --- eos/effects/chargebonuswarfarecharge.py | 8 +------ eos/effects/moduletitaneffectgenerator.py | 29 ++++++++++++----------- eos/saveddata/fit.py | 6 +---- eos/saveddata/module.py | 6 ++++- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/eos/effects/chargebonuswarfarecharge.py b/eos/effects/chargebonuswarfarecharge.py index 005101d45..83865a009 100644 --- a/eos/effects/chargebonuswarfarecharge.py +++ b/eos/effects/chargebonuswarfarecharge.py @@ -15,11 +15,7 @@ which warfareBuffID to run (shouldn't need this right now, but better safe than type = "active", "gang" def handler(fit, module, context, **kwargs): - print "In chargeBonusWarfareEffect, context: ", context - def runEffect(id, value): - print "RUN EFFECT: ", fit, - if id == 10: # Shield Burst: Shield Harmonizing: Shield Resistance for damageType in ("Em", "Explosive", "Thermal", "Kinetic"): fit.ship.boostItemAttr("shield%sDamageResonance" % damageType, value) @@ -101,12 +97,10 @@ def handler(fit, module, context, **kwargs): if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)): value = module.getModifiedChargeAttr("warfareBuff{}Multiplier".format(x)) id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x)) - print "Buff ID: ",id," value: ",value + if id: if 'commandRun' not in context: - print "Add buffID", id, " to ", fit fit.addCommandBonus(id, value, module, kwargs['effect']) elif kwargs['warfareBuffID'] is not None and kwargs['warfareBuffID'] == id: - print "Running buffID ", kwargs['warfareBuffID'], " on ", fit runEffect(kwargs['warfareBuffID'], value) diff --git a/eos/effects/moduletitaneffectgenerator.py b/eos/effects/moduletitaneffectgenerator.py index 2a5de4473..43f8c3fbe 100644 --- a/eos/effects/moduletitaneffectgenerator.py +++ b/eos/effects/moduletitaneffectgenerator.py @@ -11,43 +11,44 @@ def handler(fit, module, context, **kwargs): if id == 40: # Avatar Effect Generator : Kinetic resistance bonus for attr in ("armorKineticDamageResonance", "shieldKineticDamageResonance", "hullKineticDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) - if id == 41: # Erebus Effect Generator : Armor HP bonus + if id == 49: # Avatar Effect Generator : EM resistance penalty + for attr in ("armorEmDamageResonance", "shieldEmDamageResonance", "hullEmDamageResonance"): + fit.ship.boostItemAttr(attr, value) + + if id == 42: # Erebus Effect Generator : Armor HP bonus fit.ship.boostItemAttr("armorHP", value, stackingPenalties=True) - if id == 42: # Leviathan Effect Generator : Shield HP bonus - fit.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True) - if id == 43: # Erebus Effect Generator : Explosive resistance bonus for attr in ("armorExplosiveDamageResonance", "shieldExplosiveDamageResonance", "hullExplosiveDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 44: # Erebus Effect Generator : Thermal resistance penalty for attr in ("armorThermalDamageResonance", "shieldThermalDamageResonance", "hullThermalDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 45: # Ragnarok Effect Generator : Signature Radius bonus fit.ship.boostItemAttr("signatureRadius", value, stackingPenalties=True) if id == 46: # Ragnarok Effect Generator : Thermal resistance bonus for attr in ("armorThermalDamageResonance", "shieldThermalDamageResonance", "hullThermalDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 47: # Ragnarok Effect Generator : Explosive resistance penaly for attr in ("armorExplosiveDamageResonance", "shieldExplosiveDamageResonance", "hullExplosiveDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 48: # Leviathan Effect Generator : Shield HP bonus fit.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True) if id == 49: # Leviathan Effect Generator : EM resistance bonus for attr in ("armorEmDamageResonance", "shieldEmDamageResonance", "hullEmDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 50: # Leviathan Effect Generator : Kinetic resistance penalty for attr in ("armorKineticDamageResonance", "shieldKineticDamageResonance", "hullKineticDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 51: # Avatar Effect Generator : Velocity penalty fit.ship.boostItemAttr("maxVelocity", value, stackingPenalties=True) @@ -63,9 +64,9 @@ def handler(fit, module, context, **kwargs): fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups, "maxRange", value, stackingPenalties=True) for x in xrange(1, 4): - if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)): - value = module.getModifiedChargeAttr("warfareBuff{}Multiplier".format(x)) - id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x)) + if module.getModifiedItemAttr("warfareBuff{}ID".format(x)): + value = module.getModifiedItemAttr("warfareBuff{}Value".format(x)) + id = module.getModifiedItemAttr("warfareBuff{}ID".format(x)) if id: if 'commandRun' not in context: diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 1fe345be0..27cbece91 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -449,8 +449,6 @@ class Fit(object): # oh fuck this is so janky # @todo should we pass in min/max to this function, or is abs okay? # (abs is old method, ccp now provides the aggregate function in their data) - print "Add command bonus: ", warfareBuffID, " - value: ", value - if warfareBuffID not in self.commandBonuses or abs(self.commandBonuses[warfareBuffID][1]) < abs(value): self.commandBonuses[warfareBuffID] = (runTime, value, module, effect) @@ -514,12 +512,10 @@ class Fit(object): eos.db.saveddata_session.delete(self) if self.commandFits and not withBoosters: - print "Calculatate command fits and apply to fit" for fit in self.commandFits: if self == fit: - print "nope" continue - print "calculating ", fit + fit.calculateModifiedAttributes(self, True) # # for thing in chain(fit.modules, fit.implants, fit.character.skills, (fit.ship,)): diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 1a1c56de3..567be64d6 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -655,10 +655,14 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): effect.activeByDefault and \ (effect.isType("offline") or (effect.isType("passive") and self.state >= State.ONLINE) or + (effect.isType("active") and self.state >= State.ACTIVE))\ and ((projected and effect.isType("projected")) or not projected)\ and ((gang and effect.isType("gang")) or not gang): - effect.handler(fit, self, context) + try: + effect.handler(fit, self, context, effect=effect) + except: + effect.handler(fit, self, context) @property def cycleTime(self): From 0a28fb60df9156d8ed454e0527dd548157a19618 Mon Sep 17 00:00:00 2001 From: blitzman Date: Mon, 12 Dec 2016 00:27:36 -0500 Subject: [PATCH 11/13] oops --- eos/effects/moduletitaneffectgenerator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eos/effects/moduletitaneffectgenerator.py b/eos/effects/moduletitaneffectgenerator.py index 43f8c3fbe..e5c2b3d2e 100644 --- a/eos/effects/moduletitaneffectgenerator.py +++ b/eos/effects/moduletitaneffectgenerator.py @@ -13,7 +13,7 @@ def handler(fit, module, context, **kwargs): for attr in ("armorKineticDamageResonance", "shieldKineticDamageResonance", "hullKineticDamageResonance"): fit.ship.boostItemAttr(attr, value) - if id == 49: # Avatar Effect Generator : EM resistance penalty + if id == 41: # Avatar Effect Generator : EM resistance penalty for attr in ("armorEmDamageResonance", "shieldEmDamageResonance", "hullEmDamageResonance"): fit.ship.boostItemAttr(attr, value) From 16505b30bf4621dd018c23dceba1b26aadf3b842 Mon Sep 17 00:00:00 2001 From: blitzman Date: Mon, 12 Dec 2016 00:43:42 -0500 Subject: [PATCH 12/13] working commit --- eos/db/saveddata/fleet.py | 65 -------- eos/saveddata/fleet.py | 341 -------------------------------------- 2 files changed, 406 deletions(-) delete mode 100644 eos/db/saveddata/fleet.py delete mode 100644 eos/saveddata/fleet.py diff --git a/eos/db/saveddata/fleet.py b/eos/db/saveddata/fleet.py deleted file mode 100644 index eb644b02e..000000000 --- a/eos/db/saveddata/fleet.py +++ /dev/null @@ -1,65 +0,0 @@ -# =============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of eos. -# -# eos is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# eos is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with eos. If not, see . -# =============================================================================== - -from sqlalchemy import Table, Column, Integer, ForeignKey, String -from sqlalchemy.orm import mapper, relation - -from eos.db import saveddata_meta -from eos.db.saveddata.fit import fits_table -from eos.types import Fleet, Wing, Squad, Fit - -gangs_table = Table("gangs", saveddata_meta, - Column("ID", Integer, primary_key=True), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("name", String)) - -wings_table = Table("wings", saveddata_meta, - Column("ID", Integer, primary_key=True), - Column("gangID", ForeignKey("gangs.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("leaderID", ForeignKey("fits.ID"))) - -squads_table = Table("squads", saveddata_meta, - Column("ID", Integer, primary_key=True), - Column("wingID", ForeignKey("wings.ID")), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID"))) - -squadmembers_table = Table("squadmembers", saveddata_meta, - Column("squadID", ForeignKey("squads.ID"), primary_key=True), - Column("memberID", ForeignKey("fits.ID"), primary_key=True)) - -mapper(Fleet, gangs_table, - properties={"wings": relation(Wing, backref="gang"), - "leader": relation(Fit, primaryjoin=gangs_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin=gangs_table.c.boosterID == fits_table.c.ID)}) - -mapper(Wing, wings_table, - properties={"squads": relation(Squad, backref="wing"), - "leader": relation(Fit, primaryjoin=wings_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin=wings_table.c.boosterID == fits_table.c.ID)}) - -mapper(Squad, squads_table, - properties={"leader": relation(Fit, primaryjoin=squads_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin=squads_table.c.boosterID == fits_table.c.ID), - "members": relation(Fit, - primaryjoin=squads_table.c.ID == squadmembers_table.c.squadID, - secondaryjoin=squadmembers_table.c.memberID == fits_table.c.ID, - secondary=squadmembers_table)}) diff --git a/eos/saveddata/fleet.py b/eos/saveddata/fleet.py deleted file mode 100644 index 6fc1b6330..000000000 --- a/eos/saveddata/fleet.py +++ /dev/null @@ -1,341 +0,0 @@ -# =============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of eos. -# -# eos is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# eos is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with eos. If not, see . -# =============================================================================== - -from copy import deepcopy -from itertools import chain - -from eos.types import Skill, Module, Ship - - -class Fleet(object): - def calculateModifiedAttributes(self): - # Make sure ALL fits in the gang have been calculated - for c in chain(self.wings, (self.leader,)): - if c is not None: - c.calculateModifiedAttributes() - - leader = self.leader - self.booster = booster = self.booster if self.booster is not None else leader - self.broken = False - self.store = store = Store() - store.set(booster, "fleet") - # Go all the way down for each subtree we have. - for wing in self.wings: - wing.calculateGangBonusses(store) - - # Check skill requirements and wing amount to see if we break or not - if len(self.wings) == 0 or leader is None or leader.character is None or leader.character.getSkill( - "Fleet Command").level < len(self.wings): - self.broken = True - - # Now calculate our own if we aren't broken - if not self.broken: - # We only get our own bonuses *Sadface* - store.apply(leader, "fleet") - - def recalculateLinear(self, withBoosters=True, dirtyStorage=None): - self.store = Store() - self.linearBoosts = {} - if withBoosters is True: - if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill( - "Fleet Command").level >= 1: - self.leader.boostsFits.add(self.wings[0].squads[0].members[0].ID) - self.leader.calculateModifiedAttributes() - self.store.set(self.leader, "squad", clearingUpdate=True) - else: - self.store = Store() - if self.leader is not None: - try: - self.leader.boostsFits.remove(self.wings[0].squads[0].members[0].ID) - except KeyError: - pass - self.wings[0].recalculateLinear(self.store, withBoosters=withBoosters, dirtyStorage=dirtyStorage) - return self.linearBoosts - - def count(self): - total = 0 - for wing in self.wings: - total += wing.count() - - return total - - def extend(self): - self.wings.append(Wing()) - - def __deepcopy__(self, memo): - copy = Fleet() - copy.name = self.name - copy.booster = deepcopy(self.booster) - copy.leader = deepcopy(self.leader) - for wing in self.wings: - copy.wings.append(deepcopy(wing)) - - return copy - - -class Wing(object): - def calculateModifiedAttributes(self): - for c in chain(self.squads, (self.leader,)): - if c is not None: - c.calculateModifiedAttributes() - - def calculateGangBonusses(self, store): - self.broken = False - leader = self.leader - self.booster = booster = self.booster if self.booster is not None else leader - - store.set(booster, "wing") - - # ALWAYS move down - for squad in self.squads: - squad.calculateGangBonusses(store) - - # Check skill requirements and squad amount to see if we break or not - if len(self.squads) == 0 or leader is None or leader.character is None or leader.character.getSkill( - "Wing Command").level < len(self.squads): - self.broken = True - - # Check if we aren't broken, if we aren't, boost - if not self.broken: - store.apply(leader, "wing") - else: - # We broke, don't go up - self.gang.broken = True - - def recalculateLinear(self, store, withBoosters=True, dirtyStorage=None): - if withBoosters is True: - if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill( - "Wing Command").level >= 1: - self.leader.boostsFits.add(self.squads[0].members[0].ID) - self.leader.calculateModifiedAttributes() - store.set(self.leader, "squad", clearingUpdate=False) - else: - store = Store() - if self.gang.leader is not None: - try: - self.gang.leader.boostsFits.remove(self.squads[0].members[0].ID) - except KeyError: - pass - if self.leader is not None: - try: - self.leader.boostsFits.remove(self.squads[0].members[0].ID) - except KeyError: - pass - self.squads[0].recalculateLinear(store, withBoosters=withBoosters, dirtyStorage=dirtyStorage) - - def count(self): - total = 0 if self.leader is None else 1 - for squad in self.squads: - total += squad.count() - - return total - - def extend(self): - self.squads.append(Squad()) - - def __deepcopy__(self, memo): - copy = Wing() - copy.booster = deepcopy(self.booster) - copy.leader = deepcopy(self.leader) - for squad in self.squads: - copy.squads.append(deepcopy(squad)) - - return copy - - -class Squad(object): - def calculateModifiedAttributes(self): - for member in self.members: - member.calculateModifiedAttributes() - - def calculateGangBonusses(self, store): - self.broken = False - leader = self.leader - self.booster = booster = self.booster if self.booster is not None else leader - store.set(booster, "squad") - - # Check skill requirements and squad size to see if we break or not - if len(self.members) <= 0 or leader is None or leader.character is None or leader.character.getSkill( - "Leadership").level * 2 < len(self.members): - self.broken = True - - if not self.broken: - for member in self.members: - store.apply(member, "squad") - else: - self.wing.broken = True - - def recalculateLinear(self, store, withBoosters=True, dirtyStorage=None): - if withBoosters is True: - if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill( - "Leadership").level >= 1: - self.leader.boostsFits.add(self.members[0].ID) - self.leader.calculateModifiedAttributes(dirtyStorage=dirtyStorage) - store.set(self.leader, "squad", clearingUpdate=False) - else: - store = Store() - if self.leader is not None: - try: - self.leader.boostsFits.remove(self.members[0].ID) - except KeyError: - pass - if self.wing.leader is not None: - try: - self.wing.leader.boostsFits.remove(self.members[0].ID) - except KeyError: - pass - if self.wing.gang.leader is not None: - try: - self.wing.gang.leader.boostsFits.remove(self.members[0].ID) - except KeyError: - pass - if getattr(self.wing.gang, "linearBoosts", None) is None: - self.wing.gang.linearBoosts = {} - dict = store.bonuses["squad"] - for boostedAttr, boostInfoList in dict.iteritems(): - for boostInfo in boostInfoList: - effect, thing = boostInfo - # Get current boost value for given attribute, use 0 as fallback if - # no boosts applied yet - currBoostAmount = self.wing.gang.linearBoosts.get(boostedAttr, (0,))[0] - # Attribute name which is used to get boost value - newBoostAttr = effect.getattr("gangBonus") or "commandBonus" - # Get boost amount for current boost - newBoostAmount = thing.getModifiedItemAttr(newBoostAttr) or 0 - # Skill used to modify the gang bonus (for purposes of comparing old vs new) - newBoostSkill = effect.getattr("gangBonusSkill") - # If skill takes part in gang boosting, multiply by skill level - if type(thing) == Skill: - newBoostAmount *= thing.level - # boost the gang bonus based on skill noted in effect file - if newBoostSkill: - newBoostAmount *= thing.parent.character.getSkill(newBoostSkill).level - # If new boost is more powerful, replace older one with it - if abs(newBoostAmount) > abs(currBoostAmount): - self.wing.gang.linearBoosts[boostedAttr] = (newBoostAmount, boostInfo) - - def count(self): - return len(self.members) - - def __deepcopy__(self, memo): - copy = Squad() - copy.booster = deepcopy(self.booster) - copy.leader = deepcopy(self.leader) - for member in self.members: - copy.members.append(deepcopy(member)) - - return copy - - -class Store(object): - def __init__(self): - # Container for gang boosters and their respective bonuses, three-layered - self.bonuses = {} - for dictType in ("fleet", "wing", "squad"): - self.bonuses[dictType] = {} - # Container for boosted fits and corresponding boosts applied onto them - self.boosts = {} - - def set(self, fitBooster, layer, clearingUpdate=True): - """Add all gang boosts of given fit for given layer to boost store""" - if fitBooster is None: - return - - # This dict contains all bonuses for specified layer - dict = self.bonuses[layer] - if clearingUpdate is True: - # Clear existing bonuses - dict.clear() - - # Go through everything which can be used as gang booster - for thing in chain(fitBooster.modules, fitBooster.implants, fitBooster.character.skills, (fitBooster.ship,)): - if thing.item is None: - continue - for effect in thing.item.effects.itervalues(): - # And check if it actually has gang boosting effects - if effect.isType("gang"): - # Attribute which is boosted - boostedAttr = effect.getattr("gangBoost") - # List which contains all bonuses for given attribute for given layer - l = dict.get(boostedAttr) - # If there was no list, create it - if l is None: - l = dict[boostedAttr] = [] - # And append effect which is used to boost stuff and carrier of this effect - l.append((effect, thing)) - - contextMap = {Skill: "skill", - Ship: "ship", - Module: "module"} - - def apply(self, fitBoosted, layer): - """Applies all boosts onto given fit for given layer""" - if fitBoosted is None: - return - # Boosts dict contains all bonuses applied onto given fit - self.boosts[fitBoosted] = boosts = {} - # Go through all bonuses for given layer, and find highest one per boosted attribute - for currLayer in ("fleet", "wing", "squad"): - # Dictionary with boosts for given layer - dict = self.bonuses[currLayer] - for boostedAttr, boostInfoList in dict.iteritems(): - for boostInfo in boostInfoList: - effect, thing = boostInfo - # Get current boost value for given attribute, use 0 as fallback if - # no boosts applied yet - currBoostAmount = boosts.get(boostedAttr, (0,))[0] - # Attribute name which is used to get boost value - newBoostAttr = effect.getattr("gangBonus") or "commandBonus" - # Get boost amount for current boost - newBoostAmount = thing.getModifiedItemAttr(newBoostAttr) or 0 - # Skill used to modify the gang bonus (for purposes of comparing old vs new) - newBoostSkill = effect.getattr("gangBonusSkill") - # If skill takes part in gang boosting, multiply by skill level - if type(thing) == Skill: - newBoostAmount *= thing.level - # boost the gang bonus based on skill noted in effect file - if newBoostSkill: - newBoostAmount *= thing.parent.character.getSkill(newBoostSkill).level - # If new boost is more powerful, replace older one with it - if abs(newBoostAmount) > abs(currBoostAmount): - boosts[boostedAttr] = (newBoostAmount, boostInfo) - - # Don't look further down then current layer, wing commanders don't get squad bonuses and all that - if layer == currLayer: - break - - self.modify(fitBoosted) - - def getBoosts(self, fit): - """Return all boosts applied onto given fit""" - return self.boosts.get(fit) - - def modify(self, fitBoosted): - # Get all boosts which should be applied onto current fit - boosts = self.getBoosts(fitBoosted) - # Now we got it all figured out, actually do the useful part of all this - for name, info in boosts.iteritems(): - # Unpack all data required to run effect properly - effect, thing = info[1] - context = ("gang", self.contextMap[type(thing)]) - # Run effect, and get proper bonuses applied - try: - effect.handler(fitBoosted, thing, context) - except: - pass From f198ff17730c6d7d37715ce700d2f4792caca13e Mon Sep 17 00:00:00 2001 From: blitzman Date: Mon, 12 Dec 2016 00:49:47 -0500 Subject: [PATCH 13/13] more clean up --- eos/saveddata/fit.py | 28 ---------------------------- service/fit.py | 3 ++- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 27cbece91..01d0771ed 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -134,7 +134,6 @@ class Fit(object): self.__capRecharge = None self.__calculatedTargets = [] self.factorReload = False - self.fleet = None self.boostsFits = set() self.gangBoosts = None self.ecmProjectedStr = 1 @@ -471,14 +470,6 @@ class Fit(object): self.register(thing) effect.handler(self, thing, context, warfareBuffID = warfareBuffID) - # if effect.isType("offline") or (effect.isType("passive") and thing.state >= State.ONLINE) or \ - # (effect.isType("active") and thing.state >= State.ACTIVE): - # # Run effect, and get proper bonuses applied - # try: - # self.register(thing) - # effect.handler(self, thing, context) - # except: - # pass else: # Run effect, and get proper bonuses applied try: @@ -504,7 +495,6 @@ class Fit(object): # Don't inspect this, we genuinely want to reassign self # noinspection PyMethodFirstArgAssignment self = copy.deepcopy(self) - self.fleet = copied.fleet logger.debug("Handling self projection - making shadow copy of fit. %r => %r", copied, self) # we delete the fit because when we copy a fit, flush() is # called to properly handle projection updates. However, we do @@ -517,24 +507,6 @@ class Fit(object): continue fit.calculateModifiedAttributes(self, True) - # - # for thing in chain(fit.modules, fit.implants, fit.character.skills, (fit.ship,)): - # if thing.item is None: - # continue - # for effect in thing.item.effects.itervalues(): - # # And check if it actually has gang boosting effects - # if effect.isType("gang"): - # effect.handler(self, thing, ("commandRun")) - - # if self.fleet is not None and withBoosters is True: - # logger.debug("Fleet is set, gathering gang boosts") - # - # self.gangBoosts = self.fleet.recalculateLinear(withBoosters=withBoosters) - # - # timer.checkpoint("Done calculating gang boosts for %r"%self) - - # elif self.fleet is None: - # self.gangBoosts = None # If we're not explicitly asked to project fit onto something, # set self as target fit diff --git a/service/fit.py b/service/fit.py index 4178c2bdf..42eb60046 100644 --- a/service/fit.py +++ b/service/fit.py @@ -235,7 +235,8 @@ class Fit(object): self.recalc(fit, withBoosters=True) def getFit(self, fitID, projected=False, basic=False): - ''' Gets fit from database, and populates fleet data. + ''' Gets fit from database + Projected is a recursion flag that is set to reduce recursions into projected fits Basic is a flag to simply return the fit without any other processing '''