Skip to content

Model component widget

Composite list view-based widgets for displaying activity and NCS pathway items.

ActivityComponentWidget

ActivityComponentWidget(parent=None)

Bases: ModelComponentWidget

Widget for displaying and managing activities.

Source code in src/cplus_plugin/gui/model_component_widget.py
def __init__(self, parent=None):
    super().__init__(parent)

    self.item_model = ActivityItemModel(parent)
    self.item_model.activity_pathways_updated.connect(self.on_pathways_updated)

    self.lst_model_items.setAcceptDrops(True)
    self.lst_model_items.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)
    self.lst_model_items.setDropIndicatorShown(True)

    self.btn_reload.setVisible(False)

    self.btn_pixel_editor = None

    self.add_auxiliary_widgets()

activities

activities()

Returns a collection of activity objects in the list view.

Returns:

Type Description
list

Collection of activity objects in the list view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def activities(self) -> typing.List[Activity]:
    """Returns a collection of activity objects in the
    list view.

    :returns: Collection of activity objects in the
    list view.
    :rtype: list
    """
    return self.item_model.activities()

add_activity

add_activity(activity, layer=None)

Adds an activity object to the view with the option of specifying the layer.

Parameters:

Name Type Description Default
activity Activity

activity object to be added to the view.

required
layer QgsMapLayer

Optional map layer to be added to the activity.

None

Returns:

Type Description
bool

True if the activity was successfully added, else False.

Source code in src/cplus_plugin/gui/model_component_widget.py
def add_activity(self, activity: Activity, layer: QgsMapLayer = None):
    """Adds an activity object to the view with the option of
    specifying the layer.

    :param activity: activity object
    to be added to the view.
    :type activity: Activity

    :param layer: Optional map layer to be added to the activity.
    :type layer: QgsMapLayer

    :returns: True if the activity was successfully added, else
    False.
    :rtype: bool
    """
    return self.item_model.add_activity(activity, layer)

add_auxiliary_widgets

add_auxiliary_widgets()

Adds additional action widgets for managing activities.

Source code in src/cplus_plugin/gui/model_component_widget.py
def add_auxiliary_widgets(self):
    """Adds additional action widgets for managing activities."""
    self.btn_pixel_editor = QtWidgets.QToolButton(self)
    style_icon = FileUtils.get_icon("rendererCategorizedSymbol.svg")
    self.btn_pixel_editor.setIcon(style_icon)
    self.btn_pixel_editor.setToolTip(
        self.tr("Show dialog for ordering pixel values for styling.")
    )
    self.btn_pixel_editor.clicked.connect(self.on_show_pixel_value_editor)
    self.add_action_widget(self.btn_pixel_editor)

add_ncs_pathway_items

add_ncs_pathway_items(ncs_items)

Adds an NCS pathway item to the collection.

One, and only one, target activity item needs to have been selected.

Parameters:

Name Type Description Default
ncs_items List[NcsPathwayItem]

NCS pathway items to be added to the activity.

required

Returns:

Type Description
bool

True if the item was successfully added, else False.

Source code in src/cplus_plugin/gui/model_component_widget.py
def add_ncs_pathway_items(self, ncs_items: typing.List[NcsPathwayItem]) -> bool:
    """Adds an NCS pathway item to the collection.

    One, and only one, target activity item needs
    to have been selected.

    :param ncs_items: NCS pathway items to be added to the
    activity.
    :type ncs_items: list

    :returns: True if the item was successfully added, else False.
    :rtype: bool
    """
    selected_activities = self.selected_items()
    if len(selected_activities) == 0 or len(selected_activities) > 1:
        return False

    sel_activity = selected_activities[0]
    item_type = sel_activity.type()

    # Use the parent to add the NCS item
    if item_type == NCS_PATHWAY_TYPE:
        if sel_activity.parent is None:
            return False

        sel_activity = sel_activity.parent

    elif item_type == LAYER_ITEM_TYPE:
        return False

    status = True
    for ncs_item in ncs_items:
        status = self.item_model.add_ncs_pathway(ncs_item, sel_activity)

    return status

clear

clear()

