Merge branch 'master' into wx3

This commit is contained in:
blitzmann
2015-04-17 17:48:56 -04:00
135 changed files with 1420 additions and 508 deletions

View File

@@ -24,7 +24,7 @@ class DamagePattern(ContextMenu):
self.fit = sFit.getFit(fitID)
self.patterns = sDP.getDamagePatternList()
self.patterns.sort(key=lambda p: (p.name not in ["Uniform","Selected Ammo"], p.name))
self.patterns.sort(key=lambda p: (p.name not in ["Uniform", "Selected Ammo"], p.name))
self.patternIds = {}
self.subMenus = OrderedDict()
@@ -71,7 +71,6 @@ class DamagePattern(ContextMenu):
def getSubMenu(self, context, selection, rootMenu, i, pitem):
msw = True if "wxMSW" in wx.PlatformInfo else False
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch) # this bit is required for some reason
if self.m[i] not in self.subMenus:
# if we're trying to get submenu to something that shouldn't have one,
@@ -79,10 +78,11 @@ class DamagePattern(ContextMenu):
# our patternIds mapping, then return None for no submenu
id = pitem.GetId()
self.patternIds[id] = self.singles[i]
rootMenu.Bind(wx.EVT_MENU, self.handlePatternSwitch, pitem)
if self.patternIds[id] == self.fit.damagePattern:
bitmap = bitmapLoader.getBitmap("state_active_small", "icons")
pitem.SetBitmap(bitmap)
return None
return False
sub = wx.Menu()

View File

@@ -53,6 +53,9 @@ class PFGeneralPref ( PreferenceView):
labelSizer.Add( self.cbRackLabels, 0, wx.ALL|wx.EXPAND, 5 )
mainSizer.Add( labelSizer, 0, wx.LEFT|wx.EXPAND, 30 )
self.cbShowTooltip = wx.CheckBox( panel, wx.ID_ANY, u"Show tab tooltips", wx.DefaultPosition, wx.DefaultSize, 0 )
mainSizer.Add( self.cbShowTooltip, 0, wx.ALL|wx.EXPAND, 5 )
defCharSizer = wx.BoxSizer( wx.HORIZONTAL )
self.sFit = service.Fit.getInstance()
@@ -65,6 +68,7 @@ class PFGeneralPref ( PreferenceView):
self.cbRackLabels.SetValue(self.sFit.serviceFittingOptions["rackLabels"] or False)
self.cbCompactSkills.SetValue(self.sFit.serviceFittingOptions["compactSkills"] or False)
self.cbReopenFits.SetValue(self.openFitsSettings["enabled"])
self.cbShowTooltip.SetValue(self.sFit.serviceFittingOptions["showTooltip"] or False)
self.cbGlobalChar.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalCharStateChange)
self.cbGlobalDmgPattern.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalDmgPatternStateChange)
@@ -74,6 +78,7 @@ class PFGeneralPref ( PreferenceView):
self.cbRackLabels.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackLabels)
self.cbCompactSkills.Bind(wx.EVT_CHECKBOX, self.onCBCompactSkills)
self.cbReopenFits.Bind(wx.EVT_CHECKBOX, self.onCBReopenFits)
self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip)
self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False)
@@ -127,6 +132,9 @@ class PFGeneralPref ( PreferenceView):
def onCBReopenFits(self, event):
self.openFitsSettings["enabled"] = self.cbReopenFits.GetValue()
def onCBShowTooltip(self, event):
self.sFit.serviceFittingOptions["showTooltip"] = self.cbShowTooltip.GetValue()
def getImage(self):
return bitmapLoader.getBitmap("prefs_settings", "icons")

View File

@@ -43,12 +43,10 @@ class FirepowerViewFull(StatsView):
parent = self.panel = contentPanel
self.headerPanel = headerPanel
headerContentSizer = wx.BoxSizer(wx.HORIZONTAL)
hsizer = headerPanel.GetSizer()
hsizer.Add(headerContentSizer, 0, 0, 0)
self.stEff = wx.StaticText(headerPanel, wx.ID_ANY, "( Effective )")
headerContentSizer.Add(self.stEff)
headerPanel.GetParent().AddToggleItem(self.stEff)
hsizer = self.headerPanel.GetSizer()
self.stEff = wx.StaticText(self.headerPanel, wx.ID_ANY, "( Effective )")
hsizer.Add(self.stEff)
self.headerPanel.GetParent().AddToggleItem(self.stEff)
panel = "full"
@@ -59,7 +57,7 @@ class FirepowerViewFull(StatsView):
counter = 0
for damageType, image in (("weapon", "turret") , ("drone", "droneDPS")):
for damageType, image in (("weapon", "turret"), ("drone", "droneDPS")):
baseBox = wx.BoxSizer(wx.HORIZONTAL)
sizerFirepower.Add(baseBox, 1, wx.ALIGN_LEFT if counter == 0 else wx.ALIGN_CENTER_HORIZONTAL)
@@ -124,6 +122,12 @@ class FirepowerViewFull(StatsView):
# And no longer display us
self.panel.GetSizer().Clear(True)
self.panel.GetSizer().Layout()
# Remove effective label
hsizer = self.headerPanel.GetSizer()
hsizer.Remove(self.stEff)
self.stEff.Destroy()
# Get the new view
view = StatsView.getView("miningyieldViewFull")(self.parent)
view.populatePanel(self.panel, self.headerPanel)

View File

@@ -42,7 +42,6 @@ class Ammo(ViewColumn):
return text
def getImageId(self, mod):
return -1

