FilteringController

A PyObjC Example without documentation

Sources

FilteringArrayController.py

#
#  FilteringArrayController.py
#  FilteringController
#
#  Converted by u.fiedler on 05.02.05.
#
#  The original version was written in Objective-C by Malcolm Crawford
#  at http://homepage.mac.com/mmalc/CocoaExamples/controllers.html

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


class FilteringArrayController(NSArrayController):
    _k_searchString = ""

    def search_(self, sender):
        self.setSearchString_(sender.stringValue())
        self.rearrangeObjects()

    def newObject(self):
        """
        Creates and returns a new object of the class specified by objectClass.
        Set default values, and keep reference to new object -- see arrangeObjects_
        """
        self.newObj = super().newObject()
        self.newObj.setValue_forKey_("First", "firstName")
        self.newObj.setValue_forKey_("Last", "lastName")
        return self.newObj

    def arrangeObjects_(self, objects):
        if self._k_searchString is None or self._k_searchString == "":
            self.newObj = None
            return super().arrangeObjects_(objects)

        # Create array of objects that match search string.
        # Also add any newly-created object unconditionally:
        # (a) You'll get an error if a newly-added object isn't added to
        # arrangedObjects.
        # (b) The user will see newly-added objects even if they don't
        # match the search term.

        matchedObjects = []
        lowerSearch = self._k_searchString.lower()
        for item in objects:
            if item == self.newObj:
                # if the item has just been created, add it unconditionally
                matchedObjects.append(item)
                self.newObj = None
            else:
                lowerName = item.valueForKeyPath_("firstName").lower()
                if lowerSearch in lowerName:
                    matchedObjects.append(item)
                else:
                    lowerName = item.valueForKeyPath_("lastName").lower()
                    if lowerSearch in lowerName:
                        matchedObjects.append(item)
        return super().arrangeObjects_(matchedObjects)

    def searchString(self):
        return self._k_searchString

    def setSearchString_(self, newStr):
        self._k_searchString = newStr

FilteringController.py

#
#  FilteringController
#

import FilteringArrayController  # noqa: F401
import FilteringControllerDocument  # noqa: F401
from PyObjCTools import AppHelper

AppHelper.runEventLoop()

FilteringControllerDocument.py

#
#  FilteringControllerDocument.py
#  FilteringController
#
#  Converted by u.fiedler on 05.02.05.
#
#  The original version was written in Objective-C by Malcolm Crawford
#  at http://homepage.mac.com/mmalc/CocoaExamples/controllers.html

import objc
from Cocoa import NSDocument, NSKeyedArchiver, NSKeyedUnarchiver
from objc import super  # noqa: A004


class FilteringControllerDocument(NSDocument):
    peopleController = objc.IBOutlet()

    def init(self):
        self = super().init()
        if self is None:
            return None
        self._k_people = []
        return self

    def windowNibName(self):
        return "FilteringControllerDocument"

    def windowControllerDidLoadNib_(self, controller):
        super().windowControllerDidLoadNib_(controller)

    def dataRepresentationOfType_(self, aType):
        return NSKeyedArchiver.archivedDataWithRootObject_(self._k_people)

    def loadDataRepresentation_ofType_(self, data, aType):
        self.setPeople_(NSKeyedUnarchiver.unarchiveObjectWithData_(data))
        return True

    # indexed accessors

    def people(self):
        return self._k_people

    def setPeople_(self, people):
        self._k_people[:] = people

    @objc.accessor
    def countOfPeople(self):
        return len(self._k_people)

    @objc.accessor
    def objectInPeopleAtIndex_(self, idx):
        return self._k_people[idx]

    @objc.accessor
    def insertObject_inPeopleAtIndex_(self, obj, idx):
        self._k_people.insert(idx, obj)

    @objc.accessor
    def removeObjectFromPeopleAtIndex_(self, idx):
        del self._k_people[idx]

    @objc.accessor
    def replaceObjectInPeopleAtIndex_withObject_(self, idx, obj):
        self._k_people[idx] = obj

setup.py

"""
Script for building the example:

Usage:
    python3 setup.py py2app
"""

from setuptools import setup

plist = {
    "CFBundleDocumentTypes": [
        {
            "CFBundleTypeExtensions": ["FilteringController", "*"],
            "CFBundleTypeName": "FilteringController File",
            "CFBundleTypeRole": "Editor",
            "NSDocumentClass": "FilteringControllerDocument",
        }
    ]
}

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