Merge branch 'development' into PreferencesPaneV2

This commit is contained in:
Ebag333
2017-02-26 08:53:56 -08:00
committed by GitHub
103 changed files with 6777 additions and 530 deletions

View File

@@ -20,13 +20,15 @@
import cStringIO
import os.path
import zipfile
from config import parsePath
# noinspection PyPackageRequirements
import wx
import config
from logbook import Logger
logging = Logger(__name__)
try:
from collections import OrderedDict
except ImportError:
@@ -35,8 +37,10 @@ except ImportError:
class BitmapLoader(object):
try:
archive = zipfile.ZipFile(config.getPyfaPath('imgs.zip'), 'r')
archive = zipfile.ZipFile(os.path.join(config.pyfaPath, 'imgs.zip'), 'r')
logging.info("Using zipped image files.")
except IOError:
logging.info("Using local image files.")
archive = None
cachedBitmaps = OrderedDict()
@@ -78,7 +82,7 @@ class BitmapLoader(object):
filename = "{0}.png".format(name)
if cls.archive:
path = parsePath(location, filename)
path = os.path.join(location, filename)
if os.sep != "/" and os.sep in path:
path = path.replace(os.sep, "/")
@@ -89,7 +93,7 @@ class BitmapLoader(object):
except KeyError:
print("Missing icon file from zip: {0}".format(path))
else:
path = config.getPyfaPath('imgs' + os.sep + location + os.sep + filename)
path = os.path.join(config.pyfaPath, 'imgs' + os.sep + location + os.sep + filename)
if os.path.exists(path):
return wx.Image(path)

View File

@@ -57,6 +57,7 @@ class AmountChanger(wx.Dialog):
def change(self, event):
if self.input.GetLineText(0).strip() == '':
event.Skip()
self.Close()
return
sFit = Fit.getInstance()
@@ -73,6 +74,7 @@ class AmountChanger(wx.Dialog):
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
event.Skip()
self.Close()
# checks to make sure it's valid number
@staticmethod

View File

@@ -33,7 +33,7 @@ from gui.builtinViewColumns.state import State
from gui.bitmapLoader import BitmapLoader
import gui.builtinViews.emptyView
from gui.utils.exportHtml import exportHtml
from logging import getLogger
from logbook import Logger
from gui.chromeTabs import EVT_NOTEBOOK_PAGE_CHANGED
from service.fit import Fit
@@ -41,7 +41,7 @@ from service.market import Market
import gui.globalEvents as GE
logger = getLogger(__name__)
pyfalog = Logger(__name__)
# Tab spawning handler
@@ -61,8 +61,9 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
self.multiSwitch.SetSelection(index)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=event.fitID))
break
except:
pass
except Exception as e:
pyfalog.critical("Caught exception in fitSelected")
pyfalog.critical(e)
if count < 0:
startup = getattr(event, "startup", False) # see OpenFitsThread in gui.mainFrame
sFit = Fit.getInstance()
@@ -278,6 +279,7 @@ class FittingView(d.Display):
sFit.refreshFit(self.getActiveFit())
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
except wx._core.PyDeadObjectError:
pyfalog.warning("Caught dead object")
pass
event.Skip()
@@ -414,7 +416,7 @@ class FittingView(d.Display):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
else:
logger.error("Missing module position for: %s", str(getattr(mod2, "ID", "Unknown")))
pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown")))
def generateMods(self):
"""
@@ -483,7 +485,7 @@ class FittingView(d.Display):
self.Show(self.activeFitID is not None and self.activeFitID == event.fitID)
except wx._core.PyDeadObjectError:
pass
pyfalog.warning("Caught dead object")
finally:
event.Skip()
@@ -636,15 +638,17 @@ class FittingView(d.Display):
if 'wxMac' in wx.PlatformInfo:
try:
self.MakeSnapshot()
except:
pass
except Exception as e:
pyfalog.critical("Failed to make snapshot")
pyfalog.critical(e)
def OnShow(self, event):
if event.GetShow():
try:
self.MakeSnapshot()
except:
pass
except Exception as e:
pyfalog.critical("Failed to make snapshot")
pyfalog.critical(e)
event.Skip()
def Snapshot(self):
@@ -669,8 +673,9 @@ class FittingView(d.Display):
sFit = Fit.getInstance()
try:
fit = sFit.getFit(self.activeFitID)
except:
return
except Exception as e:
pyfalog.critical("Failed to get fit")
pyfalog.critical(e)
if fit is None:
return

View File

@@ -33,6 +33,8 @@ from service.fit import Fit
from service.character import Character
from service.network import AuthenticationError, TimeoutError
from service.market import Market
from logbook import Logger
pyfalog = Logger(__name__)
class CharacterTextValidor(BaseValidator):
@@ -55,6 +57,7 @@ class CharacterTextValidor(BaseValidator):
return True
except ValueError, e:
pyfalog.error(e)
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -628,11 +631,16 @@ class APIView(wx.Panel):
try:
activeChar = self.charEditor.entityEditor.getActiveEntity()
list = sChar.apiCharList(activeChar.ID, self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
except AuthenticationError:
self.stStatus.SetLabel("Authentication failure. Please check keyID and vCode combination.")
except TimeoutError:
self.stStatus.SetLabel("Request timed out. Please check network connectivity and/or proxy settings.")
except AuthenticationError, e:
msg = "Authentication failure. Please check keyID and vCode combination."
pyfalog.info(msg)
self.stStatus.SetLabel(msg)
except TimeoutError, e:
msg = "Request timed out. Please check network connectivity and/or proxy settings."
pyfalog.info(msg)
self.stStatus.SetLabel(msg)
except Exception, e:
pyfalog.error(e)
self.stStatus.SetLabel("Error:\n%s" % e.message)
else:
self.charChoice.Clear()
@@ -655,6 +663,7 @@ class APIView(wx.Panel):
sChar.apiFetch(activeChar.ID, charName)
self.stStatus.SetLabel("Successfully fetched %s\'s skills from EVE API." % charName)
except Exception, e:
pyfalog.error("Unable to retrieve {0}\'s skills. Error message:\n{1}", charName, e)
self.stStatus.SetLabel("Unable to retrieve %s\'s skills. Error message:\n%s" % (charName, e))

View File

@@ -24,6 +24,8 @@ import gui.globalEvents as GE
import gui.mainFrame
from service.character import Character
from service.fit import Fit
from logbook import Logger
pyfalog = Logger(__name__)
class CharacterSelection(wx.Panel):
@@ -112,9 +114,10 @@ class CharacterSelection(wx.Panel):
if charName:
try:
sChar.apiFetch(self.getActiveCharacter(), charName)
except:
except Exception as e:
# can we do a popup, notifying user of API error?
pass
pyfalog.error("API fetch error")
pyfalog.error(e)
self.refreshCharacterList()
def charChanged(self, event):

View File

@@ -25,9 +25,11 @@ import gui.utils.colorUtils as colorUtils
import gui.utils.drawUtils as drawUtils
import gui.utils.fonts as fonts
from gui.bitmapLoader import BitmapLoader
from logbook import Logger
from service.fit import Fit
pyfalog = Logger(__name__)
_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()
@@ -1093,8 +1095,9 @@ class PFTabsContainer(wx.Panel):
self.previewTab = tab
self.previewTimer.Start(500, True)
break
except:
pass
except Exception as e:
pyfalog.critical("Exception caught in CheckTabPreview.")
pyfalog.critical(e)
def CheckAddHighlighted(self, x, y):
"""

