Tableview help

The problem is that, after you delete an item, what gets saved back to theData is a mutable array, not a list, so “theData & selectedPKGPath” makes no sense. You could probably use:

set my theData to (theData as list) & selectedPKGPath

But using addObject: on the array controller is probably a better way to go anyway.

Thanks Shane, your replies… book & site have been a great help!

Hi Guys,

Thanks so much for the help so far with creating TableViews.

But, i’m stumped again…

Basically, i want to run the below to check if a file exists… If it doesn’t then display a dialog advising such (<< this is working) then change the text colour of the row/object which has the path of the missing item.

My attempt below, changes the colour of the whole table… Please enlighten me.

    on testButton_(sender)
        
        repeat with theItem in additionalPKGs
            
            try
                -- Check for file
                do shell script "ls " & quoted form of theItem
                log "Found " & theItem
                
            on error
            
                log theItem & " is missing"
                
                display dialog "Cannot Find: " & additionalPKGs & ". Do you wish to proceed?" with icon 2 buttons {"No", "Yes"}
                
                -- Set missing items text to red.
                set my selectedPKGsColor to current application's NSColor's redColor()
                
            end try
            
        end repeat
        
    end testButton_

For more context, the whole of this POC script is below:

property parent : class "NSObject"
	property additionalPKGs : {} --  the main property; array controller binds its content array to this
	
	-- IBOutlets
	property |window| : missing value
	property theArrayController : missing value
    property selectedPKGPath : missing value
    property defaults : missing value
    property testValue : missing value
    property certsAdded : 0
    property certsValue : missing value
    property selectedRow : missing value
    property selectedObjects : missing value
    property textColor : missing value
    --property NSColor : class "NSColor" of current application
    property selectedPKGsColor : missing value
    
	on applicationWillFinishLaunching:aNotification
        
        -- populate plist file with defaults (will not overwrite non-default settings))
        regDefaults_(me)
        
        -- retrieve plist values
        retrieveDefaults_(me)
        
	end applicationWillFinishLaunching:
    
    on regDefaults_(sender)
        tell current application's NSUserDefaults to set defaults to standardUserDefaults()
        tell defaults to registerDefaults_({additionalPKGs:additionalPKGs}) as list
    end regDefaults_
    
    -- Get values from plist
	on retrieveDefaults_(sender)
        tell defaults to set my additionalPKGs to objectForKey_("additionalPKGs") as list
    end retrieveDefaults_
    
    on selectPKG_(sender)
        try
            choose file of type {"com.apple.installer-package-archive"} with prompt "Select a .pkg to add:" default location (path to desktop folder)
            
            set my selectedPKGPath to POSIX path of result
            
            log selectedPKGPath
            
            tell theArrayController to addObject:selectedPKGPath
            
            log "done"
            
            log additionalPKGs
            
            tell standardUserDefaults() of current application's NSUserDefaults
                
                setObject_forKey_(additionalPKGs, "additionalPKGs")
                
            end tell
            
            log "updated plist"
            
        end try
        
    end selectPKG_
	
    on deletePKG_(sender)
    
        tell theArrayController to set my selectedObjects to selectedObjects()
        
        log selectedObjects
        
        tell theArrayController to removeObjects:selectedObjects
        
        log "done"
        
        log additionalPKGs
        
        tell standardUserDefaults() of current application's NSUserDefaults
            
            setObject_forKey_(additionalPKGs, "additionalPKGs")
            
        end tell
        
        log "updated plist"
    
    end deletePKG_
    
    on testButton_(sender)
        
        repeat with theItem in additionalPKGs
            
            try
                -- Check for file
                do shell script "ls " & quoted form of theItem
                log "Found " & theItem
                
            on error
            
                log theItem & " is missing"
                
                display dialog "Cannot Find: " & additionalPKGs & ". Do you wish to proceed?" with icon 2 buttons {"No", "Yes"}
                
                -- Set missing items text to red.
                set my selectedPKGsColor to current application's NSColor's redColor()
                
            end try
            
        end repeat
        
    end testButton_
    
	on applicationShouldTerminate:sender
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate:

