Merge branch 'test-3' into esi

# Conflicts:
#	eos/saveddata/character.py
#	service/character.py
#	service/eveapi.py
#	service/pycrest/eve.py
This commit is contained in:
blitzmann
2018-03-10 15:32:21 -05:00
113 changed files with 846 additions and 379 deletions

View File

@@ -51,6 +51,7 @@ class BoosterView(d.Display):
"Base Name",
"Side Effects",
"Price",
"Miscellanea",
]
def __init__(self, parent):
@@ -130,6 +131,7 @@ class BoosterView(d.Display):
fit = sFit.getFit(fitID)
if not fit or fit.isStructure:
event.Skip()
return
trigger = sFit.addBooster(fitID, event.itemID)

View File

@@ -210,6 +210,7 @@ class DroneView(Display):
fit = sFit.getFit(fitID)
if not fit or fit.isStructure:
event.Skip()
return
trigger = sFit.addDrone(fitID, event.itemID)

View File

@@ -91,7 +91,10 @@ class FighterView(wx.Panel):
if fit:
for x in self.labels:
slot = getattr(Slot, "F_{}".format(x.upper()))
if fit.isStructure:
slot = getattr(Slot, "FS_{}".format(x.upper()))
else:
slot = getattr(Slot, "F_{}".format(x.upper()))
used = fit.getSlotsUsed(slot)
total = fit.getNumSlots(slot)
color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings.GetColour(

View File

@@ -152,6 +152,7 @@ class ImplantDisplay(d.Display):
fit = sFit.getFit(fitID)
if not fit or fit.isStructure:
event.Skip()
return
trigger = sFit.addImplant(fitID, event.itemID)

View File

@@ -99,15 +99,22 @@ class ProjectedView(d.Display):
data[0] is hard-coded str of originating source
data[1] is typeID or index of data we want to manipulate
"""
sFit = Fit.getInstance()
fit = sFit.getFit(self.mainFrame.getActiveFit())
if data[0] == "projected":
# if source is coming from projected, we are trying to combine drones.
self.mergeDrones(x, y, int(data[1]))
elif data[0] == "fitting":
dstRow, _ = self.HitTest((x, y))
# Gather module information to get position
module = fit.modules[int(data[1])]
sFit.project(fit.ID, module.item.ID)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
elif data[0] == "market":
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
sFit.project(fitID, int(data[1]))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
sFit.project(fit.ID, int(data[1]))
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fit.ID))
def kbEvent(self, event):
keycode = event.GetKeyCode()

View File

@@ -26,57 +26,71 @@ class ChangeAmount(ContextMenu):
return u"Change {0} Quantity".format(itmContext)
def activate(self, fullContext, selection, i):
srcContext = fullContext[0]
dlg = AmountChanger(self.mainFrame, selection[0], srcContext)
dlg.ShowModal()
thing = selection[0]
mainFrame = gui.mainFrame.MainFrame.getInstance()
fitID = mainFrame.getActiveFit()
if isinstance(thing, es_Fit):
value = thing.getProjectionInfo(fitID).amount
else:
value = thing.amount
dlg = AmountChanger(self.mainFrame, value)
if dlg.ShowModal() == wx.ID_OK:
if dlg.input.GetLineText(0).strip() == '':
return
sFit = Fit.getInstance()
cleanInput = re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip())
if isinstance(thing, es_Cargo):
sFit.addCargo(fitID, thing.item.ID, int(float(cleanInput)), replace=True)
elif isinstance(thing, es_Fit):
sFit.changeAmount(fitID, thing, int(float(cleanInput)))
elif isinstance(thing, es_Fighter):
sFit.changeActiveFighters(fitID, thing, int(float(cleanInput)))
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
ChangeAmount.register()
class AmountChanger(wx.Dialog):
def __init__(self, parent, thing, context):
wx.Dialog.__init__(self, parent, title="Select Amount", size=wx.Size(220, 60))
self.thing = thing
self.context = context
def __init__(self, parent, value):
wx.Dialog.__init__(self, parent, title="Change Amount")
self.SetMinSize((346, 156))
bSizer1 = wx.BoxSizer(wx.HORIZONTAL)
bSizer1 = wx.BoxSizer(wx.VERTICAL)
bSizer2 = wx.BoxSizer(wx.VERTICAL)
text = wx.StaticText(self, wx.ID_ANY, "New Amount:")
bSizer2.Add(text, 0)
bSizer1.Add(bSizer2, 0, wx.ALL, 10)
self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
self.input.SetValue(str(value))
bSizer1.Add(self.input, 1, wx.ALL, 5)
bSizer1.Add(self.input, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 15)
bSizer3 = wx.BoxSizer(wx.VERTICAL)
bSizer3.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.BOTTOM | wx.EXPAND, 15)
bSizer3.Add(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND)
bSizer1.Add(bSizer3, 0, wx.ALL | wx.EXPAND, 10)
self.input.SetFocus()
self.input.SetInsertionPointEnd()
self.input.Bind(wx.EVT_CHAR, self.onChar)
self.input.Bind(wx.EVT_TEXT_ENTER, self.change)
self.button = wx.Button(self, wx.ID_OK, "Done")
bSizer1.Add(self.button, 0, wx.ALL, 5)
self.input.Bind(wx.EVT_TEXT_ENTER, self.processEnter)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
self.button.Bind(wx.EVT_BUTTON, self.change)
self.CenterOnParent()
self.Fit()
def change(self, event):
if self.input.GetLineText(0).strip() == '':
event.Skip()
self.Close()
return
sFit = Fit.getInstance()
cleanInput = re.sub(r'[^0-9.]', '', self.input.GetLineText(0).strip())
mainFrame = gui.mainFrame.MainFrame.getInstance()
fitID = mainFrame.getActiveFit()
if isinstance(self.thing, es_Cargo):
sFit.addCargo(fitID, self.thing.item.ID, int(float(cleanInput)), replace=True)
elif isinstance(self.thing, es_Fit):
sFit.changeAmount(fitID, self.thing, int(float(cleanInput)))
elif isinstance(self.thing, es_Fighter):
sFit.changeActiveFighters(fitID, self.thing, int(float(cleanInput)))
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
self.Close()
def processEnter(self, evt):
self.EndModal(wx.ID_OK)
# checks to make sure it's valid number
@staticmethod

View File

@@ -31,9 +31,7 @@ class FactorReload(ContextMenu):
def getBitmap(self, context, selection):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
fit = sFit.getFit(fitID)
if fit.factorReload:
if sFit.serviceFittingOptions["useGlobalForceReload"]:
return BitmapLoader.getBitmap("state_active_small", "gui")
else:
return None

View File

@@ -243,6 +243,8 @@ class ItemParams(wx.Panel):
return "%s (%d)" % (group.name, value) if group is not None else str(value)
def attributeIDCallback():
if not value: # some attributes come through with a value of 0? See #1387
return "%d" % (value)
attribute = Attribute.getInstance().getAttributeInfo(value)
return "%s (%d)" % (attribute.name.capitalize(), value)

View File

@@ -42,6 +42,15 @@ class PFGeneralPref(PreferenceView):
self.inputLogPath.SetBackgroundColour((200, 200, 200))
mainSizer.Add(self.inputLogPath, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
import requests
self.certPath = wx.StaticText(panel, wx.ID_ANY, "Cert Path:", wx.DefaultPosition, wx.DefaultSize, 0)
self.certPath .Wrap(-1)
mainSizer.Add(self.certPath, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
self.certPathCtrl = wx.TextCtrl(panel, wx.ID_ANY, requests.certs.where(), wx.DefaultPosition, wx.DefaultSize, 0)
self.certPathCtrl.SetEditable(False)
self.certPathCtrl.SetBackgroundColour((200, 200, 200))
mainSizer.Add(self.certPathCtrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
# Debug Logging
self.cbdebugLogging = wx.CheckBox(panel, wx.ID_ANY, "Debug Logging Enabled", wx.DefaultPosition, wx.DefaultSize, 0)
mainSizer.Add(self.cbdebugLogging, 0, wx.ALL | wx.EXPAND, 5)

View File

@@ -121,11 +121,11 @@ class PFNetworkPref(PreferenceView):
self.stPSetLogin = wx.StaticText(panel, wx.ID_ANY, "Username:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetLogin.Wrap(-1)
self.editProxySettingsLogin = wx.TextCtrl(panel, wx.ID_ANY, self.nAuth[0], wx.DefaultPosition, wx.DefaultSize,
0)
0)
self.stPSetPassword = wx.StaticText(panel, wx.ID_ANY, "Password:", wx.DefaultPosition, wx.DefaultSize, 0)
self.stPSetPassword.Wrap(-1)
self.editProxySettingsPassword = wx.TextCtrl(panel, wx.ID_ANY, self.nAuth[1], wx.DefaultPosition,
wx.DefaultSize, wx.TE_PASSWORD)
wx.DefaultSize, wx.TE_PASSWORD)
pAuthSizer = wx.BoxSizer(wx.HORIZONTAL)
pAuthSizer.Add(self.stPSetLogin, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
pAuthSizer.Add(self.editProxySettingsLogin, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
@@ -134,7 +134,7 @@ class PFNetworkPref(PreferenceView):
mainSizer.Add(pAuthSizer, 0, wx.EXPAND, 5)
self.stPSAutoDetected = wx.StaticText(panel, wx.ID_ANY, "Auto-detected: ", wx.DefaultPosition, wx.DefaultSize,
0)
0)
self.stPSAutoDetected.Wrap(-1)
mainSizer.Add(self.stPSAutoDetected, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
@@ -150,10 +150,10 @@ class PFNetworkPref(PreferenceView):
proxy = self.settings.autodetect()
if proxy is not None:
addr, port = proxy
txt = addr + ":" + str(port)
addr, port = proxy
txt = addr + ":" + str(port)
else:
txt = "None"
txt = "None"
self.stPSAutoDetected.SetLabel("Auto-detected: " + txt)
self.stPSAutoDetected.Disable()

View File

@@ -289,6 +289,7 @@ class FitItem(SFItem.SFBrowserItem):
def editLostFocus(self, event):
self.RestoreEditButton()
self.Refresh()
event.Skip()
def editCheckEsc(self, event):
if event.GetKeyCode() == wx.WXK_ESCAPE:

View File

@@ -51,9 +51,13 @@ class PFBitmapFrame(wx.Frame):
pass
def OnWindowPaint(self, event):
# todo: evaluate wx.DragImage, might make this class obsolete, however might also lose our customizations
# (like the sexy fade-in animation)
rect = self.GetRect()
canvas = wx.Bitmap(rect.width, rect.height)
mdc = wx.AutoBufferedPaintDC(self)
# todo: convert to context manager after updating to wxPython >v4.0.1 (4.0.1 has a bug, see #1421)
# See #1418 for discussion
mdc = wx.BufferedPaintDC(self)
mdc.SelectObject(canvas)
mdc.DrawBitmap(self.bitmap, 0, 0)
mdc.SetPen(wx.Pen("#000000", width=1))

View File

@@ -72,6 +72,10 @@ class Miscellanea(ViewColumn):
if itemGroup == "Ship Modifiers":
return "", None
elif itemGroup == "Booster":
stuff.getModifiedItemAttr("boosterDuration")
text = "{0} min".format(formatAmount(stuff.getModifiedItemAttr("boosterDuration") / 1000 / 60, 3, 0, 3))
return text, "Booster Duration"
elif itemGroup in ("Energy Weapon", "Hybrid Weapon", "Projectile Weapon", "Combat Drone", "Fighter Drone"):
trackingSpeed = stuff.getModifiedItemAttr("trackingSpeed")
if not trackingSpeed:

View File

@@ -69,11 +69,12 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
pyfalog.critical(e)
if count < 0:
startup = getattr(event, "startup", False) # see OpenFitsThread in gui.mainFrame
from_import = getattr(event, "from_import", False) # always open imported into a new tab
sFit = Fit.getInstance()
openFitInNew = sFit.serviceFittingOptions["openFitInNew"]
mstate = wx.GetMouseState()
if (not openFitInNew and mstate.CmdDown()) or startup or (openFitInNew and not mstate.CmdDown()):
if from_import or (not openFitInNew and mstate.CmdDown()) or startup or (openFitInNew and not mstate.CmdDown()):
self.multiSwitch.AddPage()
view = self.multiSwitch.GetSelectedPage()
@@ -286,6 +287,7 @@ class FittingView(d.Display):
If fit is removed and active, the page is deleted.
We also refresh the fit of the new current page in case
delete fit caused change in stats (projected)
todo: move this to the notebook, not the page. We don't want the page being responsible for deleting itself
"""
print('_+_+_+_+_+_ Fit Removed: {} {} activeFitID: {}, eventFitID: {}'.format(repr(self), str(bool(self)), self.activeFitID, event.fitID))
pyfalog.debug("FittingView::fitRemoved")
@@ -692,28 +694,26 @@ class FittingView(d.Display):
# pyfalog.critical(e)
def OnShow(self, event):
pass
# if event.Show():
# try:
# self.MakeSnapshot()
# except Exception as e:
# pyfalog.critical("Failed to make snapshot")
# pyfalog.critical(e)
# event.Skip()
if self and not self.IsShown():
try:
self.MakeSnapshot()
except Exception as e:
pyfalog.critical("Failed to make snapshot")
pyfalog.critical(e)
event.Skip()
def Snapshot(self):
return self.FVsnapshot
# noinspection PyPropertyAccess
def MakeSnapshot(self, maxColumns=1337):
if self.FVsnapshot:
del self.FVsnapshot
tbmp = wx.Bitmap(16, 16)
tdc = wx.MemoryDC()
tdc.SelectObject(tbmp)
font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
tdc.SetFont(font)
columnsWidths = []
@@ -726,6 +726,7 @@ class FittingView(d.Display):
except Exception as e:
pyfalog.critical("Failed to get fit")
pyfalog.critical(e)
return
if fit is None:
return

View File

@@ -30,7 +30,7 @@ from gui.bitmap_loader import BitmapLoader
from gui.contextMenu import ContextMenu
import gui.globalEvents as GE
from gui.builtinViews.implantEditor import BaseImplantEditorView
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator, TextEntryValidatedDialog
from service.fit import Fit
from service.character import Character
from service.network import AuthenticationError, TimeoutError
@@ -42,9 +42,21 @@ from wx.lib.agw.floatspin import FloatSpin
from gui.utils.clipboard import toClipboard, fromClipboard
import roman
import re
pyfalog = Logger(__name__)
def arabicOrRomanToInt(s):
m = re.match(r'\d+$', s)
if m:
i = int(s)
else:
i = roman.fromRoman(s)
return i
class CharacterTextValidor(BaseValidator):
def __init__(self):
BaseValidator.__init__(self)
@@ -53,14 +65,14 @@ class CharacterTextValidor(BaseValidator):
return CharacterTextValidor()
def Validate(self, win):
entityEditor = win.parent
textCtrl = self.GetWindow()
text = textCtrl.GetValue().strip()
sChar = Character.getInstance()
try:
if len(text) == 0:
raise ValueError("You must supply a name for the Character!")
elif text in [x.name for x in entityEditor.choices]:
elif text in [x.name for x in sChar.getCharacterList()]:
raise ValueError("Character name already in use, please choose another.")
return True
@@ -230,8 +242,8 @@ class CharacterEditor(wx.Frame):
def saveCharAs(self, event):
char = self.entityEditor.getActiveEntity()
dlg = SaveCharacterAs(self, char.ID)
dlg.ShowModal()
self.SaveCharacterAs(self, char.ID)
wx.PostEvent(self, GE.CharListUpdated())
def revertChar(self, event):
sChr = Character.getInstance()
@@ -273,6 +285,22 @@ class CharacterEditor(wx.Frame):
wx.Frame.Destroy(self)
@staticmethod
def SaveCharacterAs(parent, charID):
sChar = Character.getInstance()
name = sChar.getCharName(charID)
dlg = TextEntryValidatedDialog(parent, CharacterTextValidor,
"Enter a name for your new Character:",
"Save Character As...")
dlg.SetValue("{} Copy".format(name))
dlg.txtctrl.SetInsertionPointEnd()
dlg.CenterOnParent()
if dlg.ShowModal() == wx.ID_OK:
sChar = Character.getInstance()
return sChar.saveCharacterAs(charID, dlg.txtctrl.GetValue().strip())
class SkillTreeView(wx.Panel):
def __init__(self, parent):
@@ -319,8 +347,8 @@ class SkillTreeView(wx.Panel):
self.imageList = wx.ImageList(16, 16)
tree.SetImageList(self.imageList)
self.skillBookImageId = self.imageList.Add(BitmapLoader.getBitmap("skill_small", "gui"))
self.skillBookDirtyImageId = self.imageList.Add(BitmapLoader.getBitmap("skill_small_red", "gui"))
self.skillBookImageId = self.imageList.Add(wx.Icon(BitmapLoader.getBitmap("skill_small", "gui")))
self.skillBookDirtyImageId = self.imageList.Add(wx.Icon(BitmapLoader.getBitmap("skill_small_red", "gui")))
tree.AppendColumn("Skill")
tree.AppendColumn("Level")
@@ -414,7 +442,8 @@ class SkillTreeView(wx.Panel):
lines = text.splitlines()
for l in lines:
skill, level = l.strip()[:-1].strip(), int(l.strip()[-1])
s = l.strip()
skill, level = s.rsplit(None, 1)[0], arabicOrRomanToInt(s.rsplit(None, 1)[1])
skill = char.getSkill(skill)
if skill:
skill.setLevel(level, ignoreRestrict=True)
@@ -868,36 +897,6 @@ class APIView(wx.Panel):
self.stStatus.SetLabel("Unable to retrieve {}\'s skills. Error message:\n{}".format(charName, exc_obj))
class SaveCharacterAs(wx.Dialog):
def __init__(self, parent, charID):
wx.Dialog.__init__(self, parent, title="Save Character As...", size=wx.Size(300, 60))
self.charID = charID
self.parent = parent
sChar = Character.getInstance()
name = sChar.getCharName(charID)
bSizer1 = wx.BoxSizer(wx.HORIZONTAL)
self.input = wx.TextCtrl(self, wx.ID_ANY, name, style=wx.TE_PROCESS_ENTER)
bSizer1.Add(self.input, 1, wx.ALL, 5)
self.input.Bind(wx.EVT_TEXT_ENTER, self.change)
self.button = wx.Button(self, wx.ID_OK, "Save")
bSizer1.Add(self.button, 0, wx.ALL, 5)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
self.button.Bind(wx.EVT_BUTTON, self.change)
def change(self, event):
sChar = Character.getInstance()
sChar.saveCharacterAs(self.charID, self.input.GetLineText(0))
wx.PostEvent(self.parent, GE.CharListUpdated())
event.Skip()
self.Close()
class SecStatusDialog(wx.Dialog):
def __init__(self, parent, sec):

View File

@@ -97,7 +97,7 @@ class CharacterSelection(wx.Panel):
grantItem = menu.Append(wx.ID_ANY, "Grant Missing Skills")
self.Bind(wx.EVT_MENU, self.grantMissingSkills, grantItem)
exportItem = menu.Append(wx.ID_ANY, "Export Missing Skills")
exportItem = menu.Append(wx.ID_ANY, "Copy Missing Skills")
self.Bind(wx.EVT_MENU, self.exportSkills, exportItem)
self.PopupMenu(menu, pos)

View File

View File

@@ -19,7 +19,7 @@ import wx.lib.newevent
from gui.bitmap_loader import BitmapLoader
from gui.utils import draw
from gui.utils import color as color_utils
from service.fit import Fit
_PageChanging, EVT_NOTEBOOK_PAGE_CHANGING = wx.lib.newevent.NewEvent()
_PageChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent()
@@ -1057,6 +1057,10 @@ class _TabsContainer(wx.Panel):
Checks to see if we have a tab preview and sets up the timer for it
to display
"""
sFit = Fit.getInstance()
if not sFit.serviceFittingOptions["showTooltip"] or False:
return
if self.preview_timer:
if self.preview_timer.IsRunning():
if self.preview_wnd:
@@ -1286,6 +1290,7 @@ class _TabsContainer(wx.Panel):
if not self.preview_tab.GetSelected():
page = self.Parent.GetPage(self.GetTabIndex(self.preview_tab))
if page.Snapshot():
self.preview_wnd = PFNotebookPagePreview(
self,
(mposx + 3, mposy + 3),
@@ -1373,7 +1378,7 @@ class PFNotebookPagePreview(wx.Frame):
def OnWindowPaint(self, event):
rect = self.GetRect()
canvas = wx.Bitmap(rect.width, rect.height)
mdc = wx.AudoBufferedPaintDC(self)
mdc = wx.BufferedPaintDC(self)
mdc.SelectObject(canvas)
color = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
mdc.SetBackground(wx.Brush(color))

View File

@@ -170,8 +170,8 @@ class GraphFrame(wx.Frame):
self.AppendFitToList(fitID)
def close(self, event):
self.fitList.fitList.Unbind(wx.EVT_LEFT_DCLICK)
self.mainFrame.Unbind(GE.FIT_CHANGED)
self.fitList.fitList.Unbind(wx.EVT_LEFT_DCLICK, handler=self.removeItem)
self.mainFrame.Unbind(GE.FIT_CHANGED, handler=self.draw)
event.Skip()
def getView(self):
@@ -229,6 +229,15 @@ class GraphFrame(wx.Frame):
def draw(self, event=None):
global mpl_version
if event is not None:
event.Skip()
# todo: FIX THIS, see #1430. draw() is not being unbound properly when the window closes, this is an easy fix,
# but not a proper solution
if not self:
pyfalog.warning("GraphFrame handled event, however GraphFrame no longer exists. Ignoring event")
return
values = self.getValues()
view = self.getView()
self.subplot.clear()
@@ -247,7 +256,7 @@ class GraphFrame(wx.Frame):
self.subplot.plot(x, y)
legend.append(fit.name)
except:
except Exception as ex:
pyfalog.warning("Invalid values in '{0}'", fit.name)
self.SetStatusText("Invalid values in '%s'" % fit.name)
self.canvas.draw()
@@ -299,8 +308,6 @@ class GraphFrame(wx.Frame):
self.canvas.draw()
self.SetStatusText("")
if event is not None:
event.Skip()
def onFieldChanged(self, event):
self.draw()

View File

@@ -49,7 +49,7 @@ from gui.multiSwitch import MultiSwitch
from gui.statsPane import StatsPane
from gui.shipBrowser import ShipBrowser
from gui.builtinShipBrowser.events import FitSelected, ImportSelected, Stage3Selected
from gui.characterEditor import CharacterEditor, SaveCharacterAs
from gui.characterEditor import CharacterEditor
from gui.characterSelection import CharacterSelection
from gui.patternEditor import DmgPatternEditorDlg
from gui.resistsEditor import ResistsEditorDlg
@@ -358,7 +358,7 @@ class MainFrame(wx.Frame):
def ShowAboutBox(self, evt):
info = wx.adv.AboutDialogInfo()
info.Name = "pyfa"
info.Version = config.getGitVersion() # gui.aboutData.versionString
info.Version = config.getVersion() # gui.aboutData.versionString
#
# try:
# import matplotlib
@@ -683,8 +683,8 @@ class MainFrame(wx.Frame):
def saveCharAs(self, event):
charID = self.charSelection.getActiveCharacter()
dlg = SaveCharacterAs(self, charID)
dlg.ShowModal()
CharacterEditor.SaveCharacterAs(self, charID)
wx.PostEvent(self, GE.CharListUpdated())
def revertChar(self, event):
sChr = Character.getInstance()
@@ -960,7 +960,7 @@ class MainFrame(wx.Frame):
if len(fits) > 0:
if len(fits) == 1:
fit = fits[0]
wx.PostEvent(self, FitSelected(fitID=fit.ID))
wx.PostEvent(self, FitSelected(fitID=fit.ID, from_import=True))
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=fit.shipID, back=True))
else:
fits.sort(key=lambda _fit: (_fit.ship.item.name, _fit.name))

View File

@@ -38,7 +38,7 @@ class PreferenceDialog(wx.Dialog):
# self.listview.SetSize((500, -1))
self.imageList = wx.ImageList(32, 32)
self.listbook.SetImageList(self.imageList)
self.listbook.AssignImageList(self.imageList)
mainSizer.Add(self.listbook, 1, wx.EXPAND | wx.TOP | wx.BOTTOM | wx.LEFT, 5)
@@ -55,17 +55,17 @@ class PreferenceDialog(wx.Dialog):
self.Centre(wx.BOTH)
for prefView in PreferenceView.views:
page = wx.Panel(self.listbook)
page = wx.ScrolledWindow(self.listbook)
page.SetScrollbars(1, 1, 20, 20)
bmp = prefView.getImage()
if bmp:
imgID = self.imageList.Add(bmp)
else:
imgID = -1
prefView.populatePanel(page)
self.listbook.AddPage(page, prefView.title, imageId=imgID)
# Set the height based on a condition. Can all the panels fit in the current height?
# If not, use the .GetBestVirtualSize() to ensure that all content is available.
minHeight = 550
bestFit = self.GetBestVirtualSize()
if minHeight > bestFit[1]:

View File

@@ -102,9 +102,11 @@ class AttributeEditor(wx.Frame):
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
with open(path, 'rb') as csvfile:
with open(path, 'r') as csvfile:
spamreader = csv.reader(csvfile)
for row in spamreader:
if len(row) == 0: # csvwriter seems to added blank lines to the end sometimes
continue
itemID, attrID, value = row
item = getItem(int(itemID))
attr = getAttributeInfo(int(attrID))
@@ -123,7 +125,7 @@ class AttributeEditor(wx.Frame):
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
with open(path, 'wb') as csvfile:
with open(path, 'w', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
for item in items:
for key, override in item.overrides.items():

View File

@@ -18,6 +18,7 @@ import wx
from gui.utils import color as color_utils
from gui.utils import draw, anim_effects
from service.fit import Fit
class PyGauge(wx.Window):
@@ -129,11 +130,16 @@ class PyGauge(wx.Window):
return self._max_range
def Animate(self):
if not self._timer:
self._timer = wx.Timer(self, self._timer_id)
sFit = Fit.getInstance()
if sFit.serviceFittingOptions["enableGaugeAnimation"]:
if not self._timer:
self._timer = wx.Timer(self, self._timer_id)
self._anim_step = 0
self._timer.Start(self._period)
self._anim_step = 0
self._timer.Start(self._period)
else:
self._anim_value = self._percentage
self.Refresh()
def SetRange(self, range, reinit=False, animate=True):
"""

View File

@@ -62,6 +62,7 @@ class UpdateDialog(wx.Dialog):
self.browser.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self.OnNewWindow)
link_patterns = [
(re.compile("([0-9a-f]{6,40})", re.I), r"https://github.com/pyfa-org/Pyfa/commit/\1"),
(re.compile("#(\d+)", re.I), r"https://github.com/pyfa-org/Pyfa/issues/\1"),
(re.compile("@(\w+)", re.I), r"https://github.com/\1")
]

View File

@@ -63,12 +63,14 @@ class exportHtmlThread(threading.Thread):
HTML = self.generateFullHTML(sMkt, sFit, dnaUrl)
try:
FILE = open(settings.getPath(), "w")
FILE.write(HTML.encode('utf-8'))
FILE = open(settings.getPath(), "w", encoding='utf-8')
FILE.write(HTML)
FILE.close()
except IOError:
except IOError as ex:
print(("Failed to write to " + settings.getPath()))
pass
except Exception as ex:
pass
if self.callback:
wx.CallAfter(self.callback, -1)
@@ -84,6 +86,7 @@ class exportHtmlThread(threading.Thread):
<head>
<title>Pyfa Fittings</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>