View File

@@ -19,9 +19,9 @@
# noinspection PyPackageRequirements
import wx
import logging
from logbook import Logger
logger = logging.getLogger(__name__)
pyfalog = Logger(__name__)
class ContextMenu(object):
@@ -121,7 +121,7 @@ class ContextMenu(object):
debug_end = len(cls._ids)
if debug_end - debug_start:
logger.debug("%d new IDs created for this menu" % (debug_end - debug_start))
pyfalog.debug("{0} new IDs created for this menu", (debug_end - debug_start))
return rootMenu if empty is False else None
@@ -180,27 +180,27 @@ class ContextMenu(object):
# noinspection PyUnresolvedReferences
from gui.builtinContextMenus import ( # noqa: E402,F401
ammoPattern,
amount,
cargo,
changeAffectingSkills,
damagePattern,
droneRemoveStack,
droneSplit,
factorReload,
fighterAbilities,
implantSets,
itemRemove,
itemStats,
marketJump,
metaSwap,
moduleAmmoPicker,
moduleGlobalAmmoPicker,
openFit,
priceClear,
# moduleGlobalAmmoPicker,
moduleAmmoPicker,
itemStats,
damagePattern,
marketJump,
droneSplit,
itemRemove,
droneRemoveStack,
ammoPattern,
project,
factorReload,
whProjector,
cargo,
shipJump,
changeAffectingSkills,
tacticalMode,
targetResists,
whProjector
priceClear,
amount,
metaSwap,
implantSets,
fighterAbilities,
)

View File

