Source code for PyXA.apps.Keynote

""".. versionadded:: 0.0.2

Control the macOS Keynote application using JXA-like syntax.
"""
from enum import Enum
from typing import Any, Union

import AppKit

from PyXA import XABase
from PyXA import XAEvents
from PyXA.XABase import OSType

from . import iWorkApplicationBase

[docs] class XAKeynoteApplication(iWorkApplicationBase.XAiWorkApplication): """A class for managing and interacting with Keynote.app. .. seealso:: :class:`XAKeynoteWindow`, :class:`XAKeynoteDocument` .. versionadded:: 0.0.2 """
[docs] class ObjectType(Enum): """Object types available for creation in Keynote. """ DOCUMENT = "document" SHAPE = "shape" TABLE = "table" AUDIO_CLIP = "audio_clip" CHART = "chart" IMAGE = "image" SLIDE = "slide" LINE = "line" MOVIE = "movie" TEXT_ITEM = "text_item" GROUP = "group" iWORK_ITEM = "iwork_item" TRANSITION_SETTINGS = "transition_settings"
[docs] class ExportFormat(Enum): """Options for what format to export a Keynote project as. """ KEYNOTE = OSType('Knff') # The Keynote native file format HTML = OSType('Khtm') # HTML QUICKTIME_MOVIE = OSType('Kmov') # QuickTime movie PDF = OSType('Kpdf') # PDF SLIDE_IMAGES = OSType('Kimg') # image MICROSOFT_POWERPOINT = OSType('Kppt') # Microsoft PowerPoint KEYNOTE_09 = OSType('Kkey') # Keynote 09 JPEG = OSType('Kifj') # JPEG PNG = OSType('Kifp') # PNG TIFF = OSType('Kift') # TIFF f360p = OSType('Kmf3') # 360p f540p = OSType('Kmf5') # 540p f720p = OSType('Kmf7') # 720p f1080p = OSType('Kmf8') # 1080p f2160p = OSType('Kmf4') # DCI 4K (4096x2160) NativeSize = OSType('KmfN') # Exported movie will have the same dimensions as the document, up to 4096x2160
[docs] class Codec(Enum): """Options for which video codec to use. """ H264 = OSType('Kmc1') # H.264 APPLE_PRO_RES_422 = OSType('Kmc2') # Apple ProRes 422 APPLE_PRO_RES_4444 = OSType('Kmc3') # Apple ProRes 4444 APPLE_PRO_RES_422LT = OSType('Kmc4') # Apple ProRes 422LT APPLE_PRO_RES_422HQ = OSType('Kmc5') # Apple ProRes 422HQ APPLE_PRO_RES_422Proxy = OSType('Kmc6') # Apple ProRes 422Proxy HEVC = OSType('Kmc7') # HEVC
[docs] class Framerate(Enum): """Options for which framerate to use when exporting a Keynote project as a video. """ FPS_12 = OSType('Kfr1') # 12 FPS FPS_2398 = OSType('Kfr2') # 23.98 FPS FPS_24 = OSType('Kfr3') # 24 FPS FPS_25 = OSType('Kfr4') # 25 FPS FPS_2997 = OSType('Kfr5') # 29.97 FPS FPS_30 = OSType('Kfr6') # 30 FPS FPS_50 = OSType('Kfr7') # 50 FPS FPS_5994 = OSType('Kfr8') # 59.94 FPS FPS_60 = OSType('Kfr9') # 60 FPS
[docs] class PrintSetting(Enum): """Options to use when printing slides. """ STANDARD_ERROR_HANDLING = OSType('lwst') # Standard PostScript error handling DETAILED_ERROR_HANDLING = OSType('lwdt') # print a detailed report of PostScript errors INDIVIDUAL_SLIDES = OSType('Kpwi') # individual slides SLIDE_WITH_NOTES = OSType('Kpwn') # slides with notes HANDOUTS = OSType('Kpwh') # handouts
[docs] class Transition(Enum): """The available options for transitions to assign to slides. """ NONE = OSType('tnil') MAGIC_MOVE = OSType('tmjv') SHIMMER = OSType('tshm') SPARKLE = OSType('tspk') SWING = OSType('tswg') OBJECT_CUBE = OSType('tocb') OBJECT_FLIP = OSType('tofp') OBJECT_POP = OSType('topp') OBJECT_PUSH = OSType('toph') OBJECT_REVOLVE = OSType('torv') OBJECT_ZOOM = OSType('tozm') PERSPECTIVE = OSType('tprs') CLOTHESLINE = OSType('tclo') CONFETTI = OSType('tcft') DISSOLVE = OSType('tdis') DROP = OSType('tdrp') DROPLET = OSType('tdpl') FADE_THROUGH_COLOR = OSType('tftc') GRID = OSType('tgrd') IRIS = OSType('tirs') MOVE_IN = OSType('tmvi') PUSH = OSType('tpsh') REVEAL = OSType('trvl') SWITCH = OSType('tswi') WIPE = OSType('twpe') BLINDS = OSType('tbld') COLOR_PANES = OSType('tcpl') CUBE = OSType('tcub') DOORWAY = OSType('tdwy') FALL = OSType('tfal') FLIP = OSType('tfip') FLOP = OSType('tfop') MOSAIC = OSType('tmsc') PAGE_FLIP = OSType('tpfl') PIVOT = OSType('tpvt') REFLECTION = OSType('trfl') REVOLVING_DOOR = OSType('trev') SCALE = OSType('tscl') SWAP = OSType('tswp') SWOOSH = OSType('tsws') TWIRL = OSType('ttwl') TWIST = OSType('ttwi') FADE_AND_MOVE = OSType('tfad')
def __init__(self, properties): super().__init__(properties) self.xa_wcls = XAKeynoteWindow @property def properties(self) -> dict: """All properties of the Keynote application. """ raw_dict = self.xa_scel.properties() return { "slide_switcher_visible": raw_dict["slideSwitcherVisible"] == 1, "frontmost": self.frontmost, "playing": self.playing, "version": self.version, "name": self.name, } @property def playing(self) -> bool: """Whether a slideshow is currently playing. """ return self.xa_scel.playing() @property def slide_switcher_visible(self) -> bool: """Whether the slide switcher is visible. """ return self.xa_scel.slideSwitcherVisible()
[docs] def show_next(self) -> 'XAKeynoteApplication': """Advance one slide or animation build. """ self.xa_scel.showNext() return self
[docs] def show_previous(self) -> 'XAKeynoteApplication': """Go back one slide or animation build. """ self.xa_scel.showPrevious() return self
[docs] def documents(self, filter: Union[dict, None] = None) -> 'XAKeynoteDocumentList': """Returns a list of documents, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned documents will have, or None :type filter: Union[dict, None] :return: The list of documents :rtype: XAKeynoteDocumentList :Example 1: List the name of every open Keynote document >>> import PyXA >>> app = PyXA.Application("Keynote") >>> docs = app.documents() >>> for doc in docs: >>> print(doc.name) Example1.key Example2.key .. versionadded:: 0.0.2 """ return self._new_element(self.xa_scel.documents(), XAKeynoteDocumentList, filter)
[docs] def new_document(self, file_path: Union[str, XABase.XAPath] = "./Untitled.key", theme: 'XAKeynoteTheme' = None) -> 'XAKeynoteDocument': """Creates a new document at the specified path and with the specified theme. :param file_path: The path to create the document at, defaults to "./Untitled.key" :type file_path: str, optional :param template: The theme to initialize the document with, defaults to None :type template: XAKeynoteTheme, optional :return: The newly created document object :rtype: XAKeynoteDocument .. versionadded:: 0.0.8 """ if isinstance(file_path, str): file_path = XABase.XAPath(file_path) properties = { "file": file_path.xa_elem, } if theme is not None: properties["documentTheme"] = theme.xa_elem new_document = self.make("document", properties) self.documents().push(new_document) return self.documents()[0]
[docs] def themes(self, filter: Union[dict, None] = None) -> 'XAKeynoteThemeList': """Returns a list of themes, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned themes will have, or None :type filter: Union[dict, None] :return: The list of themes :rtype: XAKeynoteThemeList :Example 1: List the name of each theme >>> import PyXA >>> app = PyXA.Application("Keynote") >>> themes = app.themes() >>> print(themes.name()) ['Basic White', 'Basic Black', 'Classic White', 'White', 'Black', 'Basic Color', 'Color Gradient Light', 'Color Gradient', 'Gradient', 'Showroom', 'Modern Portfolio', 'Slate', 'Photo Essay', 'Bold Color', 'Showcase', 'Briefing', 'Academy', 'Modern Type', 'Exhibition', 'Feature Story', 'Look Book', 'Classic', 'Editorial', 'Cream Paper', 'Industrial', 'Blueprint', 'Graph Paper', 'Chalkboard', 'Photo Portfolio', 'Leather Book', 'Artisan', 'Improv', 'Drafting', 'Kyoto', 'Brushed Canvas', 'Craft', 'Parchment', 'Renaissance', 'Moroccan', 'Hard Cover', 'Linen Book', 'Vintage', 'Typeset', 'Harmony', 'Formal'] .. versionadded:: 0.0.2 """ return self._new_element(self.xa_scel.themes(), XAKeynoteThemeList, filter)
[docs] def make(self, specifier: Union[str, 'XAKeynoteApplication.ObjectType'], properties: dict = None, data: Any = None): """Creates a new element of the given specifier class without adding it to any list. Use :func:`XABase.XAList.push` to push the element onto a list. :param specifier: The classname of the object to create :type specifier: Union[str, XAKeynoteApplication.ObjectType] :param properties: The properties to give the object :type properties: dict :param data: The data to initialize the object with :type data: Any :return: A PyXA wrapped form of the object :rtype: XABase.XAObject .. versionadded:: 0.0.5 """ if isinstance(specifier, XAKeynoteApplication.ObjectType): specifier = specifier.value if data is None: camelized_properties = {} if properties is None: properties = {} for key, value in properties.items(): if key == "url": key = "URL" camelized_properties[XABase.camelize(key)] = value obj = ( self.xa_scel.classForScriptingClass_(specifier) .alloc() .initWithProperties_(camelized_properties) ) else: obj = ( self.xa_scel.classForScriptingClass_(specifier) .alloc() .initWithData_(data) ) if specifier == "document": return self._new_element(obj, XAKeynoteDocument) elif specifier == "shape": return self._new_element(obj, iWorkApplicationBase.XAiWorkShape) elif specifier == "table": return self._new_element(obj, iWorkApplicationBase.XAiWorkTable) elif specifier == "audio_clip": return self._new_element(obj, iWorkApplicationBase.XAiWorkAudioClip) elif specifier == "chart": return self._new_element(obj, iWorkApplicationBase.XAiWorkChart) elif specifier == "image": return self._new_element(obj, iWorkApplicationBase.XAiWorkImage) elif specifier == "slide": return self._new_element(obj, XAKeynoteSlide) elif specifier == "line": return self._new_element(obj, iWorkApplicationBase.XAiWorkLine) elif specifier == "movie": return self._new_element(obj, iWorkApplicationBase.XAiWorkMovie) elif specifier == "text_item": return self._new_element(obj, iWorkApplicationBase.XAiWorkTextItem) elif specifier == "group": return self._new_element(obj, iWorkApplicationBase.XAiWorkGroup) elif specifier == "iwork_item": return self._new_element(obj, iWorkApplicationBase.XAiWorkiWorkItem) elif specifier == "transition_settings": return self._new_element(obj, XAKeynoteTransitionSettings)
[docs] class XAKeynoteWindow(iWorkApplicationBase.XAiWorkWindow): """A class for managing and interacting with windows in Keynote.app. .. versionadded:: 0.0.1 """ def __init__(self, properties): super().__init__(properties) @property def document(self) -> 'XAKeynoteDocument': """The document currently displayed in the window. """ return self._new_element(self.xa_elem.document(), XAKeynoteDocument)
[docs] class XAKeynoteDocumentList(iWorkApplicationBase.XAiWorkDocumentList): """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.0.5 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, filter, XAKeynoteDocument)
[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(), "slide_numbers_showing": document.slideNumbersShowing(), "document_theme": self._new_element(document.documentTheme(), XAKeynoteTheme), "auto_loop": document.autoLoop(), "auto_play": document.autoPlay(), "auto_restart": document.autoRestart(), "maximum_idle_duration": document.maximumIdleDuration(), "current_slide": self._new_element(document.currentSlide(), XAKeynoteSlide), "height": document.height(), "width": document.width(), "selection": [self._new_element(x, iWorkApplicationBase.XAiWorkiWorkItem) for x in document.selection()], "password_protected": document.passwordProtected(), } return pyxa_dicts
[docs] def slide_numbers_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("slideNumbersShowing") or [])
[docs] def document_theme(self) -> 'XAKeynoteThemeList': ls = self.xa_elem.arrayByApplyingSelector_("documentTheme") or [] return self._new_element(ls, XAKeynoteThemeList)
[docs] def auto_loop(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("autoLoop") or [])
[docs] def auto_play(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("autoPlay") or [])
[docs] def auto_restart(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("autoRestart") or [])
[docs] def maximum_idle_duration(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("maximumIdleDuration") or [])
[docs] def current_slide(self) -> 'XAKeynoteSlideList': ls = self.xa_elem.arrayByApplyingSelector_("currentSlide") or [] return self._new_element(ls, XAKeynoteSlideList)
[docs] def height(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("height") or [])
[docs] def width(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("width") or [])
[docs] def by_properties(self, properties: dict) -> Union['XAKeynoteDocument', 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, XAKeynoteDocument)
[docs] def by_slide_numbers_showing(self, slide_numbers_showing: bool) -> Union['XAKeynoteDocument', None]: return self.by_property("slideNumbersShowing", slide_numbers_showing)
[docs] def by_document_theme(self, document_theme: 'XAKeynoteTheme') -> Union['XAKeynoteDocument', None]: return self.by_property("documentTheme", document_theme.xa_elem)
[docs] def by_auto_loop(self, auto_loop: bool) -> Union['XAKeynoteDocument', None]: return self.by_property("autoLoop", auto_loop)
[docs] def by_auto_play(self, auto_play: bool) -> Union['XAKeynoteDocument', None]: return self.by_property("autoPlay", auto_play)
[docs] def by_auto_restart(self, auto_restart: bool) -> Union['XAKeynoteDocument', None]: return self.by_property("autoRestart", auto_restart)
[docs] def by_maximum_idle_duration(self, maximum_idle_duration: int) -> Union['XAKeynoteDocument', None]: return self.by_property("maxmimumIdleDuration", maximum_idle_duration)
[docs] def by_current_slide(self, current_slide: 'XAKeynoteSlide') -> Union['XAKeynoteDocument', None]: return self.by_property("currentSlide", current_slide.xa_elem)
[docs] def by_height(self, height: int) -> Union['XAKeynoteDocument', None]: return self.by_property("height", height)
[docs] def by_width(self, width: int) -> Union['XAKeynoteDocument', None]: return self.by_property("width", width)
[docs] def by_selection(self, selection: 'iWorkApplicationBase.XAiWorkiWorkItemList') -> Union['XAKeynoteDocument', None]: return self.by_property("selection", selection.xa_elem)
[docs] def by_password_protected(self, password_protected: bool) -> Union['XAKeynoteDocument', None]: return self.by_property("passwordProtected", password_protected)
def __repr__(self): return f"<{str(type(self))}{self.name()}>"
[docs] class XAKeynoteDocument(iWorkApplicationBase.XAiWorkDocument): """A class for managing and interacting with TextEdit documents. .. seealso:: :class:`XAKeynoteApplication` .. versionadded:: 0.0.2 """ 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(), "slide_numbers_showing": self.xa_elem.slideNumbersShowing(), "document_theme": self._new_element(self.xa_elem.documentTheme(), XAKeynoteTheme), "auto_loop": self.xa_elem.autoLoop(), "auto_play": self.xa_elem.autoPlay(), "auto_restart": self.xa_elem.autoRestart(), "maximum_idle_duration": self.xa_elem.maximumIdleDuration(), "current_slide": self._new_element(self.xa_elem.currentSlide(), XAKeynoteSlide), "height": self.xa_elem.height(), "width": self.xa_elem.width(), "selection": self._new_element(self.xa_elem.selection(), iWorkApplicationBase.XAiWorkiWorkItemList), "password_protected": self.xa_elem.passwordProtected(), } 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) -> str: """The location of the document on the disk, if one exists. """ return self.xa_elem.file() @property def id(self) -> str: """The unique identifier for the document. """ return self.xa_elem.id() @property def slide_numbers_showing(self) -> bool: """Whether slide numbers are displayed. """ return self.xa_elem.slideNumbersShowing() @slide_numbers_showing.setter def slide_numbers_showing(self, slide_numbers_showing: bool): self.set_property('slideNumbersShowing', slide_numbers_showing) @property def document_theme(self) -> 'XAKeynoteTheme': """The theme assigned to the document. """ return self._new_element(self.xa_elem.documentTheme(), XAKeynoteTheme) @document_theme.setter def document_theme(self, document_theme: 'XAKeynoteTheme'): self.set_property('documentTheme', document_theme.xa_elem) @property def auto_loop(self) -> bool: """Whether the slideshow should play repeatedly. """ return self.xa_elem.autoLoop() @auto_loop.setter def auto_loop(self, auto_loop: bool): self.set_property('autoLoop', auto_loop) @property def auto_play(self) -> bool: """Whether the slideshow should automatically play when opening the file. """ return self.xa_elem.autoPlay() @auto_play.setter def auto_play(self, auto_play: bool): self.set_property('autoPlay', auto_play) @property def auto_restart(self) -> bool: """Whether the slideshow should restart if its inactive for the maximum idle duration. """ return self.xa_elem.autoRestart() @auto_restart.setter def auto_restart(self, auto_restart: bool): self.set_property('autoRestart', auto_restart) @property def maximum_idle_duration(self) -> int: """The duration before which the slideshow restarts due to inactivity. """ return self.xa_elem.maximumIdleDuration() @maximum_idle_duration.setter def maximum_idle_duration(self, maximum_idle_duration: int): self.set_property('maximumIdleDuration', maximum_idle_duration) @property def current_slide(self) -> 'XAKeynoteSlide': """The currently selected slide, or the slide that would display is the presentation was started. """ return self._new_element(self.xa_elem.currentSlide(), XAKeynoteSlide) @current_slide.setter def current_slide(self, current_slide: 'XAKeynoteSlide'): self.set_property('currentSlide', current_slide.xa_elem) @property def height(self) -> int: """The height of the document in points; standard is 768; wide slide height is 1080. """ return self.xa_elem.height() @height.setter def height(self, height: int): self.set_property('height', height) @property def width(self) -> int: """The width of the document in points; standard is 1080; wide slide width is 1920. """ return self.xa_elem.width() @width.setter def width(self, width: int): self.set_property('width', width) @property def selection(self) -> 'iWorkApplicationBase.XAiWorkiWorkItemList': """A list of the currently selected items. """ return self._new_element(self.xa_elem.selection(), iWorkApplicationBase.XAiWorkiWorkItemList) @selection.setter def selection(self, selection: Union['iWorkApplicationBase.XAiWorkiWorkItemList', list['iWorkApplicationBase.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()
[docs] def start_from(self, slide: 'XAKeynoteSlide') -> 'XAKeynoteSlide': """Starts the slideshow from the specified slide. .. versionadded:: 0.0.3 """ self.xa_elem.startFrom_(slide.xa_elem) return self
[docs] def stop(self): """Stops the currently playing slideshow. .. versionadded:: 0.0.3 """ self.xa_elem.stop()
[docs] def show_slide_switcher(self): """Shows the slide switch within the active slideshow interface. .. versionadded:: 0.0.3 """ self.xa_elem.showSlideSwitcher()
[docs] def hide_slide_switcher(self): """Hides the slide switcher. .. versionadded:: 0.0.3 """ self.xa_elem.hideSlideSwitcher()
[docs] def move_slide_switcher_forward(self): """Advances the slide switcher one slide forward. .. versionadded:: 0.0.3 """ self.xa_elem.moveSlideSwitcherForward()
[docs] def move_slide_switcher_backward(self): """Goes back one slide in the slide switcher. .. versionadded:: 0.0.3 """ self.xa_elem.moveSlideSwitcherBackward()
[docs] def cancel_slide_switcher(self): """Dismisses the slide switcher. .. versionadded:: 0.0.3 """ self.xa_elem.cancelSlideSwitcher()
[docs] def accept_slide_switcher(self): """Advances the slideshow to the selected slide of the slide switcher. .. versionadded:: 0.0.3 """ self.xa_elem.acceptSlideSwitcher()
[docs] def save(self): """Saves the Keynote file. .. versionadded:: 0.0.3 """ export_format = XAKeynoteApplication.ExportFormat.KEYNOTE.value self.xa_elem.saveIn_as_(self.file, export_format)
[docs] def export(self, file_path: Union[str, XABase.XAPath] = None, format: XAKeynoteApplication.ExportFormat = XAKeynoteApplication.ExportFormat.PDF): """Exports the slideshow in the specified format. :param file_path: The path to save the exported file at, defaults to None :type file_path: Union[str, XABase.XAPath], optional :param format: The format to export the file in, defaults to XAKeynoteApplication.ExportFormat.PDF :type format: XAKeynoteApplication.ExportFormat, optional .. versionadded:: 0.0.3 """ if file_path is None: file_path = self.file.path()[:-4] + ".pdf" if isinstance(file_path, str): file_path = XABase.XAPath(file_path) self.xa_elem.exportTo_as_withProperties_(file_path.xa_elem, format.value, None)
[docs] def make_image_slides(self, files: list[Union[str, XABase.XAPath]], set_titles: bool = False, slide_layout: 'XAKeynoteSlideLayout' = None) -> 'XAKeynoteDocument': """Creates slides out of image files. Creates a new slide for each image file path in the files list, if the image can be found. :param files: A list of paths to image files :type files: list[Union[str, XABase.XAPath]] :param set_titles: Whether to set the slide titles to the image file name, defaults to False :type set_titles: bool, optional :param slide_layout: The base slide layout to use for the new slides, defaults to None :type slide_layout: XAKeynoteSlideLayout, optional :return: A reference back to this PyXA object. :rtype: XAKeynoteDocument .. versionadded:: 0.0.3 """ urls = [] for file in files: if isinstance(file, str): file = XABase.XAPath(file) urls.append(file.xa_elem) self.xa_elem.makeImageSlidesFiles_setTitles_slideLayout_(urls, set_titles, slide_layout) return self
[docs] def slides(self, filter: Union[dict, None] = None) -> 'XAKeynoteSlideList': """Returns a list of slides, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned slides will have, or None :type filter: Union[dict, None] :return: The list of slides :rtype: XAKeynoteSlideList :Example 1: List all slides >>> import PyXA >>> app = PyXA.Application("Keynotes") >>> print(app.slides()) :Example 2: List slides after applying a filter >>> import PyXA >>> app = PyXA.Application("Keynotes") >>> print(app.slides().greater_than("slideNumber", 5)) .. versionadded:: 0.0.2 """ return self._new_element(self.xa_elem.slides(), XAKeynoteSlideList, filter)
[docs] def new_slide(self, properties: dict) -> 'XAKeynoteSlide': """Creates a new slide at the end of the presentation. :param properties: The properties to give the new slide :type properties: dict :return: A reference to the newly created slide :rtype: XAKeynoteSlide .. versionadded:: 0.0.2 """ return self.xa_prnt.xa_prnt.new_slide(self, properties)
[docs] def slide_layouts(self, filter: Union[dict, None] = None) -> 'XAKeynoteSlideLayoutList': """Returns a list of slide layouts, as PyXA objects, matching the given filter. :param filter: A dictionary specifying property-value pairs that all returned slide layouts will have, or None :type filter: Union[dict, None] :return: The list of slide layouts :rtype: XAKeynoteSlideLayoutList :Example: List all slide layouts >>> import PyXA >>> app = PyXA.Application("Keynotes") >>> print(app.slide_layouts()) .. versionadded:: 0.0.2 """ return self._new_element(self.xa_elem.slideLayouts(), XAKeynoteSlideLayoutList, filter)
def __repr__(self): return f"<{str(type(self))}{self.name}>"
[docs] class XAKeynoteThemeList(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.0.5 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, XAKeynoteTheme, filter)
[docs] def properties(self) -> list[str]: # TODO pyxa_dicts = [None] * len(self.xa_elem) for index, theme in enumerate(self.xa_elem): pyxa_dicts[index] = { "id": theme.id(), "name": theme.name() } return pyxa_dicts
[docs] def id(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("id") or [])
[docs] def name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("name") or [])
[docs] def by_properties(self, properties: dict) -> Union['XAKeynoteTheme', None]: for theme in self.xa_elem: if all(properties[x] == theme.properties()[x] for x in properties): return self._new_element(theme, XAKeynoteTheme)
[docs] def by_id(self, id: str) -> Union['XAKeynoteTheme', None]: return self.by_property("id", id)
[docs] def by_name(self, name: str) -> Union['XAKeynoteTheme', None]: return self.by_property("name", name)
def __repr__(self): return f"<{str(type(self))}{self.name()}>"
[docs] class XAKeynoteTheme(XABase.XAObject): """A class for managing and interacting with Keynote themes. .. seealso:: :class:`XAKeynoteApplication` .. versionadded:: 0.0.2 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the theme. """ return { "id": self.xa_elem.id(), "name": self.xa_elem.name() } @property def id(self) -> str: """The unique identifier for the theme. """ return self.xa_elem.id() @property def name(self) -> str: """The name of the theme. """ return self.xa_elem.name() def __repr__(self): return f"<{str(type(self))}{self.name}, id={str(self.id)}>"
[docs] class XAKeynoteContainerList(iWorkApplicationBase.XAiWorkContainerList): """A wrapper around lists of containers that employs fast enumeration techniques. .. versionadded:: 0.0.5 """ def __init__(self, properties: dict, filter: Union[dict, None] = None, obj_class = None): if obj_class is None: obj_class = XAKeynoteContainer self._xa_ccls = XAKeynoteSlideList super().__init__(properties, filter, obj_class)
[docs] class XAKeynoteContainer(iWorkApplicationBase.XAiWorkContainer): """A class for managing and interacting with containers in Keynote. .. versionadded:: 0.0.2 """ def __init__(self, properties): self._xa_ccls = XAKeynoteSlideList super().__init__(properties)
[docs] class XAKeynoteSlideList(XAKeynoteContainerList): """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.0.5 """ def __init__(self, properties: dict, filter: Union[dict, None] = None, obj_class = None): if obj_class is None: obj_class = XAKeynoteSlide super().__init__(properties, filter, obj_class)
[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] = { "default_title_item": self._new_element(raw_dict["defaultTitleItem"], iWorkApplicationBase.XAiWorkShape), "slide_number": raw_dict["slideNumber"], "default_body_item": self._new_element(raw_dict["defaultBodyItem"], iWorkApplicationBase.XAiWorkShape), "skipped": raw_dict["skipped"] == 1, "body_showing": raw_dict["bodyShowing"] == 1, "presenter_notes": self._new_element(raw_dict["presenterNotes"], XABase.XAText), "title_showing": raw_dict["titleShowing"] == 1, "transition_properties": XAKeynoteTransitionSettings({ "automatic_transition": raw_dict["transitionProperties"]["automaticTransition"] == 1, "transition_delay": raw_dict["transitionProperties"]["transitionDelay"], "transtion_duration": raw_dict["transitionProperties"]["transitionDuration"], "transition_effect": XAKeynoteApplication.Transition(XABase.OSType(raw_dict["transitionProperties"]["transitionEffect"].stringValue())) }, self._new_element(self.xa_elem[index], XAKeynoteSlide)), "base_layout": self._new_element(raw_dict["baseLayout"], XAKeynoteSlideLayout) } return pyxa_dicts
[docs] def body_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("bodyShowing") or [])
[docs] def skipped(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("skipped") or [])
[docs] def slide_number(self) -> list[int]: return list(self.xa_elem.arrayByApplyingSelector_("slideNumber") or [])
[docs] def title_showing(self) -> list[bool]: return list(self.xa_elem.arrayByApplyingSelector_("titleShowing") or [])
[docs] def transition_properties(self) -> list[dict]: raw_dicts = self.xa_elem.arrayByApplyingSelector_("transitionProperties") or [] pyxa_dicts = [None] * len(self.xa_elem) for index, raw_dict in enumerate(raw_dicts): pyxa_dicts[index] = XAKeynoteTransitionSettings({ "automatic_transition": raw_dict["automaticTransition"] == 1, "transition_delay": raw_dict["transitionDelay"], "transtion_duration": raw_dict["transitionDuration"], "transition_effect": XAKeynoteApplication.Transition(XABase.OSType(raw_dict["transitionEffect"].stringValue())) }, self._new_element(self.xa_elem[index], XAKeynoteSlide)) return pyxa_dicts
[docs] def base_layout(self) -> 'XAKeynoteSlideLayoutList': ls = self.xa_elem.arrayByApplyingSelector_("baseLayout") or [] return self._new_element(ls, XAKeynoteSlideLayoutList)
[docs] def default_body_item(self) -> 'iWorkApplicationBase.XAiWorkShapeList': ls = self.xa_elem.arrayByApplyingSelector_("defaultBodyItem") or [] return self._new_element(ls, iWorkApplicationBase.XAiWorkShapeList)
[docs] def default_title_item(self) -> 'iWorkApplicationBase.XAiWorkShapeList': ls = self.xa_elem.arrayByApplyingSelector_("defaultTitleItem") or [] return self._new_element(ls, iWorkApplicationBase.XAiWorkShapeList)
[docs] def presenter_notes(self) -> XABase.XATextList: ls = self.xa_elem.arrayByApplyingSelector_("presenterNotes") or [] return self._new_element(ls, XABase.XATextList)
[docs] def by_properties(self, properties: dict) -> 'XAKeynoteSlide': raw_dict = {} if "default_title_item" in properties: raw_dict["defaultTitleItem"] = properties["default_title_item"].xa_elem if "slide_number" in properties: raw_dict["slideNumber"] = properties["slide_number"] if "default_body_item" in properties: raw_dict["defaultBodyItem"] = properties["default_body_item"].xa_elem if "skipped" in properties: raw_dict["skipped"] = properties["skipped"] if "body_showing" in properties: raw_dict["bodyShowing"] = properties["body_showing"] if "presenter_notes" in properties: if isinstance(properties["presenter_notes"], str): raw_dict["presenterNotes"] = properties["presenter_notes"] else: raw_dict["presenterNotes"] = properties["presenter_notes"].xa_elem if "title_showing" in properties: raw_dict["titleShowing"] = properties["title_showing"] if "transition_properties" in properties: raw_dict["transitionProperties"] = {} if isinstance(properties["transition_properties"], XAKeynoteTransitionSettings): properties["transition_properties"] = properties["transition_properties"]._pyxa_dict if "automatic_transition" in properties["transition_properties"]: raw_dict["transitionProperties"]["automaticTransition"] = properties["transition_properties"]["automatic_transition"] if "transition_delay" in properties["transition_properties"]: raw_dict["transitionProperties"]["transitionDelay"] = properties["transition_properties"]["transition_delay"] if "transtion_duration" in properties["transition_properties"]: raw_dict["transitionProperties"]["transitionDuration"] = properties["transition_properties"]["transtion_duration"] if "transition_effect" in properties["transition_properties"]: raw_dict["transitionProperties"]["transitionEffect"] = XAEvents.event_from_type_code(properties["transition_properties"]["transition_effect"].value) if "base_layout" in properties: raw_dict["baseLayout"] = properties["base_layout"].xa_elem for slide in self.xa_elem: if all(raw_dict[x] == slide.properties()[x] for x in raw_dict): return self._new_element(slide, XAKeynoteSlide)
[docs] def by_body_showing(self, body_showing: bool) -> 'XAKeynoteSlide': return self.by_property("bodyShowing", body_showing)
[docs] def by_skipped(self, skipped: bool) -> 'XAKeynoteSlide': return self.by_property("skipped", skipped)
[docs] def by_slide_number(self, slide_number: int) -> 'XAKeynoteSlide': return self.by_property("slideNumber", slide_number)
[docs] def by_title_showing(self, title_showing: bool) -> 'XAKeynoteSlide': return self.by_property("titleShowing", title_showing)
[docs] def by_transition_properties(self, transition_properties: Union['XAKeynoteTransitionSettings', dict]) -> 'XAKeynoteSlide': properties = {} if isinstance(transition_properties, XAKeynoteTransitionSettings): transition_properties = transition_properties._pyxa_dict if "automatic_transition" in transition_properties: properties["automaticTransition"] = transition_properties["automatic_transition"] if "transition_delay" in transition_properties: properties["transitionDelay"] = transition_properties["transition_delay"] if "transtion_duration" in transition_properties: properties["transitionDuration"] = transition_properties["transtion_duration"] if "transition_effect" in transition_properties: properties["transitionEffect"] = XAEvents.event_from_type_code(transition_properties["transition_effect"].value) return self.by_property("transitionProperties", properties)
[docs] def by_base_layout(self, base_layout: 'XAKeynoteSlideLayout') -> 'XAKeynoteSlide': return self.by_property("baseLayout", base_layout.xa_elem)
[docs] def by_default_body_item(self, default_body_item: 'iWorkApplicationBase.XAiWorkShape') -> 'XAKeynoteSlide': return self.by_property("defaultBodyItem", default_body_item.xa_elem)
[docs] def by_default_text_item(self, default_text_item: 'iWorkApplicationBase.XAiWorkShape') -> 'XAKeynoteSlide': return self.by_property("defaultTextItem", default_text_item.xa_elem)
[docs] def by_presenter_notes(self, presenter_notes: Union[str, XABase.XAText]) -> 'XAKeynoteSlide': if isinstance(presenter_notes, str): self.by_property('presenterNotes', presenter_notes) else: self.by_property('presenterNotes', presenter_notes.xa_elem)
def __repr__(self): return "<" + str(type(self)) + "length: " + str(len(self.xa_elem)) + ">"
[docs] class XAKeynoteSlide(XAKeynoteContainer): """A class for managing and interacting with Keynote slides. .. seealso:: :class:`XAKeynoteApplication`, :class:`iWorkApplicationBase.XAiWorkiWorkItem` .. versionadded:: 0.0.2 """ def __init__(self, properties): super().__init__(properties) @property def properties(self) -> dict: """All properties of the slide. """ raw_dict = self.xa_elem.properties() pyxa_dict = { "default_title_item": self._new_element(raw_dict["defaultTitleItem"], iWorkApplicationBase.XAiWorkShape), "slide_number": raw_dict["slideNumber"], "default_body_item": self._new_element(raw_dict["defaultBodyItem"], iWorkApplicationBase.XAiWorkShape), "skipped": raw_dict["skipped"] == 1, "body_showing": raw_dict["bodyShowing"] == 1, "presenter_notes": self._new_element(raw_dict["presenterNotes"], XABase.XAText), "title_showing": raw_dict["titleShowing"] == 1, "transition_properties": XAKeynoteTransitionSettings({ "automatic_transition": raw_dict["transitionProperties"]["automaticTransition"] == 1, "transition_delay": raw_dict["transitionProperties"]["transitionDelay"], "transition_duration": raw_dict["transitionProperties"]["transitionDuration"], "transition_effect": XAKeynoteApplication.Transition(XABase.OSType(raw_dict["transitionProperties"]["transitionEffect"].stringValue())) }, self), "base_layout": self._new_element(raw_dict["baseLayout"], XAKeynoteSlideLayout) } return pyxa_dict @property def body_showing(self) -> bool: """Whether the default body text is displayed. """ return self.xa_elem.bodyShowing() @body_showing.setter def body_showing(self, body_showing: bool): self.set_property('bodyShowing', body_showing) @property def skipped(self) -> bool: """Whether the slide is skipped. """ return self.xa_elem.skipped() @skipped.setter def skipped(self, skipped: bool): self.set_property('skipped', skipped) @property def slide_number(self) -> int: """The index of the slide in the document. """ return self.xa_elem.slideNumber() @property def title_showing(self) -> bool: """Whether the default slide title is displayed. """ return self.xa_elem.titleShowing() @title_showing.setter def title_showing(self, title_showing: bool): self.set_property('titleShowing', title_showing) @property def transition_properties(self) -> dict: """The transition settings applied to the slide. """ raw_dict = self.xa_elem.transitionProperties() pyxa_dict = { "automatic_transition": raw_dict["automaticTransition"] == 1, "transition_delay": raw_dict["transitionDelay"], "transition_duration": raw_dict["transitionDuration"], "transition_effect": XAKeynoteApplication.Transition(XABase.OSType(raw_dict["transitionEffect"].stringValue())) } return XAKeynoteTransitionSettings(pyxa_dict, self) @transition_properties.setter def transition_properties(self, transition_properties: Union['XAKeynoteTransitionSettings', dict]): properties = {} if isinstance(transition_properties, XAKeynoteTransitionSettings): transition_properties = transition_properties._pyxa_dict if "automatic_transition" in transition_properties: properties["automaticTransition"] = transition_properties["automatic_transition"] if "transition_delay" in transition_properties: properties["transitionDelay"] = transition_properties["transition_delay"] if "transtion_duration" in transition_properties: properties["transitionDuration"] = transition_properties["transtion_duration"] if "transition_effect" in transition_properties: properties["transitionEffect"] = XAEvents.event_from_type_code(transition_properties["transition_effect"].value) self.set_property('transitionProperties', properties) @property def base_layout(self) -> 'XAKeynoteSlideLayout': """The slide layout this slide is based on. """ return self._new_element(self.xa_elem.baseLayout(), XAKeynoteSlideLayout) @base_layout.setter def base_layout(self, base_layout: 'XAKeynoteSlideLayout'): self.set_property('baseLayout', base_layout.xa_elem) @property def default_body_item(self) -> 'iWorkApplicationBase.XAiWorkShape': """The default body container of the slide. """ return self._new_element(self.xa_elem.defaultBodyItem(), iWorkApplicationBase.XAiWorkShape) @property def default_title_item(self) -> 'iWorkApplicationBase.XAiWorkShape': """The default title container of the slide. """ return self._new_element(self.xa_elem.defaultTitleItem(), iWorkApplicationBase.XAiWorkShape) @property def presenter_notes(self) -> XABase.XAText: """The presenter notes for the slide. """ return self._new_element(self.xa_elem.presenterNotes(), XABase.XAText) @presenter_notes.setter def presenter_notes(self, presenter_notes: Union[XABase.XAText, str]): if isinstance(presenter_notes, str): self.set_property('presenterNotes', presenter_notes) else: self.set_property('presenterNotes', presenter_notes.xa_elem)
[docs] def move(self, location: Union[XAKeynoteDocument, XAKeynoteSlideList], position: int = -1) -> 'XAKeynoteSlide': """Moves the slide to the specified location, at the specified position. :param location: The document or list of slides to move this slide to :type location: Union[XAKeynoteDocument, XAKeynoteSlideList] :param position: The index to insert the slide within a list, defaults to -1 :type position: int, optional :return: A reference to the slide object :rtype: XAKeynoteSlide :Example: >>> import PyXA >>> app = PyXA.Keynote() >>> doc = app.documents()[0] >>> doc2 = app.documents()[1] >>> doc.slides()[0].move(doc2) <<class 'PyXA.apps.Keynote.XAKeynoteSlide'>slide number: 5> .. versionadded:: 0.2.2 """ if isinstance(location, XAKeynoteSlideList): if position == -1: self.xa_elem.moveTo_(location.xa_elem.lastObject().positionAfter()) return location[-1] else: self.xa_elem.moveTo_(location.xa_elem[position].positionBefore()) return location[position] elif isinstance(location, XAKeynoteDocument): if position == -1: self.xa_elem.moveTo_(location.slides().xa_elem.lastObject().positionAfter()) return location.slides()[-1] else: self.xa_elem.moveTo_(location.slides().xa_elem[position].positionBefore()) return location.slides()[position]
[docs] def duplicate(self, location: Union[XAKeynoteDocument, XAKeynoteSlideList, None] = None, position: int = -1) -> 'XAKeynoteSlide': """Duplicates the slide, mimicking the action of copying and pasting the slide manually. :param location: The document or list of slides to duplicate this slide to, or None to duplicate into the current document, defaults to None :type location: Union[XAKeynoteDocument, XAKeynoteSlideList, None], optional :param position: The index to insert the slide within a list, defaults to -1 :type position: int, optional :return: A reference to newly created (duplicate) slide object. :rtype: XAKeynoteSlide :Example: Duplicate Slide From One Document To Another >>> import PyXA >>> app = PyXA.Keynote() >>> doc1 = app.documents()[0] >>> doc2 = app.documents()[1] >>> doc1.slides()[0].duplicate(doc2) <<class 'PyXA.apps.Keynote.XAKeynoteSlide'>slide number: 5> .. versionadded:: 0.2.2 """ if location is None: location = self.xa_prnt source = self.xa_prnt if isinstance(source, XAKeynoteSlideList): self.xa_elem.duplicateTo_withProperties_(source.xa_elem.lastObject().positionAfter(), None) return source[-1].move(location, position) elif isinstance(source, XAKeynoteDocument): self.xa_elem.duplicateTo_withProperties_(source.slides().xa_elem.lastObject().positionAfter(), None) return source.slides()[-1].move(location, position)
[docs] def delete(self): """Deletes the slide. .. versionadded:: 0.0.2 """ self.xa_elem.delete()
[docs] def add_image(self, file_path: Union[str, XABase.XAPath, XABase.XAURL]) -> 'iWorkApplicationBase.XAiWorkImage': """Adds the image at the specified path to the slide. :param file_path: The path to the image file. :type file_path: Union[str, XABase.XAPath, XABase.XAURL] :return: The newly created image object. :rtype: iWorkApplicationBase.XAiWorkImage .. versionadded:: 0.0.2 """ url = file_path if isinstance(url, str): if "://" in url: url = XABase.XAURL(url) else: url = XABase.XAPath(url) image = None parent = self.xa_prnt.xa_prnt max_backtracks = 6 # this -> slidelist -> document -> document list -> window -> window list -> application num_backtracks = 0 while not hasattr(parent, "make") and num_backtracks < max_backtracks: parent = parent.xa_prnt num_backtracks += 1 image = parent.make("image", { "file": url.xa_elem }) return self.images().push(image)
[docs] def add_chart(self, row_names: list[str], column_names: list[str], data: list[list[Any]], type: int = XAKeynoteApplication.ChartType.LINE_2D.value, group_by: int = XAKeynoteApplication.ChartGrouping.ROW.value) -> 'iWorkApplicationBase.XAiWorkChart': """_summary_ _extended_summary_ :param row_names: A list of row names. :type row_names: list[str] :param column_names: A list of column names. :type column_names: list[str] :param data: A 2d array :type data: list[list[Any]] :param type: The chart type, defaults to _KeynoteLegacyChartType.KeynoteLegacyChartTypeLine_2d.value :type type: int, optional :param group_by: The grouping schema, defaults to _KeynoteLegacyChartGrouping.KeynoteLegacyChartGroupingChartRow.value :type group_by: int, optional :return: A reference to the newly created chart object. :rtype: iWorkApplicationBase.XAiWorkChart .. versionadded:: 0.0.2 """ parent = self.xa_prnt max_backtracks = 2 # this -> slidelist -> document num_backtracks = 0 while not isinstance(parent, XAKeynoteDocument) and num_backtracks < max_backtracks: parent = parent.xa_prnt num_backtracks += 1 self.xa_prnt.set_property("currentSlide", self.xa_elem) self.xa_elem.addChartRowNames_columnNames_data_type_groupBy_(row_names, column_names, data, type, group_by) chart = self.xa_elem.charts()[-1].get() return self._new_element(chart, iWorkApplicationBase.XAiWorkChart)
def __repr__(self): return "<" + str(type(self)) + "slide number: " + str(self.slide_number) + ">"
[docs] class XAKeynoteSlideLayoutList(XAKeynoteSlideList): """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.0.5 """ def __init__(self, properties: dict, filter: Union[dict, None] = None): super().__init__(properties, XAKeynoteSlideLayout, filter)
[docs] def name(self) -> list[str]: return list(self.xa_elem.arrayByApplyingSelector_("name") or [])
[docs] def by_name(self, name: str) -> 'XAKeynoteSlideLayout': return self.by_property("name", name)
def __repr__(self): return "<" + str(type(self)) + str(self.name()) + ">"
[docs] class XAKeynoteSlideLayout(XAKeynoteSlide): """A class for managing and interacting with Keynote slide layouts. .. seealso:: :class:`XAKeynoteSlide` .. versionadded:: 0.0.2 """ def __init__(self, properties): super().__init__(properties) @property def name(self) -> str: """The name of the slide layout. """ return self.xa_elem.name() def __repr__(self): return "<" + str(type(self)) + str(self.name) + ">"
[docs] class XAKeynoteTransitionSettings(XABase.XAObject): """Properties common to all transtions. .. versionadded:: 0.1.0 """ def __init__(self, properties: dict, parent: XABase.XAObject = None): self.__automatic_transition: bool = properties["automatic_transition"] self.__transition_delay: float = properties["transition_delay"] self.__transition_duration: float = properties["transition_duration"] self.__transition_effect: XAKeynoteApplication.Transition = properties["transition_effect"] self.__parent = parent @property def _pyxa_dict(self): return { "automatic_transition": self.__automatic_transition, "transition_telay": self.__transition_delay, "transition_duration": self.__transition_duration, "transition_effect": self.__transition_effect } @property def automatic_transition(self) -> bool: return self.__automatic_transition @automatic_transition.setter def automatic_transition(self, automatic_transition: bool): self.__automatic_transition = automatic_transition if self.__parent is not None: self.__parent.transition_properties = self._pyxa_dict @property def transition_delay(self) -> float: return self.__transition_delay @transition_delay.setter def automatic_transition(self, transition_delay: float): self.__transition_delay = transition_delay if self.__parent is not None: self.__parent.transition_properties = self._pyxa_dict @property def transition_duration(self) -> float: return self.__transition_duration @transition_duration.setter def automatic_transition(self, transition_duration: float): self.__transition_duration = transition_duration if self.__parent is not None: self.__parent.transition_properties = self._pyxa_dict @property def transition_effect(self) -> XAKeynoteApplication.Transition: return self.__transition_effect @transition_effect.setter def transition_effect(self, transition_effect: XAKeynoteApplication.Transition): self.__transition_effect = transition_effect if self.__parent is not None: self.__parent.transition_properties = self._pyxa_dict def __repr__(self): return "<" + str(type(self)) + str(self._pyxa_dict) + ">"