Source code for flexicon.code.Discourse.ConstChartWordGroupOperations

#
#   ConstChartWordGroupOperations.py
#
#   Class: ConstChartWordGroupOperations
#          Constituent chart word group operations for discourse analysis in FieldWorks
#          Language Explorer projects via SIL Language and Culture Model (LCM) API.
#
#   Platform: Python.NET
#             FieldWorks Version 9+
#
#   Copyright 2025
#

# Import BaseOperations parent class
from ..BaseOperations import BaseOperations, OperationsMethod, wrap_enumerable

# Import FLEx LCM types
from SIL.LCModel import (
    IConstChartWordGroup,
    IConstChartWordGroupFactory,
    IConstChartRow,
    IAnalysis,
    ISegment,
)

# Import flexlibs exceptions
from ..FLExProject import (
    FP_ParameterError,
)


[docs] class ConstChartWordGroupOperations(BaseOperations): """ This class provides operations for managing word groups in constituent chart rows for discourse analysis in FieldWorks projects. Word groups represent segments of text being analyzed in a discourse chart. Each word group references a range of segments (words/morphemes) from the analyzed text. This class should be accessed via FLExProject.ConstChartWordGroups property. Usage:: from flexlibs2 import FLExProject project = FLExProject() project.OpenProject("my project", writeEnabled=True) # Get a row chart = project.ConstCharts.Find("Genesis 1 Analysis") row = project.ConstChartRows.Find(chart, 0) # Create a word group (referencing text segments) wg = project.ConstChartWordGroups.Create(row, begin_segment, end_segment) # Get all word groups in a row for wg in project.ConstChartWordGroups.GetAll(row): # Process word group pass project.CloseProject() """ def __init__(self, project): """ Initialize ConstChartWordGroupOperations with a FLExProject instance. Args: project: The FLExProject instance to operate on. """ super().__init__(project) # --- Core CRUD Operations --- @OperationsMethod def Create(self, row_or_hvo, begin_segment, end_segment): """ Create a new word group in a chart row. Word groups represent a range of text segments being analyzed. The begin and end segments define the span of text this word group covers. Args: row_or_hvo: Either an IConstChartRow object or its HVO begin_segment: ISegment object marking the start of the range end_segment: ISegment object marking the end of the range (inclusive) Returns: IConstChartWordGroup: The newly created word group object Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If any parameter is None FP_ParameterError: If segments are invalid Example: >>> # Get segments from a text >>> text = project.Texts.Find("Genesis 1") >>> para = text.ContentsOA.ParagraphsOS[0] >>> segments = list(para.SegmentsOS) >>> >>> # Create word group spanning first 3 words >>> wg = project.ConstChartWordGroups.Create( ... row, ... segments[0], # Begin ... segments[2] # End ... ) Notes: - Word group is appended to the row's cells collection - Segments must be from the analyzed text - Begin segment must come before or equal to end segment - Factory.Create() automatically adds word group to repository - Word groups can have moved text markers and clause markers See Also: Delete, Find, GetBeginSegment, GetEndSegment """ self._EnsureWriteEnabled() self._ValidateParam(row_or_hvo, "row_or_hvo") self._ValidateParam(begin_segment, "begin_segment") self._ValidateParam(end_segment, "end_segment") row = self.__ResolveRow(row_or_hvo) # Validate segments if not isinstance(begin_segment, ISegment): raise FP_ParameterError("begin_segment must be an ISegment object") if not isinstance(end_segment, ISegment): raise FP_ParameterError("end_segment must be an ISegment object") with self._TransactionCM("Create word group"): # Create the new word group using the factory factory = self.project.project.ServiceLocator.GetService(IConstChartWordGroupFactory) new_word_group = factory.Create() # Add to row's cells collection row.CellsOS.Add(new_word_group) # Set the segment references new_word_group.BeginSegmentRA = begin_segment new_word_group.EndSegmentRA = end_segment return new_word_group @OperationsMethod def Delete(self, group_or_hvo): """ Delete a word group from its chart row. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If group_or_hvo is None Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> if wg: ... project.ConstChartWordGroups.Delete(wg) Warning: - This is a destructive operation - All moved text markers and clause markers will be deleted - Cannot be undone Notes: - Deletion cascades to all owned objects - Remaining word groups maintain their order See Also: Create, Find """ self._EnsureWriteEnabled() self._ValidateParam(group_or_hvo, "group_or_hvo") # Resolve to word group object group = self.__ResolveObject(group_or_hvo) # Delete the word group (LCM handles removal from repository) group.Delete() @OperationsMethod def Find(self, row_or_hvo, index): """ Find a word group in a row by its index position. Args: row_or_hvo: Either an IConstChartRow object or its HVO index (int): Zero-based index of the word group to find Returns: IConstChartWordGroup or None: The word group object if found, None otherwise Raises: FP_NullParameterError: If row_or_hvo is None Example: >>> row = project.ConstChartRows.Find(chart, 0) >>> wg = project.ConstChartWordGroups.Find(row, 0) # First word group >>> if wg: ... begin = project.ConstChartWordGroups.GetBeginSegment(wg) ... print(f"Word group starts at segment {begin.Hvo}") Notes: - Index is zero-based (0 = first word group) - Returns None if index out of range - More efficient than iterating GetAll() See Also: GetAll, Create """ self._ValidateParam(row_or_hvo, "row_or_hvo") row = self.__ResolveRow(row_or_hvo) if index < 0 or index >= row.CellsOS.Count: return None return row.CellsOS[index] @wrap_enumerable @OperationsMethod def GetAll(self, row_or_hvo): """ Get all word groups in a chart row. Args: row_or_hvo: Either an IConstChartRow object or its HVO Returns: list: List of IConstChartWordGroup objects (empty list if none) Raises: FP_NullParameterError: If row_or_hvo is None Example: >>> row = project.ConstChartRows.Find(chart, 0) >>> word_groups = project.ConstChartWordGroups.GetAll(row) >>> for i, wg in enumerate(word_groups): ... print(f"Word group {i}") Notes: - Returns empty list if row has no word groups - Word groups are in row order - Each word group references a text segment range See Also: Find, Create """ self._ValidateParam(row_or_hvo, "row_or_hvo") row = self.__ResolveRow(row_or_hvo) return list(row.CellsOS) # --- Word Group Properties --- @OperationsMethod def GetBeginSegment(self, group_or_hvo): """ Get the beginning segment of a word group. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO Returns: ISegment or None: The beginning segment, or None if not set Raises: FP_NullParameterError: If group_or_hvo is None Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> begin_seg = project.ConstChartWordGroups.GetBeginSegment(wg) >>> if begin_seg: ... print(f"Starts at segment {begin_seg.Hvo}") Notes: - Returns None if segment reference not set - Segment is from the analyzed text - Begin segment must be before or equal to end segment See Also: SetBeginSegment, GetEndSegment """ self._ValidateParam(group_or_hvo, "group_or_hvo") group = self.__ResolveObject(group_or_hvo) return group.BeginSegmentRA if hasattr(group, "BeginSegmentRA") else None @OperationsMethod def SetBeginSegment(self, group_or_hvo, segment): """ Set the beginning segment of a word group. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO segment: ISegment object to set as beginning (can be None to clear) Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If group_or_hvo is None FP_ParameterError: If segment is invalid type Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> new_segment = segments[5] >>> project.ConstChartWordGroups.SetBeginSegment(wg, new_segment) Notes: - Segment can be None to clear reference - Segment must be from the analyzed text - Should be before or equal to end segment See Also: GetBeginSegment, SetEndSegment """ self._EnsureWriteEnabled() self._ValidateParam(group_or_hvo, "group_or_hvo") if segment is not None and not isinstance(segment, ISegment): raise FP_ParameterError("segment must be an ISegment object or None") group = self.__ResolveObject(group_or_hvo) group.BeginSegmentRA = segment @OperationsMethod def GetEndSegment(self, group_or_hvo): """ Get the ending segment of a word group. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO Returns: ISegment or None: The ending segment, or None if not set Raises: FP_NullParameterError: If group_or_hvo is None Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> end_seg = project.ConstChartWordGroups.GetEndSegment(wg) >>> if end_seg: ... print(f"Ends at segment {end_seg.Hvo}") Notes: - Returns None if segment reference not set - Segment is from the analyzed text - End segment must be after or equal to begin segment See Also: SetEndSegment, GetBeginSegment """ self._ValidateParam(group_or_hvo, "group_or_hvo") group = self.__ResolveObject(group_or_hvo) return group.EndSegmentRA if hasattr(group, "EndSegmentRA") else None @OperationsMethod def SetEndSegment(self, group_or_hvo, segment): """ Set the ending segment of a word group. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO segment: ISegment object to set as ending (can be None to clear) Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If group_or_hvo is None FP_ParameterError: If segment is invalid type Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> new_segment = segments[10] >>> project.ConstChartWordGroups.SetEndSegment(wg, new_segment) Notes: - Segment can be None to clear reference - Segment must be from the analyzed text - Should be after or equal to begin segment See Also: GetEndSegment, SetBeginSegment """ self._EnsureWriteEnabled() self._ValidateParam(group_or_hvo, "group_or_hvo") if segment is not None and not isinstance(segment, ISegment): raise FP_ParameterError("segment must be an ISegment object or None") group = self.__ResolveObject(group_or_hvo) group.EndSegmentRA = segment @OperationsMethod def GetColumn(self, group_or_hvo): """ Get the column position of a word group in the chart. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO Returns: ICmPossibility or None: The column object, or None if not set Raises: FP_NullParameterError: If group_or_hvo is None Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> column = project.ConstChartWordGroups.GetColumn(wg) >>> if column: ... col_name = ITsString(column.Name.BestAnalysisAlternative).Text ... print(f"Column: {col_name}") Notes: - Returns None if column not set - Column is from the chart template - Column defines position in discourse structure See Also: SetColumn """ self._ValidateParam(group_or_hvo, "group_or_hvo") group = self.__ResolveObject(group_or_hvo) return group.ColumnRA if hasattr(group, "ColumnRA") else None @OperationsMethod def SetColumn(self, group_or_hvo, column): """ Set the column position of a word group in the chart. Args: group_or_hvo: Either an IConstChartWordGroup object or its HVO column: ICmPossibility column object (can be None to clear) Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If group_or_hvo is None Example: >>> wg = project.ConstChartWordGroups.Find(row, 0) >>> # Get column from template >>> template = project.ConstCharts.GetTemplate(chart) >>> column = template.SubPossibilitiesOS[0] # First column >>> project.ConstChartWordGroups.SetColumn(wg, column) Notes: - Column can be None to clear - Column should be from chart template - Column defines position in discourse structure See Also: GetColumn """ self._EnsureWriteEnabled() self._ValidateParam(group_or_hvo, "group_or_hvo") group = self.__ResolveObject(group_or_hvo) group.ColumnRA = column # --- Private Helper Methods --- def __ResolveObject(self, group_or_hvo): """ Resolve HVO or object to IConstChartWordGroup. Args: group_or_hvo: Either an IConstChartWordGroup object or an HVO (int) Returns: IConstChartWordGroup: The resolved word group object Raises: FP_ParameterError: If HVO doesn't refer to a word group """ if isinstance(group_or_hvo, int): obj = self.project.Object(group_or_hvo) if not isinstance(obj, IConstChartWordGroup): raise FP_ParameterError("HVO does not refer to a word group") return obj return group_or_hvo def __ResolveRow(self, row_or_hvo): """ Resolve HVO or object to IConstChartRow. Args: row_or_hvo: Either an IConstChartRow object or an HVO (int) Returns: IConstChartRow: The resolved row object Raises: FP_ParameterError: If HVO doesn't refer to a chart row """ if isinstance(row_or_hvo, int): obj = self.project.Object(row_or_hvo) if not isinstance(obj, IConstChartRow): raise FP_ParameterError("HVO does not refer to a chart row") return obj return row_or_hvo # --- Reordering Support --- def _GetSequence(self, parent): """ Get the owning sequence for word groups. Args: parent: The parent IConstChartRow object Returns: ILcmOwningSequence: The CellsOS sequence Notes: - Required for BaseOperations reordering methods - Returns the CellsOS collection from the row """ return parent.CellsOS