@@ -14,6 +14,9 @@ from eos.db import getItem
from gui.display import Display
import gui.globalEvents as GE
from logbook import Logger
pyfalog = Logger(__name__)
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
from service.crest import Crest, CrestModes
@@ -147,7 +150,9 @@ class CrestFittings(wx.Frame):
self.fitTree.populateSkillTree(fittings)
del waitDialog
except requests.exceptions.ConnectionError:
self.statusbar.SetStatusText("Connection error, please check your internet connection")
msg = "Connection error, please check your internet connection"
pyfalog.error(msg)
self.statusbar.SetStatusText(msg)
def importFitting(self, event):
selection = self.fitView.fitSelection
@@ -173,7 +178,9 @@ class CrestFittings(wx.Frame):
try:
sCrest.delFitting(self.getActiveCharacter(), data['fittingID'])
except requests.exceptions.ConnectionError:
self.statusbar.SetStatusText("Connection error, please check your internet connection")
msg = "Connection error, please check your internet connection"
pyfalog.error(msg)
self.statusbar.SetStatusText(msg)
class ExportToEve(wx.Frame):
@@ -281,9 +288,12 @@ class ExportToEve(wx.Frame):
text = json.loads(res.text)
self.statusbar.SetStatusText(text['message'], 1)
except ValueError:
pyfalog.warning("Value error on loading JSON.")
self.statusbar.SetStatusText("", 1)
except requests.exceptions.ConnectionError:
self.statusbar.SetStatusText("Connection error, please check your internet connection", 1)
msg = "Connection error, please check your internet connection"
pyfalog.error(msg)
self.statusbar.SetStatusText(msg)
class CrestMgmt(wx.Dialog):
@@ -405,8 +415,9 @@ class FittingsTreeView(wx.Panel):
cargo = Cargo(getItem(item['type']['id']))
cargo.amount = item['quantity']
list.append(cargo)
except:
pass
except Exception as e:
pyfalog.critical("Exception caught in displayFit")
pyfalog.critical(e)
self.parent.fitView.fitSelection = selection
self.parent.fitView.update(list)

View File

@@ -147,6 +147,7 @@ class DroneView(Display):
def _merge(self, src, dst):
sFit = Fit.getInstance()
fitID = self.mainFrame.getActiveFit()
if sFit.mergeDrones(fitID, self.drones[src], self.drones[dst]):
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))

94
gui/errorDialog.py Normal file
View File

@@ -0,0 +1,94 @@
# ===============================================================================
# Copyright (C) 2010 Diego Duclos
#
# 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 <http://www.gnu.org/licenses/>.
# ===============================================================================
import wx
import sys
import gui.utils.fonts as fonts
import config
class ErrorFrame(wx.Frame):
def __init__(self, exception, tb):
wx.Frame.__init__(self, None, id=wx.ID_ANY, title="pyfa error", pos=wx.DefaultPosition, size=wx.Size(500, 400),
style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER | wx.STAY_ON_TOP)
desc = "pyfa has experienced an unexpected error. Below is the " \
"Traceback that contains crucial information about how this " \
"error was triggered. Please contact the developers with " \
"the information provided through the EVE Online forums " \
"or file a GitHub issue."
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
if 'wxMSW' in wx.PlatformInfo:
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
mainSizer = wx.BoxSizer(wx.VERTICAL)
headSizer = wx.BoxSizer(wx.HORIZONTAL)
self.headingText = wx.StaticText(self, wx.ID_ANY, "Error!", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE)
self.headingText.SetFont(wx.Font(14, 74, 90, 92, False))
headSizer.Add(self.headingText, 1, wx.ALL, 5)
mainSizer.Add(headSizer, 0, wx.EXPAND, 5)
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.ALL, 5)
descSizer = wx.BoxSizer(wx.HORIZONTAL)
self.descText = wx.TextCtrl(self, wx.ID_ANY, desc, wx.DefaultPosition, wx.DefaultSize,
wx.TE_AUTO_URL | wx.TE_MULTILINE | wx.TE_READONLY | wx.BORDER_NONE | wx.TRANSPARENT_WINDOW)
self.descText.SetFont(wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.NORMAL))
descSizer.Add(self.descText, 1, wx.ALL, 5)
mainSizer.Add(descSizer, 1, wx.EXPAND, 5)
self.eveForums = wx.HyperlinkCtrl(self, wx.ID_ANY, "EVE Forums Thread", "https://forums.eveonline.com/default.aspx?g=posts&t=466425",
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
mainSizer.Add(self.eveForums, 0, wx.ALL, 2)
self.eveForums = wx.HyperlinkCtrl(self, wx.ID_ANY, "Github Issues", "https://github.com/pyfa-org/Pyfa/issues",
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
mainSizer.Add(self.eveForums, 0, wx.ALL, 2)
# mainSizer.AddSpacer((0, 5), 0, wx.EXPAND, 5)
self.errorTextCtrl = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2 | wx.TE_DONTWRAP)
self.errorTextCtrl.SetFont(wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL))
mainSizer.Add(self.errorTextCtrl, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
self.errorTextCtrl.AppendText("pyfa root: ")
self.errorTextCtrl.AppendText(config.pyfaPath or "Unknown")
self.errorTextCtrl.AppendText('\n')
self.errorTextCtrl.AppendText("save path: ")
self.errorTextCtrl.AppendText(config.savePath or "Unknown")
self.errorTextCtrl.AppendText('\n')
self.errorTextCtrl.AppendText("fs encoding: ")
self.errorTextCtrl.AppendText(sys.getfilesystemencoding())
self.errorTextCtrl.AppendText('\n\n')
self.errorTextCtrl.AppendText(tb)
self.SetSizer(mainSizer)
mainSizer.Layout()
self.Layout()
self.Centre(wx.BOTH)
self.Show()

View File

@@ -18,8 +18,7 @@
# =============================================================================
import os
import logging
import imp
from logbook import Logger
# noinspection PyPackageRequirements
import wx
@@ -30,19 +29,31 @@ import gui.mainFrame
import gui.globalEvents as GE
from gui.graph import Graph
from gui.bitmapLoader import BitmapLoader
from config import parsePath
# Don't actually import the thing, since it takes for fucking ever
pyfalog = Logger(__name__)
try:
imp.find_module('matplotlib')
import matplotlib as mpl
mpl_version = int(mpl.__version__[0])
if mpl_version >= 2:
mpl.use('wxagg')
mplImported = True
else:
mplImported = False
from matplotlib.patches import Patch
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
from matplotlib.figure import Figure
graphFrame_enabled = True
mplImported = True
except ImportError:
Patch = mpl = Canvas = Figure = None
graphFrame_enabled = False
mplImported = False
logger = logging.getLogger(__name__)
pyfalog = Logger(__name__)
class GraphFrame(wx.Frame):
@@ -73,7 +84,7 @@ class GraphFrame(wx.Frame):
self.legendFix = False
if not graphFrame_enabled:
logger.info("Problems importing matplotlib; continuing without graphs")
pyfalog.info("Problems importing matplotlib; continuing without graphs")
return
try:
@@ -81,7 +92,7 @@ class GraphFrame(wx.Frame):
except:
cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))
cache_file = parsePath(cache_dir, 'fontList.cache')
cache_file = os.path.join(cache_dir, 'fontList.cache')
if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file):
# remove matplotlib font cache, see #234
@@ -244,6 +255,7 @@ class GraphFrame(wx.Frame):
self.subplot.plot(x, y)
legend.append(fit.name)
except:
pyfalog.warning("Invalid values in '{0}'", fit.name)
self.SetStatusText("Invalid values in '%s'" % fit.name)
self.canvas.draw()
return
@@ -282,7 +294,7 @@ class GraphFrame(wx.Frame):
selected_color = legend_colors[i]
except:
selected_color = None
legend2.append(self.Patch(color=selected_color, label=i_name), )
legend2.append(Patch(color=selected_color, label=i_name), )
if len(legend2) > 0:
leg = self.subplot.legend(handles=legend2)

