From 36ad31ab2546e09fb088584e8c10f577a8747e2d Mon Sep 17 00:00:00 2001 From: blitzmann Date: Sun, 20 Mar 2016 02:04:55 -0400 Subject: [PATCH] Get some initial scaffolding up for implant sets sourced from the resist code. --- eos/db/saveddata/__init__.py | 3 +- eos/db/saveddata/implant.py | 4 + eos/db/saveddata/implantSet.py | 45 ++++ eos/db/saveddata/queries.py | 25 ++- eos/saveddata/implantSet.py | 48 +++++ eos/types.py | 1 + gui/mainFrame.py | 8 + gui/mainMenuBar.py | 5 + gui/setEditor.py | 380 +++++++++++++++++++++++++++++++++ service/__init__.py | 1 + service/implantSet.py | 60 ++++++ 11 files changed, 578 insertions(+), 2 deletions(-) create mode 100644 eos/db/saveddata/implantSet.py create mode 100644 eos/saveddata/implantSet.py create mode 100644 gui/setEditor.py create mode 100644 service/implantSet.py diff --git a/eos/db/saveddata/__init__.py b/eos/db/saveddata/__init__.py index 683fb499d..e43c6e601 100644 --- a/eos/db/saveddata/__init__.py +++ b/eos/db/saveddata/__init__.py @@ -13,6 +13,7 @@ __all__ = [ "miscData", "targetResists", "override", - "crest" + "crest", + "implantSet" ] diff --git a/eos/db/saveddata/implant.py b/eos/db/saveddata/implant.py index 60e40bff7..c74def157 100644 --- a/eos/db/saveddata/implant.py +++ b/eos/db/saveddata/implant.py @@ -36,4 +36,8 @@ charImplants_table = Table("charImplants", saveddata_meta, Column("charID", ForeignKey("characters.ID"), index = True), Column("implantID", ForeignKey("implants.ID"), primary_key = True)) +implantsSetMap_table = Table("implantSetMap", saveddata_meta, + Column("setID", ForeignKey("implantSets.ID"), index = True), + Column("implantID", ForeignKey("implants.ID"), primary_key = True)) + mapper(Implant, implants_table) diff --git a/eos/db/saveddata/implantSet.py b/eos/db/saveddata/implantSet.py new file mode 100644 index 000000000..d72b9097a --- /dev/null +++ b/eos/db/saveddata/implantSet.py @@ -0,0 +1,45 @@ +#=============================================================================== +# Copyright (C) 2016 Ryan Holmes +# +# This file is part of eos. +# +# eos is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# eos is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with eos. If not, see . +#=============================================================================== + +from sqlalchemy import Table, Column, Integer, ForeignKey, String +from sqlalchemy.orm import relation, mapper + +from eos.db import saveddata_meta +from eos.db.saveddata.implant import implantsSetMap_table +from eos.types import Implant, ImplantSet +from eos.effectHandlerHelpers import HandledImplantBoosterList + +implant_set_table = Table("implantSets", saveddata_meta, + Column("ID", Integer, primary_key = True), + Column("name", String, nullable = False), +) + +mapper(ImplantSet, implant_set_table, + properties = { + "_ImplantSet__implants": relation( + Implant, + collection_class = HandledImplantBoosterList, + cascade='all,delete-orphan', + backref='set', + single_parent=True, + primaryjoin = implantsSetMap_table.c.setID == implant_set_table.c.ID, + secondaryjoin = implantsSetMap_table.c.implantID == Implant.ID, + secondary = implantsSetMap_table), + } +) diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index a305994cd..264e3c0da 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -20,7 +20,7 @@ from eos.db.util import processEager, processWhere from eos.db import saveddata_session, sd_lock -from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists, Override, CrestChar +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_ @@ -385,6 +385,29 @@ def getTargetResists(lookfor, eager=None): raise TypeError("Need integer or string as argument") return pattern +@cachedQuery(ImplantSet, 1, "lookfor") +def getImplantSet(lookfor, eager=None): + if isinstance(lookfor, int): + if eager is None: + with sd_lock: + pattern = saveddata_session.query(ImplantSet).get(lookfor) + else: + eager = processEager(eager) + with sd_lock: + pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.ID == lookfor).first() + elif isinstance(lookfor, basestring): + eager = processEager(eager) + with sd_lock: + pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.name == lookfor).first() + elif lookfor is None: + eager = processEager(eager) + with sd_lock: + patterns = saveddata_session.query(ImplantSet).options(*eager).all() + return patterns + else: + raise TypeError("Improper argument") + return pattern + def searchFits(nameLike, where=None, eager=None): if not isinstance(nameLike, basestring): raise TypeError("Need string as argument") diff --git a/eos/saveddata/implantSet.py b/eos/saveddata/implantSet.py new file mode 100644 index 000000000..00df48536 --- /dev/null +++ b/eos/saveddata/implantSet.py @@ -0,0 +1,48 @@ +#=============================================================================== +# Copyright (C) 2016 Ryan Holmes +# +# This file is part of eos. +# +# eos is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# eos is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with eos. If not, see . +#=============================================================================== + +from eos.effectHandlerHelpers import HandledImplantBoosterList + +class ImplantSet(object): + DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") + + def __init__(self, name=None): + self.name = name + self.__implants = HandledImplantBoosterList() + + @property + def implants(self): + return self.__implants + + + EXPORT_FORMAT = "ImplantSet = %s,%d,%d,%d,%d\n" + @classmethod + def exportPatterns(cls, *patterns): + out = "# Exported from pyfa\n#\n" + out += "# Values are in following format:\n" + out += "# DamageProfile = [name],[EM amount],[Thermal amount],[Kinetic amount],[Explosive amount]\n\n" + for dp in patterns: + out += cls.EXPORT_FORMAT % (dp.name, dp.emAmount, dp.thermalAmount, dp.kineticAmount, dp.explosiveAmount) + + return out.strip() + + def __deepcopy__(self, memo): + p = ImplantSet(self.name) + p.name = "%s copy" % self.name + return p diff --git a/eos/types.py b/eos/types.py index d1628b4eb..7b03d74a2 100644 --- a/eos/types.py +++ b/eos/types.py @@ -29,6 +29,7 @@ from eos.saveddata.module import Module, State, Slot, Hardpoint, Rack from eos.saveddata.drone import Drone from eos.saveddata.cargo import Cargo from eos.saveddata.implant import Implant +from eos.saveddata.implantSet import ImplantSet from eos.saveddata.booster import SideEffect from eos.saveddata.booster import Booster from eos.saveddata.ship import Ship diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 4c0d39ba7..3b76a13c9 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -50,6 +50,7 @@ from gui.characterEditor import CharacterEditor, SaveCharacterAs from gui.characterSelection import CharacterSelection from gui.patternEditor import DmgPatternEditorDlg from gui.resistsEditor import ResistsEditorDlg +from gui.setEditor import ImplantSetEditorDlg from gui.preferenceDialog import PreferenceDialog from gui.graphFrame import GraphFrame from gui.copySelectDialog import CopySelectDialog @@ -367,6 +368,11 @@ class MainFrame(wx.Frame): dlg.ShowModal() dlg.Destroy() + def showImplantSetEditor(self, event): + dlg=ImplantSetEditorDlg(self) + dlg.ShowModal() + dlg.Destroy() + def showExportDialog(self, event): """ Export active fit """ sFit = service.Fit.getInstance() @@ -418,6 +424,8 @@ class MainFrame(wx.Frame): self.Bind(wx.EVT_MENU, self.showDamagePatternEditor, id=menuBar.damagePatternEditorId) # Target Resists editor self.Bind(wx.EVT_MENU, self.showTargetResistsEditor, id=menuBar.targetResistsEditorId) + # Implant Set editor + self.Bind(wx.EVT_MENU, self.showImplantSetEditor, id=menuBar.implantSetEditorId) # Import dialog self.Bind(wx.EVT_MENU, self.fileImportDialog, id=wx.ID_OPEN) # Export dialog diff --git a/gui/mainMenuBar.py b/gui/mainMenuBar.py index 78376fde7..fda1955d9 100644 --- a/gui/mainMenuBar.py +++ b/gui/mainMenuBar.py @@ -33,6 +33,7 @@ class MainMenuBar(wx.MenuBar): self.characterEditorId = wx.NewId() self.damagePatternEditorId = wx.NewId() self.targetResistsEditorId = wx.NewId() + self.implantSetEditorId = wx.NewId() self.graphFrameId = wx.NewId() self.backupFitsId = wx.NewId() self.exportSkillsNeededId = wx.NewId() @@ -104,6 +105,10 @@ class MainMenuBar(wx.MenuBar): targetResistsEditItem.SetBitmap(BitmapLoader.getBitmap("explosive_big", "gui")) windowMenu.AppendItem(targetResistsEditItem) + implantSetEditItem = wx.MenuItem(windowMenu, self.implantSetEditorId, "Implant Set Editor\tCTRL+I") + implantSetEditItem.SetBitmap(BitmapLoader.getBitmap("damagePattern_small", "gui")) + windowMenu.AppendItem(implantSetEditItem) + graphFrameItem = wx.MenuItem(windowMenu, self.graphFrameId, "Graphs\tCTRL+G") graphFrameItem.SetBitmap(BitmapLoader.getBitmap("graphs_small", "gui")) windowMenu.AppendItem(graphFrameItem) diff --git a/gui/setEditor.py b/gui/setEditor.py new file mode 100644 index 000000000..5af848f42 --- /dev/null +++ b/gui/setEditor.py @@ -0,0 +1,380 @@ +#=============================================================================== +# Copyright (C) 2016 Ryan Holmes +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +#=============================================================================== + +import wx +from gui.bitmapLoader import BitmapLoader +import service +from gui.utils.clipboard import toClipboard, fromClipboard +from service.targetResists import ImportError + +class ImplantSetEditorDlg(wx.Dialog): + + def __init__(self, parent): + wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Implant Set Editor", size = wx.Size( 350,240 )) + + self.block = False + self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) + + mainSizer = wx.BoxSizer(wx.VERTICAL) + + self.headerSizer = headerSizer = wx.BoxSizer(wx.HORIZONTAL) + + sIS = service.ImplantSets.getInstance() + + self.choices = sIS.getImplantSetList() + + # Sort the remaining list and continue on + self.choices.sort(key=lambda s: s.name) + self.ccSets = wx.Choice(self, choices=map(lambda s: s.name, self.choices)) + self.ccSets.Bind(wx.EVT_CHOICE, self.setChanged) + self.ccSets.SetSelection(0) + + self.namePicker = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER) + self.namePicker.Bind(wx.EVT_TEXT_ENTER, self.processRename) + self.namePicker.Hide() + + size = None + headerSizer.Add(self.ccSets, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 3) + + buttons = (("new", wx.ART_NEW), + ("rename", BitmapLoader.getBitmap("rename", "gui")), + ("copy", wx.ART_COPY), + ("delete", wx.ART_DELETE)) + for name, art in buttons: + bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON) if name != "rename" else art + btn = wx.BitmapButton(self, wx.ID_ANY, bitmap) + if size is None: + size = btn.GetSize() + + btn.SetMinSize(size) + btn.SetMaxSize(size) + + btn.Layout() + setattr(self, name, btn) + btn.Enable(True) + #btn.SetToolTipString("%s resist profile" % name.capitalize()) + headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL) + + + self.btnSave = wx.Button(self, wx.ID_SAVE) + self.btnSave.Hide() + self.btnSave.Bind(wx.EVT_BUTTON, self.processRename) + headerSizer.Add(self.btnSave, 0, wx.ALIGN_CENTER) + + mainSizer.Add(headerSizer, 0, wx.EXPAND | wx.ALL, 2) + + self.sl = wx.StaticLine(self) + mainSizer.Add(self.sl, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) + + contentSizer = wx.BoxSizer(wx.VERTICAL) + + self.slfooter = wx.StaticLine(self) + contentSizer.Add(self.slfooter, 0, wx.EXPAND | wx.TOP, 5) + + footerSizer = wx.BoxSizer(wx.HORIZONTAL) + perSizer = wx.BoxSizer(wx.VERTICAL) + + self.stNotice = wx.StaticText(self, wx.ID_ANY, u"") + self.stNotice.Wrap(-1) + perSizer.Add(self.stNotice, 0, wx.BOTTOM | wx.TOP | wx.LEFT, 5) + + footerSizer.Add(perSizer, 1, wx.ALIGN_CENTER_VERTICAL, 5) + + self.totSizer = wx.BoxSizer(wx.VERTICAL) + + contentSizer.Add(footerSizer, 0, wx.EXPAND, 5) + + mainSizer.Add(contentSizer, 1, wx.EXPAND, 0) + + if "wxGTK" in wx.PlatformInfo: + self.closeBtn = wx.Button( self, wx.ID_ANY, u"Close", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.closeBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) + self.closeBtn.Bind(wx.EVT_BUTTON, self.closeEvent) + + self.SetSizer(mainSizer) + + importExport = (("Import", wx.ART_FILE_OPEN, "from"), + ("Export", wx.ART_FILE_SAVE_AS, "to")) + + for name, art, direction in importExport: + bitmap = wx.ArtProvider.GetBitmap(art, wx.ART_BUTTON) + btn = wx.BitmapButton(self, wx.ID_ANY, bitmap) + + btn.SetMinSize( btn.GetSize() ) + btn.SetMaxSize( btn.GetSize() ) + + btn.Layout() + setattr(self, name, btn) + btn.Enable(True) + btn.SetToolTipString("%s patterns %s clipboard" % (name, direction) ) + footerSizer.Add(btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_RIGHT) + + self.Layout() + bsize = self.GetBestSize() + self.SetSize((-1,bsize.height)) + + self.new.Bind(wx.EVT_BUTTON, self.newPattern) + self.rename.Bind(wx.EVT_BUTTON, self.renamePattern) + self.copy.Bind(wx.EVT_BUTTON, self.copyPattern) + self.delete.Bind(wx.EVT_BUTTON, self.deletePattern) + self.Import.Bind(wx.EVT_BUTTON, self.importPatterns) + self.Export.Bind(wx.EVT_BUTTON, self.exportPatterns) + + def closeEvent(self, event): + self.Destroy() + + def ValuesUpdated(self, event=None): + ''' + Event that is fired when resists values change. Iterates through all + resist edit fields. If blank, sets it to 0.0. If it is not a proper + decimal value, sets text color to red and refuses to save changes until + issue is resolved + ''' + if self.block: + return + + try: + p = self.getActivePattern() + + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + + if editObj.GetValue() == "": + # if we are blank, overwrite with 0 + editObj.ChangeValue("0.0") + editObj.SetInsertionPointEnd() + + value = float(editObj.GetValue()) + + # assertion, because they're easy + assert 0 <= value <= 100 + + # if everything checks out, set resist attribute + setattr(p, "%sAmount"%type, value/100) + editObj.SetForegroundColour(self.colorReset) + + self.stNotice.SetLabel("") + self.totSizer.Layout() + + if event is not None: + event.Skip() + + service.TargetResists.getInstance().saveChanges(p) + + except ValueError: + editObj.SetForegroundColour(wx.RED) + self.stNotice.SetLabel("Incorrect Formatting (decimals only)") + except AssertionError: + editObj.SetForegroundColour(wx.RED) + self.stNotice.SetLabel("Incorrect Range (must be 0-100)") + finally: # Refresh for color changes to take effect immediately + self.Refresh() + + def restrict(self): + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.Enable(False) + self.rename.Enable(False) + self.delete.Enable(False) + + def unrestrict(self): + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.Enable() + self.rename.Enable() + self.delete.Enable() + + def getActivePattern(self): + if len(self.choices) == 0: + return None + + return self.choices[self.ccSets.GetSelection()] + + def setChanged(self, event=None): + "Event fired when user selects pattern. Can also be called from script" + p = self.getActivePattern() + if p is None: + # This happens when there are no patterns in the DB. As such, force + # user to create one first or exit dlg. + self.newPattern(None) + return + + #ValuesUpdated() + + def newPattern(self, event): + ''' + Simply does new-pattern specifics: replaces label on button, restricts, + and resets values to default. Hands off to the rename function for + further handling. + ''' + self.btnSave.SetLabel("Create") + self.restrict() + # reset values + for type in self.DAMAGE_TYPES: + editObj = getattr(self, "%sEdit"%type) + editObj.ChangeValue("0.0") + editObj.SetForegroundColour(self.colorReset) + + self.Refresh() + self.renamePattern() + + def renamePattern(self, event=None): + "Changes layout to facilitate naming a pattern" + + self.showInput(True) + + if event is not None: # Rename mode + self.btnSave.SetLabel("Rename") + self.namePicker.SetValue(self.getActivePattern().name) + else: # Create mode + self.namePicker.SetValue("") + + if event is not None: + event.Skip() + + def processRename(self, event): + ''' + Processes rename event (which can be new or old patterns). If new + pattern, creates it; if old, selects it. if checks are valid, rename + saves pattern to DB. + + Also resets to default layout and unrestricts. + ''' + newName = self.namePicker.GetLineText(0) + self.stNotice.SetLabel("") + + if newName == "": + self.stNotice.SetLabel("Invalid name") + return + + sTR = service.TargetResists.getInstance() + if self.btnSave.Label == "Create": + p = sTR.newPattern() + else: + # we are renaming, so get the current selection + p = self.getActivePattern() + + # test for patterns of the same name + for pattern in self.choices: + if pattern.name == newName and p != pattern: + self.stNotice.SetLabel("Name already used, please choose another") + return + + # rename regardless of new or rename + sTR.renamePattern(p, newName) + + self.updateChoices(newName) + self.showInput(False) + sel = self.ccSets.GetSelection() + self.ValuesUpdated() + self.unrestrict() + + def copyPattern(self,event): + sTR = service.TargetResists.getInstance() + p = sTR.copyPattern(self.getActivePattern()) + self.choices.append(p) + id = self.ccSets.Append(p.name) + self.ccSets.SetSelection(id) + self.btnSave.SetLabel("Copy") + self.renamePattern() + self.setChanged() + + def deletePattern(self,event): + sTR = service.TargetResists.getInstance() + sel = self.ccSets.GetSelection() + sTR.deletePattern(self.getActivePattern()) + self.ccSets.Delete(sel) + self.ccSets.SetSelection(max(0, sel - 1)) + del self.choices[sel] + self.setChanged() + + def showInput(self, bool): + if bool and not self.namePicker.IsShown(): + self.ccSets.Hide() + self.namePicker.Show() + self.headerSizer.Replace(self.ccSets, self.namePicker) + self.namePicker.SetFocus() + for btn in (self.new, self.rename, self.delete, self.copy): + btn.Hide() + self.btnSave.Show() + self.restrict() + self.headerSizer.Layout() + elif not bool and self.namePicker.IsShown(): + self.headerSizer.Replace(self.namePicker, self.ccSets) + self.ccSets.Show() + self.namePicker.Hide() + self.btnSave.Hide() + for btn in (self.new, self.rename, self.delete, self.copy): + btn.Show() + self.unrestrict() + self.headerSizer.Layout() + + + def __del__( self ): + pass + + def updateChoices(self, select=None): + "Gathers list of patterns and updates choice selections" + sTR = service.TargetResists.getInstance() + self.choices = sTR.getTargetResistsList() + + if len(self.choices) == 0: + #self.newPattern(None) + return + + # Sort the remaining list and continue on + self.choices.sort(key=lambda p: p.name) + self.ccSets.Clear() + + for i, choice in enumerate(map(lambda p: p.name, self.choices)): + self.ccSets.Append(choice) + + if select is not None and choice == select: + self.ccSets.SetSelection(i) + + if select is None: + self.ccSets.SetSelection(0) + + self.setChanged() + + def importPatterns(self, event): + "Event fired when import from clipboard button is clicked" + + text = fromClipboard() + if text: + sTR = service.TargetResists.getInstance() + try: + sTR.importPatterns(text) + self.stNotice.SetLabel("Patterns successfully imported from clipboard") + self.showInput(False) + except service.targetResists.ImportError, e: + self.stNotice.SetLabel(str(e)) + except Exception, e: + self.stNotice.SetLabel("Could not import from clipboard: unknown errors") + finally: + self.updateChoices() + else: + self.stNotice.SetLabel("Could not import from clipboard") + + def exportPatterns(self, event): + "Event fired when export to clipboard button is clicked" + + sTR = service.TargetResists.getInstance() + toClipboard( sTR.exportPatterns() ) + self.stNotice.SetLabel("Patterns exported to clipboard") diff --git a/service/__init__.py b/service/__init__.py index e7e0286d4..b19c6db17 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -10,6 +10,7 @@ from service.update import Update from service.price import Price from service.network import Network from service.eveapi import EVEAPIConnection, ParseXML +from service.implantSet import ImplantSets import wx if not 'wxMac' in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3,0)): diff --git a/service/implantSet.py b/service/implantSet.py new file mode 100644 index 000000000..ff7469536 --- /dev/null +++ b/service/implantSet.py @@ -0,0 +1,60 @@ +#=============================================================================== +# Copyright (C) 2016 Ryan Holmes +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +#=============================================================================== + +import eos.db +import eos.types +import copy + +class ImportError(Exception): + pass + +class ImplantSets(): + instance = None + @classmethod + def getInstance(cls): + if cls.instance is None: + cls.instance = ImplantSets() + + return cls.instance + + def getImplantSetList(self): + return eos.db.getImplantSet(None) + + def getImplantSet(self, name): + return eos.db.getImplantSet(name) + + def newSet(self): + p = eos.types.ImplantSet() + p.name = "" + return p + + def renameSet(self, s, newName): + s.name = newName + eos.db.save(s) + + def deleteSet(self, s): + eos.db.remove(s) + + def copySet(self, s): + newS = copy.deepcopy(s) + eos.db.save(newS) + return newS + + def saveChanges(self, s): + eos.db.save(s)