Removes all activity items in the view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def clear(self):
    """Removes all activity items in the view."""
    items = self.model_items()
    for item in items:
        self.item_model.remove_activity(item.uuid)

load

load()

Load activities from settings.

Source code in src/cplus_plugin/gui/model_component_widget.py
def load(self):
    """Load activities from settings."""
    self.clear()

    for activity in settings_manager.get_all_activities():
        self.add_activity(activity)

model_items

model_items()

Returns a collection of all ActivityItem objects in the list view.

Returns:

Type Description
list

Collection of ActivityItem objects in the list view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def model_items(self) -> typing.List[ActivityItem]:
    """Returns a collection of all ActivityItem objects
    in the list view.

    :returns: Collection of ActivityItem objects in
    the list view.
    :rtype: list
    """
    return self.item_model.activity_items()

model_names

model_names()

Gets the names of the activities in the item model.

Returns:

Type Description
list

Returns the names of activities in lower case or an empty list if the item model has not been set.

Source code in src/cplus_plugin/gui/model_component_widget.py
def model_names(self) -> typing.List[str]:
    """Gets the names of the activities in the item model.

    :returns: Returns the names of activities in lower
    case or an empty list if the item model has not been set.
    :rtype: list
    """
    if self._item_model is None:
        return []

    model_components = self._item_model.activities()

    return [mc.name.lower() for mc in model_components]

on_pathways_updated

on_pathways_updated(activity_item)

Slot raised when the pathways of an ActivityItem have been added or removed. Persist this information in settings.

Source code in src/cplus_plugin/gui/model_component_widget.py
def on_pathways_updated(self, activity_item: ActivityItem):
    """Slot raised when the pathways of an ActivityItem
    have been added or removed. Persist this information in settings.
    """
    self._save_item(activity_item)

on_show_pixel_value_editor

on_show_pixel_value_editor()

Slot raised to show editor dialog for managing activity pixel values for styling.

Source code in src/cplus_plugin/gui/model_component_widget.py
def on_show_pixel_value_editor(self):
    """Slot raised to show editor dialog for managing activity pixel
    values for styling.
    """
    pixel_dialog = PixelValueEditorDialog(self)
    if pixel_dialog.exec_() == QtWidgets.QDialog.Accepted:
        # Update pixel values
        pixel_values = pixel_dialog.item_mapping
        for val, activity_id in pixel_values.items():
            activity = settings_manager.get_activity(activity_id)
            if not activity:
                continue
            activity.style_pixel_value = val
            settings_manager.update_activity(activity)

        self.load()

reassign_pixel_values

reassign_pixel_values(start_position)

Reassign the styling pixel values for activities from the given start position.

It is important to call this function when the maximum pixel value does not match the number of activities such as when one or more activities have been deleted.

Parameters:

Name Type Description Default
start_position int

Position to start reassigning the pixel values.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def reassign_pixel_values(self, start_position: int):
    """Reassign the styling pixel values for activities
    from the given start position.

    It is important to call this function when the maximum pixel
    value does not match the number of activities such
    as when one or more activities have been deleted.

    :param start_position: Position to start reassigning the pixel
    values.
    :type start_position: int
    """
    sorted_activities = sorted(
        settings_manager.get_all_activities(),
        key=lambda activity: activity.style_pixel_value,
    )
    remap_activities = sorted_activities[start_position - 1 :]
    for val, activity in enumerate(remap_activities, start=start_position):
        activity.style_pixel_value = val
        settings_manager.update_activity(activity)

    self.load()

remove_ncs_pathway_items

remove_ncs_pathway_items(ncs_pathway_uuid)

Delete NCS pathway items used for activities that are linked to the given NCS pathway.

Parameters:

Name Type Description Default
ncs_pathway_uuid str

NCS pathway whose corresponding items will be deleted in the activity items that contain it.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def remove_ncs_pathway_items(self, ncs_pathway_uuid: str):
    """Delete NCS pathway items used for activities that are linked to the
    given NCS pathway.

    :param ncs_pathway_uuid: NCS pathway whose corresponding items will be
    deleted in the activity items that contain it.
    :type ncs_pathway_uuid: str
    """
    self.item_model.remove_ncs_pathway_items(ncs_pathway_uuid)

