---
pyanaconda/ui/__init__.py | 41 +++++++++++++++++++++++---------
pyanaconda/ui/gui/__init__.py | 39 +++++++++++++++++++++++-------
pyanaconda/ui/gui/categories/__init__.py | 13 +++++++---
pyanaconda/ui/gui/hubs/__init__.py | 32 +++++++++++++++++++++----
pyanaconda/ui/gui/spokes/__init__.py | 17 ++++++++++---
5 files changed, 111 insertions(+), 31 deletions(-)
diff --git a/pyanaconda/ui/__init__.py b/pyanaconda/ui/__init__.py
index 80d8e6f..aabc719 100644
--- a/pyanaconda/ui/__init__.py
+++ b/pyanaconda/ui/__init__.py
@@ -98,13 +98,36 @@ class UserInterface(object):
"""
raise NotImplementedError
- def getActionClasses(self, module_pattern, path, hubs, standalone_class):
+ def _collectActionClasses(self, module_pattern_w_path, standalone_class):
"""Collect all the Hub and Spoke classes which should be enqueued
for
- processing and order them according to their pre/post dependencies.
+ processing.
- :param module_pattern: the full name pattern (pyanaconda.ui.gui.spokes.%s)
- of modules we about to import from path
- :type module_pattern: string
+ :param module_pattern_w_path: the full name patterns
(pyanaconda.ui.gui.spokes.%s)
+ and directory paths to modules we are about to
import
+ :type module_pattern_w_path: list of (string, string)
+
+ :param standalone_class: the parent type of Spokes we want to pick up
+ :type standalone_class: common.StandaloneSpoke based types
+
+ :return: list of Spoke classes with standalone_class as a parent
+ :rtype: list of Spoke classes
+
+ """
+ standalones = []
+
+ for module_pattern, path in module_pattern_w_path:
+ standalones.extend(collect(module_pattern, path, lambda obj: issubclass(obj,
standalone_class) and \
+ getattr(obj, "preForHub", False) or
getattr(obj, "postForHub", False)))
+
+ return standalones
+
+ def _orderActionClasses(self, spokes, hubs, standalone_class):
+ """Order all the Hub and Spoke classes which should be enqueued
for
+ processing according to their pre/post dependencies.
+
+ :param spokes: the classes we are to about order according
+ to the hub dependencies
+ :type spokes: list of Spoke instances
:param path: the directory we are picking up modules from
:type path: string
@@ -117,16 +140,12 @@ class UserInterface(object):
:type standalone_class: common.StandaloneSpoke based types
"""
-
- standalones = collect(module_pattern, path, lambda obj: issubclass(obj,
standalone_class) and \
- getattr(obj, "preForHub", False) or getattr(obj,
"postForHub", False))
-
actionClasses = []
for hub in hubs:
- actionClasses.extend(sorted(filter(lambda obj: getattr(obj,
"preForHub", None) == hub, standalones),
+ actionClasses.extend(sorted(filter(lambda obj: getattr(obj,
"preForHub", None) == hub, spokes),
key=lambda obj: obj.priority))
actionClasses.append(hub)
- actionClasses.extend(sorted(filter(lambda obj: getattr(obj,
"postForHub", None) == hub, standalones),
+ actionClasses.extend(sorted(filter(lambda obj: getattr(obj,
"postForHub", None) == hub, spokes),
key=lambda obj: obj.priority))
return actionClasses
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index 6bba736..f9b51e2 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -27,6 +27,7 @@ from pyanaconda.product import distributionText, isFinal
from pyanaconda.ui import UserInterface, common
from pyanaconda.ui.gui.utils import enlightbox, gtk_thread_wait
+from pyanaconda.product import isFinal, productName, productVersion
import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
@@ -42,7 +43,9 @@ class GraphicalUserInterface(UserInterface):
"""This is the standard GTK+ interface we try to steer everything to
using.
It is suitable for use both directly and via VNC.
"""
- def __init__(self, storage, payload, instclass):
+ def __init__(self, storage, payload, instclass,
+ distributionText = distributionText, isFinal = isFinal):
+
UserInterface.__init__(self, storage, payload, instclass)
self._actions = []
@@ -51,23 +54,41 @@ class GraphicalUserInterface(UserInterface):
self.data = None
+ self._distributionText = distributionText
+ self._isFinal = isFinal
+
# This is a hack to make sure the AnacondaWidgets library gets loaded
# before the introspection stuff.
import ctypes
ctypes.CDLL("libAnacondaWidgets.so.0", ctypes.RTLD_GLOBAL)
- def setup(self, data):
+ def _list_hubs(self):
from hubs.summary import SummaryHub
from hubs.progress import ProgressHub
+ return [SummaryHub, ProgressHub]
+
+ def _list_standalone_paths(self):
+ path = os.path.join(os.path.dirname(__file__), "spokes")
+ return [("pyanaconda.ui.gui.spokes.%s", path)]
+
+ def _is_standalone(self, obj):
from spokes import StandaloneSpoke
+ return isinstance(obj, StandaloneSpoke)
+ def setup(self, data):
busyCursor()
+
+ self._actions = self.getActionClasses(self._list_hubs())
+ self.data = data
- hubs = [SummaryHub, ProgressHub]
- path = os.path.join(os.path.dirname(__file__), "spokes")
+ def getActionClasses(self, hubs):
+ from spokes import StandaloneSpoke
- self._actions = self.getActionClasses("pyanaconda.ui.gui.spokes.%s",
path, hubs, StandaloneSpoke)
- self.data = data
+ # First, grab a list of all the standalone spokes.
+ standalones = self._collectActionClasses(self._list_standalone_paths(),
StandaloneSpoke)
+
+ # Second, order them according to their relationship
+ return self._orderActionClasses(standalones, hubs, StandaloneSpoke)
def _instantiateAction(self, actionClass):
from spokes import StandaloneSpoke
@@ -120,8 +141,8 @@ class GraphicalUserInterface(UserInterface):
self._currentAction.refresh()
- self._currentAction.window.set_beta(not isFinal)
- self._currentAction.window.set_property("distribution",
distributionText().upper())
+ self._currentAction.window.set_beta(not self._isFinal())
+ self._currentAction.window.set_property("distribution",
self._distributionText().upper())
# Set fonts app-wide, where possible
settings = Gtk.Settings.get_default()
@@ -241,7 +262,7 @@ class GraphicalUserInterface(UserInterface):
nextAction.initialize()
nextAction.window.set_beta(self._currentAction.window.get_beta())
- nextAction.window.set_property("distribution",
distributionText().upper())
+ nextAction.window.set_property("distribution",
self._distributionText().upper())
if not nextAction.showable:
self._currentAction.window.hide()
diff --git a/pyanaconda/ui/gui/categories/__init__.py
b/pyanaconda/ui/gui/categories/__init__.py
index b71217f..8d96b33 100644
--- a/pyanaconda/ui/gui/categories/__init__.py
+++ b/pyanaconda/ui/gui/categories/__init__.py
@@ -71,6 +71,13 @@ class SpokeCategory(object):
return g
-def collect_categories():
- """Return a list of all category subclasses."""
- return collect("pyanaconda.ui.gui.categories.%s",
os.path.dirname(__file__), lambda obj: getattr(obj, "displayOnHub", None) !=
None)
+def collect_categories(mask_paths):
+ """Return a list of all category subclasses. Look for them in modules
+ imported as module_mask % basename(f) where f is name of all files in path.
+ """
+ categories = []
+ for mask, path in mask_paths:
+ spokes.extend(collect(mask, path, lambda obj: getattr(obj,
"displayOnHub", None) != None)
+
+ return categories
+
diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py
index 642ebb3..4447367 100644
--- a/pyanaconda/ui/gui/hubs/__init__.py
+++ b/pyanaconda/ui/gui/hubs/__init__.py
@@ -111,22 +111,44 @@ class Hub(GUIObject, common.Hub):
action.apply()
action.execute()
- def _createBox(self):
- from gi.repository import Gtk, AnacondaWidgets
- from pyanaconda.ui.gui.utils import setViewportBackground
+ def _list_spokes_mask_paths(self):
+ return [("pyanaconda.ui.gui.spokes.%s",
os.path.join(os.path.dirname(__file__), "spokes"))]
+
+ def _list_categories_mask_paths(self):
+ return [("pyanaconda.ui.gui.categories.%s",
os.path.join(os.path.dirname(__file__), "categories"))]
+
+ def _collectCategoriesAndSpokes(self):
+ """collects categories and spokes to be displayed on this Hub
+ :return: dictionary mapping category class to list of spoke classes
+ :rtype: dictionary[category class] -> [ list of spoke classes ]
+ """
+
+ ret = {}
+
# Collect all the categories this hub displays, then collect all the
# spokes belonging to all those categories.
- categories = sorted(filter(lambda c: c.displayOnHub == self.__class__,
collect_categories()),
+ categories = sorted(filter(lambda c: c.displayOnHub == self.__class__,
collect_categories(self._list_categories_mask_paths())),
key=lambda c: c.title)
+ for c in categories:
+ ret[c] = collect_spokes(self._list_spokes_mask_paths(), c.__name__)
+
+ return ret
+
+ def _createBox(self):
+ from gi.repository import Gtk, AnacondaWidgets
+ from pyanaconda.ui.gui.utils import setViewportBackground
+ cats_and_spokes = self._collectCategoriesAndSpokes()
+ categories = cats_and_spokes.keys()
+
box = Gtk.VBox(False, 6)
for c in categories:
obj = c()
selectors = []
- for spokeClass in sorted(collect_spokes(obj.__class__.__name__), key=lambda
s: s.title):
+ for spokeClass in sorted(cats_and_spokes[c], key=lambda s: s.title):
# Create the new spoke and populate its UI with whatever data.
# From here on, this Spoke will always exist.
spoke = spokeClass(self.data, self.storage, self.payload,
self.instclass)
diff --git a/pyanaconda/ui/gui/spokes/__init__.py b/pyanaconda/ui/gui/spokes/__init__.py
index f25d30c..99039a6 100644
--- a/pyanaconda/ui/gui/spokes/__init__.py
+++ b/pyanaconda/ui/gui/spokes/__init__.py
@@ -94,8 +94,19 @@ class PersonalizationSpoke(Spoke, common.PersonalizationSpoke):
Spoke.__init__(self, data)
common.PersonalizationSpoke.__init__(self, data, storage, payload, instclass)
-def collect_spokes(category):
+def collect_spokes(mask_paths, category):
"""Return a list of all spoke subclasses that should appear for a
given
- category.
+ category. Look for them in files imported as module_path % basename(f)
+
+ :param mask_paths: list of mask, path tuples to search for classes
+ :type mask_paths: list of (mask, path)
+
+ :return: list of Spoke classes belonging to category
+ :rtype: list of Spoke classes
+
"""
- return collect("pyanaconda.ui.gui.spokes.%s", os.path.dirname(__file__),
lambda obj: hasattr(obj, "category") and obj.category != None and
obj.category.__name__ == category)
+ spokes = []
+ for mask, path in mask_paths:
+ spokes.extend(collect(mask, path, lambda obj: hasattr(obj, "category")
and obj.category != None and obj.category.__name__ == category))
+
+ return spokes
--
1.7.11.7