View File

@@ -62,13 +62,13 @@ class ItemStatsDialog(wx.Dialog):
):
wx.Dialog.__init__(
self,
gui.mainFrame.MainFrame.getInstance(),
wx.ID_ANY,
title="Item stats",
pos=pos,
size=size,
style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU
self,
gui.mainFrame.MainFrame.getInstance(),
wx.ID_ANY,
title="Item stats",
pos=pos,
size=size,
style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU
)
empty = getattr(victim, "isEmpty", False)
@@ -197,6 +197,10 @@ class ItemStatsContainer(wx.Panel):
self.affectedby = ItemAffectedBy(self.nbContainer, stuff, item)
self.nbContainer.AddPage(self.affectedby, "Affected by")
if config.debug:
self.properties = ItemProperties(self.nbContainer, stuff, item, context)
self.nbContainer.AddPage(self.properties, "Properties")
self.nbContainer.Bind(wx.EVT_LEFT_DOWN, self.mouseHit)
self.SetSizer(mainSizer)
self.Layout()
@@ -256,7 +260,7 @@ class ItemDescription(wx.Panel):
# Strip URLs
desc = re.sub("<( *)a(.*?)>(?P<inside>.*?)<( *)/( *)a( *)>", "\g<inside>", desc)
desc = "<body bgcolor='" + bgcolor.GetAsString(wx.C2S_HTML_SYNTAX) + "' text='" + fgcolor.GetAsString(
wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
self.description.SetPage(desc)
@@ -358,13 +362,13 @@ class ItemParams(wx.Panel):
writer = csv.writer(exportFile, delimiter=',')
writer.writerow(
[
"ID",
"Internal Name",
"Friendly Name",
"Modified Value",
"Base Value",
]
[
"ID",
"Internal Name",
"Friendly Name",
"Modified Value",
"Base Value",
]
)
for attribute in self.attrValues:
@@ -395,13 +399,13 @@ class ItemParams(wx.Panel):
attribute_modified_value = self.attrValues[attribute]
writer.writerow(
[
attribute_id,
attribute_name,
attribute_displayname,
attribute_modified_value,
attribute_value,
]
[
attribute_id,
attribute_name,
attribute_displayname,
attribute_modified_value,
attribute_value,
]
)
def PopulateList(self):
@@ -496,17 +500,19 @@ class ItemParams(wx.Panel):
attribute = Attribute.getInstance().getAttributeInfo(value)
return "%s (%d)" % (attribute.name.capitalize(), value)
trans = {"Inverse Absolute Percent": (lambda: (1 - value) * 100, unitName),
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent": (
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume": (lambda: value, u"m\u00B3"),
"Sizeclass": (lambda: value, ""),
"Absolute Percent": (lambda: (value * 100), unitName),
"Milliseconds": (lambda: value / 1000.0, unitName),
"typeID": (itemIDCallback, ""),
"groupID": (groupIDCallback, ""),
"attributeID": (attributeIDCallback, "")}
trans = {
"Inverse Absolute Percent" : (lambda: (1 - value) * 100, unitName),
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent" : (
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume" : (lambda: value, u"m\u00B3"),
"Sizeclass" : (lambda: value, ""),
"Absolute Percent" : (lambda: (value * 100), unitName),
"Milliseconds" : (lambda: value / 1000.0, unitName),
"typeID" : (itemIDCallback, ""),
"groupID" : (groupIDCallback, ""),
"attributeID" : (attributeIDCallback, "")
}
override = trans.get(unitDisplayName)
if override is not None:
@@ -689,17 +695,18 @@ class ItemCompare(wx.Panel):
attribute = Attribute.getInstance().getAttributeInfo(value)
return "%s (%d)" % (attribute.name.capitalize(), value)
trans = {"Inverse Absolute Percent": (lambda: (1 - value) * 100, unitName),
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent": (
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume": (lambda: value, u"m\u00B3"),
"Sizeclass": (lambda: value, ""),
"Absolute Percent": (lambda: (value * 100), unitName),
"Milliseconds": (lambda: value / 1000.0, unitName),
"typeID": (itemIDCallback, ""),
"groupID": (groupIDCallback, ""),
"attributeID": (attributeIDCallback, "")}
trans = {
"Inverse Absolute Percent" : (lambda: (1 - value) * 100, unitName),
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent" : (lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume" : (lambda: value, u"m\u00B3"),
"Sizeclass" : (lambda: value, ""),
"Absolute Percent" : (lambda: (value * 100), unitName),
"Milliseconds" : (lambda: value / 1000.0, unitName),
"typeID" : (itemIDCallback, ""),
"groupID" : (groupIDCallback, ""),
"attributeID" : (attributeIDCallback, "")
}
override = trans.get(unitDisplayName)
if override is not None:
@@ -849,7 +856,7 @@ class ItemEffects(wx.Panel):
If effect file does not exist, create it
"""
file_ = config.getPyfaPath(os.path.join("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()
@@ -1067,7 +1074,7 @@ class ItemAffectedBy(wx.Panel):
item = afflictor.item
items[attrName].append(
(type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False)))
(type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False)))
# Make sure projected fits are on top
rootOrder = container.keys()
@@ -1295,3 +1302,97 @@ class ItemAffectedBy(wx.Panel):
treeitem = self.affectedBy.AppendItem(child, display, attrIcon)
self.affectedBy.SetPyData(treeitem, saved)
self.treeItems.append(treeitem)
class ItemProperties(wx.Panel):
def __init__(self, parent, stuff, item, context=None):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.paramList = AutoListCtrl(self, wx.ID_ANY,
style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
mainSizer.Add(self.paramList, 1, wx.ALL | wx.EXPAND, 0)
self.SetSizer(mainSizer)
self.toggleView = 1
self.stuff = stuff
self.item = item
self.attrInfo = {}
self.attrValues = {}
self._fetchValues()
self.m_staticline = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
mainSizer.Add(self.m_staticline, 0, wx.EXPAND)
bSizer = wx.BoxSizer(wx.HORIZONTAL)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, u" ", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
mainSizer.Add(bSizer, 0, wx.ALIGN_RIGHT)
self.PopulateList()
def _fetchValues(self):
if self.stuff is None:
self.attrInfo.clear()
self.attrValues.clear()
self.attrInfo.update(self.item.attributes)
self.attrValues.update(self.item.attributes)
elif self.stuff.item == self.item:
self.attrInfo.clear()
self.attrValues.clear()
self.attrInfo.update(self.stuff.item.attributes)
self.attrValues.update(self.stuff.itemModifiedAttributes)
elif self.stuff.charge == self.item:
self.attrInfo.clear()
self.attrValues.clear()
self.attrInfo.update(self.stuff.charge.attributes)
self.attrValues.update(self.stuff.chargeModifiedAttributes)
# When item for stats window no longer exists, don't change anything
else:
return
def PopulateList(self):
self.paramList.InsertColumn(0, "Attribute")
self.paramList.InsertColumn(1, "Current Value")
self.paramList.SetColumnWidth(0, 110)
self.paramList.SetColumnWidth(1, 1500)
self.paramList.setResizeColumn(0)
if self.stuff:
names = dir(self.stuff)
else:
names = dir(self.item)
names = [a for a in names if not (a.startswith('__') and a.endswith('__'))]
idNameMap = {}
idCount = 0
for name in names:
try:
if self.stuff:
attrName = name.title()
value = getattr(self.stuff, name)
else:
attrName = name.title()
value = getattr(self.item, name)
except Exception as e:
# TODO: Add logging to this.
# We couldn't get a property for some reason. Skip it for now.
print(e)
continue
index = self.paramList.InsertStringItem(sys.maxint, attrName)
# index = self.paramList.InsertImageStringItem(sys.maxint, attrName)
idNameMap[idCount] = attrName
self.paramList.SetItemData(index, idCount)
idCount += 1
valueUnit = str(value)
self.paramList.SetStringItem(index, 1, valueUnit)
self.paramList.SortItems(lambda id1, id2: cmp(idNameMap[id1], idNameMap[id2]))
self.paramList.RefreshRows()
self.totalAttrsLabel.SetLabel("%d attributes. " % idCount)
self.Layout()

View File

@@ -19,7 +19,7 @@
import sys
import os.path
import logging
from logbook import Logger
import sqlalchemy
# noinspection PyPackageRequirements
@@ -94,7 +94,7 @@ except ImportError as e:
print("Error loading Attribute Editor: %s.\nAccess to Attribute Editor is disabled." % e.message)
disableOverrideEditor = True
logger = logging.getLogger(__name__)
pyfalog = Logger(__name__)
# dummy panel(no paint no erasebk)
@@ -145,6 +145,7 @@ class MainFrame(wx.Frame):
return cls.__instance if cls.__instance is not None else MainFrame()
def __init__(self, title="pyfa"):
pyfalog.debug("Initialize MainFrame")
self.title = title
wx.Frame.__init__(self, None, wx.ID_ANY, self.title)
@@ -399,7 +400,7 @@ class MainFrame(wx.Frame):
try:
dlg.Destroy()
except PyDeadObjectError:
logger.error("Tried to destroy an object that doesn't exist in <showDamagePatternEditor>.")
pyfalog.error("Tried to destroy an object that doesn't exist in <showDamagePatternEditor>.")
def showImplantSetEditor(self, event):
ImplantSetEditorDlg(self)
@@ -427,7 +428,7 @@ class MainFrame(wx.Frame):
try:
dlg.Destroy()
except PyDeadObjectError:
logger.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
pyfalog.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
return
with open(path, "w", encoding="utf-8") as openfile:
@@ -437,7 +438,7 @@ class MainFrame(wx.Frame):
try:
dlg.Destroy()
except PyDeadObjectError:
logger.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
pyfalog.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
def showPreferenceDialog(self, event):
dlg = PreferenceDialog(self)
@@ -734,7 +735,7 @@ class MainFrame(wx.Frame):
try:
fits = Port().importFitFromBuffer(clipboard, self.getActiveFit())
except:
logger.error("Attempt to import failed:\n%s", clipboard)
pyfalog.error("Attempt to import failed:\n{0}", clipboard)
else:
self._openAfterImport(fits)
@@ -754,7 +755,7 @@ class MainFrame(wx.Frame):
try:
dlg.Destroy()
except PyDeadObjectError:
logger.error("Tried to destroy an object that doesn't exist in <exportToClipboard>.")
pyfalog.error("Tried to destroy an object that doesn't exist in <exportToClipboard>.")
def exportSkillsNeeded(self, event):
""" Exports skills needed for active fit and active character """
@@ -811,7 +812,7 @@ class MainFrame(wx.Frame):
try:
dlg.Destroy()
except PyDeadObjectError:
logger.error("Tried to destroy an object that doesn't exist in <fileImportDialog>.")
pyfalog.error("Tried to destroy an object that doesn't exist in <fileImportDialog>.")
def backupToXml(self, event):
""" Back up all fits to EVE XML file """

View File

@@ -26,6 +26,9 @@ import gui.graphFrame
import gui.globalEvents as GE
from gui.bitmapLoader import BitmapLoader
from logbook import Logger
pyfalog = Logger(__name__)
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
from service.crest import Crest
from service.crest import CrestModes
@@ -33,6 +36,7 @@ if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION
class MainMenuBar(wx.MenuBar):
def __init__(self, mainFrame):
pyfalog.debug("Initialize MainMenuBar")
self.characterEditorId = wx.NewId()
self.damagePatternEditorId = wx.NewId()
self.targetResistsEditorId = wx.NewId()
@@ -166,6 +170,7 @@ class MainMenuBar(wx.MenuBar):
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
def fitChanged(self, event):
pyfalog.debug("fitChanged triggered")
enable = event.fitID is not None
self.Enable(wx.ID_SAVEAS, enable)
self.Enable(wx.ID_COPY, enable)

View File

@@ -26,6 +26,9 @@ import gui.PFSearchBox as SBox
from gui.cachingImageList import CachingImageList
from gui.contextMenu import ContextMenu
from gui.bitmapLoader import BitmapLoader
from logbook import Logger
pyfalog = Logger(__name__)
ItemSelected, ITEM_SELECTED = wx.lib.newevent.NewEvent()
@@ -56,6 +59,7 @@ class MetaButton(wx.ToggleButton):
class MarketBrowser(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
pyfalog.debug("Initialize marketBrowser")
vbox = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(vbox)
@@ -134,6 +138,7 @@ class SearchBox(SBox.PFSearchBox):
class MarketTree(wx.TreeCtrl):
def __init__(self, parent, marketBrowser):
wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
pyfalog.debug("Initialize marketTree")
self.root = self.AddRoot("root")
self.imageList = CachingImageList(16, 16)
@@ -182,7 +187,9 @@ class MarketTree(wx.TreeCtrl):
iconId = self.addImage(sMkt.getIconByMarketGroup(childMktGrp))
try:
childId = self.AppendItem(root, childMktGrp.name, iconId, data=wx.TreeItemData(childMktGrp.ID))
except:
except Exception as e:
pyfalog.debug("Error appending item.")
pyfalog.debug(e)
continue
if sMkt.marketGroupHasTypesCheck(childMktGrp) is False:
self.AppendItem(childId, "dummy")
@@ -226,6 +233,7 @@ class ItemView(Display):
def __init__(self, parent, marketBrowser):
Display.__init__(self, parent)
pyfalog.debug("Initialize ItemView")
marketBrowser.Bind(wx.EVT_TREE_SEL_CHANGED, self.selectionMade)
self.unfilteredStore = set()
@@ -252,6 +260,7 @@ class ItemView(Display):
self.metaMap = self.makeReverseMetaMap()
# Fill up recently used modules set
pyfalog.debug("Fill up recently used modules set")
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))

View File

@@ -25,6 +25,9 @@ from wx.lib.intctrl import IntCtrl
from gui.utils.clipboard import toClipboard, fromClipboard
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
from service.damagePattern import DamagePattern, ImportError
from logbook import Logger
pyfalog = Logger(__name__)
class DmgPatternTextValidor(BaseValidator):
@@ -47,6 +50,7 @@ class DmgPatternTextValidor(BaseValidator):
return True
except ValueError as e:
pyfalog.error(e)
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -256,9 +260,13 @@ class DmgPatternEditorDlg(wx.Dialog):
sDP.importPatterns(text)
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
except ImportError as e:
pyfalog.error(e)
self.stNotice.SetLabel(str(e))
except Exception:
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
except Exception as e:
msg = "Could not import from clipboard: unknown errors"
pyfalog.warning(msg)
pyfalog.error(e)
self.stNotice.SetLabel(msg)
finally:
self.entityEditor.refreshEntityList()
else:

View File

@@ -1,5 +1,5 @@
import csv
import logging
from logbook import Logger
# noinspection PyPackageRequirements
import wx
@@ -21,7 +21,7 @@ import gui.PFSearchBox as SBox
from gui.marketBrowser import SearchBox
from gui.bitmapLoader import BitmapLoader
logger = logging.getLogger(__name__)
pyfalog = Logger(__name__)
class AttributeEditor(wx.Frame):
@@ -270,7 +270,7 @@ class AttributeGrid(wxpg.PropertyGrid):
self.itemView.updateItems()
logger.debug('%s changed to "%s"' % (p.GetName(), p.GetValueAsString()))
pyfalog.debug('{0} changed to "{1}"', p.GetName(), p.GetValueAsString())
def OnPropGridSelect(self, event):
pass

View File

@@ -23,6 +23,9 @@ from service.targetResists import TargetResists
from gui.bitmapLoader import BitmapLoader
from gui.utils.clipboard import toClipboard, fromClipboard
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
from logbook import Logger
pyfalog = Logger(__name__)
class TargetResistsTextValidor(BaseValidator):
@@ -45,6 +48,7 @@ class TargetResistsTextValidor(BaseValidator):
return True
except ValueError as e:
pyfalog.error(e)
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -230,10 +234,14 @@ class ResistsEditorDlg(wx.Dialog):
except ValueError:
editObj.SetForegroundColour(wx.RED)
self.stNotice.SetLabel("Incorrect Formatting (decimals only)")
msg = "Incorrect Formatting (decimals only)"
pyfalog.warning(msg)
self.stNotice.SetLabel(msg)
except AssertionError:
editObj.SetForegroundColour(wx.RED)
self.stNotice.SetLabel("Incorrect Range (must be 0-100)")
msg = "Incorrect Range (must be 0-100)"
pyfalog.warning(msg)
self.stNotice.SetLabel(msg)
finally: # Refresh for color changes to take effect immediately
self.Refresh()
@@ -271,9 +279,13 @@ class ResistsEditorDlg(wx.Dialog):
sTR.importPatterns(text)
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
except ImportError as e:
pyfalog.error(e)
self.stNotice.SetLabel(str(e))
except Exception:
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
except Exception as e:
msg = "Could not import from clipboard:"
pyfalog.warning(msg)
pyfalog.error(e)
self.stNotice.SetLabel(msg)
finally:
self.entityEditor.refreshEntityList()
else:

View File

@@ -17,7 +17,7 @@
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# =============================================================================
import logging
from logbook import Logger
# noinspection PyPackageRequirements
import wx
@@ -26,7 +26,7 @@ from gui.builtinViews.implantEditor import BaseImplantEditorView
from gui.utils.clipboard import toClipboard, fromClipboard
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
logger = logging.getLogger(__name__)
pyfalog = Logger(__name__)
class ImplantTextValidor(BaseValidator):
@@ -49,6 +49,7 @@ class ImplantTextValidor(BaseValidator):
return True
except ValueError as e:
pyfalog.error(e)
wx.MessageBox(u"{}".format(e), "Error")
textCtrl.SetFocus()
return False
@@ -198,9 +199,10 @@ class ImplantSetEditorDlg(wx.Dialog):
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
self.showInput(False)
except ImportError as e:
pyfalog.error(e)
self.stNotice.SetLabel(str(e))
except Exception as e:
logging.exception("Unhandled Exception")
pyfalog.error(e)
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
finally:
self.updateChoices()

View File

@@ -21,6 +21,8 @@ import gui.utils.animEffects as animEffects
from gui.PFListPane import PFListPane
from gui.contextMenu import ContextMenu
from gui.bitmapLoader import BitmapLoader
from logbook import Logger
pyfalog = Logger(__name__)
FitRenamed, EVT_FIT_RENAMED = wx.lib.newevent.NewEvent()
FitSelected, EVT_FIT_SELECTED = wx.lib.newevent.NewEvent()
@@ -684,6 +686,7 @@ class ShipBrowser(wx.Panel):
self.lpane.Freeze()
self.lpane.RemoveAllChildren()
pyfalog.debug("Populate ship category list.")
if len(self.categoryList) == 0:
# set cache of category list
self.categoryList = list(sMkt.getShipRoot())
@@ -692,7 +695,8 @@ class ShipBrowser(wx.Panel):
# set map & cache of fittings per category
for cat in self.categoryList:
itemIDs = [x.ID for x in cat.items]
self.categoryFitCache[cat.ID] = sFit.countFitsWithShip(itemIDs) > 1
num = sFit.countFitsWithShip(itemIDs)
self.categoryFitCache[cat.ID] = num > 0
for ship in self.categoryList:
if self.filterShipsWithNoFits and not self.categoryFitCache[ship.ID]:
@@ -938,7 +942,7 @@ class ShipBrowser(wx.Panel):
if fits:
for fit in fits:
shipTrait = fit.ship.traits.traitText if (fit.ship.traits is not None) else ""
shipTrait = fit.ship.item.traits.traitText if (fit.ship.item.traits is not None) else ""
# empty string if no traits
self.lpane.AddWidget(FitItem(

View File

@@ -4,7 +4,12 @@ import time
import wx
from service.settings import HTMLExportSettings
from service.fit import Fit
from service.port import Port
from service.market import Market
from logbook import Logger
from eos.db import getFit
pyfalog = Logger(__name__)
class exportHtml(object):
@@ -184,6 +189,7 @@ class exportHtmlThread(threading.Thread):
groupFits = 0
for ship in ships:
fits = sFit.getFitsWithShip(ship.ID)
if len(fits) > 0:
groupFits += len(fits)
@@ -192,10 +198,11 @@ class exportHtmlThread(threading.Thread):
return
fit = fits[0]
try:
dnaFit = sFit.exportDna(fit[0])
dnaFit = Port.exportDna(getFit(fit[0]))
HTMLgroup += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + ship.name + ": " + \
fit[1] + '</a></li>\n'
except:
pyfalog.warning("Failed to export line")
pass
finally:
if self.callback:
@@ -214,10 +221,12 @@ class exportHtmlThread(threading.Thread):
if self.stopRunning:
return
try:
dnaFit = sFit.exportDna(fit[0])
dnaFit = Port.exportDna(getFit(fit[0]))
print dnaFit
HTMLship += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + fit[
1] + '</a></li>\n'
except:
pyfalog.warning("Failed to export line")
continue
finally:
if self.callback:
@@ -266,10 +275,11 @@ class exportHtmlThread(threading.Thread):
if self.stopRunning:
return
try:
dnaFit = sFit.exportDna(fit[0])
dnaFit = Port.exportDna(getFit(fit[0]))
HTML += '<a class="outOfGameBrowserLink" target="_blank" href="' + dnaUrl + dnaFit + '">' + ship.name + ': ' + \
fit[1] + '</a><br> \n'
except:
pyfalog.error("Failed to export line")
continue
finally:
if self.callback: