OutlineEdit

A PyObjC Example without documentation

Sources

MyDocument.py

import Cocoa
import CoreData
import objc
from objc import super  # noqa: A004

prioritySortDescriptions = Cocoa.NSArray.arrayWithObject_(
    Cocoa.NSSortDescriptor.alloc().initWithKey_ascending_("value", True)
)


class MyDocument(CoreData.NSPersistentDocument):
    outlineTreeController = objc.IBOutlet()

    def initWithType_error_(self, tp, error):
        self, error = super().initWithType_error_(tp, error)
        if self is None:
            return (None, error)

        managedObjectContext = self.managedObjectContext()

        for aPriorityValue in range(5):
            aPriority = CoreData.NSEntityDescription.insertNewObjectForEntityForName_inManagedObjectContext_(  # noqa:  B950
                "Priority", managedObjectContext
            )
            aPriority.setValue_forKey_(aPriorityValue + 1, "value")

        CoreData.NSEntityDescription.insertNewObjectForEntityForName_inManagedObjectContext_(
            "Note", managedObjectContext
        )

        managedObjectContext.processPendingChanges()
        managedObjectContext.undoManager().removeAllActions()
        self.updateChangeCount_(Cocoa.NSChangeCleared)

        return (self, None)

    def windowNibName(self):
        return "MyDocument"

    def prioritySortDescriptions(self):
        return prioritySortDescriptions

    def createNote_(self, sender):
        self.outlineTreeController.add_(sender)

    def createChildNote_(self, sender):
        self.outlineTreeController.addChild_(sender)

    def indentNote_(self, sender):
        selectionPath = self.outlineTreeController.selectionIndexPath()
        if not selectionPath:
            Cocoa.NSBeep()
            return

        selection = self.outlineTreeController.selection()

        parentNote = selection.valueForKeyPath_("parent")
        if parentNote is None:
            children = self.outlineTreeController.content()
        else:
            children = parentNote.valueForKeyPath_("children").allObjects()

        children = children.sortedArrayUsingDescriptors_(
            self.outlineTreeController.sortDescriptors()
        )

        index = selectionPath.indexAtPosition_(selectionPath.length() - 1)
        if index == 0:
            Cocoa.NSBeep()
        else:
            sibling = children.objectAtIndex_(index - 1)
            selection.setValue_forKeyPath_(sibling, "parent")

    def dedentNote_(self, sender):
        selection = self.outlineTreeController.selection()
        parent = selection.valueForKeyPath_("parent")

        if parent in (
            None,
            Cocoa.NSMultipleValuesMarker,
            Cocoa.NSNoSelectionMarker,
            Cocoa.NSNotApplicableMarker,
        ):
            Cocoa.NSBeep()
            return

        parent = parent.valueForKeyPath_("parent")
        selection.setValue_forKeyPath_(parent, "parent")

Note.py

import CoreData

noteCount = 1


class Note(CoreData.NSManagedObject):
    def awakeFromInsert(self):
        global noteCount

        contents = "Note #%d" % (noteCount,)
        noteCount += 1
        self.setValue_forKey_(contents, "contents")

main.py

import MyDocument  # noqa: F401
import Note  # noqa: F401
from PyObjCTools import AppHelper

if __name__ == "__main__":
    AppHelper.runEventLoop()

setup.py

"""
Script for building the example.

Usage:
    python3 setup.py py2app
"""

from setuptools import setup

plist = {
    "NSMainNibFile": "MainMenu",
    "CFBundleDocumentTypes": [
        {
            "CFBundleTypeExtensions": ["binary"],
            "CFBundleTypeMIMETypes": ["application/octect-stream"],
            "CFBundleTypeName": "Binary",
            "CFBundleTypeRole": "Editor",
            "LSTypeIsPackage": False,
            "NSDocumentClass": "MyDocument",
            "NSPersistentStoreTypeKey": "Binary",
        },
        {
            "CFBundleTypeExtensions": ["sql"],
            "CFBundleTypeMIMETypes": ["application/octect-stream"],
            "CFBundleTypeName": "SQL",
            "CFBundleTypeRole": "Editor",
            "LSTypeIsPackage": False,
            "NSDocumentClass": "MyDocument",
            "NSPersistentStoreTypeKey": "SQLite",
        },
        {
            "CFBundleTypeExtensions": ["xml"],
            "CFBundleTypeMIMETypes": ["text/xml"],
            "CFBundleTypeName": "XML",
            "CFBundleOSTypes": ["????"],
            "CFBundleTypeRole": "Editor",
            "LSTypeIsPackage": False,
            "NSDocumentClass": "MyDocument",
            "NSPersistentStoreTypeKey": "XML",
        },
    ],
}

setup(
    name="PyOutlineEdit",
    app=["main.py"],
    data_files=["English.lproj"],
    options={"py2app": {"plist": plist, "datamodels": ["MyDocument"]}},
    setup_requires=["py2app", "pyobjc-framework-Cocoa", "pyobjc-framework-CoreData"],
)