update_ncs_pathway_items

update_ncs_pathway_items(ncs_pathway)

Update NCS pathway items used for activities that are linked to the given NCS pathway.

Parameters:

Name Type Description Default
ncs_pathway NcsPathway

NCS pathway whose attribute values will be updated for the related pathways used in the activities.

required

Returns:

Type Description
bool

True if NCS pathway items were updated, else False.

Source code in src/cplus_plugin/gui/model_component_widget.py
def update_ncs_pathway_items(self, ncs_pathway: NcsPathway) -> bool:
    """Update NCS pathway items used for activities that are linked to the
    given NCS pathway.

    :param ncs_pathway: NCS pathway whose attribute values will be updated
    for the related pathways used in the activities.
    :type ncs_pathway: NcsPathway

    :returns: True if NCS pathway items were updated, else False.
    :rtype: bool
    """
    return self.item_model.update_ncs_pathway_items(ncs_pathway)

ModelComponentWidget

ModelComponentWidget(parent=None, item_model=None)

Bases: QWidget, WidgetUi

Widget for displaying and managing model items in a list view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def __init__(self, parent=None, item_model=None):
    super().__init__(parent)
    self.setupUi(self)

    self._item_model = item_model
    if self._item_model is not None:
        self.item_model = self._item_model

    self.lst_model_items.doubleClicked.connect(self._on_double_click_item)

    add_icon = FileUtils.get_icon("symbologyAdd.svg")
    self.btn_add.setIcon(add_icon)
    self.btn_add.clicked.connect(self._on_add_item)

    remove_icon = FileUtils.get_icon("symbologyRemove.svg")
    self.btn_remove.setIcon(remove_icon)
    self.btn_remove.setEnabled(False)
    self.btn_remove.clicked.connect(self._on_remove_item)

    edit_icon = FileUtils.get_icon("mActionToggleEditing.svg")
    self.btn_edit.setIcon(edit_icon)
    self.btn_edit.setEnabled(False)
    self.btn_edit.clicked.connect(self._on_edit_item)

    reload_icon = FileUtils.get_icon("mActionReload.svg")
    self.btn_reload.setIcon(reload_icon)
    self.btn_reload.setToolTip(self.tr("Refresh view"))
    self.btn_reload.clicked.connect(self._on_reload)

    self.btn_edit_description.setIcon(edit_icon)
    self.btn_edit_description.setToolTip(self.tr("Edit description"))
    self.btn_edit_description.setEnabled(False)
    self.btn_edit_description.clicked.connect(self._on_update_description)

item_model property writable

item_model

Returns the component item model for managing items the list view.

Returns:

Type Description
ComponentItemModel

Component item model for managing items the list view.

selection_model property

selection_model

Gets the item's view selection model.

Returns:

Type Description
QtCore.QItemSelectionModel

The item's view selection model.

title property writable

title

Returns the title of the view.

Returns:

Type Description
str

Title of the view.

add_action_widget

add_action_widget(widget)

Adds an auxiliary widget below the list view from the left-hand side.

Parameters:

Name Type Description Default
widget QWidget

Widget to be added to the collection of controls below the list view.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def add_action_widget(self, widget: QtWidgets.QWidget):
    """Adds an auxiliary widget below the list view from the left-hand side.

    :param widget: Widget to be added to the collection of controls
    below the list view.
    :type widget: QtWidgets.QWidget
    """
    self.widget_container.addWidget(widget)

clear

clear()

Remove all items in the view. To be implemented by subclasses.

Source code in src/cplus_plugin/gui/model_component_widget.py
def clear(self):
    """Remove all items in the view. To be implemented
    by subclasses."""
    pass

clear_description

clear_description()

Clears the content in the description text box.

Source code in src/cplus_plugin/gui/model_component_widget.py
def clear_description(self):
    """Clears the content in the description text box."""
    self.txt_item_description.clear()
    self.txt_item_description.setToolTip("")

enable_default_items

enable_default_items(state)

Enable or disable default model component items in the view.