View File

@@ -48,4 +48,8 @@ class AmmoIcon(ViewColumn):
else:
return -1
def getToolTip(self, mod):
if isinstance(mod, Module) and mod.charge is not None:
return mod.charge.name
AmmoIcon.register()

View File

@@ -89,6 +89,12 @@ class AttributeDisplay(ViewColumn):
def getImageId(self, mod):
return -1
def getToolTip(self, stuff):
if self.info.name == "cpu":
return "CPU"
else:
return self.info.name.title()
@staticmethod
def getParameters():
return (("attribute", str, None),

View File

@@ -34,9 +34,8 @@ class CapacitorUse(ViewColumn):
sAttr = service.Attribute.getInstance()
info = sAttr.getAttributeInfo("capacitorNeed")
self.imageId = fittingView.imageList.GetImageIndex(info.icon.iconFile, "pack")
self.bitmap = bitmapLoader.getBitmap(info.icon.iconFile, "pack")
self.imageId = fittingView.imageList.GetImageIndex("capacitorRecharge_small", "icons")
self.bitmap = bitmapLoader.getBitmap("capacitorRecharge_small", "icons")
def getText(self, mod):
if isinstance(mod, Mode):
@@ -51,4 +50,7 @@ class CapacitorUse(ViewColumn):
def getImageId(self, mod):
return -1
def getToolTip(self, mod):
return self.name
CapacitorUse.register()

View File

@@ -74,4 +74,7 @@ class MaxRange(ViewColumn):
return (("displayName", bool, False),
("showIcon", bool, True))
def getToolTip(self, mod):
return "Optimal + Falloff"
MaxRange.register()

View File

@@ -60,4 +60,7 @@ class Price(ViewColumn):
def getImageId(self, mod):
return -1
def getToolTip(self, mod):
return self.name
Price.register()

View File

@@ -44,6 +44,10 @@ class State(ViewColumn):
def getText(self, mod):
return ""
def getToolTip(self, mod):
if isinstance(mod, Module) and not mod.isEmpty:
return State_.getName(mod.state).title()
def getImageId(self, stuff):
if isinstance(stuff, Drone):
return self.checkedId if stuff.amountActive > 0 else self.uncheckedId

View File

@@ -141,6 +141,7 @@ class FittingView(d.Display):
self.Bind(wx.EVT_KEY_UP, self.kbEvent)
self.Bind(wx.EVT_LEFT_DOWN, self.click)
self.Bind(wx.EVT_RIGHT_DOWN, self.click)
self.Bind(wx.EVT_MIDDLE_DOWN, self.click)
self.Bind(wx.EVT_SHOW, self.OnShow)
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
@@ -162,12 +163,9 @@ class FittingView(d.Display):
self.hoveredColumn = col
if row != -1 and row not in self.blanks and col != -1 and col < len(self.DEFAULT_COLS):
mod = self.mods[self.GetItemData(row)]
if self.DEFAULT_COLS[col] == "Miscellanea":
tooltip = self.activeColumns[col].getToolTip(mod)
if tooltip is not None:
self.SetToolTipString(tooltip)
else:
self.SetToolTip(None)
tooltip = self.activeColumns[col].getToolTip(mod)
if tooltip is not None:
self.SetToolTipString(tooltip)
else:
self.SetToolTip(None)
else:
@@ -522,16 +520,21 @@ class FittingView(d.Display):
sFit = service.Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
ctrl = wx.GetMouseState().CmdDown()
ctrl = wx.GetMouseState().CmdDown() or wx.GetMouseState().MiddleDown()
click = "ctrl" if ctrl is True else "right" if event.Button == 3 else "left"
sFit.toggleModulesState(fitID, self.mods[self.GetItemData(row)], mods, click)
# update state tooltip
tooltip = self.activeColumns[col].getToolTip(self.mods[self.GetItemData(row)])
self.SetToolTipString(tooltip)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
else:
event.Skip()
slotColourMap = {1: wx.Colour(250, 235, 204), # yellow = low slots
2: wx.Colour(188,215,241), # blue = mid slots
3: wx.Colour(235,204,209), # red = high slots
slotColourMap = {1: wx.Colour(250, 235, 204), # yellow = low slots
2: wx.Colour(188, 215, 241), # blue = mid slots
3: wx.Colour(235, 204, 209), # red = high slots
4: '',
5: ''}

View File

@@ -25,6 +25,8 @@ import gui.utils.fonts as fonts
from gui import bitmapLoader
import gui.utils.fonts as fonts
import service
_PageChanging, EVT_NOTEBOOK_PAGE_CHANGING = wx.lib.newevent.NewEvent()
_PageChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent()
_PageAdding, EVT_NOTEBOOK_PAGE_ADDING = wx.lib.newevent.NewEvent()
@@ -680,6 +682,7 @@ class PFTabsContainer(wx.Panel):
self.containerHeight = height
self.startDrag = False
self.dragging = False
self.sFit = service.Fit.getInstance()
self.inclination = 7
if canAdd:
@@ -1013,6 +1016,9 @@ class PFTabsContainer(wx.Panel):
Checks to see if we have a tab preview and sets up the timer for it
to display
"""
if not self.sFit.serviceFittingOptions["showTooltip"] or False:
return
if self.previewTimer:
if self.previewTimer.IsRunning():
if self.previewWnd:

View File

@@ -73,18 +73,25 @@ class ContextMenu(object):
rootMenu.info[id] = (m, fullContext, it)
sub = m.getSubMenu(srcContext, selection, rootMenu, it, rootItem)
if sub is None:
# if there is no sub menu, bind the handler to the rootItem
rootMenu.Bind(wx.EVT_MENU, cls.handler, rootItem)
else:
elif sub:
# If sub exists and is not False, set submenu.
# Sub might return False when we have a mix of
# single menu items and submenus (see: damage profile
# context menu)
#
# If there is a submenu, it is expected that the sub
# logic take care of it's own binding. No binding is
# done here
# logic take care of it's own bindings, including for
# any single root items. No binding is done here
#
# It is important to remember that when binding sub
# menu items, bind them to the rootMenu for proper
# event handling, eg:
# rootMenu.Bind(wx.EVE_MENU, self.handle, menuItem)
# menu items, the menu to bind to depends on platform.
# Windows should bind to rootMenu, and all other
# platforms should bind to sub menu. See existing
# implementations for examples.
rootItem.SetSubMenu(sub)
if bitmap is not None:

View File

@@ -523,10 +523,24 @@ class ItemEffects (wx.Panel):
self.Layout()
def OnClick(self, event):
"""
Debug use: open effect file with default application.
If effect file does not exist, create it
"""
import os
file = os.path.join(config.pyfaPath,"eos","effects","%s.py"%event.GetText().lower())
file = os.path.join(config.pyfaPath, "eos", "effects", "%s.py"%event.GetText().lower())
if not os.path.isfile(file):
open(file, 'a').close()
if 'wxMSW' in wx.PlatformInfo:
os.startfile(file)
elif 'wxMac' in wx.PlatformInfo:
os.system("open "+file)
else:
import subprocess
subprocess.call(["xdg-open", file])
###########################################################################

View File

@@ -42,7 +42,7 @@ from gui.additionsPane import AdditionsPane
from gui.marketBrowser import MarketBrowser
from gui.multiSwitch import MultiSwitch
from gui.statsPane import StatsPane
from gui.shipBrowser import ShipBrowser, FitSelected
from gui.shipBrowser import ShipBrowser, FitSelected, ImportSelected, Stage3Selected
from gui.characterEditor import CharacterEditor
from gui.characterSelection import CharacterSelection
from gui.patternEditor import DmgPatternEditorDlg
@@ -54,6 +54,9 @@ from gui.utils.clipboard import toClipboard, fromClipboard
from gui.fleetBrowser import FleetBrowser
from gui.updateDialog import UpdateDialog
from gui.builtinViews import *
from time import gmtime, strftime
import locale
locale.setlocale(locale.LC_ALL, '')
@@ -201,9 +204,18 @@ class MainFrame(wx.Frame):
dlg.Destroy()
def LoadPreviousOpenFits(self):
sFit = service.Fit.getInstance()
self.prevOpenFits = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []})
fits = self.prevOpenFits['pyfaOpenFits']
# Remove any fits that cause exception when fetching (non-existent fits)
for id in fits[:]:
try:
sFit.getFit(id)
except:
fits.remove(id)
if not self.prevOpenFits['enabled'] or len(fits) is 0:
# add blank page if there are no fits to be loaded
self.fitMultiSwitch.AddPage()
@@ -327,47 +339,21 @@ class MainFrame(wx.Frame):
dlg.ShowModal()
dlg.Destroy()
def showImportDialog(self, event):
fits = []
sFit = service.Fit.getInstance()
dlg=wx.FileDialog(
self,
"Open One Or More Fitting Files",
wildcard = "EFT text fitting files (*.cfg)|*.cfg|" \
"EVE XML fitting files (*.xml)|*.xml|" \
"All Files (*)|*",
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
if (dlg.ShowModal() == wx.ID_OK):
self.waitDialog = animUtils.WaitDialog(self, title = "Importing")
sFit.importFitsThreaded(dlg.GetPaths(), self.importCallback)
dlg.Destroy()
self.waitDialog.ShowModal()
def importCallback(self, fits):
self.waitDialog.Destroy()
sFit = service.Fit.getInstance()
IDs = sFit.saveImportedFits(fits)
self._openAfterImport(len(fits), IDs)
def _openAfterImport(self, importCount, fitIDs):
if importCount == 1:
wx.PostEvent(self, FitSelected(fitID=fitIDs[0]))
self.shipBrowser.RefreshContent()
def showExportDialog(self, event):
dlg=wx.FileDialog(
self,
"Save Fitting As...",
wildcard = "EVE XML fitting files (*.xml)|*.xml",
style = wx.FD_SAVE)
if (dlg.ShowModal() == wx.ID_OK):
sFit = service.Fit.getInstance()
""" Export active fit """
sFit = service.Fit.getInstance()
fit = sFit.getFit(self.getActiveFit())
defaultFile = "%s - %s.xml"%(fit.ship.item.name, fit.name) if fit else None
dlg = wx.FileDialog(self, "Save Fitting As...",
wildcard = "EVE XML fitting files (*.xml)|*.xml",
style = wx.FD_SAVE,
defaultFile=defaultFile)
if dlg.ShowModal() == wx.ID_OK:
format = dlg.GetFilterIndex()
output = ""
path = dlg.GetPath()
if (format == 0):
output = sFit.exportXml(self.getActiveFit())
if format == 0:
output = sFit.exportXml(None, self.getActiveFit())
if '.' not in os.path.basename(path):
path += ".xml"
else:
@@ -406,7 +392,7 @@ class MainFrame(wx.Frame):
# Target Resists editor
self.Bind(wx.EVT_MENU, self.showTargetResistsEditor, id=menuBar.targetResistsEditorId)
# Import dialog
self.Bind(wx.EVT_MENU, self.showImportDialog, id=wx.ID_OPEN)
self.Bind(wx.EVT_MENU, self.fileImportDialog, id=wx.ID_OPEN)
# Export dialog
self.Bind(wx.EVT_MENU, self.showExportDialog, id=wx.ID_SAVEAS)
# Import from Clipboard
@@ -545,17 +531,16 @@ class MainFrame(wx.Frame):
def clipboardXml(self):
sFit = service.Fit.getInstance()
toClipboard(sFit.exportXml(self.getActiveFit()))
toClipboard(sFit.exportXml(None, self.getActiveFit()))
def importFromClipboard(self, event):
sFit = service.Fit.getInstance()
try:
fits = sFit.importFitFromBuffer(fromClipboard(), self.getActiveFit())
IDs = sFit.saveImportedFits(fits)
self._openAfterImport(len(fits), IDs)
except:
pass
else:
self._openAfterImport(fits)
def exportToClipboard(self, event):
CopySelectDict = {CopySelectDialog.copyFormatEft: self.clipboardEft,
@@ -571,44 +556,109 @@ class MainFrame(wx.Frame):
pass
dlg.Destroy()
def backupToXml(self, event):
def fileImportDialog(self, event):
"""Handles importing single/multiple EVE XML / EFT cfg fit files"""
sFit = service.Fit.getInstance()
saveDialog = wx.FileDialog(
self,
"Save Backup As...",
wildcard = "EVE XML fitting file (*.xml)|*.xml",
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if (saveDialog.ShowModal() == wx.ID_OK):
dlg = wx.FileDialog(self, "Open One Or More Fitting Files",
wildcard = "EVE XML fitting files (*.xml)|*.xml|" \
"EFT text fitting files (*.cfg)|*.cfg|" \
"All Files (*)|*",
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
if (dlg.ShowModal() == wx.ID_OK):
self.progressDialog = wx.ProgressDialog(
"Importing fits",
" "*100, # set some arbitrary spacing to create wifth in window
parent=self, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
self.progressDialog.message = None
sFit.importFitsThreaded(dlg.GetPaths(), self.fileImportCallback)
self.progressDialog.ShowModal()
dlg.Destroy()
def fileImportCallback(self, info, fits=None):
"""
While importing fits from file, the logic calls back to this function to
update progress bar to show activity. XML files can contain multiple
ships with multiple fits, whereas EFT cfg files contain many fits of
a single ship. When iterating through the files, we update the message
when we start a new file, and then Pulse the progress bar with every fit
that is processed.
"""
if info == -1:
# Done processing
self.progressDialog.Hide()
self._openAfterImport(fits)
elif info != self.progressDialog.message and info is not None:
# New message, overwrite cached message and update
self.progressDialog.message = info
self.progressDialog.Pulse(info)
else:
# Simply Pulse() if we don't have anything else to do
self.progressDialog.Pulse()
def _openAfterImport(self, fits):
if len(fits) > 0:
if len(fits) == 1:
fit = fits[0]
wx.PostEvent(self, FitSelected(fitID=fit.ID))
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=fit.shipID, back=True))
else:
wx.PostEvent(self.shipBrowser, ImportSelected(fits=fits, back=True))
def backupToXml(self, event):
""" Back up all fits to EVE XML file """
defaultFile = "pyfa-fits-%s.xml"%strftime("%Y%m%d_%H%M%S", gmtime())
saveDialog = wx.FileDialog(self, "Save Backup As...",
wildcard = "EVE XML fitting file (*.xml)|*.xml",
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
defaultFile=defaultFile)
if saveDialog.ShowModal() == wx.ID_OK:
filePath = saveDialog.GetPath()
if '.' not in os.path.basename(filePath):
filePath += ".xml"
self.waitDialog = animUtils.WaitDialog(self)
sFit.backupFits(filePath, self.closeWaitDialog)
self.waitDialog.ShowModal()
saveDialog.Destroy()
sFit = service.Fit.getInstance()
max = sFit.countAllFits()
self.progressDialog = wx.ProgressDialog("Backup fits",
"Backing up %d fits to: %s"%(max, filePath),
maximum=max, parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
sFit.backupFits(filePath, self.backupCallback)
self.progressDialog.ShowModal()
def backupCallback(self, info):
if info == -1:
self.progressDialog.Hide()
else:
self.progressDialog.Update(info)
def exportSkillsNeeded(self, event):
""" Exports skills needed for active fit and active character """
sCharacter = service.Character.getInstance()
saveDialog = wx.FileDialog(
self,
"Export Skills Needed As...",
wildcard = "EVEMon skills training file (*.emp)|*.emp|" \
"EVEMon skills training XML file (*.xml)|*.xml|" \
"Text skills training file (*.txt)|*.txt",
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if (saveDialog.ShowModal() == wx.ID_OK):
saveDialog = wx.FileDialog(self, "Export Skills Needed As...",
wildcard = "EVEMon skills training file (*.emp)|*.emp|" \
"EVEMon skills training XML file (*.xml)|*.xml|" \
"Text skills training file (*.txt)|*.txt",
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if saveDialog.ShowModal() == wx.ID_OK:
saveFmtInt = saveDialog.GetFilterIndex()
saveFmt = ""
if saveFmtInt == 0: # Per ordering of wildcards above
saveFmt = "emp"
elif saveFmtInt == 1:
saveFmt = "xml"
else:
saveFmt = "txt"
filePath = saveDialog.GetPath()
if '.' not in os.path.basename(filePath):
filePath += ".{0}".format(saveFmt)
self.waitDialog = animUtils.WaitDialog(self)
sCharacter.backupSkills(filePath, saveFmt, self.getActiveFit(), self.closeWaitDialog)
self.waitDialog.ShowModal()
@@ -616,29 +666,38 @@ class MainFrame(wx.Frame):
saveDialog.Destroy()
def importCharacter(self, event):
sCharacter = service.Character.getInstance()
dlg=wx.FileDialog(
self,
"Open One Or More Character Files",
wildcard = "EVE CCP API XML character files (*.xml)|*.xml|" \
"All Files (*)|*",
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
if (dlg.ShowModal() == wx.ID_OK):
self.waitDialog = animUtils.WaitDialog(self, title = "Importing Character")
""" Imports character XML file from EVE API """
dlg = wx.FileDialog(self, "Open One Or More Character Files",
wildcard="EVE API XML character files (*.xml)|*.xml|" \
"All Files (*)|*",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
if dlg.ShowModal() == wx.ID_OK:
self.waitDialog = animUtils.WaitDialog(self, title="Importing Character")
sCharacter = service.Character.getInstance()
sCharacter.importCharacter(dlg.GetPaths(), self.importCharacterCallback)
dlg.Destroy()
self.waitDialog.ShowModal()
def exportHtml(self, event):
from gui.utils.exportHtml import exportHtml
self.waitDialog = animUtils.WaitDialog(self)
exportHtml.getInstance().refreshFittingHtml(True, self.closeWaitDialog)
self.waitDialog.ShowModal()
def importCharacterCallback(self):
self.waitDialog.Destroy()
wx.PostEvent(self, GE.CharListUpdated())
def exportHtml(self, event):
from gui.utils.exportHtml import exportHtml
sFit = service.Fit.getInstance()
settings = service.settings.HTMLExportSettings.getInstance()
max = sFit.countAllFits()
path = settings.getPath()
self.progressDialog = wx.ProgressDialog("Backup fits",
"Generating HTML file at: %s"%path,
maximum=max, parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
exportHtml.getInstance().refreshFittingHtml(True, self.backupCallback)
self.progressDialog.ShowModal()
def closeWaitDialog(self):
self.waitDialog.Destroy()
@@ -650,7 +709,7 @@ class MainFrame(wx.Frame):
else:
self.graphFrame.SetFocus()
def openWXInspectTool(self,event):
def openWXInspectTool(self, event):
from wx.lib.inspection import InspectionTool
if not InspectionTool().initialized:
InspectionTool().Init()

View File

@@ -28,11 +28,11 @@ from service.damagePattern import ImportError
## Class DmgPatternEditorDlg
###########################################################################
class DmgPatternEditorDlg (wx.Dialog):
class DmgPatternEditorDlg(wx.Dialog):
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
def __init__(self, parent):
wx.Dialog.__init__ (self, parent, id = wx.ID_ANY, title = u"Damage Pattern Editor", size = wx.Size( 400,240 ))
wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Damage Pattern Editor", size = wx.Size( 400,240 ))
self.block = False
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
@@ -125,7 +125,7 @@ class DmgPatternEditorDlg (wx.Dialog):
editObj.Bind(wx.EVT_TEXT, self.ValuesUpdated)
editObj.SetLimited(True)
editObj.SetMin(0)
editObj.SetMax(99999)
editObj.SetMax(2000000)
contentSizer.Add(dmgeditSizer, 1, wx.EXPAND | wx.ALL, 5)
self.slfooter = wx.StaticLine(self)
@@ -244,23 +244,22 @@ class DmgPatternEditorDlg (wx.Dialog):
self.block = False
self.ValuesUpdated()
def newPattern(self,event):
sDP = service.DamagePattern.getInstance()
p = sDP.newPattern()
self.choices.append(p)
id = self.ccDmgPattern.Append(p.name)
self.ccDmgPattern.SetSelection(id)
def newPattern(self, event):
self.restrict()
self.block = True
# reset values
for type in self.DAMAGE_TYPES:
editObj = getattr(self, "%sEdit"%type)
editObj.SetValue(0)
self.block = False
self.btnSave.SetLabel("Create")
self.Refresh()
self.renamePattern()
def renamePattern(self,event=None):
def renamePattern(self, event=None):
if event is not None:
self.btnSave.SetLabel("Rename")
@@ -268,7 +267,12 @@ class DmgPatternEditorDlg (wx.Dialog):
self.namePicker.Show()
self.headerSizer.Replace(self.ccDmgPattern, self.namePicker)
self.namePicker.SetFocus()
self.namePicker.SetValue(self.getActivePattern().name)
if event is not None: # Rename mode
self.btnSave.SetLabel("Rename")
self.namePicker.SetValue(self.getActivePattern().name)
else: # Create mode
self.namePicker.SetValue("")
for btn in (self.new, self.rename, self.delete, self.copy):
btn.Hide()
@@ -284,19 +288,25 @@ class DmgPatternEditorDlg (wx.Dialog):
newName = self.namePicker.GetLineText(0)
self.stNotice.SetLabel("")
p = self.getActivePattern()
for pattern in self.choices:
if pattern.name == newName and p != pattern:
self.stNotice.SetLabel("Name already used, please choose another")
return
if newName == "":
self.stNotice.SetLabel("Invalid name.")
return
sDP = service.DamagePattern.getInstance()
if self.btnSave.Label == "Create":
p = sDP.newPattern()
else:
# we are renaming, so get the current selection
p = self.getActivePattern()
for pattern in self.choices:
if pattern.name == newName and p != pattern:
self.stNotice.SetLabel("Name already used, please choose another")
return
sDP.renamePattern(p, newName)
self.updateChoices(newName)
self.headerSizer.Replace(self.namePicker, self.ccDmgPattern)
self.ccDmgPattern.Show()
self.namePicker.Hide()
@@ -335,7 +345,7 @@ class DmgPatternEditorDlg (wx.Dialog):
def __del__( self ):
pass
def updateChoices(self):
def updateChoices(self, select=None):
"Gathers list of patterns and updates choice selections"
sDP = service.DamagePattern.getInstance()
self.choices = sDP.getDamagePatternList()
@@ -348,10 +358,14 @@ class DmgPatternEditorDlg (wx.Dialog):
self.choices.sort(key=lambda p: p.name)
self.ccDmgPattern.Clear()
for choice in map(lambda p: p.name, self.choices):
for i, choice in enumerate(map(lambda p: p.name, self.choices)):
self.ccDmgPattern.Append(choice)
self.ccDmgPattern.SetSelection(0)
if select is not None and choice == select:
self.ccDmgPattern.SetSelection(i)
if select is None:
self.ccDmgPattern.SetSelection(0)
self.patternChanged()
def importPatterns(self, event):

View File

@@ -23,12 +23,12 @@ import service
from gui.utils.clipboard import toClipboard, fromClipboard
from service.targetResists import ImportError
class ResistsEditorDlg (wx.Dialog):
class ResistsEditorDlg(wx.Dialog):
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
def __init__(self, parent):
wx.Dialog.__init__ (self, parent, id = wx.ID_ANY, title = u"Target Resists Editor", size = wx.Size( 350,240 ))
wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = u"Target Resists Editor", size = wx.Size( 350,240 ))
self.block = False
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
@@ -301,7 +301,7 @@ class ResistsEditorDlg (wx.Dialog):
return
sTR = service.TargetResists.getInstance()
if event.EventObject.Label == "Create":
if self.btnSave.Label == "Create":
p = sTR.newPattern()
else:
# we are renaming, so get the current selection

View File

@@ -413,4 +413,4 @@ class SFBrowserItem(wx.Window):
self.bkBitmap.state = state
self.bkBitmap.sFactor = sFactor
self.bkBitmap.eFactor = eFactor
self.bkBitmap.mFactor = mFactor
self.bkBitmap.mFactor = mFactor

View File

@@ -30,6 +30,7 @@ Stage1Selected, EVT_SB_STAGE1_SEL = wx.lib.newevent.NewEvent()
Stage2Selected, EVT_SB_STAGE2_SEL = wx.lib.newevent.NewEvent()
Stage3Selected, EVT_SB_STAGE3_SEL = wx.lib.newevent.NewEvent()
SearchSelected, EVT_SB_SEARCH_SEL = wx.lib.newevent.NewEvent()
ImportSelected, EVT_SB_IMPORT_SEL = wx.lib.newevent.NewEvent()
class PFWidgetsContainer(PFListPane):
def __init__(self,parent):
@@ -324,7 +325,7 @@ class RaceSelector(wx.Window):
event.Skip()
class NavigationPanel(SFItem.SFBrowserItem):
def __init__(self,parent, size = (-1,24)):
def __init__(self,parent, size = (-1, 24)):
SFItem.SFBrowserItem.__init__(self,parent,size = size)
self.rewBmpH = bitmapLoader.getBitmap("frewind_small","icons")
@@ -352,7 +353,7 @@ class NavigationPanel(SFItem.SFBrowserItem):
self.padding = 4
self.lastSearch = ""
self.recentSearches = []
self.recentSearches = [] # not used?
self.inSearch = False
self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL)
@@ -371,23 +372,14 @@ class NavigationPanel(SFItem.SFBrowserItem):
self.Bind(wx.EVT_SIZE, self.OnResize)
def OnScheduleSearch(self, event):
search = self.BrowserSearchBox.GetValue()
# Make sure we do not count wildcard as search symbol
realsearch = search.replace("*", "")
if len(realsearch) < 3 and len(realsearch) >= 0:
if self.inSearch == True:
self.inSearch = False
if len(self.shipBrowser.browseHist) > 0:
stage,data = self.shipBrowser.browseHist.pop()
self.gotoStage(stage,data)
else:
if search:
wx.PostEvent(self.shipBrowser,SearchSelected(text=search, back = False))
self.inSearch = True
else:
self.inSearch = False
if len(realsearch) >= 3:
self.lastSearch = search
wx.PostEvent(self.shipBrowser,SearchSelected(text=search, back = False))
def ToggleSearchBox(self):
if self.BrowserSearchBox.IsShown():
@@ -401,8 +393,6 @@ class NavigationPanel(SFItem.SFBrowserItem):
self.OnBrowserSearchBoxLostFocus(None)
def OnBrowserSearchBoxLostFocus(self, event):
self.lastSearch = self.BrowserSearchBox.GetValue()
self.BrowserSearchBox.ChangeValue("")
self.BrowserSearchBox.Show(False)
def OnBrowserSearchBoxEsc(self, event):
@@ -411,7 +401,6 @@ class NavigationPanel(SFItem.SFBrowserItem):
else:
event.Skip()
def OnResize(self, event):
self.Refresh()
@@ -449,7 +438,7 @@ class NavigationPanel(SFItem.SFBrowserItem):
sFit = service.Fit.getInstance()
fitID = sFit.newFit(shipID, "%s fit" %shipName)
self.shipBrowser.fitIDMustEditName = fitID
wx.PostEvent(self.Parent,Stage3Selected(shipID=shipID, back = True))
wx.PostEvent(self.Parent,Stage3Selected(shipID=shipID))
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
def OnHistoryReset(self):
@@ -460,11 +449,11 @@ class NavigationPanel(SFItem.SFBrowserItem):
def OnHistoryBack(self):
if len(self.shipBrowser.browseHist) > 0:
stage,data = self.shipBrowser.browseHist.pop()
self.gotoStage(stage,data)
self.gotoStage(stage, data)
def AdjustChannels(self, bitmap):
img = wx.ImageFromBitmap(bitmap)
img = img.AdjustChannels(1.05,1.05,1.05,1)
img = img.AdjustChannels(1.05, 1.05, 1.05, 1)
return wx.BitmapFromImage(img)
def UpdateElementsPos(self, mdc):
@@ -536,20 +525,20 @@ class NavigationPanel(SFItem.SFBrowserItem):
self.bkBitmap.mFactor = mFactor
def gotoStage(self,stage, data = None):
def gotoStage(self, stage, data=None):
if stage == 1:
wx.PostEvent(self.Parent,Stage1Selected())
wx.PostEvent(self.Parent, Stage1Selected())
elif stage == 2:
wx.PostEvent(self.Parent,Stage2Selected(categoryID=data, back = True))
wx.PostEvent(self.Parent, Stage2Selected(categoryID=data, back=True))
elif stage == 3:
wx.PostEvent(self.Parent,Stage3Selected(shipID=data, back = 1))
wx.PostEvent(self.Parent, Stage3Selected(shipID=data))
elif stage == 4:
self.shipBrowser._activeStage = 4
self.stStatus.SetLabel("Search: %s" % data.capitalize())
self.Layout()
wx.PostEvent(self.Parent,SearchSelected(text=data, back = True))
wx.PostEvent(self.Parent, SearchSelected(text=data, back=True))
elif stage == 5:
wx.PostEvent(self.Parent, ImportSelected(fits=data))
else:
wx.PostEvent(self.Parent,Stage1Selected())
wx.PostEvent(self.Parent, Stage1Selected())
class ShipBrowser(wx.Panel):
@@ -610,6 +599,7 @@ class ShipBrowser(wx.Panel):
self.Bind(EVT_SB_STAGE1_SEL, self.stage1)
self.Bind(EVT_SB_STAGE3_SEL, self.stage3)
self.Bind(EVT_SB_SEARCH_SEL, self.searchStage)
self.Bind(EVT_SB_IMPORT_SEL, self.importStage)
self.mainFrame.Bind(GE.FIT_CHANGED, self.RefreshList)
@@ -654,6 +644,8 @@ class ShipBrowser(wx.Panel):
return self._stage2Data
if stage == 3:
return self._stage3Data
if stage == 4:
return self.navpanel.lastSearch
return -1
def GetStage3ShipName(self):
@@ -809,13 +801,15 @@ class ShipBrowser(wx.Panel):
self.lpane.ShowLoading(False)
if event.back == 0:
self.browseHist.append( (2,self._stage2Data) )
elif event.back == -1:
if len(self.navpanel.recentSearches)>0:
# If back is False, do not append to history. This could be us calling
# the stage from previous history, creating / copying fit, etc.
# We also have to use conditional for search stage since it's last data
# is kept elsewhere
if getattr(event, "back", False):
if self._activeStage == 4 and self.navpanel.lastSearch != "":
self.browseHist.append((4, self.navpanel.lastSearch))
elif event.back > 0:
self.browseHist.append( (2,event.back) )
else:
self.browseHist.append((self._activeStage, self.lastdata))
shipID = event.shipID
self.lastdata = shipID
@@ -868,11 +862,11 @@ class ShipBrowser(wx.Panel):
self.navpanel.ShowSwitchEmptyGroupsButton(False)
if not event.back:
if self._activeStage !=4:
if len(self.browseHist) >0:
self.browseHist.append( (self._activeStage, self.lastdata) )
if self._activeStage != 4:
if len(self.browseHist) > 0:
self.browseHist.append((self._activeStage, self.lastdata))
else:
self.browseHist.append((1,0))
self.browseHist.append((1, 0))
self._lastStage = self._activeStage
self._activeStage = 4
@@ -903,6 +897,46 @@ class ShipBrowser(wx.Panel):
self.raceselect.Show(False)
self.Layout()
def importStage(self, event):
self.lpane.ShowLoading(False)
self.navpanel.ShowNewFitButton(False)
self.navpanel.ShowSwitchEmptyGroupsButton(False)
if getattr(event, "back", False):
self.browseHist.append((self._activeStage, self.lastdata))
self._lastStage = self._activeStage
self._activeStage = 5
fits = event.fits
# sort by ship name, then fit name
fits.sort(key=lambda fit: (fit.ship.item.name, fit.name))
self.lastdata = fits
self.lpane.Freeze()
self.lpane.RemoveAllChildren()
if fits:
for fit in fits:
self.lpane.AddWidget(FitItem(
self.lpane,
fit.ID, (
fit.ship.item.name,
fit.name,
fit.booster,
fit.timestamp),
fit.ship.item.ID))
self.lpane.RefreshList(doFocus=False)
self.lpane.Thaw()
self.raceselect.RebuildRaces(self.RACE_ORDER)
if self.showRacesFilterInStage2Only:
self.raceselect.Show(False)
self.Layout()
class PFStaticText(wx.Panel):
def __init__(self, parent, label=wx.EmptyString):
wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size = parent.GetSize())
@@ -1165,7 +1199,7 @@ class ShipItem(SFItem.SFBrowserItem):
else:
shipName, fittings = self.shipFittingInfo
if fittings > 0:
wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back = -1 if self.shipBrowser.GetActiveStage() == 4 else 0))
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID, back=True))
else:
self.newBtnCB()
@@ -1577,7 +1611,7 @@ class FitItem(SFItem.SFBrowserItem):
sFit = service.Fit.getInstance()
fitID = sFit.copyFit(self.fitID)
self.shipBrowser.fitIDMustEditName = fitID
wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back=True))
wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID))
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
def renameBtnCB(self):
@@ -1620,18 +1654,22 @@ class FitItem(SFItem.SFBrowserItem):
self.deleted = True
sFit = service.Fit.getInstance()
fit = sFit.getFit(self.fitID)
sFit.deleteFit(self.fitID)
if self.shipBrowser.GetActiveStage() == 4:
wx.PostEvent(self.shipBrowser,SearchSelected(text=self.shipBrowser.navpanel.lastSearch,back=True))
if self.shipBrowser.GetActiveStage() == 5:
if fit in self.shipBrowser.lastdata: # remove fit from import cache
self.shipBrowser.lastdata.remove(fit)
wx.PostEvent(self.shipBrowser, ImportSelected(fits=self.shipBrowser.lastdata))
elif self.shipBrowser.GetActiveStage() == 4:
wx.PostEvent(self.shipBrowser, SearchSelected(text=self.shipBrowser.navpanel.lastSearch, back=True))
else:
wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back=True))
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID))
wx.PostEvent(self.mainFrame, FitRemoved(fitID=self.fitID))
def MouseLeftUp(self, event):
if self.dragging and self.dragged:
self.dragging = False
self.dragged = False

View File

@@ -7,7 +7,7 @@ class exportHtml():
_instance = None
@classmethod
def getInstance(cls):
if cls._instance == None:
if cls._instance is None:
cls._instance = exportHtml()
return cls._instance
@@ -15,17 +15,17 @@ class exportHtml():
def __init__(self):
self.thread = exportHtmlThread()
def refreshFittingHtml(self, force = False, callback = False):
def refreshFittingHtml(self, force=False, callback=False):
settings = service.settings.HTMLExportSettings.getInstance()
if (force or settings.getEnabled()):
if force or settings.getEnabled():
self.thread.stop()
self.thread = exportHtmlThread(callback)
self.thread.start()
class exportHtmlThread(threading.Thread):
def __init__(self, callback = False):
def __init__(self, callback=False):
threading.Thread.__init__(self)
self.callback = callback
self.stopRunning = False
@@ -40,7 +40,7 @@ class exportHtmlThread(threading.Thread):
return
sMkt = service.Market.getInstance()
sFit = service.Fit.getInstance()
sFit = service.Fit.getInstance()
settings = service.settings.HTMLExportSettings.getInstance()
timestamp = time.localtime(time.time())
@@ -135,6 +135,9 @@ class exportHtmlThread(threading.Thread):
HTML += ' <ul data-role="listview" class="ui-listview-outer" data-inset="true" data-filter="true">\n'
categoryList = list(sMkt.getShipRoot())
categoryList.sort(key=lambda ship: ship.name)
count = 1
for group in categoryList:
# init market group string to give ships something to attach to
HTMLgroup = ''
@@ -153,9 +156,16 @@ class exportHtmlThread(threading.Thread):
if self.stopRunning:
return
fit = fits[0]
dnaFit = sFit.exportDna(fit[0])
HTMLgroup += (
' <li><a data-dna="' + dnaFit + '" target="_blank">' + ship.name + ": " + fit[1] + '</a></li>\n')
try:
dnaFit = sFit.exportDna(fit[0])
HTMLgroup += (
' <li><a data-dna="' + dnaFit + '" target="_blank">' + ship.name + ": " + fit[1] + '</a></li>\n')
except:
pass
finally:
count += 1
if self.callback:
wx.CallAfter(self.callback, count)
else:
# Ship group header
HTMLship = (
@@ -166,11 +176,18 @@ class exportHtmlThread(threading.Thread):
for fit in fits:
if self.stopRunning:
return
dnaFit = sFit.exportDna(fit[0])
HTMLship += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + fit[1] + '</a></li>\n'
try:
dnaFit = sFit.exportDna(fit[0])
HTMLship += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + fit[1] + '</a></li>\n'
except:
continue
finally:
count += 1
if self.callback:
wx.CallAfter(self.callback, count)
HTMLgroup += HTMLship + (' </ul>\n'
' </li>\n')
if groupFits > 0:
# Market group header
HTML += (
@@ -197,5 +214,5 @@ class exportHtmlThread(threading.Thread):
pass
if self.callback:
wx.CallAfter(self.callback)
wx.CallAfter(self.callback, -1)

View File

@@ -50,7 +50,7 @@ class ViewColumn(object):
return ""
def getToolTip(self, mod):
return ""
return None
def getImageId(self, mod):
return -1