Merge branch 'overrides' into singularity

Conflicts:
	eos/db/__init__.py
	eos/db/saveddata/__init__.py
	eos/db/saveddata/queries.py
	gui/mainFrame.py
	gui/mainMenuBar.py
This commit is contained in:
blitzmann
2015-11-02 19:01:12 -05:00
22 changed files with 505 additions and 27 deletions

View File

@@ -11,7 +11,7 @@ TextTyped, EVT_TEXT = wx.lib.newevent.NewEvent()
class PFSearchBox(wx.Window):
def __init__(self, parent, id = wx.ID_ANY, value = "", pos = wx.DefaultPosition, size = wx.Size(-1,24), style = 0):
wx.Window.__init__(self, parent, id, pos, size, style = 0)
wx.Window.__init__(self, parent, id, pos, size, style = style)
self.isSearchButtonVisible = False
self.isCancelButtonVisible = False

View File

@@ -35,9 +35,6 @@ class CharacterEditor(wx.Frame):
size=wx.Size(641, 600), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.TAB_TRAVERSAL)
i = wx.IconFromBitmap(BitmapLoader.getBitmap("character_small", "gui"))
self.mainFrame = parent
self.SetIcon(i)
self.disableWin= wx.WindowDisabler(self)

View File

@@ -55,7 +55,12 @@ from gui.copySelectDialog import CopySelectDialog
from gui.utils.clipboard import toClipboard, fromClipboard
from gui.fleetBrowser import FleetBrowser
from gui.updateDialog import UpdateDialog
from gui.propertyEditor import AttributeEditor
from gui.builtinViews import *
# import this to access override setting
from eos.modifiedAttributeDict import ModifiedAttributeDict
from time import gmtime, strftime
from service.crest import CrestModes
@@ -340,6 +345,10 @@ class MainFrame(wx.Frame):
dlg=CharacterEditor(self)
dlg.Show()
def showAttrEditor(self, event):
dlg=AttributeEditor(self)
dlg.Show()
def showTargetResistsEditor(self, event):
dlg=ResistsEditorDlg(self)
dlg.ShowModal()
@@ -427,6 +436,7 @@ 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)
# Export to EVE
@@ -434,6 +444,11 @@ class MainFrame(wx.Frame):
# Login to EVE
self.Bind(wx.EVT_MENU, self.ssoLogin, id = menuBar.ssoLoginId)
# Open attribute editor
self.Bind(wx.EVT_MENU, self.showAttrEditor, id = menuBar.attrEditorId)
# Toggle Overrides
self.Bind(wx.EVT_MENU, self.toggleOverrides, id = menuBar.toggleOverridesId)
#Clipboard exports
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY)
@@ -534,6 +549,12 @@ class MainFrame(wx.Frame):
dlg=ExportToEve(self)
dlg.Show()
def toggleOverrides(self, event):
ModifiedAttributeDict.OVERRIDES = not ModifiedAttributeDict.OVERRIDES
wx.PostEvent(self, GE.FitChanged(fitID=self.getActiveFit()))
menu = self.GetMenuBar()
menu.SetLabel(menu.toggleOverridesId, "Turn Overrides Off" if ModifiedAttributeDict.OVERRIDES else "Turn Overrides On")
def saveChar(self, event):
sChr = service.Character.getInstance()
charID = self.charSelection.getActiveCharacter()

View File

@@ -47,6 +47,8 @@ class MainMenuBar(wx.MenuBar):
self.eveFittingsId = wx.NewId()
self.exportToEveId = wx.NewId()
self.ssoLoginId = wx.NewId()
self.attrEditorId = wx.NewId()
self.toggleOverridesId = wx.NewId()
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
@@ -87,6 +89,9 @@ class MainMenuBar(wx.MenuBar):
editMenu.Append(self.saveCharId, "Save Character")
editMenu.Append(self.saveCharAsId, "Save Character As...")
editMenu.Append(self.revertCharId, "Revert Character")
editMenu.AppendSeparator()
editMenu.Append(self.toggleOverridesId, "Turn Overrides On")
# Character menu
windowMenu = wx.Menu()
self.Append(windowMenu, "&Window")
@@ -125,6 +130,10 @@ class MainMenuBar(wx.MenuBar):
self.Enable(self.eveFittingsId, False)
self.Enable(self.exportToEveId, False)
attrItem = wx.MenuItem(windowMenu, self.attrEditorId, "Attribute Overrides\tCTRL+A")
attrItem.SetBitmap(BitmapLoader.getBitmap("fit_rename_small", "gui"))
windowMenu.AppendItem(attrItem)
# Help menu
helpMenu = wx.Menu()
self.Append(helpMenu, "&Help")

View File

