diff --git a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py index a31e56f8a..51d32ab5d 100644 --- a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py +++ b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py @@ -76,10 +76,6 @@ class PFGeneralPref(PreferenceView): self.cbGaugeAnimation = wx.CheckBox(panel, wx.ID_ANY, "Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5) - self.cbExportCharges = wx.CheckBox(panel, wx.ID_ANY, "Export loaded charges", wx.DefaultPosition, - wx.DefaultSize, 0) - mainSizer.Add(self.cbExportCharges, 0, wx.ALL | wx.EXPAND, 5) - self.cbOpenFitInNew = wx.CheckBox(panel, wx.ID_ANY, "Open fittings in a new page by default", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5) @@ -133,7 +129,6 @@ class PFGeneralPref(PreferenceView): self.cbShowTooltip.SetValue(self.sFit.serviceFittingOptions["showTooltip"] or False) self.cbMarketShortcuts.SetValue(self.sFit.serviceFittingOptions["showMarketShortcuts"] or False) self.cbGaugeAnimation.SetValue(self.sFit.serviceFittingOptions["enableGaugeAnimation"]) - self.cbExportCharges.SetValue(self.sFit.serviceFittingOptions["exportCharges"]) self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"]) self.chPriceSource.SetStringSelection(self.sFit.serviceFittingOptions["priceSource"]) self.chPriceSystem.SetStringSelection(self.sFit.serviceFittingOptions["priceSystem"]) @@ -151,7 +146,6 @@ class PFGeneralPref(PreferenceView): self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip) self.cbMarketShortcuts.Bind(wx.EVT_CHECKBOX, self.onCBShowShortcuts) self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation) - self.cbExportCharges.Bind(wx.EVT_CHECKBOX, self.onCBExportCharges) self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew) self.chPriceSource.Bind(wx.EVT_CHOICE, self.onPricesSourceSelection) self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection) @@ -220,9 +214,6 @@ class PFGeneralPref(PreferenceView): def onCBGaugeAnimation(self, event): self.sFit.serviceFittingOptions["enableGaugeAnimation"] = self.cbGaugeAnimation.GetValue() - def onCBExportCharges(self, event): - self.sFit.serviceFittingOptions["exportCharges"] = self.cbExportCharges.GetValue() - def onCBOpenFitInNew(self, event): self.sFit.serviceFittingOptions["openFitInNew"] = self.cbOpenFitInNew.GetValue() diff --git a/gui/copySelectDialog.py b/gui/copySelectDialog.py index 10eff2647..91725e048 100644 --- a/gui/copySelectDialog.py +++ b/gui/copySelectDialog.py @@ -18,9 +18,13 @@ # ============================================================================= +from collections import OrderedDict + # noinspection PyPackageRequirements import wx + from service.port.eft import EFT_OPTIONS +from service.port.multibuy import MULTIBUY_OPTIONS from service.settings import SettingsProvider @@ -37,39 +41,53 @@ class CopySelectDialog(wx.Dialog): style=wx.DEFAULT_DIALOG_STYLE) mainSizer = wx.BoxSizer(wx.VERTICAL) - self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": 0}) + self.copyFormats = OrderedDict(( + ("EFT", (CopySelectDialog.copyFormatEft, EFT_OPTIONS)), + ("MultiBuy", (CopySelectDialog.copyFormatMultiBuy, MULTIBUY_OPTIONS)), + ("ESI", (CopySelectDialog.copyFormatEsi, None)), + ("EFS", (CopySelectDialog.copyFormatEfs, None)), + # ("XML", (CopySelectDialog.copyFormatXml, None)), + # ("DNA", (CopySelectDialog.copyFormatDna, None)), + )) - self.copyFormats = { - "EFT": CopySelectDialog.copyFormatEft, - "XML": CopySelectDialog.copyFormatXml, - "DNA": CopySelectDialog.copyFormatDna, - "ESI": CopySelectDialog.copyFormatEsi, - "MultiBuy": CopySelectDialog.copyFormatMultiBuy, - "EFS": CopySelectDialog.copyFormatEfs - } + defaultFormatOptions = {} + for formatId, formatOptions in self.copyFormats.values(): + if formatOptions is None: + continue + defaultFormatOptions[formatId] = {opt[0]: opt[3] for opt in formatOptions} + + self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": defaultFormatOptions}) + # Options used to be stored as int (EFT export options only), + # overwrite them with new format when needed + if isinstance(self.settings["options"], int): + self.settings["options"] = defaultFormatOptions self.options = {} - for i, format in enumerate(self.copyFormats.keys()): - if i == 0: - rdo = wx.RadioButton(self, wx.ID_ANY, format, style=wx.RB_GROUP) + initialized = False + for formatName, formatData in self.copyFormats.items(): + formatId, formatOptions = formatData + if not initialized: + rdo = wx.RadioButton(self, wx.ID_ANY, formatName, style=wx.RB_GROUP) + initialized = True else: - rdo = wx.RadioButton(self, wx.ID_ANY, format) + rdo = wx.RadioButton(self, wx.ID_ANY, formatName) rdo.Bind(wx.EVT_RADIOBUTTON, self.Selected) - if self.settings['format'] == self.copyFormats[format]: + if self.settings['format'] == formatId: rdo.SetValue(True) - self.copyFormat = self.copyFormats[format] + self.copyFormat = formatId mainSizer.Add(rdo, 0, wx.EXPAND | wx.ALL, 5) - if format == "EFT": + if formatOptions: bsizer = wx.BoxSizer(wx.VERTICAL) + self.options[formatId] = {} - for x, v in EFT_OPTIONS.items(): - ch = wx.CheckBox(self, -1, v['name']) - self.options[x] = ch - if self.settings['options'] & x: - ch.SetValue(True) - bsizer.Add(ch, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3) + for optId, optName, optDesc, _ in formatOptions: + checkbox = wx.CheckBox(self, -1, optName) + self.options[formatId][optId] = checkbox + if self.settings['options'].get(formatId, {}).get(optId, defaultFormatOptions.get(formatId, {}).get(optId)): + checkbox.SetValue(True) + bsizer.Add(checkbox, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3) mainSizer.Add(bsizer, 1, wx.EXPAND | wx.LEFT, 20) buttonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL) @@ -83,21 +101,21 @@ class CopySelectDialog(wx.Dialog): def Selected(self, event): obj = event.GetEventObject() - format = obj.GetLabel() - self.copyFormat = self.copyFormats[format] + formatName = obj.GetLabel() + self.copyFormat = self.copyFormats[formatName][0] self.toggleOptions() self.Fit() def toggleOptions(self): - for ch in self.options.values(): - ch.Enable(self.GetSelected() == CopySelectDialog.copyFormatEft) + for formatId in self.options: + for checkbox in self.options[formatId].values(): + checkbox.Enable(self.GetSelected() == formatId) def GetSelected(self): return self.copyFormat def GetOptions(self): - i = 0 - for x, v in self.options.items(): - if v.IsChecked(): - i = i ^ x - return i + options = {} + for formatId in self.options: + options[formatId] = {optId: ch.IsChecked() for optId, ch in self.options[formatId].items()} + return options diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 5f3aa6441..d5bc8f0e9 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -703,10 +703,6 @@ class MainFrame(wx.Frame): fit = db_getFit(self.getActiveFit()) toClipboard(Port.exportEft(fit, options)) - def clipboardEftImps(self, options): - fit = db_getFit(self.getActiveFit()) - toClipboard(Port.exportEftImps(fit)) - def clipboardDna(self, options): fit = db_getFit(self.getActiveFit()) toClipboard(Port.exportDna(fit)) @@ -721,7 +717,7 @@ class MainFrame(wx.Frame): def clipboardMultiBuy(self, options): fit = db_getFit(self.getActiveFit()) - toClipboard(Port.exportMultiBuy(fit)) + toClipboard(Port.exportMultiBuy(fit, options)) def clipboardEfs(self, options): fit = db_getFit(self.getActiveFit()) @@ -744,22 +740,22 @@ class MainFrame(wx.Frame): def exportToClipboard(self, event): CopySelectDict = {CopySelectDialog.copyFormatEft: self.clipboardEft, - # CopySelectDialog.copyFormatEftImps: self.clipboardEftImps, CopySelectDialog.copyFormatXml: self.clipboardXml, CopySelectDialog.copyFormatDna: self.clipboardDna, CopySelectDialog.copyFormatEsi: self.clipboardEsi, CopySelectDialog.copyFormatMultiBuy: self.clipboardMultiBuy, CopySelectDialog.copyFormatEfs: self.clipboardEfs} dlg = CopySelectDialog(self) - dlg.ShowModal() - selected = dlg.GetSelected() - options = dlg.GetOptions() + btnPressed = dlg.ShowModal() - settings = SettingsProvider.getInstance().getSettings("pyfaExport") - settings["format"] = selected - settings["options"] = options + if btnPressed == wx.ID_OK: + selected = dlg.GetSelected() + options = dlg.GetOptions() - CopySelectDict[selected](options) + settings = SettingsProvider.getInstance().getSettings("pyfaExport") + settings["format"] = selected + settings["options"] = options + CopySelectDict[selected](options.get(selected)) try: dlg.Destroy() diff --git a/service/fit.py b/service/fit.py index ad1e5c4dd..035bb50ee 100644 --- a/service/fit.py +++ b/service/fit.py @@ -89,7 +89,6 @@ class Fit(FitDeprecated): "showTooltip": True, "showMarketShortcuts": False, "enableGaugeAnimation": True, - "exportCharges": True, "openFitInNew": False, "priceSystem": "Jita", "priceSource": "eve-marketdata.com", diff --git a/service/port/dna.py b/service/port/dna.py index bd2645ef8..bc64e9e99 100644 --- a/service/port/dna.py +++ b/service/port/dna.py @@ -138,7 +138,7 @@ def exportDna(fit): mods[mod.itemID] = 0 mods[mod.itemID] += 1 - if mod.charge and sFit.serviceFittingOptions["exportCharges"]: + if mod.charge: if mod.chargeID not in charges: charges[mod.chargeID] = 0 # `or 1` because some charges (ie scripts) are without qty diff --git a/service/port/eft.py b/service/port/eft.py index 1cc262e78..4c0d1c6a8 100644 --- a/service/port/eft.py +++ b/service/port/eft.py @@ -19,6 +19,7 @@ import re +from enum import Enum from logbook import Logger @@ -36,7 +37,6 @@ from service.fit import Fit as svcFit from service.market import Market from service.port.muta import parseMutant, renderMutant from service.port.shared import IPortUser, fetchItem, processing_notify -from enum import Enum pyfalog = Logger(__name__) @@ -45,23 +45,20 @@ pyfalog = Logger(__name__) class Options(Enum): IMPLANTS = 1 MUTATIONS = 2 + LOADED_CHARGES = 3 + + +EFT_OPTIONS = ( + (Options.LOADED_CHARGES.value, 'Loaded Charges', 'Export charges loaded into modules', True), + (Options.MUTATIONS.value, 'Mutated Attributes', 'Export mutated modules\' stats', True), + (Options.IMPLANTS.value, 'Implants && Boosters', 'Export implants and boosters', True), +) MODULE_CATS = ('Module', 'Subsystem', 'Structure Module') SLOT_ORDER = (Slot.LOW, Slot.MED, Slot.HIGH, Slot.RIG, Slot.SUBSYSTEM, Slot.SERVICE) OFFLINE_SUFFIX = '/OFFLINE' -EFT_OPTIONS = { - Options.IMPLANTS.value: { - "name": "Implants", - "description": "Exports implants" - }, - Options.MUTATIONS.value: { - "name": "Mutated Attributes", - "description": "Exports Abyssal stats" - } -} - def exportEft(fit, options): # EFT formatted export is split in several sections, each section is @@ -73,7 +70,6 @@ def exportEft(fit, options): # Section 1: modules, rigs, subsystems, services modsBySlotType = {} - sFit = svcFit.getInstance() for module in fit.modules: modsBySlotType.setdefault(module.slot, []).append(module) modSection = [] @@ -85,20 +81,19 @@ def exportEft(fit, options): modules = modsBySlotType.get(slotType, ()) for module in modules: if module.item: - mutated = bool(module.mutators) # if module was mutated, use base item name for export - if mutated: + if module.isMutated: modName = module.baseItem.name else: modName = module.item.name - if mutated and options & Options.MUTATIONS.value: + if module.isMutated and options[Options.MUTATIONS.value]: mutants[mutantReference] = module mutationSuffix = ' [{}]'.format(mutantReference) mutantReference += 1 else: mutationSuffix = '' modOfflineSuffix = ' {}'.format(OFFLINE_SUFFIX) if module.state == State.OFFLINE else '' - if module.charge and sFit.serviceFittingOptions['exportCharges']: + if module.charge and options[Options.LOADED_CHARGES.value]: rackLines.append('{}, {}{}{}'.format( modName, module.charge.name, modOfflineSuffix, mutationSuffix)) else: @@ -127,7 +122,7 @@ def exportEft(fit, options): sections.append('\n\n'.join(minionSection)) # Section 3: implants, boosters - if options & Options.IMPLANTS.value: + if options[Options.IMPLANTS.value]: charSection = [] implantLines = [] for implant in fit.implants: @@ -154,7 +149,7 @@ def exportEft(fit, options): # Section 5: mutated modules' details mutationLines = [] - if mutants and options & Options.MUTATIONS.value: + if mutants and options[Options.MUTATIONS.value]: for mutantReference in sorted(mutants): mutant = mutants[mutantReference] mutationLines.append(renderMutant(mutant, firstPrefix='[{}] '.format(mutantReference), prefix=' ')) diff --git a/service/port/esi.py b/service/port/esi.py index f1e02d13a..8268f23fa 100644 --- a/service/port/esi.py +++ b/service/port/esi.py @@ -97,7 +97,7 @@ def exportESI(ofit): item['type_id'] = module.item.ID fit['items'].append(item) - if module.charge and sFit.serviceFittingOptions["exportCharges"]: + if module.charge: if module.chargeID not in charges: charges[module.chargeID] = 0 # `or 1` because some charges (ie scripts) are without qty diff --git a/service/port/multibuy.py b/service/port/multibuy.py index f50750e76..1c6b78836 100644 --- a/service/port/multibuy.py +++ b/service/port/multibuy.py @@ -18,10 +18,23 @@ # ============================================================================= -from service.fit import Fit as svcFit +from enum import Enum -def exportMultiBuy(fit): +class Options(Enum): + IMPLANTS = 1 + CARGO = 2 + LOADED_CHARGES = 3 + + +MULTIBUY_OPTIONS = ( + (Options.LOADED_CHARGES.value, 'Loaded Charges', 'Export charges loaded into modules', True), + (Options.IMPLANTS.value, 'Implants && Boosters', 'Export implants and boosters', False), + (Options.CARGO.value, 'Cargo', 'Export cargo contents', True), +) + + +def exportMultiBuy(fit, options): itemCounts = {} def addItem(item, quantity=1): @@ -29,11 +42,13 @@ def exportMultiBuy(fit): itemCounts[item] = 0 itemCounts[item] += quantity - exportCharges = svcFit.getInstance().serviceFittingOptions["exportCharges"] for module in fit.modules: if module.item: + # Mutated items are of no use for multibuy + if module.isMutated: + continue addItem(module.item) - if exportCharges and module.charge: + if module.charge and options[Options.LOADED_CHARGES.value]: addItem(module.charge, module.numCharges) for drone in fit.drones: @@ -42,14 +57,16 @@ def exportMultiBuy(fit): for fighter in fit.fighters: addItem(fighter.item, fighter.amountActive) - for cargo in fit.cargo: - addItem(cargo.item, cargo.amount) + if options[Options.CARGO.value]: + for cargo in fit.cargo: + addItem(cargo.item, cargo.amount) - for implant in fit.implants: - addItem(implant.item) + if options[Options.IMPLANTS.value]: + for implant in fit.implants: + addItem(implant.item) - for booster in fit.boosters: - addItem(booster.item) + for booster in fit.boosters: + addItem(booster.item) exportLines = [] exportLines.append(fit.ship.item.name) diff --git a/service/port/port.py b/service/port/port.py index cad3dfae2..409991819 100644 --- a/service/port/port.py +++ b/service/port/port.py @@ -284,5 +284,5 @@ class Port(object): # Multibuy-related methods @staticmethod - def exportMultiBuy(fit): - return exportMultiBuy(fit) + def exportMultiBuy(fit, options): + return exportMultiBuy(fit, options) diff --git a/service/port/xml.py b/service/port/xml.py index 54d5a98eb..432bbcdd8 100644 --- a/service/port/xml.py +++ b/service/port/xml.py @@ -283,7 +283,7 @@ def exportXml(iportuser, *fits): hardware.setAttribute("slot", "%s slot %d" % (slotName, slotId)) fitting.appendChild(hardware) - if module.charge and sFit.serviceFittingOptions["exportCharges"]: + if module.charge: if module.charge.name not in charges: charges[module.charge.name] = 0 # `or 1` because some charges (ie scripts) are without qty