If you want to do anything other than a simple single-column table with no frills, you have to provide a list of records rather than a simple list of strings. That’s what all the multi-column examples in my book use. Then you can have a value in the records that contains a color, and bind the text color property of the column to it.

So your records might be something like:

{thePath:“/blah/blah/blah”, theColor:textColor}

Once you get the bindings set up, you would change an entry’s color by changing the the value of its theColor property.

Thanks Shane, but if I change the colour of a column. That will change all the text across all rows right?

The below is bound to the table views text color:

set my selectedPKGsColor to current application's NSColor's redColor()

Can changing the color as you mentioned target a single row?

No. It’s like binding a column’s value – it uses the value for a particular row.

Sorry Shane, I don’t follow.

If I have the text color of the table view or textfield & set to red, it changes for the whole table.

What’s the method to change only a wanted rows color?

(Not via the GUI, but programmatically).

Still struggling.

Shane… i guess you mean something like (which you had posted earlier):

But, when I bind “theColor” to Text Color of the Text Field Cell in the Table View, i either get uncaught exception errors… or weirdly, the Table Views contents change to sections of my screen.

As an alternative, perhaps I could add a column with icons. Green for ok, Red for not.

Would that be easier than trying to change the texts colour? (which seems to be more of a PITA than it should be).

This looks promising:

theItem's cell's setTextColor_(NSColor's redColor)

setTextColor should be able to be used for theItem’s text field cell, but i can’t seem to get it to work.

Does textColor always contain an NSColor? It soundd like it doesn’t.

That’s what I’d do. How many tables do you see that change the color of an entry? I can’t think of any off-hand. It’s not standard UI, and you will often find it’s harder to do non-standard things.

The property was being declared as missing value, so I guess I need to figure out how to declare it as black.

When trying: property selectedPKGsColour :

"NSCalibratedRGBColorSpace 1 0 0 1"

i get the error:

This works:

property selectedPKGsColour : missing value
    
	on applicationWillFinishLaunching:aNotification
        
        set my selectedPKGsColour to current application's NSColor's blackColor()
        
        log selectedPKGsColour
        
        -- populate plist file with defaults (will not overwrite non-default settings))
        regDefaults_(me)
        
        -- retrieve plist values
        retrieveDefaults_(me)
        
	end applicationWillFinishLaunching:

But when changing the colour later using the below, all text in the tableview changes to red. How do i target a row?

set my selectedPKGsColour to current application's NSColor's redColor()

You change the value in the record/dictionary that represents that row.

You are binding the color to the array controller’s arrangedObjects, aren’t you?

Just to add, this behaviour seems common in some Mac admin tools such as Apple Remote Desktop & Casper Remote.

Yes

