Merge branch 'master' into singularity
Conflicts: eos/db/saveddata/fit.py gui/additionsPane.py
This commit is contained in:
14
eos/db/migrations/upgrade16.py
Normal file
14
eos/db/migrations/upgrade16.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Migration 16
|
||||
|
||||
- Alters fits table to introduce notes attribute
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update fits schema to include notes attribute
|
||||
try:
|
||||
saveddata_engine.execute("SELECT notes FROM fits LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN notes VARCHAR;")
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,49 +15,46 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.module import modules_table
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.drone import drones_table
|
||||
from eos.db.saveddata.fighter import fighters_table
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.implant import fitImplants_table
|
||||
from eos.types import Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, TargetResists, ImplantLocation
|
||||
from eos.db.saveddata.module import modules_table
|
||||
from eos.effectHandlerHelpers import *
|
||||
from eos.types import Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, \
|
||||
TargetResists, ImplantLocation
|
||||
|
||||
fits_table = Table("fits", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True),
|
||||
Column("shipID", Integer, nullable = False, index = True),
|
||||
Column("name", String, nullable = False),
|
||||
Column("timestamp", Integer, nullable = False),
|
||||
Column("characterID", ForeignKey("characters.ID"), nullable = True),
|
||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||
Column("booster", Boolean, nullable = False, index = True, default = 0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||
)
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True, index=True),
|
||||
Column("shipID", Integer, nullable=False, index=True),
|
||||
Column("name", String, nullable=False),
|
||||
Column("timestamp", Integer, nullable=False),
|
||||
Column("characterID", ForeignKey("characters.ID"), nullable=True),
|
||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||
Column("booster", Boolean, nullable=False, index=True, default=0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||
Column("notes", String, nullable = True),
|
||||
)
|
||||
|
||||
projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||
Column("sourceID", ForeignKey("fits.ID"), primary_key = True),
|
||||
Column("victimID", ForeignKey("fits.ID"), primary_key = True),
|
||||
Column("amount", Integer, nullable = False, default = 1),
|
||||
Column("active", Boolean, nullable = False, default = 1),
|
||||
)
|
||||
Column("sourceID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("victimID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("amount", Integer, nullable=False, default=1),
|
||||
Column("active", Boolean, nullable=False, default=1),
|
||||
)
|
||||
|
||||
commandFits_table = Table("commandFits", saveddata_meta,
|
||||
Column("boosterID", ForeignKey("fits.ID"), primary_key = True),
|
||||
Column("boostedID", ForeignKey("fits.ID"), primary_key = True),
|
||||
Column("active", Boolean, nullable = False, default = 1)
|
||||
)
|
||||
|
||||
class ProjectedFit(object):
|
||||
def __init__(self, sourceID, source_fit, amount=1, active=True):
|
||||
@@ -89,25 +86,6 @@ class ProjectedFit(object):
|
||||
self.sourceID, self.victimID, self.amount, self.active, hex(id(self))
|
||||
)
|
||||
|
||||
class CommandFit(object):
|
||||
def __init__(self, boosterID, booster_fit, active=True):
|
||||
self.boosterID = boosterID
|
||||
self.booster_fit = booster_fit
|
||||
self.active = active
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
if self.booster_fit.isInvalid:
|
||||
# Very rare for this to happen, but be prepared for it
|
||||
eos.db.saveddata_session.delete(self.booster_fit)
|
||||
eos.db.saveddata_session.flush()
|
||||
eos.db.saveddata_session.refresh(self.boosted_fit)
|
||||
|
||||
def __repr__(self):
|
||||
return "CommandFit(boosterID={}, boostedID={}, active={}) at {}".format(
|
||||
self.boosterID, self.boostedID, self.active, hex(id(self))
|
||||
)
|
||||
|
||||
|
||||
Fit._Fit__projectedFits = association_proxy(
|
||||
"victimOf", # look at the victimOf association...
|
||||
@@ -115,111 +93,91 @@ Fit._Fit__projectedFits = association_proxy(
|
||||
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
|
||||
)
|
||||
|
||||
Fit._Fit__commandFits = association_proxy(
|
||||
"boostedOf", # look at the boostedOf association...
|
||||
"booster_fit", # .. and return the booster fit
|
||||
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
|
||||
)
|
||||
|
||||
mapper(Fit, fits_table,
|
||||
properties = {
|
||||
"_Fit__modules": relation(
|
||||
Module,
|
||||
collection_class=HandledModuleList,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False),
|
||||
order_by=modules_table.c.position,
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"_Fit__projectedModules": relation(
|
||||
Module,
|
||||
collection_class=HandledProjectedModList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)),
|
||||
"owner": relation(
|
||||
User,
|
||||
backref="fits"),
|
||||
"itemID": fits_table.c.shipID,
|
||||
"shipID": fits_table.c.shipID,
|
||||
"_Fit__boosters": relation(
|
||||
Booster,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True),
|
||||
"_Fit__drones": relation(
|
||||
Drone,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
|
||||
"_Fit__fighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)),
|
||||
"_Fit__cargo": relation(
|
||||
Cargo,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
|
||||
"_Fit__projectedDrones": relation(
|
||||
Drone,
|
||||
collection_class=HandledProjectedDroneList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)),
|
||||
"_Fit__projectedFighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledProjectedDroneList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)),
|
||||
"_Fit__implants": relation(
|
||||
Implant,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='fit',
|
||||
single_parent=True,
|
||||
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
|
||||
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
|
||||
secondary=fitImplants_table),
|
||||
"_Fit__character": relation(
|
||||
Character,
|
||||
backref="fits"),
|
||||
"_Fit__damagePattern": relation(DamagePattern),
|
||||
"_Fit__targetResists": relation(TargetResists),
|
||||
"projectedOnto": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"victimOf": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
||||
backref='victim_fit',
|
||||
collection_class=attribute_mapped_collection('sourceID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"boostedOnto": relationship(
|
||||
CommandFit,
|
||||
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
|
||||
backref='booster_fit',
|
||||
collection_class=attribute_mapped_collection('boostedID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"boostedOf": relationship(
|
||||
CommandFit,
|
||||
primaryjoin=fits_table.c.ID == commandFits_table.c.boostedID,
|
||||
backref='boosted_fit',
|
||||
collection_class=attribute_mapped_collection('boosterID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
properties={
|
||||
"_Fit__modules": relation(
|
||||
Module,
|
||||
collection_class=HandledModuleList,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False),
|
||||
order_by=modules_table.c.position,
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"_Fit__projectedModules": relation(
|
||||
Module,
|
||||
collection_class=HandledProjectedModList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)),
|
||||
"owner": relation(
|
||||
User,
|
||||
backref="fits"),
|
||||
"itemID": fits_table.c.shipID,
|
||||
"shipID": fits_table.c.shipID,
|
||||
"_Fit__boosters": relation(
|
||||
Booster,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True),
|
||||
"_Fit__drones": relation(
|
||||
Drone,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
|
||||
"_Fit__fighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)),
|
||||
"_Fit__cargo": relation(
|
||||
Cargo,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
|
||||
"_Fit__projectedDrones": relation(
|
||||
Drone,
|
||||
collection_class=HandledProjectedDroneList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)),
|
||||
"_Fit__projectedFighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledProjectedDroneList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)),
|
||||
"_Fit__implants": relation(
|
||||
Implant,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='fit',
|
||||
single_parent=True,
|
||||
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
|
||||
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
|
||||
secondary=fitImplants_table),
|
||||
"_Fit__character": relation(
|
||||
Character,
|
||||
backref="fits"),
|
||||
"_Fit__damagePattern": relation(DamagePattern),
|
||||
"_Fit__targetResists": relation(TargetResists),
|
||||
"projectedOnto": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"victimOf": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
||||
backref='victim_fit',
|
||||
collection_class=attribute_mapped_collection('sourceID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
mapper(ProjectedFit, projectedFits_table,
|
||||
properties = {
|
||||
"_ProjectedFit__amount": projectedFits_table.c.amount,
|
||||
properties={
|
||||
"_ProjectedFit__amount": projectedFits_table.c.amount,
|
||||
}
|
||||
)
|
||||
|
||||
mapper(CommandFit, commandFits_table)
|
||||
)
|
||||
|
||||
@@ -1137,6 +1137,7 @@ class Fit(object):
|
||||
copy.name = "%s copy" % self.name
|
||||
copy.damagePattern = self.damagePattern
|
||||
copy.targetResists = self.targetResists
|
||||
copy.notes = self.notes
|
||||
|
||||
toCopy = (
|
||||
"modules",
|
||||
|
||||
@@ -25,7 +25,9 @@ from gui.fighterView import FighterView
|
||||
from gui.cargoView import CargoView
|
||||
from gui.implantView import ImplantView
|
||||
from gui.projectedView import ProjectedView
|
||||
|
||||
from gui.commandView import CommandView
|
||||
from gui.notesView import NotesView
|
||||
from gui.pyfatogglepanel import TogglePanel
|
||||
from gui.gangView import GangView
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
@@ -58,6 +60,7 @@ class AdditionsPane(TogglePanel):
|
||||
projectedImg = BitmapLoader.getImage("projected_small", "gui")
|
||||
gangImg = BitmapLoader.getImage("fleet_fc_small", "gui")
|
||||
cargoImg = BitmapLoader.getImage("cargo_small", "gui")
|
||||
notesImg = BitmapLoader.getImage("skill_small", "gui")
|
||||
|
||||
self.drone = DroneView(self.notebook)
|
||||
self.notebook.AddPage(self.drone, "Drones", tabImage = droneImg, showClose = False)
|
||||
@@ -80,9 +83,13 @@ class AdditionsPane(TogglePanel):
|
||||
self.gangPage = CommandView(self.notebook)
|
||||
self.notebook.AddPage(self.gangPage, "Command", tabImage = gangImg, showClose = False)
|
||||
|
||||
self.notes = NotesView(self.notebook)
|
||||
self.notebook.AddPage(self.notes, "Notes", tabImage = notesImg, showClose = False)
|
||||
|
||||
self.notebook.SetSelection(0)
|
||||
|
||||
PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected", "Command"]
|
||||
PANES = ["Drones", "Fighters", "Cargo", "Implants", "Boosters", "Projected", "Command", "Notes"]
|
||||
|
||||
def select(self, name):
|
||||
self.notebook.SetSelection(self.PANES.index(name))
|
||||
|
||||
|
||||
45
gui/notesView.py
Normal file
45
gui/notesView.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import wx
|
||||
|
||||
import service
|
||||
import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
|
||||
class NotesView(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.lastFitId = None
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.editNotes = wx.TextCtrl(self, style=wx.TE_MULTILINE)
|
||||
mainSizer.Add(self.editNotes, 1, wx.EXPAND)
|
||||
self.SetSizer(mainSizer)
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
self.Bind(wx.EVT_TEXT, self.onText)
|
||||
self.saveTimer = wx.Timer(self)
|
||||
self.Bind(wx.EVT_TIMER, self.delayedSave, self.saveTimer)
|
||||
|
||||
def fitChanged(self, event):
|
||||
sFit = service.Fit.getInstance()
|
||||
fit = sFit.getFit(event.fitID)
|
||||
|
||||
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
|
||||
|
||||
if event.fitID is None and self.lastFitId is not None:
|
||||
self.lastFitId = None
|
||||
event.Skip()
|
||||
return
|
||||
elif event.fitID != self.lastFitId:
|
||||
self.lastFitId = event.fitID
|
||||
self.editNotes.SetValue(fit.notes or "")
|
||||
|
||||
def onText(self, event):
|
||||
# delay the save so we're not writing to sqlite on every keystroke
|
||||
self.saveTimer.Stop() # cancel the existing timer
|
||||
self.saveTimer.Start(1000, True)
|
||||
|
||||
def delayedSave(self, event):
|
||||
sFit = service.Fit.getInstance()
|
||||
fit = sFit.getFit(self.lastFitId)
|
||||
newNotes = self.editNotes.GetValue()
|
||||
fit.notes = newNotes
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
|
||||
Reference in New Issue
Block a user