Did one of you ever save NSMatrix’s contents to a file? If yes, how?
Whatever it is in a matrix (strings, integer and so on) it can certainly be considered as an array, so the first idea I had was something like:
set gList to {}
gMatrix's sendAction_to_forAllCells_("cellAppend:",me,1)
-- store array into a NSDictionary and write it.
.
on cellAppend_(aCell)
set my gList to gList & aCell
return 1
end
Someone has a better idea?
I do regret than there is no clear and simple indexing syntax in Applescript. It would be nice to code:
set myList [4] to something rather than set item 4 of myList to something
or even better:
set myMatrix [6,8] to something rather than. nothing.
It’s much easier than that. Just archive it. I tried this with a small matrix, and it worked fine. So to save I did:
on saveFileAs_(sender) -- connected to the "Save As" menu item
set sp to current application's NSSavePanel's savePanel()
sp's setAllowedFileTypes_({"matrix"})
sp's setNameFieldStringValue_("Untitled")
sp's runModal()
set theData to current application's NSKeyedArchiver's archivedDataWithRootObject_(mat)
theData's writeToURL_atomically_(sp's |URL|(), 1)
end saveFileAs_
To bring it back in:
on applicationWillFinishLaunching_(aNotification)
set ans to the button returned of (display dialog "Open a Document or Make a New one?" buttons {"Open", "Make New"})
if ans is "Open" then
set op to current application's NSOpenPanel's openPanel()
op's setAllowedFileTypes_({"matrix"})
op's runModal()
set openedFilePath to op's URLs()'s objectAtIndex_(0)'s |path|()
setNewMat_(current application's NSKeyedUnarchiver's unarchiveObjectWithFile_(openedFilePath))
contentView's replaceSubview_with_(mat, newMat)
setMat_(newMat)
end if
end applicationWillFinishLaunching_
So, mat, newMat, contentView and theData are all defined as properties. mat is the IBOutlet for the matrix and contentView is the IBOutlet for the window’s content view.
Ric
After Edit: Actually, I don’t know if this will work for your project. It worked with a matrix of text cells – the text I entered in the cells was restored when I read the file back in. However, when I tried it with a matrix where I changed the background color by clicking in the cells, the matrix that was read back in didn’t retain the background colors.
After a second edit: I tested a few things to see what was saved and restored properly and what wasn’t. I tested this on my program where I created the matrix in code. It saves the matrix’s size, number of rows, cell size and autoresizing behavior – pretty much everything. As for the cells of the matrix, it seems that it saves the bezel style, size, title, and tag but not the background color – why that one thing isn’t saved, I don’t know. But, if you are using tags to represent the background color, then this method might work.
Thank you Ric. I read the doc about archieving and saw that “almost all” was saved. So my first idea was to save the whole window’s content view
As I don’t save the cells bkcolor but a reference, I have to save these colors along with the matrix (and the legends too), so I have to make make a dictionary for them and then save it with the matrix as root object? It should’t be a problem as texts and colors are properties too…
Hopefully, that will work. I wonder if things that can’t be set in IB are some how different than those that can – for instance, you can set the background color of a matrix in IB, and that is saved with the archive, but you can’t set the background color of a button or button cell in IB, and that is not saved. Could it be that the background color of a cell is not a property of the cell? But it does have a setter and getter, so that means it is a property, right?
I don’t know. private variable? variable from an helper class? I found nothing.
There is a problem when saving an object and reloading it from a file: the link between the object and the script’s property is broken. You have to re-bind “by hand”.
Say I save a view with subviews. I can easily identify the enclosing view and set the property to it again, but what if one or more of its subviews are properties too?
I know that subviews are listed in a NSArray, but it’s written in the docs I can’t really rely on their order. I could, again, use the tags, but I’m not sure they are saved with the object. Given properties gSubview and gEnclosingView. The message
set my gSubview to gEnclosingView's viewWithTag_(99999)
returns nil.
After Edit 1: The tags seem to be not saved to file with the object – and my app relies on tags. Darn.
After Edit 2: What is this? I’m not sure I understand.
It seems that tags are saved finally. But WHY does this not work:
gLegends's viewWithTag_(9999) --> returns the correct object
set my gTempLegends to (current application's NSKeyedUnarchiver's unarchiveObjectWithFile_("legends.atmp"))
mapSuperView's replaceSubview_with_(gLegends, gTempLegends)
set my gLegends to gTempLegends
gLegends's viewWithTag_(9999) --> returns NIL.
Once again, it suddenly worked - sometimes passing the “Clear” command for the project is a good thing.
I found the making of the matrix slow until I realized that Cocoa had to create, allocate, init and arrange 4096 fully functional and ready-to-respond NSCell objects into my matrix.
Not bad in two seconds.
Note : the code I wrote in my first post is wrong, because I can access to the array of cells using “gMatrix’s cells()”