pyfa-org / Pyfa

Python fitting assistant, cross-platform fitting tool for EVE Online
GNU General Public License v3.0
1.59k stars 403 forks source link

Opening "Global -> Preferences" failed #2528

Open samlior opened 10 months ago

samlior commented 10 months ago

Bug Report

pyfa v2.53.0
EVE Data Version: 2291895 (2023-06-13 23:48:15)

OS version: Linux-6.1.45-1-lts-x86_64-with-glibc2.38
Python version: 3.11.3 (main, Jun  5 2023, 09:32:32) [GCC 13.1.1 20230429]
wxPython version: 4.2.1 (wxWidgets 3.2.2.1)
SQLAlchemy version: 1.4.44
Logbook version: 1.5.3
Requests version: 2.28.2
Dateutil version: 2.8.2

####################

Traceback (most recent call last):
  File "/usr/share/pyfa/gui/mainFrame.py", line 486, in OnShowPreferenceDialog
    with PreferenceDialog(self) as dlg:
         ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/pyfa/gui/preferenceDialog.py", line 68, in __init__
    prefView.populatePanel(page)
  File "/usr/share/pyfa/gui/builtinPreferenceViews/pyfaGeneralPreferences.py", line 93, in populatePanel
    langBox.Add(wx.StaticText(panel, wx.ID_ANY,
wx._core.wxAssertionError: C++ assertion "CheckSizerFlags(!((flags) & (wxALIGN_CENTRE_VERTICAL)))" failed at /usr/src/debug/wxwidgets/wxWidgets-3.2.2.1/src/common/sizer.cpp(2258) in DoInsert(): wxALIGN_CENTRE_VERTICAL will be ignored in this sizer: only horizontal alignment flags can be used in vertical sizers

DO NOT PANIC !!

If you're an end user running a program not developed by you, please ignore this message, it is harmless, and please try reporting the problem to the program developers.

You may also set WXSUPPRESS_SIZER_FLAGS_CHECK environment variable to suppress all such checks when running this program.

If you're the developer, simply remove this flag from your code to avoid getting this message. You can also call wxSizerFlags::DisableConsistencyChecks() to globally disable all such checks, but this is strongly not recommended.

Expected behavior:

Actual behavior:

Detailed steps to reproduce:

Global -> Preferences

Fits involved in EFT format (Edit > To Clipboard > EFT):

Release or development git branch? Please note the release version or commit hash:

Release v2.53.0

Operating system and version (eg: Windows 10, OS X 10.9, OS X 10.11, Ubuntu 16.10):

Archlinux rolling

Other relevant information:

tadeasf commented 9 months ago

well, it took me ages to figure out the requirements for m1 macs, but here we go!

also related to this: https://github.com/pyfa-org/Pyfa/issues/2517

  1. i switched to conda (anaconda3-2023.07-2). then you can actually install most of the original reqs even on m1. environment.yml:
name: pyfa-conda-env
channels:
  - conda-forge
dependencies:
  - altgraph=0.17.4=pyhd8ed1ab_0
  - appdirs=1.4.4=pyh9f0ad1d_0
  - attrs=23.1.0=pyh71513ae_1
  - beautifulsoup4=4.12.2=pyha770c72_0
  - brotli-python=1.1.0=py39hb198ff7_1
  - bson=0.5.9=py_0
  - bzip2=1.0.8=h3422bc3_4
  - ca-certificates=2023.7.22=hf0a4a13_0
  - cattrs=23.1.2=pyhd8ed1ab_0
  - certifi=2023.7.22=pyhd8ed1ab_0
  - cffi=1.16.0=py39he153c15_0
  - charset-normalizer=2.1.1=pyhd8ed1ab_0
  - cryptography=41.0.4=py39had97604_0
  - ecdsa=0.18.0=pyhd8ed1ab_1
  - exceptiongroup=1.1.3=pyhd8ed1ab_0
  - expat=2.5.0=hb7217d7_1
  - freetype=2.12.1=hadb7bae_2
  - future=0.18.3=pyhd8ed1ab_0
  - gettext=0.21.1=h0186832_0
  - gmp=6.2.1=h9f76cd9_0
  - gmpy2=2.1.2=py39h0b4f9c6_1
  - idna=3.4=pyhd8ed1ab_0
  - itsdangerous=2.1.2=pyhd8ed1ab_0
  - jpeg=9e=h1a8c8d9_3
  - lcms2=2.15=h481adae_0
  - lerc=4.0.0=h9a09cb3_0
  - libblas=3.9.0=18_osxarm64_openblas
  - libcblas=3.9.0=18_osxarm64_openblas
  - libcxx=16.0.6=h4653b0c_0
  - libdeflate=1.17=h1a8c8d9_0
  - libexpat=2.5.0=hb7217d7_1
  - libffi=3.4.2=h3422bc3_5
  - libgfortran=5.0.0=13_2_0_hd922786_1
  - libgfortran5=13.2.0=hf226fd6_1
  - libiconv=1.17=he4db4b2_0
  - liblapack=3.9.0=18_osxarm64_openblas
  - libopenblas=0.3.24=openmp_hd76b1f2_0
  - libpng=1.6.39=h76d750c_0
  - libsqlite=3.43.0=hb31c410_0
  - libtiff=4.5.0=h5dffbdd_2
  - libwebp-base=1.3.2=hb547adb_0
  - libxcb=1.13=h9b22ae9_1004
  - libzlib=1.2.13=h53f4e23_5
  - llvm-openmp=16.0.6=h1c12783_0
  - logbook=1.6.0=py39h0f82c59_1
  - macholib=1.16.3=pyhd8ed1ab_0
  - markdown2=2.4.10=pyhd8ed1ab_0
  - modulegraph=0.19.6=pyhd8ed1ab_0
  - mpc=1.3.1=h91ba8db_0
  - mpfr=4.2.0=he09a6ba_0
  - ncurses=6.4=h7ea286d_0
  - numpy=1.19.2=py39h676175f_1
  - openjpeg=2.5.0=hbc2ba62_2
  - openssl=3.1.3=h53f4e23_0
  - packaging=23.1=pyhd8ed1ab_0
  - pathlib2=2.3.7.post1=py39h2804cbe_3
  - pillow=9.4.0=py39h8bd98a6_1
  - pip=23.2.1=pyhd8ed1ab_0
  - platformdirs=3.10.0=pyhd8ed1ab_0
  - pthread-stubs=0.4=h27ca646_1001
  - py2app=0.28.6=py39h0f82c59_0
  - pycparser=2.21=pyhd8ed1ab_0
  - pypubsub=4.0.3=py_0
  - pysocks=1.7.1=pyha2e5f31_6
  - python=3.9.18=hfa1ae8a_0_cpython
  - python-dateutil=2.8.2=pyhd8ed1ab_0
  - python-jose=3.0.1=pyh9f0ad1d_0
  - python.app=1.4=py39h8feb81c_3
  - python_abi=3.9=4_cp39
  - pyyaml=6.0.1=py39h0f82c59_1
  - readline=8.2=h92ec313_1
  - requests=2.28.1=pyhd8ed1ab_1
  - requests-cache=1.1.0=pyhd8ed1ab_0
  - roman=4.1=pyhd8ed1ab_0
  - setuptools=68.2.2=pyhd8ed1ab_0
  - six=1.16.0=pyh6c4a22f_0
  - soupsieve=2.5=pyhd8ed1ab_1
  - sqlalchemy=1.3.23=py39h5161555_0
  - tk=8.6.13=hb31c410_0
  - typing-extensions=4.8.0=hd8ed1ab_0
  - typing_extensions=4.8.0=pyha770c72_0
  - tzdata=2023c=h71feb2d_0
  - ujson=5.8.0=py39hb198ff7_0
  - url-normalize=1.4.3=pyhd8ed1ab_0
  - urllib3=1.26.16=pyhd8ed1ab_0
  - wheel=0.41.2=pyhd8ed1ab_0
  - wxpython=4.1.1=py39h2d7ee21_9
  - xorg-libxau=1.0.11=hb547adb_0
  - xorg-libxdmcp=1.1.3=h27ca646_0
  - xz=5.2.6=h57fd34a_0
  - yaml=0.2.5=h3422bc3_2
  - zlib=1.2.13=h53f4e23_5
  - zstd=1.5.5=h4f39d0f_0
  1. change pyfa.spec a variable, remove git if you want to build the .app package locally etc:

    
    # -*- mode: python -*-

import os from itertools import chain import subprocess import requests.certs

label = "v2.54.0"

block_cipher = None

added_files = [ ('../../imgs/gui/.png', 'imgs/gui'), ('../../imgs/gui/.gif', 'imgs/gui'), ('../../imgs/icons/.png', 'imgs/icons'), ('../../imgs/renders/.png', 'imgs/renders'), ('../../dist_assets/win/pyfa.ico', '.'), ('../../service/jargon/*.yaml', 'service/jargon'), ('../../locale', 'locale'), (requests.certs.where(), '.'), # is this needed anymore? ('../../eve.db', '.'), ('../../README.md', '.'), ('../../LICENSE', '.'), ('../../version.yml', '.'), ]

import_these = [ 'numpy.core._dtype_ctypes', # https://github.com/pyinstaller/pyinstaller/issues/3982 'sqlalchemy.ext.baked', # windows build doesn't launch without if when using sqlalchemy 1.3.x 'pkg_resources.py2_warn' # issue 2156 ]

icon = os.path.join(os.getcwd(), "dist_assets", "mac", "pyfa.icns")

Walk directories that do dynamic importing

paths = ('eos/db/migrations', 'service/conversions') for root, folders, files in chain.fromiterable(os.walk(path) for path in paths): for file in files: if file.endswith(".py") and not file.startswith("_"): modname = "{}.{}".format( root.replace("/", "."), file.split(".py")[0], ) import_these.append(mod_name)

a = Analysis([r'/Users/tadeasfort/Downloads/pyfa/pyfa.py'], pathex=['/Users/tadeasfort/.pyenv/versions/anaconda3-2023.07-2/envs/pyfa-ocnda-env/bin'], binaries=[], datas=added_files, hiddenimports=import_these, hookspath=['dist_assets/pyinstaller_hooks'], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='pyfa', debug=False, strip=False, upx=True, runtime_tmpdir=None, console=False , icon=icon, )

app = BUNDLE( exe, name='pyfa.app', icon=icon, bundle_identifier=None, info_plist={ 'NSHighResolutionCapable': 'True', 'NSPrincipalClass': 'NSApplication', 'CFBundleName': 'pyfa', 'CFBundleDisplayName': 'pyfa', 'CFBundleIdentifier': 'org.pyfaorg.pyfa', } )


after this you need to update the preferences panel as we are using 4.1.1 wxpython instead of 4.0.6 and there were some changes regarding sizer

pyfaGeneralPreferences.py:

``` python
# noinspection PyPackageRequirements
import wx

import gui.globalEvents as GE
import gui.mainFrame
from gui.bitmap_loader import BitmapLoader
from gui.preferenceView import PreferenceView
from service.fit import Fit
from service.settings import SettingsProvider, LocaleSettings
import eos.config
import wx.lib.agw.hyperlink as hl

_t = wx.GetTranslation

class PFGeneralPref(PreferenceView):
    def populatePanel(self, panel):
        self.title = _t("General")
        self.mainFrame = gui.mainFrame.MainFrame.getInstance()
        self.dirtySettings = False
        self.openFitsSettings = SettingsProvider.getInstance().getSettings(
            "pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []}
        )
        self.localeSettings = LocaleSettings.getInstance()
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.stTitle = wx.StaticText(
            panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0
        )
        self.stTitle.Wrap(-1)
        self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString))
        mainSizer.Add(self.stTitle, 0, wx.EXPAND | wx.ALL, 5)

        helpCursor = wx.Cursor(wx.CURSOR_QUESTION_ARROW)

        self.m_staticline1 = wx.StaticLine(
            panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL
        )
        mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)

        langBox = wx.StaticBoxSizer(
            wx.VERTICAL, panel, _t("Language (requires restart)")
        )
        mainSizer.Add(langBox, 0, wx.EXPAND | wx.TOP | wx.RIGHT | wx.BOTTOM, 10)

        langSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.langChoices = sorted(
            [
                langInfo
                for lang, langInfo in LocaleSettings.supported_langauges().items()
            ],
            key=lambda x: x.Description,
        )
        pyfaLangsEnabled = bool(self.langChoices)

        if pyfaLangsEnabled:
            self.stLangLabel = wx.StaticText(
                panel, wx.ID_ANY, _t("pyfa:"), wx.DefaultPosition, wx.DefaultSize, 0
            )
            self.stLangLabel.Wrap(-1)
            langSizer.Add(self.stLangLabel, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

            def langDisplay(langInfo):
                progress = self.localeSettings.get_progress(langInfo.CanonicalName)
                progress_display = (
                    " ({}%)".format(progress["translated_progress"])
                    if progress is not None
                    else ""
                )
                return langInfo.Description + progress_display

            self.chLang = wx.Choice(
                panel,
                wx.ID_ANY,
                wx.DefaultPosition,
                wx.DefaultSize,
                [langDisplay(x) for x in self.langChoices],
                0,
            )
            self.chLang.Bind(wx.EVT_CHOICE, self.onLangSelection)

            selectedIndex = self.langChoices.index(
                next(
                    (
                        x
                        for x in self.langChoices
                        if x.CanonicalName == self.localeSettings.get("locale")
                    ),
                    None,
                )
            )
            self.chLang.SetSelection(selectedIndex)

            langSizer.Add(self.chLang, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
            langBox.Add(langSizer)
            langBox.Add(
                hl.HyperLinkCtrl(
                    panel,
                    -1,
                    _t("Interested in helping with translations?"),
                    URL="https://github.com/pyfa-org/Pyfa/blob/master/locale/README.md",
                ),
                0,
                wx.LEFT | wx.ALIGN_CENTER_VERTICAL,
                15,
            )
        else:
            self.stLangLabel = wx.StaticText(
                panel,
                wx.ID_ANY,
                _t(
                    "Pyfa language selection disabled. Please check if .mo files have been generated.\nRefer to locale/README.md for info."
                ),
                wx.DefaultPosition,
                wx.DefaultSize,
                0,
            )
            self.stLangLabel.Wrap(-1)
            langSizer.Add(self.stLangLabel, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
            langBox.Add(langSizer)

        eosLangSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.stEosLangLabel = wx.StaticText(
            panel, wx.ID_ANY, _t("EVE Data:"), wx.DefaultPosition, wx.DefaultSize, 0
        )
        self.stEosLangLabel.Wrap(-1)
        eosLangSizer.Add(self.stEosLangLabel, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        self.eosLangChoices = [
            (
                LocaleSettings.defaults["eos_locale"],
                LocaleSettings.defaults["eos_locale"],
            )
        ] + sorted(
            [
                (wx.Locale.FindLanguageInfo(x).Description, x)
                for x in eos.config.translation_mapping.keys()
            ],
            key=lambda x: x[0],
        )

        self.chEosLang = wx.Choice(
            panel,
            wx.ID_ANY,
            wx.DefaultPosition,
            wx.DefaultSize,
            [x[0] for x in self.eosLangChoices],
            0,
        )
        self.chEosLang.Bind(wx.EVT_CHOICE, self.onEosLangSelection)

        selectedIndex = self.eosLangChoices.index(
            next(
                (
                    x
                    for x in self.eosLangChoices
                    if x[1] == self.localeSettings.get("eos_locale")
                ),
                None,
            )
        )
        self.chEosLang.SetSelection(selectedIndex)

        eosLangSizer.Add(self.chEosLang, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        langBox.Add(eosLangSizer)
        langBox.Add(
            wx.StaticText(
                panel,
                wx.ID_ANY,
                _t(
                    "Auto will use the same language pyfa uses if available, otherwise English"
                ),
                wx.DefaultPosition,
                wx.DefaultSize,
                0,
            ),
            proportion=0,
            flag=wx.LEFT,
            border=15,
        )

        self.cbGlobalChar = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Use global character"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbGlobalChar, 0, wx.ALL | wx.EXPAND, 5)

        self.cbDefaultCharImplants = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Use character implants by default for new fits"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbDefaultCharImplants, 0, wx.ALL | wx.EXPAND, 5)

        self.cbGlobalDmgPattern = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Use global damage pattern"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbGlobalDmgPattern, 0, wx.ALL | wx.EXPAND, 5)

        self.cbCompactSkills = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Compact skills needed tooltip"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbCompactSkills, 0, wx.ALL | wx.EXPAND, 5)

        self.cbFitColorSlots = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Color fitting view by slot"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbFitColorSlots, 0, wx.ALL | wx.EXPAND, 5)

        self.cbReopenFits = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Reopen previous fits on startup"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbReopenFits, 0, wx.ALL | wx.EXPAND, 5)

        self.cbRackSlots = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Separate Racks"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbRackSlots, 0, wx.ALL | wx.EXPAND, 5)

        labelSizer = wx.BoxSizer(wx.VERTICAL)
        self.cbRackLabels = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Show Rack Labels"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        labelSizer.Add(self.cbRackLabels, 0, wx.ALL | wx.EXPAND, 5)
        mainSizer.Add(labelSizer, 0, wx.LEFT | wx.EXPAND, 30)

        self.cbShowTooltip = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Show fitting tab tooltips"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbShowTooltip, 0, wx.ALL | wx.EXPAND, 5)

        self.cbGaugeAnimation = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Animate gauges"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5)

        self.cbOpenFitInNew = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Open fittings in a new page by default"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5)

        self.cbShowShipBrowserTooltip = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Show ship browser tooltip"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        mainSizer.Add(self.cbShowShipBrowserTooltip, 0, wx.ALL | wx.EXPAND, 5)

        self.cbReloadAll = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Change charge in all modules of the same type"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        if "wxGTK" not in wx.PlatformInfo:
            self.cbReloadAll.SetCursor(helpCursor)
        self.cbReloadAll.SetToolTip(
            wx.ToolTip(
                _t(
                    "When disabled, reloads charges just in selected modules. Action can be reversed by holding Ctrl or Alt key while changing charge."
                )
            )
        )
        mainSizer.Add(self.cbReloadAll, 0, wx.ALL | wx.EXPAND, 5)

        self.cbExpMutants = wx.CheckBox(
            panel,
            wx.ID_ANY,
            _t("Include more information in names of mutated items"),
            wx.DefaultPosition,
            wx.DefaultSize,
            0,
        )
        if "wxGTK" not in wx.PlatformInfo:
            self.cbExpMutants.SetCursor(helpCursor)
        self.cbExpMutants.SetToolTip(
            wx.ToolTip(
                _t(
                    "Use short mutaplasmid name and base item name instead of actual item name. Works if EVE data language is set to English."
                )
            )
        )
        mainSizer.Add(self.cbExpMutants, 0, wx.ALL | wx.EXPAND, 5)

        self.rbAddLabels = wx.RadioBox(
            panel,
            -1,
            _t("Extra info in Additions panel tab names"),
            wx.DefaultPosition,
            wx.DefaultSize,
            [_t("None"), _t("Quantity of active items"), _t("Quantity of all items")],
            1,
            wx.RA_SPECIFY_COLS,
        )
        mainSizer.Add(
            self.rbAddLabels, 0, wx.EXPAND | wx.TOP | wx.RIGHT | wx.BOTTOM, 10
        )
        self.rbAddLabels.Bind(wx.EVT_RADIOBOX, self.OnAddLabelsChange)

        self.sFit = Fit.getInstance()

        self.cbGlobalChar.SetValue(
            self.sFit.serviceFittingOptions["useGlobalCharacter"]
        )
        self.cbDefaultCharImplants.SetValue(
            self.sFit.serviceFittingOptions["useCharacterImplantsByDefault"]
        )
        self.cbGlobalDmgPattern.SetValue(
            self.sFit.serviceFittingOptions["useGlobalDamagePattern"]
        )
        self.cbFitColorSlots.SetValue(
            self.sFit.serviceFittingOptions["colorFitBySlot"] or False
        )
        self.cbRackSlots.SetValue(self.sFit.serviceFittingOptions["rackSlots"] or False)
        self.cbRackLabels.SetValue(
            self.sFit.serviceFittingOptions["rackLabels"] or False
        )
        self.cbCompactSkills.SetValue(
            self.sFit.serviceFittingOptions["compactSkills"] or False
        )
        self.cbReopenFits.SetValue(self.openFitsSettings["enabled"])
        self.cbShowTooltip.SetValue(
            self.sFit.serviceFittingOptions["showTooltip"] or False
        )
        self.cbGaugeAnimation.SetValue(
            self.sFit.serviceFittingOptions["enableGaugeAnimation"]
        )
        self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"])
        self.cbShowShipBrowserTooltip.SetValue(
            self.sFit.serviceFittingOptions["showShipBrowserTooltip"]
        )
        self.cbReloadAll.SetValue(self.sFit.serviceFittingOptions["ammoChangeAll"])
        self.cbExpMutants.SetValue(
            self.sFit.serviceFittingOptions["expandedMutantNames"]
        )
        self.rbAddLabels.SetSelection(
            self.sFit.serviceFittingOptions["additionsLabels"]
        )

        self.cbGlobalChar.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalCharStateChange)
        self.cbDefaultCharImplants.Bind(
            wx.EVT_CHECKBOX, self.OnCBDefaultCharImplantsStateChange
        )
        self.cbGlobalDmgPattern.Bind(
            wx.EVT_CHECKBOX, self.OnCBGlobalDmgPatternStateChange
        )
        self.cbFitColorSlots.Bind(wx.EVT_CHECKBOX, self.onCBGlobalColorBySlot)
        self.cbRackSlots.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackSlots)
        self.cbRackLabels.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackLabels)
        self.cbCompactSkills.Bind(wx.EVT_CHECKBOX, self.onCBCompactSkills)
        self.cbReopenFits.Bind(wx.EVT_CHECKBOX, self.onCBReopenFits)
        self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip)
        self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation)
        self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew)
        self.cbShowShipBrowserTooltip.Bind(
            wx.EVT_CHECKBOX, self.onCBShowShipBrowserTooltip
        )
        self.cbReloadAll.Bind(wx.EVT_CHECKBOX, self.onCBReloadAll)
        self.cbExpMutants.Bind(wx.EVT_CHECKBOX, self.onCBExpMutants)

        self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False)

        panel.SetSizer(mainSizer)
        panel.Layout()

    def onLangSelection(self, event):
        selection = self.chLang.GetSelection()
        locale = self.langChoices[selection]
        self.localeSettings.set("locale", locale.CanonicalName)

    def onEosLangSelection(self, event):
        selection = self.chEosLang.GetSelection()
        locale = self.eosLangChoices[selection]
        self.localeSettings.set("eos_locale", locale[1])

    def onCBGlobalColorBySlot(self, event):
        # todo: maybe create a SettingChanged event that we can fire, and have other things hook into, instead of having the preference panel itself handle the
        # updating of things related to settings.
        self.sFit.serviceFittingOptions[
            "colorFitBySlot"
        ] = self.cbFitColorSlots.GetValue()
        fitID = self.mainFrame.getActiveFit()
        self.sFit.refreshFit(fitID)

        iView = self.mainFrame.marketBrowser.itemView
        if iView.active:
            iView.update(iView.active)

        wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
        event.Skip()

    def onCBGlobalRackSlots(self, event):
        self.sFit.serviceFittingOptions["rackSlots"] = self.cbRackSlots.GetValue()
        self.cbRackLabels.Enable(self.cbRackSlots.GetValue())
        fitID = self.mainFrame.getActiveFit()
        self.sFit.refreshFit(fitID)
        wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
        event.Skip()

    def onCBGlobalRackLabels(self, event):
        self.sFit.serviceFittingOptions["rackLabels"] = self.cbRackLabels.GetValue()
        fitID = self.mainFrame.getActiveFit()
        self.sFit.refreshFit(fitID)
        wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
        event.Skip()

    def OnCBGlobalCharStateChange(self, event):
        self.sFit.serviceFittingOptions[
            "useGlobalCharacter"
        ] = self.cbGlobalChar.GetValue()
        event.Skip()

    def OnCBDefaultCharImplantsStateChange(self, event):
        self.sFit.serviceFittingOptions[
            "useCharacterImplantsByDefault"
        ] = self.cbDefaultCharImplants.GetValue()
        event.Skip()

    def OnCBGlobalDmgPatternStateChange(self, event):
        self.sFit.serviceFittingOptions[
            "useGlobalDamagePattern"
        ] = self.cbGlobalDmgPattern.GetValue()
        event.Skip()

    def onCBCompactSkills(self, event):
        self.sFit.serviceFittingOptions[
            "compactSkills"
        ] = self.cbCompactSkills.GetValue()
        fitID = self.mainFrame.getActiveFit()
        self.sFit.refreshFit(fitID)
        wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
        event.Skip()

    def onCBReopenFits(self, event):
        self.openFitsSettings["enabled"] = self.cbReopenFits.GetValue()

    def onCBShowTooltip(self, event):
        self.sFit.serviceFittingOptions["showTooltip"] = self.cbShowTooltip.GetValue()

    def onCBGaugeAnimation(self, event):
        self.sFit.serviceFittingOptions[
            "enableGaugeAnimation"
        ] = self.cbGaugeAnimation.GetValue()

    def onCBOpenFitInNew(self, event):
        self.sFit.serviceFittingOptions["openFitInNew"] = self.cbOpenFitInNew.GetValue()

    def onCBShowShipBrowserTooltip(self, event):
        self.sFit.serviceFittingOptions[
            "showShipBrowserTooltip"
        ] = self.cbShowShipBrowserTooltip.GetValue()

    def onCBReloadAll(self, event):
        self.sFit.serviceFittingOptions["ammoChangeAll"] = self.cbReloadAll.GetValue()

    def onCBExpMutants(self, event):
        self.sFit.serviceFittingOptions[
            "expandedMutantNames"
        ] = self.cbExpMutants.GetValue()
        fitID = self.mainFrame.getActiveFit()
        wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))

    def OnAddLabelsChange(self, event):
        self.sFit.serviceFittingOptions["additionsLabels"] = event.GetInt()
        fitID = self.mainFrame.getActiveFit()
        self.sFit.refreshFit(fitID)
        wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,)))
        event.Skip()

    def getImage(self):
        return BitmapLoader.getBitmap("prefs_settings", "gui")

PFGeneralPref.register()

also change similarly the preferenceDialog.py:

import wx
from gui.preferenceView import PreferenceView
from gui.bitmap_loader import BitmapLoader

_t = wx.GetTranslation

class PreferenceDialog(wx.Dialog):

    def __init__(self, parent):
        super().__init__(parent, id=wx.ID_ANY, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE)
        self.SetTitle("pyfa - " + _t("Preferences"))
        i = wx.Icon(BitmapLoader.getBitmap("preferences_small", "gui"))
        self.SetIcon(i)
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.listbook = wx.Listbook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LB_DEFAULT)

        self.listview = self.listbook.GetListView()
        # self.listview.SetMinSize((500, -1))
        # self.listview.SetSize((500, -1))

        self.imageList = wx.ImageList(32, 32)
        self.listbook.AssignImageList(self.imageList)

        mainSizer.Add(self.listbook, 1, wx.EXPAND | wx.TOP | wx.BOTTOM | wx.LEFT, 5)

        self.m_staticline2 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
        mainSizer.Add(self.m_staticline2, 0, wx.EXPAND, 5)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.AddStretchSpacer()
        # localization todo: "OK" button shoudl be a built in thing that is already localized...
        self.btnOK = wx.Button(self, wx.ID_ANY, "OK", wx.DefaultPosition, wx.DefaultSize, 0)
        btnSizer.Add(self.btnOK, 0, wx.ALL, 5)
        mainSizer.Add(btnSizer, 0, wx.EXPAND, 5)
        self.SetSizer(mainSizer)

        self.Centre(wx.BOTH)

        for prefView in PreferenceView.views:
            page = wx.ScrolledWindow(self.listbook)
            page.SetScrollRate(15, 15)
            bmp = prefView.getImage()
            if bmp:
                imgID = self.imageList.Add(bmp)
            else:
                imgID = -1
            prefView.populatePanel(page)

            self.listbook.AddPage(page, prefView.title, imageId=imgID)

        bestFit = self.GetBestVirtualSize()
        width = max(bestFit[0], 800 if "wxGTK" in wx.PlatformInfo else 650)
        height = max(bestFit[1], 550)
        self.SetSize(width, height)

        self.Layout()

        self.Bind(wx.EVT_CHAR_HOOK, self.kbEvent)
        self.btnOK.Bind(wx.EVT_BUTTON, self.OnBtnOK)

    def OnBtnOK(self, event):
        self.Close()

    def kbEvent(self, event):
        if event.GetKeyCode() == wx.WXK_ESCAPE and event.GetModifiers() == wx.MOD_NONE:
            self.Close()
            return
        event.Skip()

and finally modify the osx-package.sh script to accommodate these changes and use the conda virtual env we've created:

#!/usr/bin/env bash

# Activate your conda environment
source activate /Users/tadeasfort/.pyenv/versions/anaconda3-2023.07-2/envs/pyfa-ocnda-env

# Check if PYFA_VERSION is set
if [ -z "$PYFA_VERSION" ]; then
  echo "PYFA_VERSION is not set. Exiting."
  exit 1
fi

# Check if version.yml exists
if [ ! -f "version.yml" ]; then
  echo "version.yml not found. Exiting."
  exit 1
fi

echo "Pyfa version (ENV): $PYFA_VERSION"
echo "Pyfa version (YAML):"
cat version.yml

# Build the application
echo "Building distributive..."
python -m PyInstaller -y --clean dist_assets/mac/pyfa.spec

# Check if dist directory exists
if [ ! -d "dist" ]; then
  echo "dist directory not found. Exiting."
  exit 1
fi

echo "Compressing distributive..."
cd dist
/usr/libexec/PlistBuddy -c "Add :CFBundleVersion string $PYFA_VERSION" "pyfa.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $PYFA_VERSION" "pyfa.app/Contents/Info.plist"
zip -r "pyfa-$PYFA_VERSION-mac.zip" pyfa.app
md5 -r "pyfa-$PYFA_VERSION-mac.zip"

i suppose you won't be interested in doing this, so I am including link for modified .app which works flawlessly on my m1 pro. but i haven't tested extensivelly, mind you.

https://file.io/jQmdQCW3POA6