Parameters:

Name Type Description Default
state bool

True to enable or False to disable default model component items.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def enable_default_items(self, state: bool):
    """Enable or disable default model component items in the view.

    :param state: True to enable or False to disable default model
    component items.
    :type state: bool
    """
    self._item_model.enable_default_items(state)

    # If false, deselect default items
    if not state:
        selection_model = self.lst_model_items.selectionModel()
        selected_idxs = selection_model.selectedRows()
        for sel_idx in selected_idxs:
            item = self._item_model.item(sel_idx.row(), 0)
            # If not enabled then deselect
            if not item.isEnabled():
                selection_model.select(sel_idx, QtCore.QItemSelectionModel.Deselect)

load

load()

Subclass to determine how to initialize the items.

Source code in src/cplus_plugin/gui/model_component_widget.py
def load(self):
    """Subclass to determine how to initialize the items."""
    pass

model_names

model_names()

Gets the names of the components in the item model.

Returns:

Type Description
list

Returns the model names in lower case or an empty list if the item model has not been set.

Source code in src/cplus_plugin/gui/model_component_widget.py
def model_names(self) -> typing.List[str]:
    """Gets the names of the components in the item model.

    :returns: Returns the model names in lower case or an empty
    list if the item model has not been set.
    :rtype: list
    """
    if self._item_model is None:
        return []

    model_components = self._item_model.model_components()

    return [mc.name.lower() for mc in model_components]

selected_items

selected_items()

Returns the selected items in the list view.

Returns:

Type Description
list

A collection of the selected model component items. Returns an empty list if the item model has not been set.

Source code in src/cplus_plugin/gui/model_component_widget.py
def selected_items(self) -> typing.List[ModelComponentItemType]:
    """Returns the selected items in the list view.

    :returns: A collection of the selected model component items. Returns
    an empty list if the item model has not been set.
    :rtype: list
    """
    if self._item_model is None:
        return []

    selection_model = self.lst_model_items.selectionModel()
    idxs = selection_model.selectedRows()

    return [self._item_model.item(idx.row()) for idx in idxs]

set_description

set_description(description)

Updates the text for the selected item.

Parameters:

Name Type Description Default
description str

Description for the selected item.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def set_description(self, description: str):
    """Updates the text for the selected item.

    :param description: Description for the selected item.
    :type description: str
    """
    self.txt_item_description.setText(description)
    self.txt_item_description.setToolTip(description)

NcsComponentWidget

NcsComponentWidget(parent=None)

Bases: ModelComponentWidget

Widget for displaying and managing NCS pathways.

Source code in src/cplus_plugin/gui/model_component_widget.py
def __init__(self, parent=None):
    super().__init__(parent)

    # Add option for deleting disabled items
    self.btn_remove.clicked.disconnect(self._on_remove_item)
    self._delete_menu = QtWidgets.QMenu()

    self._remove_default_action = self._delete_menu.addAction(
        FileUtils.get_icon("symbologyRemove.svg"), "Remove Selected"
    )
    self._remove_default_action.setEnabled(False)
    self._remove_default_action.triggered.connect(self._on_remove_item)

    self._remove_disabled_action = self._delete_menu.addAction(
        FileUtils.get_icon("repositoryDisabled.svg"), "Remove Disabled"
    )
    self._remove_disabled_action.setEnabled(False)
    self._remove_disabled_action.triggered.connect(self._on_remove_disabled)

    self.btn_remove.setMenu(self._delete_menu)
    self.btn_remove.setDefaultAction(self._remove_default_action)
    self.btn_remove.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
    self.btn_remove.triggered.connect(self.on_delete_triggered)

    self.item_model = NcsPathwayItemModel(parent)
    self.item_model.itemChanged.connect(self.on_item_changed)

    self.lst_model_items.setDragEnabled(True)
    self.lst_model_items.setDragDropMode(QtWidgets.QAbstractItemView.DragOnly)
    self.lst_model_items.setAcceptDrops(False)

    self._validation_manager = validation_manager
    self._validation_submit_result = None

    self.btn_validate_pathways = None

    self.add_auxiliary_widgets()

