diff --git a/eos/db/__init__.py b/eos/db/__init__.py index 9455dec37..807ce950f 100644 --- a/eos/db/__init__.py +++ b/eos/db/__init__.py @@ -75,7 +75,7 @@ from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithS getFitList, getFleetList, getFleet, save, remove, commit, add, \ getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \ getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists,\ - clearPrices, countAllFits, getCrestCharacters + clearPrices, countAllFits, getCrestCharacters, getCrestCharacter #If using in memory saveddata, you'll want to reflect it so the data structure is good. if config.saveddata_connectionstring == "sqlite:///:memory:": diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index 68af39398..c467153c3 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -422,6 +422,24 @@ def getCrestCharacters(eager=None): characters = saveddata_session.query(Crest).options(*eager).all() return characters +@cachedQuery(Crest, 1, "lookfor") +def getCrestCharacter(lookfor, eager=None): + if isinstance(lookfor, int): + if eager is None: + with sd_lock: + character = saveddata_session.query(Crest).get(lookfor) + else: + eager = processEager(eager) + with sd_lock: + character = saveddata_session.query(Crest).options(*eager).filter(Crest.ID == lookfor).first() + elif isinstance(lookfor, basestring): + eager = processEager(eager) + with sd_lock: + character = saveddata_session.query(Crest).options(*eager).filter(Crest.name == lookfor).first() + else: + raise TypeError("Need integer or string as argument") + return character + def removeInvalid(fits): invalids = [f for f in fits if f.isInvalid] diff --git a/gui/crestFittings.py b/gui/crestFittings.py new file mode 100644 index 000000000..45f2c4df8 --- /dev/null +++ b/gui/crestFittings.py @@ -0,0 +1,127 @@ +import wx +import service +import gui.display as d +from eos.types import Cargo +from eos.db import getItem + +class CrestFittings(wx.Frame): + + def __init__(self, parent): + wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition, size=wx.Size( 550,450 ), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) + + self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE)) + + mainSizer = wx.BoxSizer(wx.VERTICAL) + sCrest = service.Crest.getInstance() + + self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, []) + chars = sCrest.getCrestCharacters() + for char in chars: + self.charChoice.Append(char.name, char.ID) + + characterSelectSizer = wx.BoxSizer( wx.HORIZONTAL ) + self.charChoice.SetSelection(0) + + + characterSelectSizer.Add( self.charChoice, 1, wx.ALL, 5 ) + self.fetchBtn = wx.Button( self, wx.ID_ANY, u"Fetch Fits", wx.DefaultPosition, wx.DefaultSize, 5 ) + characterSelectSizer.Add( self.fetchBtn, 0, wx.ALL, 5 ) + mainSizer.Add( characterSelectSizer, 0, wx.EXPAND, 5 ) + + self.sl = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + mainSizer.Add( self.sl, 0, wx.EXPAND |wx.ALL, 5 ) + + contentSizer = wx.BoxSizer( wx.HORIZONTAL ) + browserSizer = wx.BoxSizer( wx.VERTICAL ) + + self.fitTree = FittingsTreeView(self) + browserSizer.Add( self.fitTree, 1, wx.ALL|wx.EXPAND, 5 ) + contentSizer.Add( browserSizer, 1, wx.EXPAND, 0 ) + fitSizer = wx.BoxSizer( wx.VERTICAL ) + + self.fitView = FitView(self) + self.importBtn = wx.Button( self, wx.ID_ANY, u"Import", wx.DefaultPosition, wx.DefaultSize, 5 ) + fitSizer.Add( self.fitView, 1, wx.ALL|wx.EXPAND, 5 ) + fitSizer.Add( self.importBtn, 0, wx.ALL|wx.EXPAND, 5 ) + + contentSizer.Add(fitSizer, 1, wx.EXPAND, 0) + mainSizer.Add(contentSizer, 1, wx.EXPAND, 5) + + self.fetchBtn.Bind(wx.EVT_BUTTON, self.fetchFittings) + + self.SetSizer(mainSizer) + self.Layout() + + self.Centre(wx.BOTH) + + def getActiveCharacter(self): + selection = self.charChoice.GetCurrentSelection() + return self.charChoice.GetClientData(selection) if selection is not None else None + + def fetchFittings(self, event): + sCrest = service.Crest.getInstance() + fittings = sCrest.getFittings(self.getActiveCharacter()) + self.fitTree.populateSkillTree(fittings) + + +class FittingsTreeView(wx.Panel): + def __init__(self, parent): + wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, style=wx.TAB_TRAVERSAL) + self.parent = parent + pmainSizer = wx.BoxSizer(wx.VERTICAL) + + tree = self.fittingsTreeCtrl = wx.TreeCtrl(self, wx.ID_ANY, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT) + pmainSizer.Add(tree, 1, wx.EXPAND | wx.ALL, 0) + + self.root = tree.AddRoot("Fits") + self.populateSkillTree(None) + + self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.displayFit) + + self.SetSizer(pmainSizer) + + self.Layout() + + def populateSkillTree(self, json): + if json is None: + return + root = self.root + tree = self.fittingsTreeCtrl + tree.DeleteChildren(root) + + dict = {} + fits = json['items'] + for fit in fits: + if fit['ship']['name'] not in dict: + dict[fit['ship']['name']] = [] + dict[fit['ship']['name']].append(fit) + + for name, fits in dict.iteritems(): + shipID = tree.AppendItem(root, name) + for fit in fits: + fitId = tree.AppendItem(shipID, fit['name']) + tree.SetPyData(fitId, fit['items']) + + tree.SortChildren(root) + + def displayFit(self, event): + selection = self.fittingsTreeCtrl.GetSelection() + items = self.fittingsTreeCtrl.GetPyData(selection) + list = [] + + for item in items: + cargo = Cargo(getItem(item['type']['id'])) + cargo.amount = item['quantity'] + list.append(cargo) + self.parent.fitView.populate(list) + self.parent.fitView.refresh(list) + +class FitView(d.Display): + DEFAULT_COLS = ["Base Icon", + "Base Name"] + + def __init__(self, parent): + d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL) + + #self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem) + #self.Bind(wx.EVT_KEY_UP, self.kbEvent) diff --git a/gui/mainFrame.py b/gui/mainFrame.py index cb90ce0cc..2ce0413c1 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -44,6 +44,7 @@ from gui.multiSwitch import MultiSwitch from gui.statsPane import StatsPane from gui.shipBrowser import ShipBrowser, FitSelected, ImportSelected, Stage3Selected from gui.characterEditor import CharacterEditor, SaveCharacterAs +from gui.crestFittings import CrestFittings from gui.characterSelection import CharacterSelection from gui.patternEditor import DmgPatternEditorDlg from gui.resistsEditor import ResistsEditorDlg @@ -57,7 +58,6 @@ from gui.builtinViews import * from time import gmtime, strftime - #dummy panel(no paint no erasebk) class PFPanel(wx.Panel): def __init__(self,parent): @@ -416,6 +416,8 @@ class MainFrame(wx.Frame): self.Bind(wx.EVT_MENU, self.saveCharAs, id = menuBar.saveCharAsId) # Save current character self.Bind(wx.EVT_MENU, self.revertChar, id = menuBar.revertCharId) + # Browse fittings + self.Bind(wx.EVT_MENU, self.eveFittings, id = menuBar.eveFittingsId) #Clipboard exports self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY) @@ -480,6 +482,10 @@ class MainFrame(wx.Frame): atable = wx.AcceleratorTable(actb) self.SetAcceleratorTable(atable) + def eveFittings(self, event): + dlg=CrestFittings(self) + dlg.Show() + def saveChar(self, event): sChr = service.Character.getInstance() charID = self.charSelection.getActiveCharacter() diff --git a/gui/mainMenuBar.py b/gui/mainMenuBar.py index 7c971ae4d..76ea60f75 100644 --- a/gui/mainMenuBar.py +++ b/gui/mainMenuBar.py @@ -40,6 +40,7 @@ class MainMenuBar(wx.MenuBar): self.saveCharId = wx.NewId() self.saveCharAsId = wx.NewId() self.revertCharId = wx.NewId() + self.eveFittingsId = wx.NewId() self.mainFrame = gui.mainFrame.MainFrame.getInstance() @@ -102,6 +103,12 @@ class MainMenuBar(wx.MenuBar): preferencesItem.SetBitmap(BitmapLoader.getBitmap("preferences_small", "gui")) windowMenu.AppendItem(preferencesItem) + # CREST Menu + crestMenu = wx.Menu() + self.Append(crestMenu, "&CREST") + eveFittings = wx.MenuItem(crestMenu, self.eveFittingsId, "Browse EVE Fittings") + crestMenu.AppendItem(eveFittings) + # Help menu helpMenu = wx.Menu() self.Append(helpMenu, "&Help") diff --git a/service/__init__.py b/service/__init__.py index 8e9e9f6f5..00e0e1153 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -10,3 +10,4 @@ from service.update import Update from service.price import Price from service.network import Network from service.eveapi import EVEAPIConnection, ParseXML +from service.crest import Crest