So you set the theColor property (or whatever you call it) of every item to current application’s NSColor’s blackColor() (or a property containing same. Then when you want one to appear in red, you set it’s theColor property to current application’s NSColor’s redColor().

Thanks Shane, still unclear how to isolate a row.

My binding for text colour of the text field cell in the table view is set to "selectedPKGsColour.’

If i change this to red, it changes the value for all text field cells.

So how do you tell it to only change the wanted rows colour?

Something like the below fails:

set my theItem's selectedPKGsColour to current application's NSColor's redColor()

As Shane mentioned before, the database of a table view is an array/list of dictionaries/records of the same type or an array/list of custom class objects.
A column is bound to a specific property. For example with this array of dictionaries

{ {thePath:"/blah/blah/blah", theColor:blackColor}, {thePath:"/foo/foo/foo", theColor:redColor} }
if you bind “thePath” to the value and the “theColor” to the text color of the text field of column 1 the table view will look like

/blah/blah/blah
/foo/foo/foo

so to change the color of a specific row you have to change the value of the respective “theColor” property in the array

Thanks both for your patience & perseverance.

I’ll see what i can do.

Sorry, still struggling. Code below.

script AEXAppDelegate
    
    property parent : class "NSObject"
    property theItem : {} -- the main property; array controller binds its content array to this
    
    -- IBOutlets
    property |window| : missing value
    property theArrayController : missing value
    property selectedPKGPath : missing value
    property defaults : missing value
    property testValue : missing value
    property certsAdded : 0
    property certsValue : missing value
    property selectedRow : missing value
    property selectedObjects : missing value
    property NSColor : class "NSColor" of current application
    property theColor : missing value
    property selectedPKGsColour : missing value
    property thePath : missing value
    property runNumber : 0
    property additionalPKGs : missing value
    
    on applicationWillFinishLaunching:aNotification
        
        set my selectedPKGsColour to current application's NSColor's blackColor()
        
        log selectedPKGsColour
        
        -- populate plist file with defaults (will not overwrite non-default settings))
        regDefaults_(me)
        
        -- retrieve plist values
        retrieveDefaults_(me)
        
        set my theItem to {thePath:additionalPKGs, theColor:selectedPKGsColour}
        
        log theItem
        
    end applicationWillFinishLaunching:
    
    on regDefaults_(sender)
        tell current application's NSUserDefaults to set defaults to standardUserDefaults()
        tell defaults to registerDefaults_({additionalPKGs:additionalPKGs}) as list
    end regDefaults_
    
    -- Get values from plist
    on retrieveDefaults_(sender)
        tell defaults to set my additionalPKGs to objectForKey_("additionalPKGs") as list
    end retrieveDefaults_
    
    on selectPKG_(sender)
        try
            
            set runNumber to runNumber + 1
            
            choose file of type {"com.apple.installer-package-archive"} with prompt "Select a .pkg to add:" default location (path to desktop folder)
            
            set my selectedPKGPath to POSIX path of result
            
            tell theArrayController to addObject:selectedPKGPath
            
            tell defaults to registerDefaults_({additionalPKGs:additionalPKGs}) as list
            
            set my theItem to theItem & {thePath:additionalPKGs, theColor:selectedPKGsColour}
            
            log theItem

            tell standardUserDefaults() of current application's NSUserDefaults
                
                setObject_forKey_(additionalPKGs, "additionalPKGs")
                
            end tell
            
        end try
        
        if runNumber is greater than 1
        
            set my selectedPKGsColour to current application's NSColor's redColor()
            
            log selectedPKGsColour
        
        end if
    
    end selectPKG_

    on deletePKG_(sender)
        
        tell theArrayController to set my selectedObjects to selectedObjects()
        
        log selectedObjects
        
        tell theArrayController to removeObjects:selectedObjects
        
        log "done"
        
        log additionalPKGs
        
        tell standardUserDefaults() of current application's NSUserDefaults
            
            setObject_forKey_(additionalPKGs, "additionalPKGs")
            
        end tell
        
        log "updated plist"
        
    end deletePKG_
    
    on testButton_(sender)
        
        repeat with theItem in additionalPKGs
            
            try
                -- Check for file
                do shell script "ls " & quoted form of theItem
                log "Found " & theItem
                
            on error
                
                log theItem & " is missing"
                
                display dialog "Cannot Find: " & additionalPKGs & ". Do you wish to proceed?" with icon 2 buttons {"No", "Yes"}
                
                -- Set missing items text to red.
                set my selectedPKGsColour to current application's NSColor's redColor()
                
            end try
            
        end repeat
        
    end testButton_
    
    on applicationShouldTerminate:sender
        -- Insert code here to do any housekeeping before your application quits
        return current application's NSTerminateNow
    end applicationShouldTerminate:
    
end script

How do I implement:

{
{thePath:"/blah/blah/blah", theColor:blackColor},
{thePath:"/foo/foo/foo", theColor:redColor}
}

I changed the array controllers content array bindings to a “Content Array For Mulitple Selection” which allows the app to compile.

In the bindings for “packages” column, i have the value bound to the array controller. The “Controller Key” is arrangedObjects & the “Model Key Path” is thePath.

I get the below in the apps logs, but nothing in the TableView.