add_auxiliary_widgets

add_auxiliary_widgets()

Adds additional action widgets for managing NCS pathways.

Source code in src/cplus_plugin/gui/model_component_widget.py
def add_auxiliary_widgets(self):
    """Adds additional action widgets for managing NCS pathways."""
    self.btn_validate_pathways = QtWidgets.QToolButton(self)
    style_icon = FileUtils.get_icon("mIconRasterValidate.svg")
    self.btn_validate_pathways.setIcon(style_icon)
    self.btn_validate_pathways.setToolTip(self.tr("Show validation inspector"))
    self.btn_validate_pathways.clicked.connect(self.on_load_validation_inspector)
    self.add_action_widget(self.btn_validate_pathways)

add_ncs_pathway

add_ncs_pathway(ncs_pathway)

Adds an NCS pathway object to the view.

Parameters:

Name Type Description Default
ncs_pathway NcsPathway

NCS pathway object to be added to the view.

required

Returns:

Type Description
bool

Returns True if the NcsPathway was successfully added, else False.

Source code in src/cplus_plugin/gui/model_component_widget.py
def add_ncs_pathway(self, ncs_pathway: NcsPathway) -> bool:
    """Adds an NCS pathway object to the view.

    :param ncs_pathway: NCS pathway object to be added to the view.
    :type ncs_pathway: NcsPathway

    :returns: Returns True if the NcsPathway was successfully added,
    else False.
    :rtype: bool
    """
    return self.item_model.add_ncs_pathway(ncs_pathway)

clear

clear()

Removes all NCS pathway items in the view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def clear(self):
    """Removes all NCS pathway items in the view."""
    items = self.ncs_items()
    for item in items:
        self.item_model.remove_ncs_pathway(item.uuid)

is_valid

is_valid()

Returns whether the NCS pathways are valid based on the validation against a given set of rules defined for an NCSValidator.

The validation process is automatically triggered through the validation manager object.

Returns:

Type Description
bool

True if the NCS pathways are valid, else False. If the validation result has warnings and no errors, the overall results will be True. However, if there are errors, it will return False.

Source code in src/cplus_plugin/gui/model_component_widget.py
def is_valid(self) -> bool:
    """Returns whether the NCS pathways are valid based on the validation against
    a given set of rules defined for an NCSValidator.

    The validation process is automatically triggered through the
    validation manager object.

    :returns: True if the NCS pathways are valid, else False. If the validation
    result has warnings and no errors, the overall results will be True. However,
    if there are errors, it will return False.
    :rtype: bool
    """
    if self._validation_submit_result is None:
        return False

    if not self._validation_submit_result.success:
        return False

    if self._validation_manager.is_validation_complete(
        self._validation_submit_result
    ):
        validation_result = self._validation_manager.validation_result(
            self._validation_submit_result
        )
        if validation_result.success:
            return True

        if validation_result.warnings and not validation_result.errors:
            return True

    return False

load

load()

Load items from settings.

Source code in src/cplus_plugin/gui/model_component_widget.py
def load(self):
    """Load items from settings."""
    self.clear()

    settings_manager.update_ncs_pathways()
    ncs_pathways = settings_manager.get_all_ncs_pathways()

    if len(ncs_pathways) > 0:
        progress_dialog = QtWidgets.QProgressDialog(self)
        progress_dialog.setWindowTitle(self.tr("Load NCS Pathways"))
        progress_dialog.setMinimum(0)
        progress_dialog.setMaximum(len(ncs_pathways))
        progress_dialog.setLabelText(self.tr("Updating NCS pathways..."))
        for i, ncs in enumerate(ncs_pathways, start=1):
            progress_dialog.setValue(i)
            if progress_dialog.wasCanceled():
                break
            self.add_ncs_pathway(ncs)

        self.validate_pathways()

ncs_items

ncs_items()

Returns a collection of all NcsPathwayItem objects in the list view.

Returns:

Type Description
list

Collection of NcsPathwayItem objects in the list view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def ncs_items(self) -> typing.List[NcsPathwayItem]:
    """Returns a collection of all NcsPathwayItem objects in the
    list view.

    :returns: Collection of NcsPathwayItem objects in the list view.
    :rtype: list
    """
    return self.item_model.model_component_items()