@@ -103,8 +103,8 @@ class MarketBrowser(wx.Panel):
self.marketView.jump(item)
class SearchBox(SBox.PFSearchBox):
def __init__(self, parent):
SBox.PFSearchBox.__init__(self, parent)
def __init__(self, parent, **kwargs):
SBox.PFSearchBox.__init__(self, parent, **kwargs)
cancelBitmap = BitmapLoader.getBitmap("fit_delete_small","gui")
searchBitmap = BitmapLoader.getBitmap("fsearch_small","gui")
self.SetSearchBitmap(searchBitmap)

264
gui/propertyEditor.py Normal file
View File

@@ -0,0 +1,264 @@
import wx
import wx.propgrid as wxpg
import gui.PFSearchBox as SBox
from gui.marketBrowser import SearchBox
import gui.display as d
import gui.globalEvents as GE
from gui.bitmapLoader import BitmapLoader
import service
import csv
import eos.db
import logging
logger = logging.getLogger(__name__)
class AttributeEditor( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__(self, parent, wx.ID_ANY, title="Attribute Editor", pos=wx.DefaultPosition,
size=wx.Size(650, 600), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.TAB_TRAVERSAL)
i = wx.IconFromBitmap(BitmapLoader.getBitmap("fit_rename_small", "gui"))
self.SetIcon(i)
self.mainFrame = parent
menubar = wx.MenuBar()
fileMenu = wx.Menu()
fileImport = fileMenu.Append(wx.ID_ANY, 'Import', 'Import overrides')
fileExport = fileMenu.Append(wx.ID_ANY, 'Export', 'Import overrides')
fileClear = fileMenu.Append(wx.ID_ANY, 'Clear All', 'Clear all overrides')
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnImport, fileImport)
self.Bind(wx.EVT_MENU, self.OnExport, fileExport)
self.Bind(wx.EVT_MENU, self.OnClear, fileClear)
i = wx.IconFromBitmap(BitmapLoader.getBitmap("fit_rename_small", "gui"))
self.SetIcon(i)
self.mainFrame = parent
self.panel = panel = wx.Panel(self, wx.ID_ANY)
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
leftSizer = wx.BoxSizer(wx.VERTICAL)
leftPanel = wx.Panel(panel, wx.ID_ANY, style=wx.DOUBLE_BORDER if 'wxMSW' in wx.PlatformInfo else wx.SIMPLE_BORDER)
self.searchBox = SearchBox(leftPanel)
self.itemView = ItemView(leftPanel)
leftSizer.Add(self.searchBox, 0, wx.EXPAND)
leftSizer.Add(self.itemView, 1, wx.EXPAND)
leftPanel.SetSizer(leftSizer)
mainSizer.Add(leftPanel, 1, wx.ALL | wx.EXPAND, 5)
rightSizer = wx.BoxSizer(wx.VERTICAL)
self.btnRemoveOverrides = wx.Button( panel, wx.ID_ANY, u"Remove Overides for Item", wx.DefaultPosition, wx.DefaultSize, 0 )
self.pg = AttributeGrid(panel)
rightSizer.Add(self.pg, 1, wx.ALL|wx.EXPAND, 5)
rightSizer.Add(self.btnRemoveOverrides, 0, wx.ALL | wx.EXPAND, 5 )
self.btnRemoveOverrides.Bind(wx.EVT_BUTTON, self.pg.removeOverrides)
self.btnRemoveOverrides.Enable(False)
mainSizer.Add(rightSizer, 1, wx.EXPAND)
panel.SetSizer(mainSizer)
mainSizer.SetSizeHints(panel)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel, 1, wx.EXPAND)
self.SetSizer(sizer)
self.SetAutoLayout(True)
self.Bind(wx.EVT_CLOSE, self.OnClose)
def OnClose(self, event):
fitID = self.mainFrame.getActiveFit()
if fitID is not None:
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
self.Destroy()
def OnImport(self, event):
dlg = wx.FileDialog(self, "Import pyfa override file",
wildcard = "pyfa override file (*.csv)|*.csv",
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if (dlg.ShowModal() == wx.ID_OK):
path = dlg.GetPath()
with open(path, 'rb') as csvfile:
spamreader = csv.reader(csvfile)
for row in spamreader:
itemID, attrID, value = row
item = eos.db.getItem(int(itemID))
attr = eos.db.getAttributeInfo(int(attrID))
item.setOverride(attr, float(value))
self.itemView.updateItems(True)
def OnExport(self, event):
sMkt = service.Market.getInstance()
items = sMkt.getItemsWithOverrides()
defaultFile = "pyfa_overrides.csv"
dlg = wx.FileDialog(self, "Save Overrides As...",
wildcard = "pyfa overrides (*.csv)|*.csv",
style = wx.FD_SAVE,
defaultFile=defaultFile)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
with open(path, 'wb') as csvfile:
writer = csv.writer(csvfile)
for item in items:
for key, override in item.overrides.iteritems():
writer.writerow([item.ID, override.attrID, override.value])
def OnClear(self, event):
dlg = wx.MessageDialog(self,
"Are you sure you want to delete all overrides?",
"Confirm Delete", wx.YES | wx.NO | wx.ICON_EXCLAMATION)
if dlg.ShowModal() == wx.ID_YES:
sMkt = service.Market.getInstance()
items = sMkt.getItemsWithOverrides()
# We can't just delete overrides, as loaded items will still have
# them assigned. Deleting them from the database won't propagate
# them due to the eve/user database disconnect. We must loop through
# all items that have overrides and remove them
for item in items:
for _, x in item.overrides.items():
item.deleteOverride(x.attr)
self.itemView.updateItems(True)
self.pg.Clear()
# This is literally a stripped down version of the market.
class ItemView(d.Display):
DEFAULT_COLS = ["Base Icon",
"Base Name",
"attr:power,,,True",
"attr:cpu,,,True"]
def __init__(self, parent):
d.Display.__init__(self, parent)
sMkt = service.Market.getInstance()
self.things = sMkt.getItemsWithOverrides()
self.items = self.things
self.searchBox = parent.Parent.Parent.searchBox
# Bind search actions
self.searchBox.Bind(SBox.EVT_TEXT_ENTER, self.scheduleSearch)
self.searchBox.Bind(SBox.EVT_SEARCH_BTN, self.scheduleSearch)
self.searchBox.Bind(SBox.EVT_CANCEL_BTN, self.clearSearch)
self.searchBox.Bind(SBox.EVT_TEXT, self.scheduleSearch)
self.update(self.items)
def clearSearch(self, event=None):
if event:
self.searchBox.Clear()
self.items = self.things
self.update(self.items)
def updateItems(self, updateDisplay=False):
sMkt = service.Market.getInstance()
self.things = sMkt.getItemsWithOverrides()
self.items = self.things
if updateDisplay:
self.update(self.things)
def scheduleSearch(self, event=None):
sMkt = service.Market.getInstance()
search = self.searchBox.GetLineText(0)
# Make sure we do not count wildcard as search symbol
realsearch = search.replace("*", "")
# Show nothing if query is too short
if len(realsearch) < 3:
self.clearSearch()
return
sMkt.searchItems(search, self.populateSearch, False)
def populateSearch(self, items):
self.items = list(items)
self.update(items)
class AttributeGrid(wxpg.PropertyGrid):
def __init__(self, parent):
wxpg.PropertyGrid.__init__(self, parent, style=wxpg.PG_HIDE_MARGIN|wxpg.PG_HIDE_CATEGORIES|wxpg.PG_BOLD_MODIFIED|wxpg.PG_TOOLTIPS)
self.SetExtraStyle(wxpg.PG_EX_HELP_AS_TOOLTIPS)
self.item = None
self.itemView = parent.Parent.itemView
self.btn = parent.Parent.btnRemoveOverrides
self.Bind( wxpg.EVT_PG_CHANGED, self.OnPropGridChange )
self.Bind( wxpg.EVT_PG_SELECTED, self.OnPropGridSelect )
self.Bind( wxpg.EVT_PG_RIGHT_CLICK, self.OnPropGridRightClick )
self.itemView.Bind(wx.EVT_LIST_ITEM_SELECTED, self.itemActivated)
self.itemView.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemActivated)
def itemActivated(self, event):
self.Clear()
self.btn.Enable(True)
sel = event.EventObject.GetFirstSelected()
self.item = item = self.itemView.items[sel]
for key in sorted(item.attributes.keys()):
override = item.overrides.get(key, None)
default = item.attributes[key].value
if override and override.value != default:
prop = wxpg.FloatProperty(key, value=override.value)
prop.SetModifiedStatus(True)
else:
prop = wxpg.FloatProperty(key, value=default)
prop.SetClientData(item.attributes[key]) # set this so that we may access it later
prop.SetHelpString("%s\n%s"%(item.attributes[key].displayName or key, "Default Value: %0.3f"%default))
self.Append(prop)
def removeOverrides(self, event):
if self.item is None:
return
for _, x in self.item.overrides.items():
self.item.deleteOverride(x.attr)
self.itemView.updateItems(True)
self.ClearModifiedStatus()
self.itemView.Select(self.itemView.GetFirstSelected(), on=False)
self.Clear()
def Clear(self):
self.item = None
self.btn.Enable(False)
wxpg.PropertyGrid.Clear(self)
def OnPropGridChange(self, event):
p = event.GetProperty()
attr = p.GetClientData()
if p.GetValue() == attr.value:
self.item.deleteOverride(attr)
p.SetModifiedStatus(False)
else:
self.item.setOverride(attr, p.GetValue())
self.itemView.updateItems()
logger.debug('%s changed to "%s"' % (p.GetName(), p.GetValueAsString()))
def OnPropGridSelect(self, event):
pass
def OnPropGridRightClick(self, event):
pass