diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py
index 4504130a1..dacdcc3fb 100644
--- a/eos/saveddata/fit.py
+++ b/eos/saveddata/fit.py
@@ -42,10 +42,13 @@ from eos.saveddata.targetProfile import TargetProfile
from eos.utils.float import floatUnerr
from eos.utils.stats import DmgTypes, RRTypes
-
pyfalog = Logger(__name__)
+def _t(x):
+ return x
+
+
class FitLite:
def __init__(self, id=None, name=None, shipID=None, shipName=None, shipNameShort=None):
@@ -395,16 +398,16 @@ class Fit:
@property
def scanType(self):
maxStr = -1
- type = None
- for scanType in ("Magnetometric", "Ladar", "Radar", "Gravimetric"):
+ type_ = None
+ for scanType in (_t("Magnetometric"), _t("Ladar"), _t("Radar"), _t("Gravimetric")):
currStr = self.ship.getModifiedItemAttr("scan%sStrength" % scanType)
if currStr > maxStr:
maxStr = currStr
- type = scanType
+ type_ = scanType
elif currStr == maxStr:
- type = "Multispectral"
+ type_ = _t("Multispectral")
- return type
+ return type_
@property
def jamChance(self):
@@ -443,9 +446,9 @@ class Fit:
@validates("ID", "ownerID", "shipID")
def validator(self, key, val):
map = {
- "ID" : lambda _val: isinstance(_val, int),
+ "ID": lambda _val: isinstance(_val, int),
"ownerID": lambda _val: isinstance(_val, int) or _val is None,
- "shipID" : lambda _val: isinstance(_val, int) or _val is None
+ "shipID": lambda _val: isinstance(_val, int) or _val is None
}
if not map[key](val):
@@ -578,15 +581,15 @@ class Fit:
if warfareBuffID == 11: # Shield Burst: Active Shielding: Repair Duration/Capacitor
self.modules.filteredItemBoost(
- lambda mod: mod.item.requiresSkill("Shield Operation") or
- mod.item.requiresSkill("Shield Emission Systems") or
- mod.item.requiresSkill("Capital Shield Emission Systems"),
- "capacitorNeed", value)
+ lambda mod: mod.item.requiresSkill("Shield Operation") or
+ mod.item.requiresSkill("Shield Emission Systems") or
+ mod.item.requiresSkill("Capital Shield Emission Systems"),
+ "capacitorNeed", value)
self.modules.filteredItemBoost(
- lambda mod: mod.item.requiresSkill("Shield Operation") or
- mod.item.requiresSkill("Shield Emission Systems") or
- mod.item.requiresSkill("Capital Shield Emission Systems"),
- "duration", value)
+ lambda mod: mod.item.requiresSkill("Shield Operation") or
+ mod.item.requiresSkill("Shield Emission Systems") or
+ mod.item.requiresSkill("Capital Shield Emission Systems"),
+ "duration", value)
if warfareBuffID == 12: # Shield Burst: Shield Extension: Shield HP
self.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True)
@@ -597,15 +600,15 @@ class Fit:
if warfareBuffID == 14: # Armor Burst: Rapid Repair: Repair Duration/Capacitor
self.modules.filteredItemBoost(
- lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
- mod.item.requiresSkill("Repair Systems") or
- mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
- "capacitorNeed", value)
+ lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
+ mod.item.requiresSkill("Repair Systems") or
+ mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
+ "capacitorNeed", value)
self.modules.filteredItemBoost(
- lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
- mod.item.requiresSkill("Repair Systems") or
- mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
- "duration", value)
+ lambda mod: mod.item.requiresSkill("Remote Armor Repair Systems") or
+ mod.item.requiresSkill("Repair Systems") or
+ mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
+ "duration", value)
if warfareBuffID == 15: # Armor Burst: Armor Reinforcement: Armor HP
self.ship.boostItemAttr("armorHP", value, stackingPenalties=True)
@@ -980,14 +983,14 @@ class Fit:
for _ in range(projectionInfo.amount):
targetFit.register(item, origin=self)
item.calculateModifiedAttributes(
- targetFit, runTime, forceProjected=True,
- forcedProjRange=0)
+ targetFit, runTime, forceProjected=True,
+ forcedProjRange=0)
for mod in self.modules:
for _ in range(projectionInfo.amount):
targetFit.register(mod, origin=self)
mod.calculateModifiedAttributes(
- targetFit, runTime, forceProjected=True,
- forcedProjRange=projectionInfo.projectionRange)
+ targetFit, runTime, forceProjected=True,
+ forcedProjRange=projectionInfo.projectionRange)
def fill(self):
"""
@@ -1003,7 +1006,8 @@ class Fit:
# Look for any dummies of that type to remove
posToRemove = {}
- for slotType in (FittingSlot.LOW.value, FittingSlot.MED.value, FittingSlot.HIGH.value, FittingSlot.RIG.value, FittingSlot.SUBSYSTEM.value, FittingSlot.SERVICE.value):
+ for slotType in (
+ FittingSlot.LOW.value, FittingSlot.MED.value, FittingSlot.HIGH.value, FittingSlot.RIG.value, FittingSlot.SUBSYSTEM.value, FittingSlot.SERVICE.value):
amount = self.getSlotsFree(slotType, True)
if amount > 0:
for _ in range(int(amount)):
@@ -1080,22 +1084,23 @@ class Fit:
for mod in chain(self.modules, self.fighters):
if mod.slot is type and (not getattr(mod, "isEmpty", False) or countDummies):
- if type in (FittingSlot.F_HEAVY, FittingSlot.F_SUPPORT, FittingSlot.F_LIGHT, FittingSlot.FS_HEAVY, FittingSlot.FS_LIGHT, FittingSlot.FS_SUPPORT) and not mod.active:
+ if type in (FittingSlot.F_HEAVY, FittingSlot.F_SUPPORT, FittingSlot.F_LIGHT, FittingSlot.FS_HEAVY, FittingSlot.FS_LIGHT,
+ FittingSlot.FS_SUPPORT) and not mod.active:
continue
amount += 1
return amount
slots = {
- FittingSlot.LOW : "lowSlots",
- FittingSlot.MED : "medSlots",
- FittingSlot.HIGH : "hiSlots",
- FittingSlot.RIG : "rigSlots",
+ FittingSlot.LOW: "lowSlots",
+ FittingSlot.MED: "medSlots",
+ FittingSlot.HIGH: "hiSlots",
+ FittingSlot.RIG: "rigSlots",
FittingSlot.SUBSYSTEM: "maxSubSystems",
- FittingSlot.SERVICE : "serviceSlots",
- FittingSlot.F_LIGHT : "fighterLightSlots",
+ FittingSlot.SERVICE: "serviceSlots",
+ FittingSlot.F_LIGHT: "fighterLightSlots",
FittingSlot.F_SUPPORT: "fighterSupportSlots",
- FittingSlot.F_HEAVY : "fighterHeavySlots",
+ FittingSlot.F_HEAVY: "fighterHeavySlots",
FittingSlot.FS_LIGHT: "fighterStandupLightSlots",
FittingSlot.FS_SUPPORT: "fighterStandupSupportSlots",
FittingSlot.FS_HEAVY: "fighterStandupHeavySlots",
@@ -1377,8 +1382,8 @@ class Fit:
"""Return how much cap regen do we gain from having this module"""
currentRegen = self.calculateCapRecharge()
nomodRegen = self.calculateCapRecharge(
- capacity=self.ship.getModifiedItemAttrExtended("capacitorCapacity", ignoreAfflictors=[mod]),
- rechargeRate=self.ship.getModifiedItemAttrExtended("rechargeRate", ignoreAfflictors=[mod]) / 1000.0)
+ capacity=self.ship.getModifiedItemAttrExtended("capacitorCapacity", ignoreAfflictors=[mod]),
+ rechargeRate=self.ship.getModifiedItemAttrExtended("rechargeRate", ignoreAfflictors=[mod]) / 1000.0)
return currentRegen - nomodRegen
def getRemoteReps(self, spoolOptions=None):
@@ -1422,7 +1427,8 @@ class Fit:
"armorRepair": self.extraAttributes["armorRepair"],
"armorRepairPreSpool": self.extraAttributes["armorRepairPreSpool"],
"armorRepairFullSpool": self.extraAttributes["armorRepairFullSpool"],
- "hullRepair": self.extraAttributes["hullRepair"]}
+ "hullRepair": self.extraAttributes["hullRepair"]
+ }
return reps
@property
@@ -1462,7 +1468,8 @@ class Fit:
"armorRepair": self.extraAttributes["armorRepair"],
"armorRepairPreSpool": self.extraAttributes["armorRepairPreSpool"],
"armorRepairFullSpool": self.extraAttributes["armorRepairFullSpool"],
- "hullRepair": self.extraAttributes["hullRepair"]}
+ "hullRepair": self.extraAttributes["hullRepair"]
+ }
if not self.capStable or self.factorReload:
# Map a local repairer type to the attribute it uses
groupAttrMap = {
@@ -1470,14 +1477,16 @@ class Fit:
"Ancillary Shield Booster": "shieldBonus",
"Armor Repair Unit": "armorDamageAmount",
"Ancillary Armor Repairer": "armorDamageAmount",
- "Hull Repair Unit": "structureDamageAmount"}
+ "Hull Repair Unit": "structureDamageAmount"
+ }
# Map local repairer type to tank type
groupStoreMap = {
"Shield Booster": "shieldRepair",
"Ancillary Shield Booster": "shieldRepair",
"Armor Repair Unit": "armorRepair",
"Ancillary Armor Repairer": "armorRepair",
- "Hull Repair Unit": "hullRepair"}
+ "Hull Repair Unit": "hullRepair"
+ }
repairers = []
localAdjustment = {"shieldRepair": 0, "armorRepair": 0, "hullRepair": 0}
capUsed = self.capUsed
@@ -1529,7 +1538,7 @@ class Fit:
# Sort repairers by efficiency. We want to use the most efficient repairers first
repairers.sort(key=lambda _mod: _mod.getModifiedItemAttr(
- groupAttrMap[_mod.item.group.name]) * (_mod.getModifiedItemAttr(
+ groupAttrMap[_mod.item.group.name]) * (_mod.getModifiedItemAttr(
"chargedArmorDamageMultiplier") or 1) / _mod.getModifiedItemAttr("capacitorNeed"), reverse=True)
# Loop through every module until we're above peak recharge
@@ -1654,7 +1663,6 @@ class Fit:
secstatus = FitSystemSecurity.NULLSEC
return secstatus
-
def activeModulesIter(self):
for mod in self.modules:
if mod.state >= FittingModuleState.ACTIVE:
diff --git a/eos/utils/stats.py b/eos/utils/stats.py
index 76ed3edeb..5b6329c16 100644
--- a/eos/utils/stats.py
+++ b/eos/utils/stats.py
@@ -22,6 +22,10 @@ from eos.utils.float import floatUnerr
from utils.repr import makeReprStr
+def _t(x):
+ return x
+
+
class DmgTypes:
"""Container for damage data stats."""
@@ -116,7 +120,7 @@ class DmgTypes:
@staticmethod
def names(short=None, postProcessor=None):
- value = ['em', 'th', 'kin', 'exp'] if short else ['em', 'thermal', 'kinetic', 'explosive']
+ value = [_t('em'), _t('th'), _t('kin'), _t('exp')] if short else [_t('em'), _t('thermal'), _t('kinetic'), _t('explosive')]
if postProcessor:
value = [postProcessor(x) for x in value]
diff --git a/gui/builtinContextMenus/itemRemove.py b/gui/builtinContextMenus/itemRemove.py
index b0b875862..8e8908b80 100644
--- a/gui/builtinContextMenus/itemRemove.py
+++ b/gui/builtinContextMenus/itemRemove.py
@@ -39,9 +39,9 @@ class RemoveItem(ContextMenuCombined):
return True
def getText(self, callingWindow, itmContext, mainItem, selection):
- return _t('Remove {}{}').format(
- itmContext if itmContext is not None else _t('Item'),
- _t(' Stack') if self.srcContext in ('droneItem', 'projectedDrone', 'cargoItem', 'projectedFit') else '')
+ return _t('Remove {item}{stack}').format(
+ item=itmContext if itmContext is not None else _t('Item'),
+ stack=_t(' Stack') if self.srcContext in ('droneItem', 'projectedDrone', 'cargoItem', 'projectedFit') else '')
def activate(self, callingWindow, fullContext, mainItem, selection, i):
handlerMap = {
diff --git a/gui/builtinStatsViews/capacitorViewFull.py b/gui/builtinStatsViews/capacitorViewFull.py
index 9ba2a0cf5..dd89ed5b0 100644
--- a/gui/builtinStatsViews/capacitorViewFull.py
+++ b/gui/builtinStatsViews/capacitorViewFull.py
@@ -136,10 +136,9 @@ class CapacitorViewFull(StatsView):
label.SetToolTip(wx.ToolTip("%.1f" % value))
if labelName == 'label%sCapacitorDelta' and (cap_recharge or cap_use):
- lines = []
- lines.append('Capacitor delta:')
- lines.append(' +{} GJ/s'.format(formatAmount(cap_recharge, 3, 0, 3)))
- lines.append(' -{} GJ/s'.format(formatAmount(cap_use, 3, 0, 3)))
+ lines = [_t('Capacitor delta:'),
+ ' +{} GJ/s'.format(formatAmount(cap_recharge, 3, 0, 3)),
+ ' -{} GJ/s'.format(formatAmount(cap_use, 3, 0, 3))]
delta = round(cap_recharge - cap_use, 3)
if delta > 0 and 0 < round(neut_res, 4) < 1:
lines.append('')
@@ -147,9 +146,9 @@ class CapacitorViewFull(StatsView):
lines.append(' +{} GJ/s'.format(formatAmount(delta / neut_res, 3, 0, 3)))
label.SetToolTip(wx.ToolTip('\n'.join(lines)))
if labelName == 'label%sCapacitorResist':
- texts = ['Neutralizer resistance']
+ texts = [_t('Neutralizer resistance')]
if cap_amount > 0 and 0 < round(neut_res, 4) < 1:
- texts.append('Effective capacity: {} GJ'.format(formatAmount(cap_amount / neut_res, 3, 0, 9)))
+ texts.append(_t('Effective capacity') + ': {} GJ'.format(formatAmount(cap_amount / neut_res, 3, 0, 9)))
label.SetToolTip(wx.ToolTip('\n'.join(texts)))
capState = fit.capState if fit is not None else 0
diff --git a/gui/builtinStatsViews/firepowerViewFull.py b/gui/builtinStatsViews/firepowerViewFull.py
index 62ae6cc2a..8540accc6 100644
--- a/gui/builtinStatsViews/firepowerViewFull.py
+++ b/gui/builtinStatsViews/firepowerViewFull.py
@@ -166,20 +166,20 @@ class FirepowerViewFull(StatsView):
hasSpool = hasSpoolUp(preSpool, fullSpool)
lines = []
if hasSpool:
- lines.append("Spool up: {}-{}".format(
- formatAmount(preSpool.total, prec, lowest, highest),
- formatAmount(fullSpool.total, prec, lowest, highest)))
+ lines.append(_t("Spool up") + ": {}-{}".format(
+ formatAmount(preSpool.total, prec, lowest, highest),
+ formatAmount(fullSpool.total, prec, lowest, highest)))
if getattr(normal, 'total', None):
if hasSpool:
lines.append("")
- lines.append("Current: {}".format(formatAmount(normal.total, prec, lowest, highest)))
+ lines.append(_t("Current") + ": {}".format(formatAmount(normal.total, prec, lowest, highest)))
for dmgType in normal.names():
val = getattr(normal, dmgType, None)
if val:
lines.append("{}{}: {}%".format(
- " " if hasSpool else "",
- dmgType.capitalize(),
- formatAmount(val / normal.total * 100, 3, 0, 0)))
+ " " if hasSpool else "",
+ _t(dmgType).capitalize(),
+ formatAmount(val / normal.total * 100, 3, 0, 0)))
return "\n".join(lines)
defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage']
@@ -218,8 +218,8 @@ class FirepowerViewFull(StatsView):
if self._cachedValues[counter] != val:
tooltipText = dpsToolTip(val, preSpoolVal, fullSpoolVal, prec, lowest, highest)
label.SetLabel(valueFormat.format(
- formatAmount(0 if val is None else val.total, prec, lowest, highest),
- "\u02e2" if hasSpoolUp(preSpoolVal, fullSpoolVal) else ""))
+ formatAmount(0 if val is None else val.total, prec, lowest, highest),
+ "\u02e2" if hasSpoolUp(preSpoolVal, fullSpoolVal) else ""))
label.SetToolTip(wx.ToolTip(tooltipText))
self._cachedValues[counter] = val
counter += 1
diff --git a/gui/builtinStatsViews/outgoingViewFull.py b/gui/builtinStatsViews/outgoingViewFull.py
index 8b214c052..655cee084 100644
--- a/gui/builtinStatsViews/outgoingViewFull.py
+++ b/gui/builtinStatsViews/outgoingViewFull.py
@@ -29,25 +29,25 @@ _t = wx.GetTranslation
stats = [
(
- "labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", "Capacitor restored",
+ "labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", _t("Capacitor restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).capacitor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).capacitor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).capacitor,
3, 0, 0),
(
- "labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", "Shield restored",
+ "labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", _t("Shield restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).shield,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).shield,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).shield,
3, 0, 0),
(
- "labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", "Armor restored",
+ "labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", _t("Armor restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).armor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).armor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).armor,
3, 0, 0),
(
- "labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", "Hull restored",
+ "labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", _t("Hull restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).hull,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).hull,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).hull,
diff --git a/gui/builtinStatsViews/outgoingViewMinimal.py b/gui/builtinStatsViews/outgoingViewMinimal.py
index 9ce5439a8..17f1b0a44 100644
--- a/gui/builtinStatsViews/outgoingViewMinimal.py
+++ b/gui/builtinStatsViews/outgoingViewMinimal.py
@@ -28,25 +28,25 @@ _t = wx.GetTranslation
stats = [
(
- "labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", "Capacitor restored",
+ "labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", _t("Capacitor restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).capacitor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).capacitor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).capacitor,
3, 0, 0),
(
- "labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", "Shield restored",
+ "labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", _t("Shield restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).shield,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).shield,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).shield,
3, 0, 0),
(
- "labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", "Armor restored",
+ "labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", _t("Armor restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).armor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).armor,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).armor,
3, 0, 0),
(
- "labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", "Hull restored",
+ "labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", _t("Hull restored"),
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, spool, False)).hull,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 0, True)).hull,
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SPOOL_SCALE, 1, True)).hull,
diff --git a/gui/builtinStatsViews/targetingMiscViewMinimal.py b/gui/builtinStatsViews/targetingMiscViewMinimal.py
index 8a0f023e5..99ac46169 100644
--- a/gui/builtinStatsViews/targetingMiscViewMinimal.py
+++ b/gui/builtinStatsViews/targetingMiscViewMinimal.py
@@ -215,11 +215,11 @@ class TargetingMiscViewMinimal(StatsView):
ecmChance = otherValues["jamChance"]
ecmChance = round(ecmChance, 1)
if ecmChance > 0:
- label.SetToolTip(wx.ToolTip(_t("Type: {0}\n").foramt(fit.scanType) +
+ label.SetToolTip(wx.ToolTip(_t("Type: {0}\n").foramt(_t(fit.scanType)) +
# xgettext:no-python-format,python-brace-format
_t("{}% chance to be jammed").format(formatAmount(ecmChance, 3, 0, 0))))
else:
- label.SetToolTip(wx.ToolTip(_t("Type: {}").format(fit.scanType)))
+ label.SetToolTip(wx.ToolTip(_t("Type: {}").format(_t(fit.scanType))))
elif labelName == "labelFullAlignTime":
alignTime = _t("Align:\t%.3fs") % mainValue
mass = _t('Mass:\t{:,.0f}kg').format(fit.ship.getModifiedItemAttr("mass"))
diff --git a/locale/README.md b/locale/README.md
index ce28d2ab1..3a8cf3196 100644
--- a/locale/README.md
+++ b/locale/README.md
@@ -6,12 +6,12 @@ pyfa provides community-driven translations for a variety of languages. It is im
* Ship browser
* Item names, description, traits, attributes
-If there is a tranlation issue in EVE data, you must submit a ticket to CCP instead.
+If there is a translation issue in EVE data, you must submit a ticket to CCP instead.
## Getting Involved
Translations are done mainly through [Crowdin](https://crowdin.com/project/pyfa). This platform allows translations to be done by anyone without any real need to understand the project's internals. Simply sign up, join the project as a Translator, and start translating!
-
+
As a general rule of thumb, we consider translations community-driven. The pyfa team isn't going to
1) Maintain individual language packs as a part of general development work, or
@@ -42,13 +42,13 @@ msgstr "点击切换有效HP和原始HP"
[Poedit](https://poedit.net/) offers a nice GUI for updating translations.
-##### To update PO file for existing translation
+#### To update PO file for existing translation
1. open a existing `locale/ll_CC/LC_MESSAGES/lang.po`
2. *Catalog* -> *Update from POT file*
3. select pre-prepared `lang.pot` file
-##### To translate and generate MO file
+#### To translate and generate MO file
edit the translation and hit Save :)
@@ -59,7 +59,8 @@ A: This is probably one of two things:
1. Missing annotations in the source code. All text that needs to be translated needs to be wrapped with `_t()` to make it locale-aware
2. Out of date `.po` file. As pyfa development continues, the `.po` file may fall behind. See next question.
-
+
+
Q: How do I update the `.po` file for my language?
A: See `Commands` section below for a number of useful commands
@@ -70,31 +71,32 @@ A: If you're running from source / your own method, this is because the `.mo` fi
Below is a summary of [GNU gettext](https://www.gnu.org/software/gettext/) manual, adapted for Pyfa i18n workflow.
-[Poedit](https://poedit.net/) offers a nice GUI for same GNU gettext translation workflow.
-
-## i18n with command line
-
-Windows users can get these tools via Git for windows, Msys2 or Cygwin; or just use WSL / WSL2.
-For Linux and macOS users these tools might be available out-of-box.
+Windows users can get these tools via Git for windows, Msys2 or Cygwin; or just use WSL / WSL2. For Linux and macOS users these tools might be available out-of-box.
### To generate new template for translation:
```console
-$ find gui/ *.py -name "*.py" | xgettext --from-code=UTF-8 -o locale/lang.pot -d lang -k_t -f - -s
+$ find * -name "*.py" | xgettext --from-code=UTF-8 -o locale/lang.pot -d lang -k_t -k_t:1,2,3t -k_t:1,2c,2t -f - -s
```
explanation:
-* `find gui/ *.py -name "*.py"`: collect all `.py` file path in `gui` folder and all sub-folders, write it to stdout
-* `xgettext`: a utility looking for keyword and put string literals in a specific format for human translation
+* `find * -name "*.py"`: collect all `.py` file path in current folder and all sub-folders, write it to stdout
+ * except those starts with `.`. E.g. `.env`, `.idea`, `.venv`.
+ * can also append `-not -path 'path/to/venv/*` to exclude `path/to/venv` recursively.
+
+* `xgettext` ([doc](https://www.gnu.org/software/gettext/manual/gettext.html#Template)): a utility looking for keyword and put string literals in a specific format for human translation
* `--from-code=UTF-8`: designates encoding of files
* `-o locale/lang.pot`: let `xgettext` write to `locale/lang.pot`
* `-d lang`: default language domain is `lang`
- * `-k_t`: besides default keyword (including `_`, see `info xgettext` for detail), also look for `_t`
- * `-f -`: let `xgettext` to read from stdin, which is connected to `find` stdout
+ * `-k_t`: besides default keyword (including `_`, see `info xgettext` for detail), also look for `_t`,
+ where the string literal (`msgid`) will be the first argument of this function call
+ * `-k_t:1,2,3t`: look for `_t`, first arg is `msgid`, second arg is `msgid_plural`, 3 args in total
+ * `-k_t:1,2c,2t`: look for `_t`, first arg is `msgid`, second arg is `msgctxt`, 2 args in total
+ * `-f -`: let `xgettext` to read filenames from stdin, which is connected to `find` stdout
* `-s`: sort output according to `msgid`
-this `locale/lang.pot` is called PO template, which is discarded once actual `ll_CC/LC_MESSAGES/lang.po` is ready for use.
+this `locale/lang.pot` is called PO template, which is the source file for Crowdin translation.
### To initialize PO file for new language
diff --git a/locale/lang.pot b/locale/lang.pot
index 260871d3e..e234bbc99 100644
--- a/locale/lang.pot
+++ b/locale/lang.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-07-17 11:42+0800\n"
+"POT-Creation-Date: 2020-07-27 15:29+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -16,6 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: gui/builtinStatsViews/firepowerViewFull.py:107
msgid " DPS: "
@@ -32,7 +33,9 @@ msgstr ""
#: gui/builtinItemStatsViews/itemProperties.py:98
#, python-format
msgid "%d attribute."
-msgstr ""
+msgid_plural "%d attributes."
+msgstr[0] ""
+msgstr[1] ""
#: gui/mainMenuBar.py:73
msgid "&Backup All Fittings"
@@ -276,6 +279,10 @@ msgstr ""
msgid "Add Fits"
msgstr ""
+#: gui/builtinContextMenus/targetProfile/adder.py:29
+msgid "Add Target Profile"
+msgstr ""
+
#: gui/builtinContextMenus/cargoAddAmmo.py:28
#, python-brace-format
msgid "Add {0} to Cargo (x1000)"
@@ -370,7 +377,7 @@ msgstr ""
msgid "Angel Cartel"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:70
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:73
msgid "Animate gauges"
msgstr ""
@@ -420,6 +427,11 @@ msgstr ""
msgid "Armor resistance"
msgstr ""
+#: gui/builtinStatsViews/outgoingViewFull.py:44
+#: gui/builtinStatsViews/outgoingViewMinimal.py:43
+msgid "Armor restored"
+msgstr ""
+
#: gui/builtinStatsViews/resistancesViewFull.py:206
msgid "Armor: "
msgstr ""
@@ -462,6 +474,11 @@ msgstr ""
msgid "Auto"
msgstr ""
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:145
+msgid ""
+"Auto will use the same language pyfa uses if available, otherwise English"
+msgstr ""
+
#: gui/builtinPreferenceViews/pyfaNetworkPreferences.py:87
msgid "Auto-detected proxy settings"
msgstr ""
@@ -622,6 +639,15 @@ msgstr ""
msgid "Capacitor"
msgstr ""
+#: gui/builtinStatsViews/capacitorViewFull.py:139
+msgid "Capacitor delta:"
+msgstr ""
+
+#: gui/builtinStatsViews/outgoingViewFull.py:32
+#: gui/builtinStatsViews/outgoingViewMinimal.py:31
+msgid "Capacitor restored"
+msgstr ""
+
#: gui/builtinStatsViews/capacitorViewFull.py:57
msgid "Capacitor stability"
msgstr ""
@@ -678,7 +704,7 @@ msgstr ""
msgid "Change Skills"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:81
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:84
msgid "Change charge in all modules of the same type"
msgstr ""
@@ -761,7 +787,7 @@ msgstr ""
msgid "Client Secret:"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:51
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:54
msgid "Color fitting view by slot"
msgstr ""
@@ -785,7 +811,7 @@ msgstr ""
msgid "Command center hold"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:47
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:50
msgid "Compact skills needed tooltip"
msgstr ""
@@ -902,6 +928,10 @@ msgstr ""
msgid "Cruor (Blood Raiders)"
msgstr ""
+#: gui/builtinStatsViews/firepowerViewFull.py:175
+msgid "Current"
+msgstr ""
+
#: gui/builtinItemStatsViews/itemAttributes.py:45
#: gui/builtinItemStatsViews/itemProperties.py:57
msgid "Current Value"
@@ -1131,7 +1161,7 @@ msgstr ""
msgid "Drag a fit to this area"
msgstr ""
-#: gui/builtinAdditionPanes/projectedView.py:226
+#: gui/builtinAdditionPanes/projectedView.py:224
msgid "Drag an item or fit, or use right-click menu for wormhole effects"
msgstr ""
@@ -1240,6 +1270,10 @@ msgstr ""
msgid "EVE API XML character files"
msgstr ""
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:127
+msgid "EVE Data:"
+msgstr ""
+
#: gui/builtinPreferenceViews/pyfaHTMLExportPreferences.py:49
msgid "EVE IGB HTML fitting file"
msgstr ""
@@ -1278,6 +1312,10 @@ msgstr ""
msgid "Effective HP: "
msgstr ""
+#: gui/builtinStatsViews/capacitorViewFull.py:151
+msgid "Effective capacity"
+msgstr ""
+
#: graphs/data/fitDamageStats/graph.py:85
msgid "Effective damage inflicted"
msgstr ""
@@ -1558,7 +1596,7 @@ msgstr ""
msgid "Exporting skills needed..."
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:89
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:92
msgid "Extra info in Additions panel tab names"
msgstr ""
@@ -1758,7 +1796,7 @@ msgstr ""
msgid "Gas hold"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:17
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:20
msgid "General"
msgstr ""
@@ -1795,6 +1833,10 @@ msgstr ""
msgid "Graphs"
msgstr ""
+#: eos/saveddata/fit.py:402
+msgid "Gravimetric"
+msgstr ""
+
#: graphs/style.py:53
msgid "Green"
msgstr ""
@@ -1861,6 +1903,11 @@ msgstr ""
msgid "Hull resistance"
msgstr ""
+#: gui/builtinStatsViews/outgoingViewFull.py:50
+#: gui/builtinStatsViews/outgoingViewMinimal.py:49
+msgid "Hull restored"
+msgstr ""
+
#: gui/builtinStatsViews/resistancesViewFull.py:206
msgid "Hull: "
msgstr ""
@@ -2025,6 +2072,10 @@ msgstr ""
msgid "Interceptor"
msgstr ""
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:122
+msgid "Interested in helping with translations?"
+msgstr ""
+
#: eos/saveddata/damagePattern.py:127 eos/saveddata/damagePattern.py:128
#: eos/saveddata/damagePattern.py:132 eos/saveddata/damagePattern.py:135
#: eos/saveddata/damagePattern.py:138 eos/saveddata/targetProfile.py:94
@@ -2092,8 +2143,12 @@ msgstr ""
msgid "Kinetic resistance"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:96
-msgid "Language (restart required):"
+#: eos/saveddata/fit.py:402
+msgid "Ladar"
+msgstr ""
+
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:97
+msgid "Language (requires restart)"
msgstr ""
#: gui/builtinStatsViews/targetingMiscViewMinimal.py:120
@@ -2101,7 +2156,7 @@ msgid "Large ship hold"
msgstr ""
#: gui/builtinStatsViews/capacitorViewFull.py:77
-#: gui/builtinStatsViews/capacitorViewFull.py:171
+#: gui/builtinStatsViews/capacitorViewFull.py:170
msgid "Lasts "
msgstr ""
@@ -2208,6 +2263,10 @@ msgstr ""
msgid "Magenta"
msgstr ""
+#: eos/saveddata/fit.py:402
+msgid "Magnetometric"
+msgstr ""
+
#: gui/builtinStatsViews/targetingMiscViewMinimal.py:114
msgid "Maintenance bay"
msgstr ""
@@ -2378,6 +2437,10 @@ msgstr ""
msgid "Multifrequency"
msgstr ""
+#: eos/saveddata/fit.py:408
+msgid "Multispectral"
+msgstr ""
+
#: gui/copySelectDialog.py:54
msgid "Mutated Attributes"
msgstr ""
@@ -2497,6 +2560,10 @@ msgstr ""
msgid "Network"
msgstr ""
+#: gui/builtinStatsViews/capacitorViewFull.py:149
+msgid "Neutralizer resistance"
+msgstr ""
+
#: graphs/data/fitEwarStats/graph.py:36
msgid "Neuts: cap per second"
msgstr ""
@@ -2540,7 +2607,7 @@ msgstr ""
msgid "No proxy"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:90
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:93
#: gui/builtinPreferenceViews/pyfaStatViewPreferences.py:42
#: gui/builtinPreferenceViews/pyfaStatViewPreferences.py:50
#: gui/builtinPreferenceViews/pyfaStatViewPreferences.py:58
@@ -2613,7 +2680,7 @@ msgstr ""
msgid "Open Widgets Inspect tool"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:73
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:76
msgid "Open fittings in a new page by default"
msgstr ""
@@ -2769,10 +2836,10 @@ msgstr ""
msgid "Projected"
msgstr ""
-#: gui/builtinAdditionPanes/projectedView.py:306
-#: gui/builtinAdditionPanes/projectedView.py:316
-#: gui/builtinAdditionPanes/projectedView.py:321
-#: gui/builtinAdditionPanes/projectedView.py:326
+#: gui/builtinAdditionPanes/projectedView.py:304
+#: gui/builtinAdditionPanes/projectedView.py:314
+#: gui/builtinAdditionPanes/projectedView.py:319
+#: gui/builtinAdditionPanes/projectedView.py:324
msgid "Projected Item"
msgstr ""
@@ -2832,14 +2899,18 @@ msgstr ""
msgid "Quafe hold"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:90
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:93
msgid "Quantity of active items"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:90
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:93
msgid "Quantity of all items"
msgstr ""
+#: eos/saveddata/fit.py:402
+msgid "Radar"
+msgstr ""
+
#: eos/saveddata/damagePattern.py:45
msgid "Radio"
msgstr ""
@@ -2929,14 +3000,15 @@ msgid "Remove Overides for Item"
msgstr ""
#: gui/builtinContextMenus/itemRemove.py:42
-msgid "Remove {}{}"
+#, python-brace-format
+msgid "Remove {item}{stack}"
msgstr ""
#: gui/builtinShipBrowser/fitItem.py:108
msgid "Rename"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:55
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:58
msgid "Reopen previous fits on startup"
msgstr ""
@@ -3040,6 +3112,10 @@ msgstr ""
msgid "Salvage hold"
msgstr ""
+#: locale_test/getTextLocale.py:4
+msgid "Sample Title Text English"
+msgstr ""
+
#: eos/saveddata/damagePattern.py:156 eos/saveddata/targetProfile.py:80
#: gui/builtinContextMenus/envEffectAdd.py:112
msgid "Sansha Incursion"
@@ -3130,7 +3206,7 @@ msgstr ""
msgid "Sentinel"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:59
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:62
msgid "Separate Racks"
msgstr ""
@@ -3200,6 +3276,11 @@ msgstr ""
msgid "Shield resistance"
msgstr ""
+#: gui/builtinStatsViews/outgoingViewFull.py:38
+#: gui/builtinStatsViews/outgoingViewMinimal.py:37
+msgid "Shield restored"
+msgstr ""
+
#: gui/builtinPreferenceViews/pyfaStatViewPreferences.py:58
msgid "Shield/Armor Tank"
msgstr ""
@@ -3230,7 +3311,7 @@ msgstr ""
msgid "Short Range"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:63
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:66
msgid "Show Rack Labels"
msgstr ""
@@ -3238,7 +3319,7 @@ msgstr ""
msgid "Show empty ship groups"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:67
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:70
msgid "Show fitting tab tooltips"
msgstr ""
@@ -3250,7 +3331,7 @@ msgstr ""
msgid "Show market shortcuts"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:77
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:80
msgid "Show ship browser tooltip"
msgstr ""
@@ -3329,6 +3410,10 @@ msgstr ""
msgid "Split {} Stack"
msgstr ""
+#: gui/builtinStatsViews/firepowerViewFull.py:169
+msgid "Spool up"
+msgstr ""
+
#: gui/builtinPreferenceViews/pyfaContextMenuPreferences.py:76
msgid "Spoolup"
msgstr ""
@@ -3337,7 +3422,7 @@ msgstr ""
msgid "Spoolup Cycles"
msgstr ""
-#: gui/builtinStatsViews/capacitorViewFull.py:171
+#: gui/builtinStatsViews/capacitorViewFull.py:170
msgid "Stable: "
msgstr ""
@@ -3768,15 +3853,15 @@ msgstr ""
msgid "Use capacitor simulator"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:39
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:42
msgid "Use character implants by default for new fits"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:35
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:38
msgid "Use global character"
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:43
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:46
msgid "Use global damage pattern"
msgstr ""
@@ -3847,7 +3932,7 @@ msgid ""
"behavior)."
msgstr ""
-#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:86
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:89
msgid ""
"When disabled, reloads charges just in selected modules. Action can be "
"reversed by holding Ctrl or Alt key while changing charge."
@@ -3971,6 +4056,26 @@ msgstr ""
msgid "[T2] Void"
msgstr ""
+#: eos/utils/stats.py:123
+msgid "em"
+msgstr ""
+
+#: eos/utils/stats.py:123
+msgid "exp"
+msgstr ""
+
+#: eos/utils/stats.py:123
+msgid "explosive"
+msgstr ""
+
+#: eos/utils/stats.py:123
+msgid "kin"
+msgstr ""
+
+#: eos/utils/stats.py:123
+msgid "kinetic"
+msgstr ""
+
#: gui/builtinPreferenceViews/pyfaDatabasePreferences.py:38
msgid "pyfa User Path:"
msgstr ""
@@ -4004,6 +4109,18 @@ msgstr ""
msgid "pyfa.io"
msgstr ""
+#: gui/builtinPreferenceViews/pyfaGeneralPreferences.py:102
+msgid "pyfa:"
+msgstr ""
+
+#: eos/utils/stats.py:123
+msgid "th"
+msgstr ""
+
+#: eos/utils/stats.py:123
+msgid "thermal"
+msgstr ""
+
#: gui/builtinContextMenus/itemMarketJump.py:44
#, python-brace-format
msgid "{0} Market Group"
@@ -4038,7 +4155,9 @@ msgstr ""
#: gui/builtinViewColumns/baseName.py:104
msgid "{} {} Slot"
-msgstr ""
+msgid_plural "{} {} Slots"
+msgstr[0] ""
+msgstr[1] ""
#: gui/builtinStatsViews/targetingMiscViewMinimal.py:220
#, no-python-format, python-brace-format