Source code for flexicon.code.Scripture.ScrAnnotationsOperations

#
#   ScrAnnotationsOperations.py
#
#   Class: ScrAnnotationsOperations
#          Scripture book annotations operations for 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

# Import FLEx LCM types
from SIL.LCModel import (
    IScrBook,
    IScrBookAnnotations,
    IScrBookAnnotationsFactory,
    IScrScriptureNote,
)

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


[docs] class ScrAnnotationsOperations(BaseOperations): """ This class provides operations for managing Scripture book annotations in a FieldWorks project. Scripture book annotations are containers for notes (translator notes, consultant notes, etc.) associated with a Scripture book. This class should be accessed via FLExProject.ScrAnnotations property. Usage:: from flexlibs2 import FLExProject project = FLExProject() project.OpenProject("my project", writeEnabled=True) # Get a book genesis = project.ScrBooks.Find(1) # Create annotations container annotations = project.ScrAnnotations.Create(genesis, "note") # Get annotations for a book annotations = project.ScrAnnotations.GetForBook(genesis) # Get notes in annotations notes = project.ScrAnnotations.GetNotes(annotations) project.CloseProject() """ def __init__(self, project): """ Initialize ScrAnnotationsOperations with a FLExProject instance. Args: project: The FLExProject instance to operate on. """ super().__init__(project) # --- Core CRUD Operations --- @OperationsMethod def Create(self, book_or_hvo, type="note"): """ Create a new Scripture book annotations container. Args: book_or_hvo: Either an IScrBook object or its HVO type (str, optional): Annotation type. Defaults to "note". Types: "note", "translator_note", "consultant_note" Returns: IScrBookAnnotations: The newly created annotations object Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If book_or_hvo is None FP_ParameterError: If book doesn't exist or annotations already exist Example: >>> genesis = project.ScrBooks.Find(1) >>> annotations = project.ScrAnnotations.Create(genesis) >>> # Create consultant notes container >>> annotations = project.ScrAnnotations.Create( ... genesis, ... "consultant_note" ... ) Notes: - Annotations container is created per book - Each book can have one annotations container - Container holds all notes for the book - Type parameter is for categorization See Also: Delete, GetForBook """ self._EnsureWriteEnabled() self._ValidateParam(book_or_hvo, "book_or_hvo") # Resolve to book object book = self.__ResolveBook(book_or_hvo) # Check if annotations already exist if book.FootnotesOS.Count > 0: raise FP_ParameterError("Book already has annotations container. Use GetForBook() instead.") with self._TransactionCM("Create annotations"): # Create the new annotations using the factory factory = self.project.project.ServiceLocator.GetService(IScrBookAnnotationsFactory) new_annotations = factory.Create() # Add to book's footnotes (annotations are stored in FootnotesOS) book.FootnotesOS.Add(new_annotations) return new_annotations @OperationsMethod def Delete(self, annotations_or_hvo): """ Delete a Scripture book annotations container from the FLEx project. Args: annotations_or_hvo: Either an IScrBookAnnotations object or its HVO Raises: FP_ReadOnlyError: If project is not opened with write enabled FP_NullParameterError: If annotations_or_hvo is None FP_ParameterError: If annotations doesn't exist Example: >>> annotations = project.ScrAnnotations.GetForBook(genesis) >>> if annotations: ... project.ScrAnnotations.Delete(annotations) Warning: - This is a destructive operation - All notes in the container will be deleted - Cannot be undone Notes: - Deletion cascades to all owned notes See Also: Create """ self._EnsureWriteEnabled() self._ValidateParam(annotations_or_hvo, "annotations_or_hvo") # Resolve to annotations object annotations = self.__ResolveObject(annotations_or_hvo) # Delete the annotations (LCM handles removal from repository) annotations.Delete() @OperationsMethod def GetForBook(self, book_or_hvo): """ Get the annotations container for a Scripture book. Args: book_or_hvo: Either an IScrBook object or its HVO Returns: IScrBookAnnotations or None: The annotations object if found, None otherwise Raises: FP_NullParameterError: If book_or_hvo is None Example: >>> genesis = project.ScrBooks.Find(1) >>> annotations = project.ScrAnnotations.GetForBook(genesis) >>> if annotations: ... notes = project.ScrAnnotations.GetNotes(annotations) ... print(f"Book has {len(notes)} notes") Notes: - Returns None if book has no annotations container - Each book can have one annotations container - Container holds all notes for the book See Also: Create, GetNotes """ self._ValidateParam(book_or_hvo, "book_or_hvo") # Resolve to book object book = self.__ResolveBook(book_or_hvo) # Get first annotations (typically there's only one per book) if book.FootnotesOS.Count > 0: return book.FootnotesOS[0] return None # --- Annotations Properties --- @OperationsMethod def GetNotes(self, annotations_or_hvo): """ Get all notes in a Scripture book annotations container. Args: annotations_or_hvo: Either an IScrBookAnnotations object or its HVO Returns: list: List of IScrScriptureNote objects (empty list if none) Raises: FP_NullParameterError: If annotations_or_hvo is None Example: >>> annotations = project.ScrAnnotations.GetForBook(genesis) >>> if annotations: ... notes = project.ScrAnnotations.GetNotes(annotations) ... for note in notes: ... text = project.ScrNotes.GetText(note) ... print(f"Note: {text}") Notes: - Returns empty list if container has no notes - Notes are in database order - Use ScrNoteOperations for note-level operations See Also: GetForBook, ScrNoteOperations """ self._ValidateParam(annotations_or_hvo, "annotations_or_hvo") annotations = self.__ResolveObject(annotations_or_hvo) return list(annotations.NotesOS) # --- Private Helper Methods --- def __ResolveObject(self, annotations_or_hvo): """ Resolve HVO or object to IScrBookAnnotations. Args: annotations_or_hvo: Either an IScrBookAnnotations object or an HVO (int) Returns: IScrBookAnnotations: The resolved annotations object Raises: FP_ParameterError: If HVO doesn't refer to Scripture annotations """ if isinstance(annotations_or_hvo, int): obj = self.project.Object(annotations_or_hvo) if not isinstance(obj, IScrBookAnnotations): raise FP_ParameterError("HVO does not refer to Scripture annotations") return obj return annotations_or_hvo def __ResolveBook(self, book_or_hvo): """ Resolve HVO or object to IScrBook. Args: book_or_hvo: Either an IScrBook object or an HVO (int) Returns: IScrBook: The resolved book object Raises: FP_ParameterError: If HVO doesn't refer to a Scripture book """ if isinstance(book_or_hvo, int): obj = self.project.Object(book_or_hvo) if not isinstance(obj, IScrBook): raise FP_ParameterError("HVO does not refer to a Scripture book") return obj return book_or_hvo