224 lines
6.8 KiB
Python
224 lines
6.8 KiB
Python
from typing import override
|
|
|
|
from archinstall.default_profiles.profile import GreeterType, Profile
|
|
from archinstall.lib.general.system_menu import select_driver
|
|
from archinstall.lib.hardware import GfxDriver
|
|
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
|
|
from archinstall.lib.menu.helpers import Confirmation, Selection
|
|
from archinstall.lib.models.profile import ProfileConfiguration
|
|
from archinstall.lib.translationhandler import tr
|
|
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
|
|
from archinstall.tui.ui.result import ResultType
|
|
|
|
|
|
class ProfileMenu(AbstractSubMenu[ProfileConfiguration]):
|
|
def __init__(
|
|
self,
|
|
preset: ProfileConfiguration | None = None,
|
|
):
|
|
if preset:
|
|
self._profile_config = preset
|
|
else:
|
|
self._profile_config = ProfileConfiguration()
|
|
|
|
menu_options = self._define_menu_options()
|
|
self._item_group = MenuItemGroup(menu_options, checkmarks=True)
|
|
|
|
super().__init__(
|
|
self._item_group,
|
|
self._profile_config,
|
|
allow_reset=True,
|
|
)
|
|
|
|
def _define_menu_options(self) -> list[MenuItem]:
|
|
return [
|
|
MenuItem(
|
|
text=tr('Type'),
|
|
action=self._select_profile,
|
|
value=self._profile_config.profile,
|
|
preview_action=self._preview_profile,
|
|
key='profile',
|
|
),
|
|
MenuItem(
|
|
text=tr('Graphics driver'),
|
|
action=self._select_gfx_driver,
|
|
value=self._profile_config.gfx_driver if self._profile_config.profile and self._profile_config.profile.is_graphic_driver_supported() else None,
|
|
preview_action=self._prev_gfx,
|
|
enabled=self._profile_config.profile.is_graphic_driver_supported() if self._profile_config.profile else False,
|
|
dependencies=['profile'],
|
|
key='gfx_driver',
|
|
),
|
|
MenuItem(
|
|
text=tr('Greeter'),
|
|
action=lambda x: select_greeter(preset=x),
|
|
value=self._profile_config.greeter if self._profile_config.profile and self._profile_config.profile.is_greeter_supported() else None,
|
|
enabled=self._profile_config.profile.is_graphic_driver_supported() if self._profile_config.profile else False,
|
|
preview_action=self._prev_greeter,
|
|
dependencies=['profile'],
|
|
key='greeter',
|
|
),
|
|
]
|
|
|
|
@override
|
|
async def show(self) -> ProfileConfiguration | None:
|
|
return await super().show()
|
|
|
|
async def _select_profile(self, preset: Profile | None) -> Profile | None:
|
|
profile = await select_profile(preset)
|
|
|
|
if profile is not None:
|
|
if not profile.is_graphic_driver_supported():
|
|
self._item_group.find_by_key('gfx_driver').enabled = False
|
|
self._item_group.find_by_key('gfx_driver').value = None
|
|
else:
|
|
self._item_group.find_by_key('gfx_driver').enabled = True
|
|
self._item_group.find_by_key('gfx_driver').value = GfxDriver.AllOpenSource
|
|
|
|
if not profile.is_greeter_supported():
|
|
self._item_group.find_by_key('greeter').enabled = False
|
|
self._item_group.find_by_key('greeter').value = None
|
|
else:
|
|
self._item_group.find_by_key('greeter').enabled = True
|
|
self._item_group.find_by_key('greeter').value = profile.default_greeter_type
|
|
else:
|
|
self._item_group.find_by_key('gfx_driver').value = None
|
|
self._item_group.find_by_key('greeter').value = None
|
|
|
|
return profile
|
|
|
|
async def _select_gfx_driver(self, preset: GfxDriver | None = None) -> GfxDriver | None:
|
|
driver = preset
|
|
profile: Profile | None = self._item_group.find_by_key('profile').value
|
|
|
|
if profile:
|
|
if profile.is_graphic_driver_supported():
|
|
driver = await select_driver(preset=preset)
|
|
|
|
if driver and 'Sway' in profile.current_selection_names():
|
|
if driver.is_nvidia_proprietary():
|
|
header = tr('The proprietary Nvidia driver is not supported by Sway.') + '\n'
|
|
header += tr('It is likely that you will run into issues, are you okay with that?') + '\n'
|
|
|
|
result = await Confirmation(
|
|
header=header,
|
|
allow_skip=False,
|
|
preset=False,
|
|
).show()
|
|
|
|
return driver if result.get_value() else preset
|
|
|
|
return driver
|
|
|
|
def _prev_gfx(self, item: MenuItem) -> str | None:
|
|
if item.value:
|
|
driver = item.get_value().value
|
|
packages = item.get_value().packages_text()
|
|
return f'Driver: {driver}\n{packages}'
|
|
return None
|
|
|
|
def _prev_greeter(self, item: MenuItem) -> str | None:
|
|
if item.value:
|
|
return f'{tr("Greeter")}: {item.value.value}'
|
|
return None
|
|
|
|
def _preview_profile(self, item: MenuItem) -> str | None:
|
|
profile: Profile | None = item.value
|
|
text = ''
|
|
|
|
if profile:
|
|
if (sub_profiles := profile.current_selection) is not None:
|
|
text += tr('Selected profiles: ')
|
|
text += ', '.join(p.name for p in sub_profiles) + '\n'
|
|
|
|
if packages := profile.packages_text(include_sub_packages=True):
|
|
text += f'{packages}'
|
|
|
|
if text:
|
|
return text
|
|
|
|
return None
|
|
|
|
|
|
async def select_greeter(
|
|
profile: Profile | None = None,
|
|
preset: GreeterType | None = None,
|
|
) -> GreeterType | None:
|
|
if not profile or profile.is_greeter_supported():
|
|
items = [MenuItem(greeter.value, value=greeter) for greeter in GreeterType]
|
|
group = MenuItemGroup(items, sort_items=True)
|
|
|
|
default: GreeterType | None = None
|
|
if preset is not None:
|
|
default = preset
|
|
elif profile is not None:
|
|
default_greeter = profile.default_greeter_type
|
|
default = default_greeter if default_greeter else None
|
|
|
|
group.set_default_by_value(default)
|
|
|
|
result = await Selection[GreeterType](
|
|
group,
|
|
header=tr('Select which greeter to install'),
|
|
allow_skip=True,
|
|
).show()
|
|
|
|
match result.type_:
|
|
case ResultType.Skip:
|
|
return preset
|
|
case ResultType.Selection:
|
|
return result.get_value()
|
|
case ResultType.Reset:
|
|
raise ValueError('Unhandled result type')
|
|
|
|
return None
|
|
|
|
|
|
async def select_profile(
|
|
current_profile: Profile | None = None,
|
|
header: str | None = None,
|
|
allow_reset: bool = True,
|
|
) -> Profile | None:
|
|
from archinstall.lib.profile.profiles_handler import profile_handler
|
|
|
|
top_level_profiles = profile_handler.get_top_level_profiles()
|
|
|
|
if header is None:
|
|
header = tr('Select a profile type')
|
|
|
|
items = [MenuItem(p.name, value=p) for p in top_level_profiles]
|
|
group = MenuItemGroup(items, sort_items=True)
|
|
group.set_selected_by_value(current_profile)
|
|
|
|
result = await Selection[Profile](
|
|
group,
|
|
header=header,
|
|
allow_reset=allow_reset,
|
|
allow_skip=True,
|
|
).show()
|
|
|
|
match result.type_:
|
|
case ResultType.Reset:
|
|
return None
|
|
case ResultType.Skip:
|
|
return current_profile
|
|
case ResultType.Selection:
|
|
profile_selection = result.get_value()
|
|
select_result = await profile_selection.do_on_select()
|
|
|
|
if not select_result:
|
|
return None
|
|
|
|
# we're going to reset the currently selected profile(s) to avoid
|
|
# any stale data laying around
|
|
match select_result:
|
|
case select_result.NewSelection:
|
|
profile_handler.reset_top_level_profiles(exclude=[profile_selection])
|
|
current_profile = profile_selection
|
|
case select_result.ResetCurrent:
|
|
profile_handler.reset_top_level_profiles()
|
|
current_profile = None
|
|
case select_result.SameSelection:
|
|
pass
|
|
|
|
return current_profile
|