You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qubes-installer-qubes-os/anaconda/pyanaconda/ui/tui/spokes/software.py

226 lines
8.1 KiB

# Software selection text spoke
#
# Copyright (C) 2013 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
# the GNU General Public License v.2, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY expressed or implied, including the implied warranties 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 this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
# source code or documentation are not subject to the GNU General Public
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
# Red Hat Author(s): Samantha N. Bueno <sbueno@redhat.com>
#
from pyanaconda.flags import flags
from pyanaconda.ui.tui.spokes import NormalTUISpoke
from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget, CheckboxWidget
from pyanaconda.threads import threadMgr, AnacondaThread
from pyanaconda.packaging import MetadataError, DependencyError
from pyanaconda.i18n import _
from pyanaconda.constants import THREAD_PAYLOAD, THREAD_PAYLOAD_MD
from pyanaconda.constants import THREAD_CHECK_SOFTWARE, THREAD_SOFTWARE_WATCHER
from pyanaconda.constants_text import INPUT_PROCESSED
__all__ = ["SoftwareSpoke"]
class SoftwareSpoke(NormalTUISpoke):
""" Spoke used to read new value of text to represent source repo. """
title = _("Software selection")
category = "software"
def __init__(self, app, data, storage, payload, instclass):
NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
self._ready = False
self.errors = []
self._tx_id = None
# default to first selection (Gnome) in list of environments
self._selection = 0
self.environment = None
# for detecting later whether any changes have been made
self._origEnv = None
# are we taking values (package list) from a kickstart file?
self._kickstarted = flags.automatedInstall and self.data.packages.seen
def initialize(self):
NormalTUISpoke.initialize(self)
threadMgr.add(AnacondaThread(name=THREAD_SOFTWARE_WATCHER, target=self._initialize))
def _initialize(self):
""" Private initialize. """
threadMgr.wait(THREAD_PAYLOAD)
if self._kickstarted:
threadMgr.wait(THREAD_PAYLOAD_MD)
else:
try:
self.payload.environments
except MetadataError:
self.errors.append(_("No installation source available"))
return
self.payload.release()
self._ready = True
@property
def status(self):
""" Where we are in the process """
if self.errors:
return _("Error checking software selection")
if not self.ready:
return _("Processing...")
if not self.payload.baseRepo:
return _("Installation source not set up")
if not self.txid_valid:
return _("Source changed - please verify")
## FIXME:
# quite ugly, but env isn't getting set to gnome (or anything) by
# default, and it really should be so we can maintain consistency
# with graphical behavior
if self._selection >= 0 and not self.environment \
and not self._kickstarted:
self.apply()
if not self.environment:
# Ks installs with %packages will have an env selected, unless
# they did an install without a desktop environment. This should
# catch that one case.
if self._kickstarted:
return _("Custom software selected")
return _("Nothing selected")
return self.payload.environmentDescription(self.environment)[0]
@property
def completed(self):
""" Make sure our threads are done running and vars are set. """
processingDone = not threadMgr.get(THREAD_CHECK_SOFTWARE) and \
not self.errors and self.txid_valid
if flags.automatedInstall:
return processingDone and self.payload.baseRepo and self.data.packages.seen
else:
return self.payload.baseRepo and self.environment is not None and processingDone
def refresh(self, args=None):
""" Refresh screen. """
NormalTUISpoke.refresh(self, args)
if not self.payload.baseRepo:
message = TextWidget(_("Installation source needs to be set up first."))
self._window.append(message)
# add some more space below
self._window.append(TextWidget(""))
return True
threadMgr.wait(THREAD_CHECK_SOFTWARE)
# put a title above the list and some space below it
self._window.append(TextWidget(_("Base environment")))
self._window.append(TextWidget(""))
environments = self.payload.environments
displayed = []
for env in environments:
name = self.payload.environmentDescription(env)[0]
displayed.append(CheckboxWidget(title="%s" % name, completed=(environments.index(env) == self._selection)))
print(_("Base environment"))
def _prep(i, w):
""" Do some format magic for display. """
num = TextWidget("%2d)" % (i + 1))
return ColumnWidget([(4, [num]), (None, [w])], 1)
# split list of DE's into two columns
mid = len(environments) / 2
left = [_prep(i, w) for i, w in enumerate(displayed) if i <= mid]
right = [_prep(i, w) for i, w in enumerate(displayed) if i > mid]
cw = ColumnWidget([(38, left), (38, right)], 2)
self._window.append(cw)
return True
def input(self, args, key):
""" Handle the input; this chooses the desktop environment. """
try:
keyid = int(key) - 1
except ValueError:
if key.lower() == "c" and 0 <= self._selection < len(self.payload.environments):
self.apply()
self.close()
return INPUT_PROCESSED
else:
return key
if 0 <= keyid < len(self.payload.environments):
self._selection = keyid
return INPUT_PROCESSED
@property
def ready(self):
""" If we're ready to move on. """
return (not threadMgr.get(THREAD_SOFTWARE_WATCHER) and
not threadMgr.get(THREAD_PAYLOAD_MD) and
not threadMgr.get(THREAD_CHECK_SOFTWARE))
def apply(self):
""" Apply our selections """
self._apply()
# no longer using values from kickstart
self._kickstarted = False
self.data.packages.seen = True
threadMgr.add(AnacondaThread(name=THREAD_CHECK_SOFTWARE,
target=self.checkSoftwareSelection))
def _apply(self):
""" Private apply. """
self.environment = self.payload.environments[self._selection]
if not self.environment:
return
if not self._origEnv:
# nothing selected before, select the environment
self.payload.selectEnvironment(self.environment)
elif self._origEnv != self.environment:
# environment changed, clear the list of packages and select the new
# one
self.payload.data.packages.groupList = []
self.payload.selectEnvironment(self.environment)
else:
# no change
return
self._origEnv = self.environment
def checkSoftwareSelection(self):
""" Depsolving """
try:
self.payload.checkSoftwareSelection()
except DependencyError:
self._tx_id = None
else:
self._tx_id = self.payload.txID
@property
def txid_valid(self):
""" Whether we have a valid yum tx id. """
return self._tx_id == self.payload.txID