Source code for PyXA.apps.iWorkApplicationBase

""".. versionadded:: 0.1.1

Control iWork applications using JXA-like syntax.
"""
from datetime import datetime
from enum import Enum
from pprint import pprint
from time import sleep
from typing import Any, Union

import AppKit, ScriptingBridge

from PyXA import XABase
from PyXA import XAEvents
from PyXA.XABase import OSType
from PyXA import XABaseScriptable
from ..XAProtocols import XACanOpenPath, XACloseable


[docs] class XAiWorkApplication(XABaseScriptable.XASBApplication, XACanOpenPath): """A class for managing and interacting with iWork applications. .. versionadded:: 0.1.1 """
[docs] class ImageQuality(Enum): """Options for the quality of exported images.""" GOOD = OSType("KnP0") #: Good quality BETTER = OSType("KnP1") #: Better quality BEST = OSType("KnP2") #: Best quality
[docs] class Alignment(Enum): """Options for the horizontal and vertical alignment of content within table containers.""" BOTTOM = OSType("avbt") #: Bottom-align content. CENTER_VERTICAL = OSType("actr") #: Center-align content. TOP = OSType("avtp") #: Top-align content. AUTO = OSType("aaut") #: Auto-align based on content type. CENTER_HORIZONTAL = OSType("actr") #: Center-align content. JUSTIFY = OSType("ajst") #: Fully justify (left and right) content. LEFT = OSType("alft") #: Left-align content. RIGHT = OSType("arit") #: Right-align content.
[docs] class SortDirection(Enum): """Options for the direction of sorting when sorting table cells.""" ASCENDING = OSType("ascn") #: Sort in increasing value order DESCENDING = OSType("dscn") #: Sort in decreasing value order
[docs] class CellFormat(Enum): """Options for the format to use when formatting table cells.""" AUTO = OSType("faut") #: Automatic format CHECKBOX = OSType("fcch") #: Checkbox control format (Numbers only) CURRENCY = OSType("fcur") #: Currency number format DATE_AND_TIME = OSType("fdtm") #: Date and time format FRACTION = OSType("ffra") #: Fraction number format DECIMAL_NUMBER = OSType("nmbr") #: Decimal number format PERCENT = OSType("fper") #: Percentage number format POPUP_MENU = OSType("fcpp") #: Pop-up menu control format (Numbers only) SCIENTIFIC = OSType("fsci") #: Scientific notation format SLIDER = OSType("fcsl") #: Slider control format (Numbers only) STEPPER = OSType("fcst") #: Stepper control format (Numbers only) TEXT = OSType("ctxt") #: Text format DURATION = OSType("fdur") #: Duration format RATING = OSType("frat") #: Rating format. (Numbers only) NUMERAL_SYSTEM = OSType("fcns") #: Numeral System
[docs] class ChartType(Enum): """Options for available chart types.""" PIE_2D = OSType("pie2") #: Two-dimensional pie chart VERTICAL_BAR_2D = OSType("vbr2") #: Two-dimensional vertical bar chart STACKED_VERTICAL_BAR_2D = OSType( "svb2" ) #: Two-dimensional stacked vertical bar chart HORIZONTAL_BAR_2D = OSType("hbr2") #: Two-dimensional horizontal bar chart STACKED_HORIZONTAL_BAR_2D = OSType( "shb2" ) #: Two-dimensional stacked horizontal bar chart PIE_3D = OSType("pie3") #: Three-dimensional pie chart. VERTICAL_BAR_3D = OSType("vbr3") #: Three-dimensional vertical bar chart STACKED_VERTICAL_BAR_3D = OSType("svb3") #: Three-dimensional stacked bar chart HORIZONTAL_BAR_3D = OSType("hbr3") #: Three-dimensional horizontal bar chart STACKED_HORIZONTAL_BAR_3D = OSType( "shb3" ) #: Three-dimensional stacked horizontal bar chart AREA_2D = OSType("are2") #: Two-dimensional area chart. STACKED_AREA_2D = OSType("sar2") #: Two-dimensional stacked area chart LINE_2D = OSType("lin2") #: Two-dimensional line chart. LINE_3D = OSType("lin3") #: Three-dimensional line chart AREA_3D = OSType("are3") #: Three-dimensional area chart STACKED_AREA_3D = OSType("sar3") #: Three-dimensional stacked area chart SCATTERPLOT_2D = OSType("scp2") #: Two-dimensional scatterplot chart
[docs] class ChartGrouping(Enum): """Options for how data is grouped within a chart.""" ROW = OSType("KCgr") #: Group by row COLUMN = OSType("KCgc") #: Group by column
[docs] class FillOption(Enum): """Options for the type of fill to use.""" NO_FILL = OSType("fino") COLOR_FILL = OSType("fico") GRADIENT_FILL = OSType("figr") ADVANCED_GRADIENT_FILL = OSType("fiag") IMAGE_FILL = OSType("fiim") ADVANCED_IMAGE_FILL = OSType("fiai")
[docs] class RepetitionMethod(Enum): """Options for whether and how a clip will repeat.""" NONE = OSType("mvrn") #: Clip does not repeat LOOP = OSType("mvlp") #: Clip repeats sequentially LOOP_BACK_AND_FORTH = OSType( "mvbf" ) #: Clip boomerangs back and forth repeatedly
[docs] class KeyAction(Enum): """Options for key states and interactions.""" COMMAND_DOWN = OSType("Kcmd") CONTROL_DOWN = OSType("Kctl") OPTION_DOWN = OSType("Kopt") SHIFT_DOWN = OSType("Ksft")
def __init__(self, properties): super().__init__(properties) self.xa_wcls = XAiWorkWindow @property def properties(self) -> dict: """All properties of the Keynote application.""" raw_dict = self.xa_scel.properties() return { "frontmost": self.frontmost, "version": self.version, "name": self.name, } @property def name(self) -> str: """The name of the application.""" return self.xa_scel.name() @property def frontmost(self) -> bool: """Whether this application is the active application.""" return self.xa_scel.frontmost() @property def version(self) -> str: """The application version number.""" return self.xa_scel.version() @property def current_document(self) -> "XAiWorkDocument": """The current document of the front window.""" return self.front_window.document
[docs] def print( self, item: Union["XAiWorkDocument", XABaseScriptable.XASBWindow], print_properties: dict = None, show_dialog: bool = True, ) -> "XAiWorkApplication": """Prints a document or window. :param item: The document or window to print :type item: Union[XAiWorkDocument, XABaseScriptable.XASBWindow] :param print_properties: The settings to pre-populate the print dialog with, defaults to None :type print_properties: dict, optional :param show_dialog: Whether to show the print dialog or skip right to printing, defaults to True :type show_dialog: bool, optional :return: A reference to the PyXA application object :rtype: XAiWorkApplication .. versionadded:: 0.1.1 """ if print_properties is None: print_properties = {} self.xa_scel.print_withProperties_printDialog_( item.xa_elem, print_properties, show_dialog ) return self
[docs] def open(self, path: Union[str, XABase.XAPath]) -> "XAiWorkDocument": """Opens the file at the given filepath. :param target: The path of the file to open. :type target: Union[str, XABase.XAPath] :return: A reference to newly created document object :rtype: XAiWorkDocument .. versionadded:: 0.1.1 """ if isinstance(path, str): path = XABase.XAPath(path) self.xa_wksp.openURLs_withAppBundleIdentifier_options_additionalEventParamDescriptor_launchIdentifiers_( [path.xa_elem], self.xa_elem.bundleIdentifier(), 0, None, None ) return self.documents()[0]
[docs] def set_password( self, document: "XAiWorkDocument", password: str, hint: str, save_in_keychain: bool = True, ) -> "XAiWorkApplication": """Sets the password of an unencrypted document, optionally storing the password in the user's keychain. :param document: The document to set the password for :type document: XAiWorkDocument :param password: The password :type password: str :param hint: A hint for the password :type hint: str :param save_in_keychain: Whether to save the password in the user's keychain, defaults to True :type save_in_keychain: bool, optional :return: A reference to the PyXA application object :rtype: XAiWorkApplication .. versionadded:: 0.1.1 """ self.xa_scel.setPassword_to_hint_savingInKeychain_( password, document.xa_elem, hint, save_in_keychain ) return self
[docs] def remove_password( self, document: "XAiWorkDocument", password: str ) -> "XAiWorkApplication": """Removes the password from a document. :param document: The document to remove the password to :type document: XAiWorkDocument :param password: The current password :type password: str :return: A reference to the PyXA application object :rtype: XAiWorkApplication .. versionadded:: 0.1.1 """ self.xa_scel.removePassword_from_(password, document.xa_elem) return self
[docs] class XAiWorkWindow( XABaseScriptable.XASBWindow, XABaseScriptable.XASBPrintable, XABase.XAObject ): """A window of an iWork application. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties)
[docs] class XAiWorkDocumentList(XABase.XAList): """A wrapper around lists of themes that employs fast enumeration techniques. All properties of themes can be called as methods on the wrapped list, returning a list containing each theme's value for the property. .. versionadded:: 0.1.1 """ def __init__( self, properties: dict, filter: Union[dict, None] = None, obj_class=None ): if obj_class is None: obj_class = XAiWorkDocument super().__init__(properties, obj_class, filter)
[docs] def properties(self) -> list[dict]: pyxa_dicts = [None] * len(self.xa_elem) for index, document in enumerate(self.xa_elem): pyxa_dicts[index] = { "name": document.name(), "modified": document.modified(), "file": XABase.XAPath(document.file()), "id": document.id(), } return pyxa_dicts
[docs] def name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("name") or [])
[docs] def modified(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("modified") or [])
[docs] def file(self) -> list[XABase.XAPath]: ls = self.xa_elem.arrayByApplyingSelector_("file") or [] return [XABase.XAPath(x) for x in ls]
[docs] def id(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("id") or [])
[docs] def selection(self) -> "XAiWorkiWorkItemList": ls = self.xa_elem.arrayByApplyingSelector_("selection") or [] ls = [x for t in ls for x in t] return self._new_element(ls, XAiWorkiWorkItemList)
[docs] def password_protected(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("passwordProtected") or [])
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkDocument", None]: raw_dict = {} if "name" in properties: raw_dict["name"] = properties["name"] if "file" in properties: if isinstance(properties["file"], str): raw_dict["file"] = properties["file"] else: raw_dict["file"] = properties["file"].xa_elem if "slide_numbers_showing" in properties: raw_dict["slideNumbersShowing"] = properties["slide_numbers_showing"] if "document_theme" in properties: raw_dict["documentTheme"] = properties["document_theme"].xa_elem if "auto_loop" in properties: raw_dict["autoLoop"] = properties["auto_loop"] if "auto_play" in properties: raw_dict["autoPlay"] = properties["auto_play"] if "auto_restart" in properties: raw_dict["autoRestart"] = properties["auto_restart"] if "maximum_idle_duration" in properties: raw_dict["maximumIdleDuration"] = properties["maximum_idle_duration"] if "height" in properties: raw_dict["height"] = properties["height"] if "width" in properties: raw_dict["width"] = properties["width"] for document in self.xa_elem: if all(raw_dict[x] == document.properties()[x] for x in raw_dict): return self._new_element(document, XAiWorkDocument)
[docs] def by_name(self, name: str) -> Union["XAiWorkDocument", None]: return self.by_property("name", name)
[docs] def by_modified(self, modified: bool) -> Union["XAiWorkDocument", None]: return self.by_property("modified", modified)
[docs] def by_file( self, file: Union[str, XABase.XAPath] ) -> Union["XAiWorkDocument", None]: if isinstance(file, XABase.XAPath): file = file.url return self.by_property("file", file)
[docs] def by_id(self, id: str) -> Union["XAiWorkDocument", None]: return self.by_property("id", id)
[docs] def by_selection( self, selection: Union["XAiWorkiWorkItemList", list["XAiWorkiWorkItem"]] ) -> Union["XAiWorkDocument", None]: if isinstance(selection, list): selection = [x.xa_elem for x in selection] elif isinstance(selection, XAiWorkiWorkItemList): selection = selection.xa_elem return self.by_property("selection", selection)
[docs] def by_password_protected( self, password_protected: bool ) -> Union["XAiWorkDocument", None]: return self.by_property("passwordProtected", password_protected)
def __repr__(self): return f"<{str(type(self))}{self.name()}>"
[docs] class XAiWorkDocument(XABaseScriptable.XASBPrintable, XACloseable): """A class for managing and interacting with TextEdit documents. .. seealso:: :class:`XAiWorkApplication` .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the document.""" pyxa_dict = { "name": self.xa_elem.name(), "modified": self.xa_elem.modified(), "file": XABase.XAPath(self.xa_elem.file()), "id": self.xa_elem.id(), } return pyxa_dict @property def name(self) -> str: """The name of the document.""" return self.xa_elem.name() @property def modified(self) -> bool: """Whether the document has been modified since its last save.""" return self.xa_elem.modified() @property def file(self) -> XABase.XAPath: """The location of the document on the disk, if one exists.""" file = self.xa_elem.file() if file is not None: return XABase.XAPath(file) @property def id(self) -> str: """The unique identifier for the document.""" return self.xa_elem.id() @property def selection(self) -> "XAiWorkiWorkItemList": """A list of the currently selected items.""" return self._new_element(self.xa_elem.selection(), XAiWorkiWorkItemList) @selection.setter def selection(self, selection: Union["XAiWorkiWorkItemList", "XAiWorkiWorkItem"]): if isinstance(selection, list): selection = [x.xa_elem for x in selection] self.set_property("selection", selection) else: self.set_property("selection", selection.xa_elem) @property def password_protected(self) -> bool: """Whether the document is password protected.""" return self.xa_elem.passwordProtected() def __repr__(self): return f"<{str(type(self))}{self.name}>"
[docs] class XAiWorkContainerList(XABase.XAList): """A wrapper around lists of containers that employs fast enumeration techniques. .. versionadded:: 0.1.1 """ def __init__( self, properties: dict, filter: Union[dict, None] = None, obj_class=None ): if obj_class is None: obj_class = XAiWorkContainer super().__init__(properties, obj_class, filter) # Specialize to group or specific container type if self.__class__ == XAiWorkContainerList: if all([x.parent().get() == None for x in self.xa_elem]): if hasattr(self, "_xa_ccls"): new_self = self._new_element(self.xa_elem, self._xa_ccls) self.__class__ = new_self.__class__ self.__dict__.update(new_self.__dict__) elif all([x.parent().get() != None for x in self.xa_elem]): new_self = self._new_element(self.xa_elem, XAiWorkGroupList) self.__class__ = new_self.__class__ self.__dict__.update(new_self.__dict__)
[docs] def charts(self, filter: Union[dict, None] = None) -> "XAiWorkChartList": ls = self.xa_elem.arrayByApplyingSelector_("charts") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkChartList, filter)
[docs] def groups(self, filter: Union[dict, None] = None) -> "XAiWorkGroupList": ls = self.xa_elem.arrayByApplyingSelector_("groups") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkGroupList, filter)
[docs] def images(self, filter: Union[dict, None] = None) -> "XAiWorkImageList": ls = self.xa_elem.arrayByApplyingSelector_("images") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkImageList, filter)
[docs] def iwork_items(self, filter: Union[dict, None] = None) -> "XAiWorkiWorkItemList": ls = self.xa_elem.arrayByApplyingSelector_("iWorkItems") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkiWorkItemList, filter)
[docs] def lines(self, filter: Union[dict, None] = None) -> "XAiWorkLineList": ls = self.xa_elem.arrayByApplyingSelector_("lines") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkLineList, filter)
[docs] def movies(self, filter: Union[dict, None] = None) -> "XAiWorkMovieList": ls = self.xa_elem.arrayByApplyingSelector_("movies") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkMovieList, filter)
[docs] def shapes(self, filter: Union[dict, None] = None) -> "XAiWorkShapeList": ls = self.xa_elem.arrayByApplyingSelector_("shapes") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkShapeList, filter)
[docs] def tables(self, filter: Union[dict, None] = None) -> "XAiWorkTableList": ls = self.xa_elem.arrayByApplyingSelector_("tables") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkTableList, filter)
[docs] def text_items(self, filter: Union[dict, None] = None) -> "XAiWorkTextItemList": ls = self.xa_elem.arrayByApplyingSelector_("textItems") or [] if isinstance(ls[0], ScriptingBridge.SBElementArray): ls = [x for sublist in ls for x in sublist] else: ls = [x for x in ls] return self._new_element(ls, XAiWorkTableList, filter)
def __repr__(self): return "<" + str(type(self)) + "length: " + str(len(self.xa_elem)) + ">"
[docs] class XAiWorkContainer(XABase.XAObject): """A class for managing and interacting with containers in Keynote. .. seealso:: :class:`XAiWorkApplication`, :class:`XAiWorkiWorkItem` .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) # Specialize to group or specific container type if self.__class__ == XAiWorkContainer: if self.xa_elem.baseLayout().get() is not None: if hasattr(self, "_xa_ccls"): new_self = self._new_element(self.xa_elem, self._xa_ccls) self.__class__ = new_self.__class__ self.__dict__.update(new_self.__dict__) elif self.xa_elem.parent().get() is not None: new_self = self._new_element(self.xa_elem, XAiWorkGroup) self.__class__ = new_self.__class__ self.__dict__.update(new_self.__dict__)
[docs] def iwork_items(self, filter: Union[dict, None] = None) -> "XAiWorkiWorkItemList": """Returns a list of iWork items, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned iWork items will have, or None :type filter: Union[dict, None] :return: The list of iWork items :rtype: XAiWorkiWorkItemList .. versionadded:: 0.1.1 """ return self._new_element( self.xa_elem.iWorkItems(), XAiWorkiWorkItemList, filter )
[docs] def audio_clips(self, filter: Union[dict, None] = None) -> "XAiWorkAudioClipList": """Returns a list of audio clips, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned audio clips will have, or None :type filter: Union[dict, None] :return: The list of audio clips :rtype: XAiWorkAudioClipList .. versionadded:: 0.1.1 """ return self._new_element( self.xa_elem.audioClips(), XAiWorkAudioClipList, filter )
[docs] def charts(self, filter: Union[dict, None] = None) -> "XAiWorkChartList": """Returns a list of charts, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned charts will have, or None :type filter: Union[dict, None] :return: The list of charts :rtype: XAiWorkChartList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.charts(), XAiWorkChartList, filter)
[docs] def images(self, filter: Union[dict, None] = None) -> "XAiWorkImageList": """Returns a list of images, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned images will have, or None :type filter: Union[dict, None] :return: The list of images :rtype: XAiWorkImageList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.images(), XAiWorkImageList, filter)
[docs] def groups(self, filter: Union[dict, None] = None) -> "XAiWorkGroupList": """Returns a list of groups, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned groups will have, or None :type filter: Union[dict, None] :return: The list of groups :rtype: XAiWorkGroupList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.groups(), XAiWorkGroupList, filter)
[docs] def lines(self, filter: Union[dict, None] = None) -> "XAiWorkLineList": """Returns a list of lines, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned lines will have, or None :type filter: Union[dict, None] :return: The list of lines :rtype: XAiWorkLineList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.lines(), XAiWorkLineList, filter)
[docs] def movies(self, filter: Union[dict, None] = None) -> "XAiWorkMovieList": """Returns a list of movies, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned movies will have, or None :type filter: Union[dict, None] :return: The list of movies :rtype: XAiWorkMovieList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.movies(), XAiWorkMovieList, filter)
[docs] def shapes(self, filter: Union[dict, None] = None) -> "XAiWorkShapeList": """Returns a list of shapes, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned shapes will have, or None :type filter: Union[dict, None] :return: The list of shapes :rtype: XAiWorkShapeList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.shapes(), XAiWorkShapeList, filter)
[docs] def tables(self, filter: Union[dict, None] = None) -> "XAiWorkTableList": """Returns a list of tables, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned tables will have, or None :type filter: Union[dict, None] :return: The list of tables :rtype: XAiWorkTableList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.tables(), XAiWorkTableList, filter)
[docs] def text_items(self, filter: Union[dict, None] = None) -> "XAiWorkTextItemList": """Returns a list of text_items, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned text_items will have, or None :type filter: Union[dict, None] :return: The list of text_items :rtype: XAiWorkTextItemList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.textItems(), XAiWorkTextItemList, filter)
[docs] class XAiWorkiWorkItemList(XABase.XAList): """A wrapper around a list of documents. .. versionadded:: 0.1.1 """ def __init__( self, properties: dict, filter: Union[dict, None] = None, obj_class=None ): if obj_class is None: obj_class = XAiWorkiWorkItem super().__init__(properties, obj_class, filter)
[docs] def properties(self) -> list[dict]: pyxa_dicts = [None] * len(self.xa_elem) for index, item in enumerate(self.xa_elem): pyxa_dicts[index] = { "parent": self._new_element(item.parent(), XAiWorkiWorkItem), "locked": item.locked(), "height": item.height(), "position": tuple(item.position()), "width": item.width(), } return pyxa_dicts
[docs] def height(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("height") or [])
[docs] def locked(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("locked") or [])
[docs] def width(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("width") or [])
[docs] def parent(self) -> XAiWorkContainerList: ls = self.xa_elem.arrayByApplyingSelector_("parent") or [] return self._new_element(ls, XAiWorkContainerList)
[docs] def position(self) -> list[tuple[int, int]]: ls = self.xa_elem.arrayByApplyingSelector_("position") or [] return [tuple(x.pointValue()) for x in ls]
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkiWorkItem", None]: raw_dict = {} if "parent" in properties: raw_dict["parent"] = properties["parent"].xa_elem if "locked" in properties: raw_dict["locked"] = properties["locked"] if "height" in properties: raw_dict["height"] = properties["height"] if "position" in properties: raw_dict["position"] = properties["position"] if "width" in properties: raw_dict["width"] = properties["width"] for item in self.xa_elem: item_properties = item.properties() if all(item_properties[x] == raw_dict[x] for x in raw_dict): return self._new_element(item, XAiWorkiWorkItem)
[docs] def by_height(self, height: int) -> Union["XAiWorkiWorkItem", None]: return self.by_property("height", height)
[docs] def by_locked(self, locked: bool) -> Union["XAiWorkiWorkItem", None]: return self.by_property("locked", locked)
[docs] def by_width(self, width: int) -> Union["XAiWorkiWorkItem", None]: return self.by_property("width", width)
[docs] def by_parent(self, parent: XAiWorkContainer) -> Union["XAiWorkiWorkItem", None]: return self.by_property("parent", parent.xa_elem)
[docs] def by_position(self, position: tuple[int, int]) -> Union["XAiWorkiWorkItem", None]: return self.by_property("position", position)
def __repr__(self): return "<" + str(type(self)) + "length:" + str(len(self.xa_elem)) + ">"
[docs] class XAiWorkiWorkItem(XABase.XAObject): """A class for managing and interacting with text, shapes, images, and other elements in Keynote. .. seealso:: :class:`XAiWorkApplication` .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) if self.__class__ == XAiWorkiWorkItem: description = self.xa_elem.get().description() # Specialize to some iWork Item type new_self = None if ( ": defaultTitleItem" in description or ": defaultBodyItem" in description or ": <class 'sshp'>" in description ): new_self = self._new_element(self.xa_elem, XAiWorkShape) elif ": <class 'imag'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkImage) elif ": <class 'igrp'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkGroup) elif ": <class 'shtx'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkTextItem) elif ": <class 'NmTb'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkTable) elif ": <class 'iWln'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkLine) elif ": <class 'shmv'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkMovie) elif ": <class 'shau'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkAudioClip) elif ": <class 'shct'>" in description: new_self = self._new_element(self.xa_elem, XAiWorkChart) if new_self is not None: new_self.xa_prnt = self.xa_prnt self.__class__ = new_self.__class__ self.__dict__.update(new_self.__dict__) else: print(description) @property def height(self) -> int: """The height of the iWork item.""" return self.xa_elem.height() @height.setter def height(self, height: int): self.set_property("height", height) @property def locked(self) -> bool: """Whether the object is locked.""" return self.xa_elem.locked() @locked.setter def locked(self, locked: bool): self.set_property("locked", locked) @property def width(self) -> int: """The width of the iWork item.""" return self.xa_elem.width() @width.setter def width(self, width: int): self.set_property("width", width) @property def parent(self) -> XAiWorkContainer: """The iWork container that contains the iWork item.""" return self._new_element(self.xa_elem.parent(), XAiWorkContainer) @property def position(self) -> tuple[int, int]: """The horizontal and vertical coordinates of the top left point of the iWork item.""" return tuple(self.xa_elem.position()) @position.setter def position(self, position: tuple[int, int]): self.set_property("position", position)
[docs] def delete(self): """Deletes the item. .. versionadded:: 0.1.1 """ self.xa_elem.delete()
[docs] def duplicate(self) -> "XAiWorkiWorkItem": """Duplicates the item. :return: A reference to the PyXA object that called this method. :rtype: XAiWorkiWorkItem .. versionadded:: 0.1.1 """ if isinstance(self.xa_prnt, XAiWorkiWorkItemList): self.xa_elem.duplicateTo_withProperties_(self.xa_elem.positionAfter(), {}) else: self.xa_elem.duplicateTo_withProperties_( self.xa_prnt.xa_elem.iWorkItems(), {} ) return self
[docs] def resize(self, width: int, height: int) -> "XAiWorkiWorkItem": """Sets the width and height of the item. :param width: The desired width, in pixels :type width: int :param height: The desired height, in pixels :type height: int :return: The iWork item :rtype: XAiWorkiWorkItem .. versionadded:: 0.1.1 """ self.set_properties( { "width": width, "height": height, } ) return self
[docs] def lock(self) -> "XAiWorkiWorkItem": """Locks the properties of the item, preventing changes. :return: The iWork item :rtype: XAiWorkiWorkItem .. versionadded:: 0.1.1 """ self.set_property("locked", True) return self
[docs] def unlock(self) -> "XAiWorkiWorkItem": """Unlocks the properties of the item, allowing changes. :return: The iWork item :rtype: XAiWorkiWorkItem .. versionadded:: 0.1.1 """ self.set_property("locked", False) return self
[docs] def set_position(self, x: int, y: int) -> "XAiWorkiWorkItem": position = AppKit.NSValue.valueWithPoint_(AppKit.NSPoint(x, y)) self.xa_elem.setValue_forKey_(position, "position")
def __repr__(self): return "<" + str(type(self)) + "position: " + str(self.position) + ">"
[docs] class XAiWorkGroupList(XAiWorkContainerList): """A wrapper around lists of themes that employs fast enumeration techniques. All properties of themes can be called as methods on the wrapped list, returning a list containing each theme's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkGroup)
[docs] def height(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("height") or [])
[docs] def position(self) -> list[tuple[int, int]]: ls = self.xa_elem.arrayByApplyingSelector_("position") or [] return [tuple(point.pointValue()) for point in ls]
[docs] def width(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("width") or [])
[docs] def rotation(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rotation") or [])
[docs] def parent(self) -> XAiWorkContainerList: ls = self.xa_elem.arrayByApplyingSelector_("parent") or [] return self._new_element(ls, XAiWorkContainerList)
[docs] def by_height(self, height: int) -> "XAiWorkGroup": return self.by_property("height", height)
[docs] def by_position(self, position: tuple[int, int]) -> "XAiWorkGroup": return self.by_property("position", position)
[docs] def by_width(self, width: int) -> "XAiWorkGroup": return self.by_property("width", width)
[docs] def by_rotation(self, rotation: int) -> "XAiWorkGroup": return self.by_property("rotation", rotation)
[docs] def by_parent(self, parent: XAiWorkContainer) -> "XAiWorkGroup": return self.by_property("parent", parent.xa_elem)
[docs] class XAiWorkGroup(XAiWorkContainer): """A class for managing and interacting with iWork item groups in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def height(self) -> int: """The height of the group.""" return self.xa_elem.height() @height.setter def height(self, height: int): self.set_property("height", height) @property def position(self) -> tuple[int, int]: """The horizontal and vertical coordinates of the top left point of the group.""" return self.xa_elem.position() @position.setter def position(self, position: tuple[int, int]): self.set_property("position", position) @property def width(self) -> int: """The width of the group.""" return self.xa_elem.width() @width.setter def width(self, width: int): self.set_property("width", width) @property def rotation(self) -> int: """The rotation of the group, in degrees from 0 to 359.""" return self.xa_elem.rotation() @rotation.setter def rotation(self, rotation: int): self.set_property("rotation", rotation) @property def parent(self) -> XAiWorkContainer: """The container which contains the group.""" return self._new_element(self.xa_elem.parent(), XAiWorkContainer)
[docs] class XAiWorkImageList(XAiWorkiWorkItemList): """A wrapper around lists of images that employs fast enumeration techniques. All properties of images can be called as methods on the wrapped list, returning a list containing each image's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkImage)
[docs] def description(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("objectDescription") or [])
[docs] def file(self) -> list[str]: return [x.file() for x in self.xa_elem]
[docs] def file_name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("fileName") or [])
[docs] def opacity(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("opacity") or [])
[docs] def reflection_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionShowing") or [])
[docs] def reflection_value(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionValue") or [])
[docs] def rotation(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rotation") or [])
[docs] def by_description(self, description: str) -> "XAiWorkImage": return self.by_property("objectDescription", description)
[docs] def by_file(self, file: str) -> "XAiWorkImage": return self.by_property("file", file)
[docs] def by_file_name(self, file_name: str) -> "XAiWorkImage": return self.by_property("fileName", file_name)
[docs] def by_opacity(self, opacity: int) -> "XAiWorkImage": return self.by_property("opacity", opacity)
[docs] def by_reflection_showing(self, reflection_showing: bool) -> "XAiWorkImage": return self.by_property("reflectionShowing", reflection_showing)
[docs] def by_reflection_value(self, reflection_value: int) -> "XAiWorkImage": return self.by_property("reflectionValue", reflection_value)
[docs] def by_rotation(self, rotation: int) -> "XAiWorkImage": return self.by_property("rotation", rotation)
def __repr__(self): return "<" + str(type(self)) + str(self.file_name()) + ">"
[docs] class XAiWorkImage(XAiWorkiWorkItem): """A class for managing and interacting with images in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def description(self) -> str: """Text associated with the image, read aloud by VoiceOVer.""" return self.xa_elem.object_description() @description.setter def description(self, description: str): self.set_property("description", description) @property def file(self) -> str: """The image file.""" return self.xa_elem.file() @property def file_name(self) -> str: """The name of the image file.""" return self.xa_elem.fileName().get() @file_name.setter def file_name(self, file_name: str): self.set_property("fileName", file_name) @property def opacity(self) -> int: """The opacity of the image, in percent from 0 to 100.""" return self.xa_elem.opacity() @opacity.setter def opacity(self, opacity: int): self.set_property("opacity", opacity) @property def reflection_showing(self) -> bool: """Whether the image displays a reflection.""" return self.xa_elem.reflectionShowing() @reflection_showing.setter def reflection_showing(self, reflection_showing: bool): self.set_property("reflectionShowing", reflection_showing) @property def reflection_value(self) -> int: """The percentage of reflection of the image, from 0 to 100.""" return self.xa_elem.reflectionValue() @reflection_value.setter def reflection_value(self, reflection_value: int): self.set_property("reflectionValue", reflection_value) @property def rotation(self) -> int: """The rotation of the image, in degrees from 0 to 359.""" return self.xa_elem.rotation() @rotation.setter def rotation(self, rotation: int): self.set_property("rotation", rotation)
[docs] def replace_with( self, img_path: Union[str, XABase.XAPath, XABase.XAURL] ) -> "XAiWorkImage": """Removes the image and inserts another in its place with the same width and height. :param img_path: The path to the new image file. :type img_path: Union[str, XABase.XAPath, XABase.XAURL] :return: A reference to the new PyXA image object. :rtype: XAiWorkImage .. versionadded:: 0.1.1 """ self.delete() if isinstance(img_path, str): if "://" in img_path: img_path = XABase.XAURL(img_path) else: img_path = XABase.XAPath(img_path) parent = self.xa_prnt while not hasattr(parent, "add_image"): parent = parent.xa_prnt return parent.add_image(img_path)
def __repr__(self): return "<" + str(type(self)) + str(self.file_name) + ">"
[docs] class XAiWorkAudioClipList(XAiWorkiWorkItemList): """A wrapper around lists of audio clips that employs fast enumeration techniques. All properties of audio clips can be called as methods on the wrapped list, returning a list containing each audio clips's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkAudioClip)
[docs] def file_name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("fileName") or [])
[docs] def clip_volume(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("clipVolume") or [])
[docs] def repetition_method(self) -> list[XAiWorkApplication.RepetitionMethod]: ls = self.xa_elem.arrayByApplyingSelector_("repetitionMethod") or [] return [ XAiWorkApplication.RepetitionMethod(XABase.OSType(x.stringValue())) for x in ls ]
[docs] def by_file_name(self, file_name: str) -> "XAiWorkAudioClip": return self.by_property("fileName", file_name)
[docs] def by_clip_volume(self, clip_volume: int) -> "XAiWorkAudioClip": return self.by_property("clipVolume", clip_volume)
[docs] def by_repetition_method( self, repetition_method: XAiWorkApplication.RepetitionMethod ) -> "XAiWorkAudioClip": for audio_clip in self.xa_elem: if audio_clip.repetitionMethod() == repetition_method.value: return self._new_element(audio_clip, XAiWorkAudioClip)
def __repr__(self): return "<" + str(type(self)) + str(self.file_name()) + ">"
[docs] class XAiWorkAudioClip(XAiWorkiWorkItem): """A class for managing and interacting with audio clips in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def file_name(self) -> str: """The name of the audio file.""" return self.xa_elem.fileName().get() @file_name.setter def file_name(self, file_name: str): self.set_property("fileName", file_name) @property def clip_volume(self) -> int: """The volume setting for the audio clip, from 0 to 100.""" return self.xa_elem.clipVolume() @clip_volume.setter def clip_volume(self, clip_volume: int): self.set_property("clipVolume", clip_volume) @property def repetition_method(self) -> XAiWorkApplication.RepetitionMethod: """Whether or how the audio clip repeats.""" return XAiWorkApplication.RepetitionMethod(self.xa_elem.repetitionMethod()) @repetition_method.setter def repetition_method(self, repetition_method: XAiWorkApplication.RepetitionMethod): self.set_property("repetitionMethod", repetition_method.value) def __repr__(self): return "<" + str(type(self)) + str(self.file_name) + ">"
[docs] class XAiWorkShapeList(XAiWorkiWorkItemList): """A wrapper around lists of shapes that employs fast enumeration techniques. All properties of shapes can be called as methods on the wrapped list, returning a list containing each shape's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkShape)
[docs] def properties(self) -> list[dict]: return [ { "reflection_showing": shape.reflectionShowing(), "rotation": shape.rotation(), "position": tuple(shape.position()), "parent": self._new_element(shape.parent(), XAiWorkContainer), "width": shape.width(), "opacity": shape.opacity(), "locked": shape.locked(), "height": shape.height(), "background_fill_type": XAiWorkApplication.FillOption( shape.backgroundFillType() ), "reflection_value": shape.reflectionValue(), "object_text": shape.objectText().get(), } for shape in self.xa_elem ]
[docs] def background_fill_type(self) -> list[XAiWorkApplication.FillOption]: ls = self.xa_elem.arrayByApplyingSelector_("backgroundFillType") or [] return [ XAiWorkApplication.FillOption(XABase.OSType(x.stringValue())) for x in ls ]
[docs] def object_text(self) -> XABase.XATextList: ls = self.xa_elem.arrayByApplyingSelector_("objectText") or [] return self._new_element(ls, XABase.XATextList)
[docs] def opacity(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("opacity") or [])
[docs] def reflection_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionShowing") or [])
[docs] def reflection_value(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionValue") or [])
[docs] def rotation(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rotation") or [])
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkShape", None]: raw_dict = {} if "reflection_show" in properties: raw_dict["reflectionShowing"] = properties["reflection_showing"] if "rotation" in properties: raw_dict["rotation"] = properties["rotation"] if "position" in properties: raw_dict["position"] = properties["position"] if "parent" in properties: raw_dict["parent"] = properties["parent"].xa_elem if "width" in properties: raw_dict["width"] = properties["width"] if "opacity" in properties: raw_dict["opacity"] = properties["opacity"] if "locked" in properties: raw_dict["locked"] = properties["lockedv"] if "height" in properties: raw_dict["height"] = properties["height"] if "background_fill_type" in properties: raw_dict["backgroundFillType"] = properties["background_fill_type"] if "reflection_value" in properties: raw_dict["reflectionValue"] = properties["reflection_value"] if "object_text" in properties: raw_dict["objectText"] = properties["object_text"] for shape in self.xa_elem: if all([raw_dict[x] == shape.properties()[x] for x in raw_dict]): return self._new_element(shape, XAiWorkShape)
[docs] def by_background_fill_type( self, background_fill_type: XAiWorkApplication.FillOption ) -> Union["XAiWorkShape", None]: for shape in self.xa_elem: if shape.backgroundFillType() == background_fill_type.value: return self._new_element(shape, XAiWorkShape)
[docs] def by_object_text( self, object_text: Union[str, XABase.XAText] ) -> Union["XAiWorkShape", None]: if isinstance(object_text, str): return self.by_property("objectText", object_text) else: return self.by_property("objectText", object_text.xa_elem)
[docs] def by_opacity(self, opacity: int) -> Union["XAiWorkShape", None]: return self.by_property("opacity", opacity)
[docs] def by_reflection_showing( self, reflection_showing: bool ) -> Union["XAiWorkShape", None]: return self.by_property("reflectionShowing", reflection_showing)
[docs] def by_reflection_value(self, reflection_value: int) -> Union["XAiWorkShape", None]: return self.by_property("reflectionValue", reflection_value)
[docs] def by_rotation(self, rotation: int) -> Union["XAiWorkShape", None]: return self.by_property("rotation", rotation)
[docs] class XAiWorkShape(XAiWorkiWorkItem): """A class for managing and interacting with shapes in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the shape.""" return self.xa_elem.properties() @property def background_fill_type(self) -> XAiWorkApplication.FillOption: """The background, if any, for the shape.""" return XAiWorkApplication.FillOption(self.xa_elem.backgroundFillType()) @property def object_text(self) -> XABase.XAText: """The text contained within the shape.""" return self._new_element(self.xa_elem.objectText(), XABase.XAText) @object_text.setter def object_text(self, object_text: Union[str, XABase.XAText]): if isinstance(object_text, str): self.set_property("objectText", object_text) else: self.set_property("objectText", object_text.xa_elem) @property def opacity(self) -> int: """The percent opacity of the object.""" return self.xa_elem.opacity() @opacity.setter def opacity(self, opacity: int): self.set_property("opacity", opacity) @property def reflection_showing(self) -> bool: """Whether the iWork item displays a reflection.""" return self.xa_elem.reflectionShowing() @reflection_showing.setter def reflection_showing(self, reflection_showing: bool): self.set_property("reflectionShowing", reflection_showing) @property def reflection_value(self) -> int: """The percentage of relfection that the iWork item displays, from 0 to 100.""" return self.xa_elem.reflectionValue() @reflection_value.setter def reflection_value(self, reflection_value: int): self.set_property("reflectionValue", reflection_value) @property def rotation(self) -> int: """The rotation of the iWork item, in degrees, from 0 to 359.""" return self.xa_elem.rotation() @rotation.setter def rotation(self, rotation: int): self.set_property("rotation", rotation)
[docs] def set_property(self, property_name: str, value: Any): if isinstance(value, tuple): if isinstance(value[0], int): # Value is a position value = AppKit.NSValue.valueWithPoint_( AppKit.NSPoint(value[0], value[1]) ) super().set_property(property_name, value)
[docs] class XAiWorkChartList(XAiWorkiWorkItemList): """A wrapper around lists of themes that employs fast enumeration techniques. All properties of themes can be called as methods on the wrapped list, returning a list containing each theme's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkChart)
[docs] class XAiWorkChart(XAiWorkiWorkItem): """A class for managing and interacting with charts in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties)
[docs] class XAiWorkLineList(XAiWorkiWorkItemList): """A wrapper around lists of shapes that employs fast enumeration techniques. All properties of shapes can be called as methods on the wrapped list, returning a list containing each shape's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkLine)
[docs] def end_point(self) -> list[tuple[int, int]]: return list(self.xa_elem.arrayByApplyingSelector_("end_point") or [])
[docs] def reflection_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionShowing") or [])
[docs] def reflection_value(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionValue") or [])
[docs] def rotation(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rotation") or [])
[docs] def start_point(self) -> list[tuple[int, int]]: return list(self.xa_elem.arrayByApplyingSelector_("start_point") or [])
[docs] def by_end_point(self, end_point: tuple[int, int]) -> "XAiWorkLine": return self.by_property("endPoint", end_point)
[docs] def by_reflection_showing(self, reflection_showing: bool) -> "XAiWorkLine": return self.by_property("reflectionShowing", reflection_showing)
[docs] def by_reflection_value(self, reflection_value: int) -> "XAiWorkLine": return self.by_property("reflectionValue", reflection_value)
[docs] def by_rotation(self, rotation: int) -> "XAiWorkLine": return self.by_property("rotation", rotation)
[docs] def by_start_point(self, start_point: tuple[int, int]) -> "XAiWorkLine": return self.by_property("startPoint", start_point)
[docs] class XAiWorkLine(XAiWorkiWorkItem): """A class for managing and interacting with lines in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def end_point(self) -> tuple[int, int]: """A list of two numbers indicating the horizontal and vertical position of the line ending point.""" return self.xa_elem.endPoint() @end_point.setter def end_point(self, end_point: tuple[int, int]): self.set_property("endPoint", end_point) @property def reflection_showing(self) -> bool: """Whether the line displays a reflection.""" return self.xa_elem.reflectionShowing() @reflection_showing.setter def reflection_showing(self, reflection_showing: bool): self.set_property("reflectionShowing", reflection_showing) @property def reflection_value(self) -> int: """The percent of reflection of the line, from 0 to 100.""" return self.xa_elem.reflectionValue() @reflection_value.setter def reflection_value(self, reflection_value: int): self.set_property("reflectionValue", reflection_value) @property def rotation(self) -> int: """The rotation of the line, in degrees from 0 to 359.""" return self.xa_elem.rotation() @rotation.setter def rotation(self, rotation: int): self.set_property("rotation", rotation) @property def start_point(self) -> tuple[int, int]: """A list of two numbers indicating the horizontal and vertical position of the line starting point.""" return self.xa_elem.startPoint() @start_point.setter def start_point(self, start_point: tuple[int, int]): self.set_property("startPoint", start_point)
[docs] class XAiWorkMovieList(XAiWorkiWorkItemList): """A wrapper around lists of movies that employs fast enumeration techniques. All properties of movies can be called as methods on the wrapped list, returning a list containing each movie's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkMovie)
[docs] def file_name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("fileName") or [])
[docs] def movie_volume(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("movieVolume") or [])
[docs] def opacity(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("opacity") or [])
[docs] def reflection_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionShowing") or [])
def reflection_value(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionValue") or [])
[docs] def reflection_value(self) -> list[XAiWorkApplication.RepetitionMethod]: ls = self.xa_elem.arrayByApplyingSelector_("repetitionMethod") or [] return [XAiWorkApplication.RepetitionMethod(x) for x in ls]
[docs] def rotation(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rotation") or [])
[docs] def by_file_name(self, file_name: str) -> "XAiWorkMovie": return self.by_property("fileName", file_name)
[docs] def by_movie_volume(self, movie_volume: int) -> "XAiWorkMovie": return self.by_property("movieVolume", movie_volume)
[docs] def by_opacity(self, opacity: int) -> "XAiWorkMovie": return self.by_property("opacity", opacity)
[docs] def by_reflection_showing(self, reflection_showing: bool) -> "XAiWorkMovie": return self.by_property("reflectionShowing", reflection_showing)
[docs] def by_reflection_value(self, reflection_value: int) -> "XAiWorkMovie": return self.by_property("reflectionValue", reflection_value)
[docs] def by_repetition_method( self, repetition_method: XAiWorkApplication.RepetitionMethod ) -> "XAiWorkMovie": return self.by_property("repetitionMethod", repetition_method.value)
[docs] def by_rotation(self, rotation: int) -> "XAiWorkMovie": return self.by_property("rotation", rotation)
[docs] class XAiWorkMovie(XAiWorkiWorkItem): """A class for managing and interacting with movie containers in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def file_name(self) -> str: """The name of the movie file.""" return self.xa_elem.fileName() @file_name.setter def file_name(self, file_name: str): self.set_property("fileName", file_name) @property def movie_volume(self) -> int: """The volume setting for the movie, from 0 to 100.""" return self.xa_elem.movieVolume() @movie_volume.setter def movie_volume(self, movie_volume: int): self.set_property("movieVolume", movie_volume) @property def opacity(self) -> int: """The percent opacity of the object.""" return self.xa_elem.opacity() @opacity.setter def opacity(self, opacity: int): self.set_property("opacity", opacity) @property def reflection_showing(self) -> bool: """Whether the movie displays a reflection.""" return self.xa_elem.reflectionShowing() @reflection_showing.setter def reflection_showing(self, reflection_showing: bool): self.set_property("reflectionShowing", reflection_showing) @property def reflection_value(self) -> int: """The percentage of reflection of the movie, from 0 to 100.""" return self.xa_elem.reflectionValue() @reflection_value.setter def reflection_value(self, reflection_value: int): self.set_property("reflection_value", reflection_value) @property def repetition_method(self) -> XAiWorkApplication.RepetitionMethod: """Whether or how the movie repeats.""" return XAiWorkApplication.RepetitionMethod(self.xa_elem.repetitionMethod()) @repetition_method.setter def repetition_method(self, repetition_method: XAiWorkApplication.RepetitionMethod): self.set_property("repetitionMethod", repetition_method.value) @property def rotation(self) -> int: """The rotation of the movie, in degrees from 0 to 359.""" return self.xa_elem.rotation() @rotation.setter def rotation(self, rotation: int): self.set_property("rotation", rotation)
[docs] class XAiWorkTextItemList(XAiWorkiWorkItemList): """A wrapper around lists of text items that employs fast enumeration techniques. All properties of text items can be called as methods on the wrapped list, returning a list containing each text item's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkTextItem)
[docs] def background_fill_type(self) -> list[XAiWorkApplication.FillOption]: ls = self.xa_elem.arrayByApplyingSelector_("fileName") or [] return [XAiWorkApplication.FillOption(x) for x in ls]
[docs] def text(self) -> XABase.XATextList: ls = self.xa_elem.arrayByApplyingSelector_("text") or [] return self._new_element(ls, XABase.XATextList)
[docs] def opacity(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("opacity") or [])
[docs] def reflection_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionShowing") or [])
[docs] def reflection_value(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("reflectionValue") or [])
[docs] def rotation(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rotation") or [])
[docs] def by_background_fill_type( self, background_fill_type: XAiWorkApplication.FillOption ) -> "XAiWorkTextItem": return self.by_property("backgroundFillType", background_fill_type.value)
[docs] def by_text(self, text: Union[str, XABase.XAText]) -> "XAiWorkTextItem": if isinstance(text, str): self.by_property("text", text) else: self.by_property("text", text.xa_elem)
[docs] def by_opacity(self, opacity: int) -> "XAiWorkTextItem": return self.by_property("opacity", opacity)
[docs] def by_reflection_showing(self, reflection_showing: bool) -> "XAiWorkTextItem": return self.by_property("reflectionShowing", reflection_showing)
[docs] def by_reflection_value(self, reflection_value: int) -> "XAiWorkTextItem": return self.by_property("reflectionValue", reflection_value)
[docs] def by_rotation(self, rotation: int) -> "XAiWorkTextItem": return self.by_property("rotation", rotation)
[docs] class XAiWorkTextItem(XAiWorkiWorkItem): """A class for managing and interacting with text items in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def background_fill_type(self) -> XAiWorkApplication.FillOption: """The background of the text item.""" return XAiWorkApplication.FillOption(self.xa_elem.backgroundFillType()) @property def text(self) -> XABase.XAText: """The text contained within the text item.""" return self._new_element(self.xa_elem.text(), XABase.XAText) @text.setter def text(self, text: Union[str, XABase.XAText]): if isinstance(text, str): self.set_property("text", text) else: self.set_property("text", text.xa_elem) @property def opacity(self) -> int: """The opacity of the text item.""" return self.xa_elem.opacity() @opacity.setter def opacity(self, opacity: int): self.set_property("opacity", opacity) @property def reflection_showing(self) -> bool: """Whether the text item displays a reflection.""" return self.xa_elem.reflectionShowing() @reflection_showing.setter def reflection_showing(self, reflection_showing: bool): self.set_property("reflectionShowing", reflection_showing) @property def reflection_value(self) -> int: """The percentage of reflection of the text item, from 0 to 100.""" return self.xa_elem.reflectionValue() @reflection_value.setter def reflection_value(self, reflection_value: int): self.set_property("reflectionValue", reflection_value) @property def rotation(self) -> int: """The rotation of the text item, in degrees from 0 to 359.""" return self.xa_elem.rotation() @rotation.setter def rotation(self, rotation: int): self.set_property("rotation", rotation)
[docs] class XAiWorkTableList(XAiWorkiWorkItemList): """A wrapper around lists of shapes that employs fast enumeration techniques. All properties of shapes can be called as methods on the wrapped list, returning a list containing each shape's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkTable)
[docs] def name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("name") or [])
[docs] def row_count(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("rowCount") or [])
[docs] def column_count(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("columnCount") or [])
[docs] def header_row_count(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("headerRowCount") or [])
[docs] def header_column_count(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("headerColumnCount") or [])
[docs] def footer_row_count(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("footerRowCount") or [])
[docs] def cell_range(self) -> "XAiWorkRangeList": ls = self.xa_elem.arrayByApplyingSelector_("cellRange") or [] return self._new_element(ls, XAiWorkRangeList)
[docs] def selection_range(self) -> "XAiWorkRangeList": ls = self.xa_elem.arrayByApplyingSelector_("selectionRange") or [] return self._new_element(ls, XAiWorkRangeList)
[docs] def by_name(self, name: str) -> Union["XAiWorkTable", None]: return self.by_property("name", name)
[docs] def by_row_count(self, row_count: int) -> Union["XAiWorkTable", None]: return self.by_property("rowCount", row_count)
[docs] def by_column_count(self, column_count: int) -> Union["XAiWorkTable", None]: return self.by_property("columnCount", column_count)
[docs] def by_header_row_count(self, header_row_count: int) -> Union["XAiWorkTable", None]: return self.by_property("headerRowCount", header_row_count)
[docs] def by_header_column_count( self, header_column_count: int ) -> Union["XAiWorkTable", None]: return self.by_property("headerColumnCount", header_column_count)
[docs] def by_cell_range(self, cell_range: "XAiWorkRange") -> Union["XAiWorkTable", None]: return self.by_property("cellRange", cell_range.xa_elem)
[docs] def by_selection_range( self, selection_range: "XAiWorkRange" ) -> Union["XAiWorkTable", None]: return self.by_property("selectionRange", selection_range.xa_elem)
def __repr__(self): return "<" + str(type(self)) + str(self.name()) + ">"
[docs] class XAiWorkTable(XAiWorkiWorkItem): """A class for managing and interacting with tables in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def name(self) -> str: """The name of the table.""" return self.xa_elem.name() @name.setter def name(self, name: str): self.set_property("name", name) @property def row_count(self) -> int: """The number of rows in the table.""" return self.xa_elem.rowCount() @row_count.setter def row_count(self, row_count: int): self.set_property("rowCount", row_count) @property def column_count(self) -> int: """The number of columns in the table.""" return self.xa_elem.columnCount() @column_count.setter def column_count(self, column_count: int): self.set_property("columnCount", column_count) @property def header_row_count(self) -> int: """The number of header rows in the table.""" return self.xa_elem.headerRowCount() @header_row_count.setter def header_row_count(self, header_row_count: int): self.set_property("headerRowCount", header_row_count) @property def header_column_count(self) -> int: """The number of header columns in the table.""" return self.xa_elem.headerColumnCount() @header_column_count.setter def header_column_count(self, header_column_count: int): self.set_property("headerColumnCount", header_column_count) @property def footer_row_count(self) -> int: """The number of footer rows in the table.""" return self.xa_elem.footerRowCount() @footer_row_count.setter def footer_row_count(self, footer_row_count: int): self.set_property("footerRowCount", footer_row_count) @property def cell_range(self) -> "XAiWorkRange": """The range of all cells in the table.""" return self._new_element(self.xa_elem.cellRange(), XAiWorkRange) @property def selection_range(self) -> "XAiWorkRange": """The currently selected cells.""" return self._new_element(self.xa_elem.selectionRange(), XAiWorkRange) @selection_range.setter def selection_range(self, selection_range: "XAiWorkRange"): self.set_property("selectionRange", selection_range.xa_elem)
[docs] def sort( self, by_column: "XAiWorkColumn", in_rows: Union[list["XAiWorkRow"], "XAiWorkRowList", None] = None, direction: XAiWorkApplication.SortDirection = XAiWorkApplication.SortDirection.ASCENDING, ) -> "XAiWorkTable": """Sorts the table according to the specified column, in the specified sorting direction. :param by_column: The column to sort by :type by_column: XAiWorkColumn :param in_rows: The rows to sort, or None to sort the whole table, defaults to None :type in_rows: Union[list[XAiWorkRow], XAiWorkRowList, None], optional :param direction: The direction to sort in, defaults to XAiWorkApplication.SortDirection.ASCENDING :type direction: XAiWorkApplication.SortDirection, optional :return: The table object :rtype: XAiWorkTable .. versionadded:: 0.1.1 """ if isinstance(in_rows, list): in_rows = [row.xa_elem for row in in_rows] elif isinstance(in_rows, XABase.XAList): in_rows = in_rows.xa_elem self.xa_elem.sortBy_direction_inRows_( by_column.xa_elem, direction.value, in_rows ) return self
[docs] def cells(self, filter: Union[dict, None] = None) -> "XAiWorkCellList": """Returns a list of cells, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned cells will have, or None :type filter: Union[dict, None] :return: The list of cells :rtype: XAiWorkCellList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.cells(), XAiWorkCellList, filter)
[docs] def columns(self, filter: Union[dict, None] = None) -> "XAiWorkColumnList": """Returns a list of columns, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned columns will have, or None :type filter: Union[dict, None] :return: The list of columns :rtype: XAiWorkColumnList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.columns(), XAiWorkColumnList, filter)
[docs] def rows(self, filter: Union[dict, None] = None) -> "XAiWorkRowList": """Returns a list of rows, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned rows will have, or None :type filter: Union[dict, None] :return: The list of rows :rtype: XAiWorkRowList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.rows(), XAiWorkRowList, filter)
[docs] def ranges(self, filter: Union[dict, None] = None) -> "XAiWorkRangeList": """Returns a list of ranges, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned ranges will have, or None :type filter: Union[dict, None] :return: The list of ranges :rtype: XAiWorkRangeList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.ranges(), XAiWorkRangeList, filter)
def __repr__(self): try: return "<" + str(type(self)) + str(self.name) + ">" except AttributeError: # Probably dealing with a proxy object created via make() return "<" + str(type(self)) + str(self.xa_elem) + ">"
[docs] class XAiWorkRangeList(XABase.XAList): """A wrapper around lists of themes that employs fast enumeration techniques. All properties of themes can be called as methods on the wrapped list, returning a list containing each theme's value for the property. .. versionadded:: 0.1.1 """ def __init__( self, properties: dict, filter: Union[dict, None] = None, obj_class=None ): if obj_class is None: obj_class = XAiWorkRange super().__init__(properties, obj_class, filter)
[docs] def properties(self) -> list[dict]: raw_dicts = self.xa_elem.arrayByApplyingSelector_("properties") or [] pyxa_dicts = [None] * len(self.xa_elem) for index, raw_dict in enumerate(raw_dicts): pyxa_dicts[index] = { "background_color": XABase.XAColor(raw_dict["backgroundColor"]) if raw_dict["backgroundColor"] is not None else None, "font_size": raw_dict["fontSize"], "name": raw_dict["name"], "format": XAiWorkApplication.CellFormat( XABase.OSType(raw_dict["format"].stringValue()) ), "vertical_alignment": XAiWorkApplication.Alignment( XABase.OSType(raw_dict["verticalAlignment"].stringValue()) ), "font_name": raw_dict["fontName"], "alignment": XAiWorkApplication.Alignment( XABase.OSType(raw_dict["alignment"].stringValue()) ), "text_wrap": raw_dict["textWrap"], "text_color": XABase.XAColor(raw_dict["textColor"]), } return pyxa_dicts
[docs] def font_name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("fontName") or [])
[docs] def font_size(self) -> list[float]: return list(self.xa_elem.arrayByApplyingSelector_("fontSize") or [])
[docs] def format(self) -> list[XAiWorkApplication.CellFormat]: ls = self.xa_elem.arrayByApplyingSelector_("format") or [] return [XAiWorkApplication.CellFormat(x) for x in ls]
[docs] def alignment(self) -> list[XAiWorkApplication.Alignment]: ls = self.xa_elem.arrayByApplyingSelector_("alignment") or [] return [ XAiWorkApplication.Alignment(XABase.OSType(x.stringValue())) for x in ls ]
[docs] def name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("name") or [])
[docs] def text_color(self) -> list[XABase.XAColor]: ls = self.xa_elem.arrayByApplyingSelector_("textColor") or [] return [XABase.XAColor(x) for x in ls]
[docs] def text_wrap(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("textWrap") or [])
[docs] def background_color(self) -> list[XABase.XAColor]: ls = self.xa_elem.arrayByApplyingSelector_("backgroundColor") or [] return [XABase.XAColor(x) for x in ls]
[docs] def vertical_alignment(self) -> list[XAiWorkApplication.Alignment]: ls = self.xa_elem.arrayByApplyingSelector_("verticalAlignment") or [] return [ XAiWorkApplication.Alignment(XABase.OSType(x.stringValue())) for x in ls ]
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkRange", None]: raw_dict = {} if "background_color" in properties: raw_dict["backgroundColor"] = properties["background_color"].xa_elem if "font_size" in properties: raw_dict["fontSize"] = properties["font_size"] if "name" in properties: raw_dict["name"] = properties["name"] if "format" in properties: raw_dict["format"] = properties["format"].value if "vertical_alignment" in properties: raw_dict["verticalAlignment"] = XAEvents.event_from_type_code( properties["vertical_alignment"].value ) if "font_name" in properties: raw_dict["fontName"] = properties["font_name"] if "alignment" in properties: raw_dict["alignment"] = XAEvents.event_from_type_code( properties["alignment"].value ) if "text_wrap" in properties: raw_dict["textWrap"] = properties["text_wrap"] if "text_color" in properties: raw_dict["textColor"] = properties["text_color"].xa_elem for page_range in self.xa_elem: if all([raw_dict[x] == page_range.properties()[x] for x in raw_dict]): return self._new_element(page_range, XAiWorkRange)
[docs] def by_font_name(self, font_name: str) -> Union["XAiWorkRange", None]: return self.by_property("fontName", font_name)
[docs] def by_font_size(self, font_size: float) -> Union["XAiWorkRange", None]: return self.by_property("fontSize", font_size)
[docs] def by_format( self, format: XAiWorkApplication.CellFormat ) -> Union["XAiWorkRange", None]: return self.by_property("format", format.value)
[docs] def by_alignment( self, alignment: XAiWorkApplication.Alignment ) -> Union["XAiWorkRange", None]: for page_range in self.xa_elem: if page_range.alignment() == alignment.value: return self._new_element(page_range, XAiWorkRange)
[docs] def by_name(self, name: str) -> Union["XAiWorkRange", None]: return self.by_property("name", name)
[docs] def by_text_color(self, text_color: XABase.XAColor) -> Union["XAiWorkRange", None]: return self.by_property("textColor", text_color.xa_elem)
[docs] def by_text_wrap(self, text_wrap: bool) -> Union["XAiWorkRange", None]: return self.by_property("textWrap", text_wrap)
[docs] def by_background_color( self, background_color: XABase.XAColor ) -> Union["XAiWorkRange", None]: return self.by_property("backgroundColor", background_color.xa_elem)
[docs] def by_vertical_alignment( self, vertical_alignment: XAiWorkApplication.Alignment ) -> Union["XAiWorkRange", None]: for page_range in self.xa_elem: if page_range.verticalAlignment() == vertical_alignment.value: return self._new_element(page_range, XAiWorkRange)
def __repr__(self): return "<" + str(type(self)) + str(self.name()) + ">"
[docs] class XAiWorkRange(XABase.XAObject): """A class for managing and interacting with ranges of table cells in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the range.""" raw_dict = self.xa_elem.properties() return { "background_color": XABase.XAColor(raw_dict["backgroundColor"]), "font_size": raw_dict["fontSize"], "name": raw_dict["name"], "format": XAiWorkApplication.CellFormat( XABase.OSType(raw_dict["format"].stringValue()) ), "vertical_alignment": XAiWorkApplication.Alignment( XABase.OSType(raw_dict["verticalAlignment"].stringValue()) ), "font_name": raw_dict["fontName"], "alignment": XAiWorkApplication.Alignment( XABase.OSType(raw_dict["alignment"].stringValue()) ), "text_wrap": raw_dict["textWrap"], "text_color": XABase.XAColor(raw_dict["textColor"]), } @property def font_name(self) -> str: """The font of the range's cells.""" return self.xa_elem.fontName() @font_name.setter def font_name(self, font_name: str): self.set_property("fontName", font_name) @property def font_size(self) -> float: """The font size of the range's cells.""" return self.xa_elem.fontSize() @font_size.setter def font_size(self, font_size: float): self.set_property("fontSize", font_size) @property def format(self) -> XAiWorkApplication.CellFormat: """The format of the range's cells.""" return XAiWorkApplication.CellFormat(self.xa_elem.format()) @format.setter def format(self, format: XAiWorkApplication.CellFormat): self.set_property("format", format.value) @property def alignment(self) -> XAiWorkApplication.Alignment: """The horizontal alignment of content within the range's cells.""" return XAiWorkApplication.Alignment(self.xa_elem.alignment()) @alignment.setter def alignment(self, alignment: XAiWorkApplication.Alignment): self.set_property("alignment", alignment.value) @property def name(self) -> str: """The range's coordinates.""" return self.xa_elem.name() @name.setter def name(self, name: str): self.set_property("name", name) @property def text_color(self) -> XABase.XAColor: """The text color of the range's cells.""" return XABase.XAColor(self.xa_elem.textColor()) @text_color.setter def text_color(self, text_color: XABase.XAColor): self.set_property("textColor", text_color.xa_elem) @property def text_wrap(self) -> bool: """Whether text within the range's cell should wrap.""" return self.xa_elem.textWrap() @text_wrap.setter def text_wrap(self, text_wrap: bool): self.set_property("textWrap", text_wrap) @property def background_color(self) -> XABase.XAColor: """The background color of the range's cells.""" return XABase.XAColor(self.xa_elem.backgroundColor()) @background_color.setter def background_color(self, background_color: XABase.XAColor): self.set_property("backgroundColor", background_color.xa_elem) @property def vertical_alignment(self) -> XAiWorkApplication.Alignment: """The vertical alignment of content in the range's cells.""" return XAiWorkApplication.Alignment(self.xa_elem.verticalAlignment()) @vertical_alignment.setter def vertical_alignment(self, vertical_alignment: XAiWorkApplication.Alignment): self.set_property("verticalAlignment", vertical_alignment.value)
[docs] def clear(self) -> "XAiWorkRange": """Clears the content of every cell in the range. :return: The range object :rtype: XAiWorkRange :Example 1: Clear all cells in a table >>> import PyXA >>> app = PyXA.Application("Keynote") >>> range = app.documents()[0].slides()[0].tables()[0].cell_range >>> range.clear() :Example 2: Clear all cells whose value is 3 >>> import PyXA >>> app = PyXA.Application("Keynote") >>> cells = app.documents()[0].slides()[0].tables()[0].cells() >>> for cell in cells: >>> if cell.value == 3: >>> cell.clear() .. versionadded:: 0.1.1 """ self.xa_elem.clear() return self
[docs] def merge(self) -> "XAiWorkRange": """Merges all cells in the range. :return: The range object :rtype: XAiWorkRange :Example 1: Merge all cells in the first row of a table >>> import PyXA >>> app = PyXA.Application("Keynote") >>> table = app.documents()[0].slides()[0].tables()[0] >>> row = table.rows()[0] >>> row.merge() :Example 2: Merge all cells in the first column of a table >>> import PyXA >>> app = PyXA.Application("Keynote") >>> table = app.documents()[0].slides()[0].tables()[0] >>> col = table.columns()[0] >>> col.merge() .. note:: If you merge an entire row, then merge an entire column, all cells in the table will be merged. The same is true if the row and column operations are flipped. .. versionadded:: 0.1.1 """ self.xa_elem.merge() return self
[docs] def unmerge(self) -> "XAiWorkRange": """Unmerges all cells in the range. :return: The range object :rtype: XAiWorkRange :Example 1: Unmerge all merged cells >>> import PyXA >>> app = PyXA.Application("Keynote") >>> range = app.documents()[0].slides()[0].tables()[0].cell_range >>> range.unmerge() .. versionadded:: 0.1.1 """ self.xa_elem.unmerge() return self
[docs] def cells(self, filter: Union[dict, None] = None) -> "XAiWorkCellList": """Returns a list of cells, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned cells will have, or None :type filter: Union[dict, None] :return: The list of cells :rtype: XAiWorkCellList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.cells(), XAiWorkCellList, filter)
[docs] def columns(self, filter: Union[dict, None] = None) -> "XAiWorkColumnList": """Returns a list of columns, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned columns will have, or None :type filter: Union[dict, None] :return: The list of columns :rtype: XAiWorkColumnList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.columns(), XAiWorkColumnList, filter)
[docs] def rows(self, filter: Union[dict, None] = None) -> "XAiWorkRowList": """Returns a list of rows, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned rows will have, or None :type filter: Union[dict, None] :return: The list of rows :rtype: XAiWorkRowList .. versionadded:: 0.1.1 """ return self._new_element(self.xa_elem.rows(), XAiWorkRowList, filter)
def __repr__(self): return "<" + str(type(self)) + str(self.name) + ">"
[docs] class XAiWorkRowList(XAiWorkRangeList): """A wrapper around lists of rows that employs fast enumeration techniques. All properties of rows can be called as methods on the wrapped list, returning a list containing each row's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkRow)
[docs] def properties(self) -> list[dict]: raw_dicts = self.xa_elem.arrayByApplyingSelector_("properties") or [] pyxa_dicts = super().properties() for index, raw_dict in enumerate(raw_dicts): properties = pyxa_dicts[index] properties["address"] = raw_dict["address"] properties["height"] = raw_dict["height"] return pyxa_dicts
[docs] def address(self) -> list[float]: return list(self.xa_elem.arrayByApplyingSelector_("address") or [])
[docs] def height(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("height") or [])
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkRow", None]: raw_dict = {} if "background_color" in properties: raw_dict["backgroundColor"] = properties["background_color"].xa_elem if "font_size" in properties: raw_dict["fontSize"] = properties["font_size"] if "name" in properties: raw_dict["name"] = properties["name"] if "format" in properties: raw_dict["format"] = properties["format"].value if "vertical_alignment" in properties: raw_dict["verticalAlignment"] = XAEvents.event_from_type_code( properties["vertical_alignment"].value ) if "font_name" in properties: raw_dict["fontName"] = properties["font_name"] if "alignment" in properties: raw_dict["alignment"] = XAEvents.event_from_type_code( properties["alignment"].value ) if "text_wrap" in properties: raw_dict["textWrap"] = properties["text_wrap"] if "text_color" in properties: raw_dict["textColor"] = properties["text_color"].xa_elem if "address" in properties: raw_dict["address"] = properties["address"] if "height" in properties: raw_dict["height"] = properties["height"] for page_range in self.xa_elem: if all([raw_dict[x] == page_range.properties()[x] for x in raw_dict]): return self._new_element(page_range, XAiWorkRow)
[docs] def by_address(self, address: float) -> Union["XAiWorkRow", None]: return self.by_property("address", address)
[docs] def by_height(self, height: int) -> Union["XAiWorkRow", None]: return self.by_property("height", height)
[docs] class XAiWorkRow(XAiWorkRange): """A class for managing and interacting with table rows in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the row.""" raw_dict = self.xa_elem.properties() properties = super().properties properties["address"] = raw_dict["address"] properties["height"] = raw_dict["height"] return properties @property def address(self) -> int: """The index of the row in the table.""" return self.xa_elem.address() @property def height(self) -> float: """The height of the row in pixels.""" return self.xa_elem.height() @height.setter def height(self, height: float): self.set_property("height", height)
[docs] class XAiWorkColumnList(XAiWorkRangeList): """A wrapper around lists of columns that employs fast enumeration techniques. All properties of columns can be called as methods on the wrapped list, returning a list containing each column's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkColumn)
[docs] def properties(self) -> list[dict]: raw_dicts = self.xa_elem.arrayByApplyingSelector_("properties") or [] pyxa_dicts = super().properties() for index, raw_dict in enumerate(raw_dicts): properties = pyxa_dicts[index] properties["address"] = raw_dict["address"] properties["width"] = raw_dict["width"] return pyxa_dicts
[docs] def address(self) -> list[float]: return list(self.xa_elem.arrayByApplyingSelector_("address") or [])
[docs] def width(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("width") or [])
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkColumn", None]: raw_dict = {} if "background_color" in properties: raw_dict["backgroundColor"] = properties["background_color"].xa_elem if "font_size" in properties: raw_dict["fontSize"] = properties["font_size"] if "name" in properties: raw_dict["name"] = properties["name"] if "format" in properties: raw_dict["format"] = properties["format"].value if "vertical_alignment" in properties: raw_dict["verticalAlignment"] = XAEvents.event_from_type_code( properties["vertical_alignment"].value ) if "font_name" in properties: raw_dict["fontName"] = properties["font_name"] if "alignment" in properties: raw_dict["alignment"] = XAEvents.event_from_type_code( properties["alignment"].value ) if "text_wrap" in properties: raw_dict["textWrap"] = properties["text_wrap"] if "text_color" in properties: raw_dict["textColor"] = properties["text_color"].xa_elem if "address" in properties: raw_dict["address"] = properties["address"] if "width" in properties: raw_dict["width"] = properties["width"] for page_range in self.xa_elem: if all([raw_dict[x] == page_range.properties()[x] for x in raw_dict]): return self._new_element(page_range, XAiWorkColumn)
[docs] def by_address(self, address: float) -> Union["XAiWorkColumn", None]: return self.by_property("address", address)
[docs] def by_width(self, width: int) -> Union["XAiWorkColumn", None]: return self.by_property("width", width)
[docs] class XAiWorkColumn(XAiWorkRange): """A class for managing and interacting with table columns in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the column.""" raw_dict = self.xa_elem.properties() properties = super().properties properties["address"] = raw_dict["address"] properties["width"] = raw_dict["width"] return properties @property def address(self) -> int: """The index of the column in the table.""" return self.xa_elem.address() @property def width(self) -> float: """The width of the column in pixels.""" return self.xa_elem.width() @width.setter def width(self, width: float): self.set_property("width", width)
[docs] class XAiWorkCellList(XAiWorkRangeList): """A wrapper around lists of cells that employs fast enumeration techniques. All properties of cells can be called as methods on the wrapped list, returning a list containing each cell's value for the property. .. versionadded:: 0.1.1 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAiWorkCell)
[docs] def properties(self) -> list[dict]: raw_dicts = self.xa_elem.arrayByApplyingSelector_("properties") or [] pyxa_dicts = super().properties() for index, raw_dict in enumerate(raw_dicts): properties = pyxa_dicts[index] properties["formatted_value"] = raw_dict["formattedValue"] properties["formula"] = raw_dict["formula"] properties["value"] = raw_dict["value"] properties["column"] = self._new_element(raw_dict["column"], XAiWorkColumn) properties["row"] = self._new_element(raw_dict["row"], XAiWorkRow) return pyxa_dicts
[docs] def formatted_value(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("formattedValue") or [])
[docs] def formula(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("formula") or [])
[docs] def value(self) -> list[Any]: return list(self.xa_elem.arrayByApplyingSelector_("value") or [])
[docs] def column(self) -> XAiWorkColumnList: ls = self.xa_elem.arrayByApplyingSelector_("column") or [] return self._new_element(ls, XAiWorkColumnList)
[docs] def row(self) -> XAiWorkRowList: ls = self.xa_elem.arrayByApplyingSelector_("row") or [] return self._new_element(ls, XAiWorkRowList)
[docs] def by_properties(self, properties: dict) -> Union["XAiWorkCell", None]: raw_dict = {} if "background_color" in properties: raw_dict["backgroundColor"] = properties["background_color"].xa_elem if "font_size" in properties: raw_dict["fontSize"] = properties["font_size"] if "name" in properties: raw_dict["name"] = properties["name"] if "format" in properties: raw_dict["format"] = properties["format"].value if "vertical_alignment" in properties: raw_dict["verticalAlignment"] = XAEvents.event_from_type_code( properties["vertical_alignment"].value ) if "font_name" in properties: raw_dict["fontName"] = properties["font_name"] if "alignment" in properties: raw_dict["alignment"] = XAEvents.event_from_type_code( properties["alignment"].value ) if "text_wrap" in properties: raw_dict["textWrap"] = properties["text_wrap"] if "text_color" in properties: raw_dict["textColor"] = properties["text_color"].xa_elem if "formatted_value" in properties: raw_dict["formattedValue"] = properties["formatted_value"] if "formula" in properties: raw_dict["formula"] = properties["formula"] if "value" in properties: raw_dict["value"] = properties["value"] if "column" in properties: raw_dict["column"] = properties["column"].xa_elem if "row" in properties: raw_dict["row"] = properties["row"].xa_elem for page_range in self.xa_elem: if all([raw_dict[x] == page_range.properties()[x] for x in raw_dict]): return self._new_element(page_range, XAiWorkCell)
[docs] def by_formatted_value(self, formatted_value: str) -> Union["XAiWorkCell", None]: return self.by_property("formattedValue", formatted_value)
[docs] def by_formula(self, formula: str) -> Union["XAiWorkCell", None]: return self.by_property("formula", formula)
[docs] def by_value(self, value: Any) -> Union["XAiWorkCell", None]: return self.by_property("value", value)
[docs] def by_column(self, column: XAiWorkColumn) -> Union["XAiWorkCell", None]: return self.by_property("column", column.xa_elem)
[docs] def by_row(self, row: XAiWorkRow) -> Union["XAiWorkCell", None]: return self.by_property("row", row.xa_elem)
[docs] class XAiWorkCell(XAiWorkRange): """A class for managing and interacting with table cells in Keynote. .. versionadded:: 0.1.1 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the cell.""" raw_dict = self.xa_elem.properties() properties = super().properties properties["formatted_value"] = raw_dict["formattedValue"] properties["formula"] = raw_dict["formula"] properties["value"] = raw_dict["value"] properties["column"] = self._new_element(raw_dict["column"], XAiWorkColumn) properties["row"] = self._new_element(raw_dict["row"], XAiWorkRow) return properties @property def formatted_value(self) -> str: """The formatted form of the value stored in the cell.""" return self.xa_elem.formattedValue() @property def formula(self) -> str: """The formula in the cell as text.""" return self.xa_elem.formula() @property def value(self) -> Union[int, float, datetime, str, bool, None]: """The value stored in the cell.""" return self.xa_elem.value().get() @value.setter def value(self, value: Union[int, float, datetime, str, bool, None]): self.set_property("value", value) @property def column(self) -> XAiWorkColumn: """The cell's column.""" return self._new_element(self.xa_elem.column(), XAiWorkColumn) @property def row(self) -> XAiWorkRow: """The cell's row.""" return self._new_element(self.xa_elem.row(), XAiWorkRow)