ToDos

A PyObjC Example without documentation

Sources

Category.py

#
#  Category.py
#  ToDos
#
#  Converted by u.fiedler on 09.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 Foundation import NSObject


class Category(NSObject):
    title = objc.ivar("title")
    priority = objc.ivar("priority", objc._C_INT)

    @classmethod
    def allCategories(cls):
        """Predefined global list of categories"""
        return categories

    @classmethod
    def categoryForPriority_(cls, thePriority):
        for category in categories:
            if thePriority >= category.priority:
                return category
        return None

    @classmethod
    def categoryWithTitle_andPriority_(cls, aTitle, aValue):
        """Convenience constructor"""
        newCategory = Category.alloc().init()
        newCategory.title = aTitle
        newCategory.priority = aValue
        return newCategory

    # NSCoding methods
    # To encode, simply save 'priority'; on decode, replace self with
    # the existing instance from 'allCategories' with the same priority

    def encodeWithCoder_(self, encoder):
        if encoder.allowsKeyedCoding():
            encoder.encodeInt_forKey_(self.priority, "priority")
        else:
            encoder.encodeObject_(self.priority)

    def initWithCoder_(self, decoder):
        if decoder.allowsKeyedCoding():
            thePriority = decoder.decodeIntForKey_("priority")
        else:
            thePriority = decoder.decodeObject()
        return Category.categoryForPriority_(thePriority)


categories = [
    Category.categoryWithTitle_andPriority_("Vital", 11),
    Category.categoryWithTitle_andPriority_("Very Important", 4),
    Category.categoryWithTitle_andPriority_("Important", 3),
    Category.categoryWithTitle_andPriority_("Not Important", 2),
    Category.categoryWithTitle_andPriority_("Whenever", 0),
]

OverdueTransformer.py

#
#  OverdueTransformer.py
#  ToDos
#
#  Converted by u.fiedler on 09.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 NSColor, NSValueTransformer


class OverdueTransformer(NSValueTransformer):
    @classmethod
    def transformedValueClass(cls):
        return NSColor

    @classmethod
    def allowsReverseTransformation(cls):
        return False

    def transformedValue_(self, aDate):
        if aDate is None:
            return None
        if aDate.timeIntervalSinceNow() < 0:
            return NSColor.redColor()
        return NSColor.blackColor()

PriorityToColourTransformer.py

#
#  PriorityToColourTransformer.py
#  ToDos
#
#  Converted by u.fiedler on 09.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 NSColor, NSValueTransformer


class PriorityToColourTransformer(NSValueTransformer):
    @classmethod
    def transformedValueClass(cls):
        return NSColor

    @classmethod
    def allowsReverseTransformation(cls):
        return False

    def transformedValue_(self, priority):
        if priority is None:
            return NSColor.blackColor()
        elif priority > 4:
            return NSColor.redColor()
        elif priority > 3:
            return NSColor.orangeColor()
        elif priority > 2:
            return NSColor.blueColor()
        elif priority > 1:
            return NSColor.greenColor()
        elif priority > 0:
            return NSColor.brownColor()
        else:
            return NSColor.blackColor()

ToDos.py

import ToDosDocument  # noqa: F401

if __name__ == "__main__":
    from PyObjCTools import AppHelper

    AppHelper.runEventLoop()

ToDosDocument.py

#
#  ToDosDocument.py
#  ToDos
#
#  Converted by u.fiedler on 09.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 Category import Category
from Cocoa import (
    NSDocument,
    NSKeyedArchiver,
    NSKeyedUnarchiver,
    NSMutableArray,
    NSValueTransformer,
)
from objc import super  # noqa: A004
from OverdueTransformer import OverdueTransformer
from PriorityToColourTransformer import PriorityToColourTransformer


class ToDosDocument(NSDocument):
    nix = objc.IBOutlet()
    toDos = objc.ivar()

    def init(self):
        self = super().init()
        if self is None:
            return None
        self.toDos = NSMutableArray()
        return self  # if this line is missing you will get the
        # simple message: "Can't create new document"

    def categories(self):
        return Category.allCategories()

    def windowNibName(self):
        return "ToDosDocument"

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

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


priorityTransformer = PriorityToColourTransformer.alloc().init()
NSValueTransformer.setValueTransformer_forName_(
    priorityTransformer, "PriorityToColourTransformer"
)

overdueTransformer = OverdueTransformer.alloc().init()
NSValueTransformer.setValueTransformer_forName_(
    overdueTransformer, "OverdueTransformer"
)

setup.py

"""
Script for building the example:

Usage:
    python3 setup.py py2app
"""

from setuptools import setup

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

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