on_delete_triggered

on_delete_triggered(action)

Slot raised to select the default delete action.

Parameters:

Name Type Description Default
action QAction

Action that has been triggered.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def on_delete_triggered(self, action: QtWidgets.QAction):
    """Slot raised to select the default delete action.

    :param action: Action that has been triggered.
    :type action: QtWidgets.QAction
    """
    self.btn_remove.setDefaultAction(action)

on_item_changed

on_item_changed(item)

Slot raised when the data of an NCS pathway item changes.

Parameters:

Name Type Description Default
item NcsPathwayItem

NCS pathway item whose data has changed.

required
Source code in src/cplus_plugin/gui/model_component_widget.py
def on_item_changed(self, item: NcsPathwayItem):
    """Slot raised when the data of an NCS pathway item changes.

    :param item: NCS pathway item whose data has changed.
    :type item: NcsPathwayItem
    """
    # Check if there are items disabled and enable or disable
    # the option for deleting disabled items.
    self._on_item_and_selection_changed()

on_load_validation_inspector

on_load_validation_inspector()

Slot raised to show the validation inspector dialog.

If the validation process is not yet completed, a progress dialog will be shown.

Source code in src/cplus_plugin/gui/model_component_widget.py
def on_load_validation_inspector(self):
    """Slot raised to show the validation inspector dialog.

    If the validation process is not yet completed, a
    progress dialog will be shown.
    """
    if self._validation_submit_result is None:
        QtWidgets.QMessageBox.critical(
            self,
            self.tr("Load Validation Inspector"),
            self.tr(
                "Unable to show the validation inspector window.\nNo request for validation has been submitted."
            ),
        )
        log(message="Unable to load validation inspector", info=False)
        return

    if self._validation_manager.is_validation_complete(
        self._validation_submit_result
    ):
        validation_result = self._validation_manager.validation_result(
            self._validation_submit_result
        )
        if validation_result is None:
            return

        self.inspector_dialog = ValidationInspectorDialog(result=validation_result)
        self.inspector_dialog.setModal(False)
        self.inspector_dialog.show()

    else:
        # Show progress dialog
        progress_dialog = ValidationProgressDialog(
            self._validation_submit_result, self
        )
        progress_dialog.exec_()

pathways

pathways(valid_only=False)

Returns a collection of NcsPathway objects in the list view.

Parameters:

Name Type Description Default
valid_only bool

True to only return those NcsPathway objects that are valid, default is False.

False

Returns:

Type Description
list

Collection of NcsPathway objects in the list view.

Source code in src/cplus_plugin/gui/model_component_widget.py
def pathways(self, valid_only=False) -> typing.List[NcsPathway]:
    """Returns a collection of NcsPathway objects in the list view.

    :param valid_only: True to only return those NcsPathway objects that
    are valid, default is False.
    :type valid_only: bool

    :returns: Collection of NcsPathway objects in the list view.
    :rtype: list
    """
    return self.item_model.pathways(valid_only)

validate_pathways

validate_pathways()

Validates NCS pathway model components against a given set of rules using the ValidationManager.

Source code in src/cplus_plugin/gui/model_component_widget.py
def validate_pathways(self):
    """Validates NCS pathway model components against a given set of
    rules using the ValidationManager.
    """
    self._validation_submit_result = None

    ncs_pathways = self.pathways()
    # No need for validating if there are no NCS pathways.
    if len(ncs_pathways) == 0:
        log(
            message="At least one NCS pathway is required for the validation process to be initiated.",
            info=False,
        )
        return

    self._validation_submit_result = validation_manager.validate_ncs_pathways(
        ncs_pathways
    )
    if not self._validation_submit_result.success:
        QtWidgets.QMessageBox.critical(
            self,
            self.tr("Validate NCS Pathways"),
            self.tr("Unable to submit NCS pathways for validation"),
        )
        log(message="Unable to submit NCS pathways for validation", info=False)
        return

Last update: October 2, 2024
Back to top