mutableCopy() error

Hello,

I want to use a view, created in IB, like a model to allow the user to save a modified version to a file.

The idea is :

  1. get the model view instance into a property and remove it from the window
  2. each time the user wants to create a new version of the view, make a copy and add this copy to the window
  3. when the copy is saved to file, remove it.

So what’s NOT correct here ?

script SUBVIEWSAppDelegate
	property parent : class "NSObject"

    property gModelView : missing value -- IBOutlet for the Model View
    property gModelViewCopy : missing value -- the duplicate
    property gSuperView : missing value -- IBOutlet for the enclosing view

    on applicationWillFinishLaunching_(aNotification)
        gModelView's retain() -- as a removed view is released (I'm not sure it's needed in ASOC, but it won't hurt)
        gModelView's removeFromSuperview()
    end

    on createNewCopy_(sender)
        set gModelViewCopy to gModelView's mutableCopy() -- should create a new object with different memory location.
        gSuperView's addSubview_(gModelViewCopy)
    end

    on releaseAfterSaving_(sender)
        gModelViewCopy's removeFromSuperview()
    end
	
end script

I get an error, whatever I try to copy, for example with a button:

Buttons, and I think all the things that are descendants of NSView, don’t adopt the NSCopying protocol, so they don’t understand the copy or mutableCopy commands. At the top of the class descriptions there is a section labeled “Conforms to” – if you don’t see NSCopying there, then you can’t copy (unless you subclass and adopt the protocol in your subclass).

Ric

Great…

I suppose I can do this from ASOC?

When you write

set a to “hello”
set b to a
set b to “world”
display dialog a

you get “hello”, so b is a new object and not an variable address – does it mean Applescript can make copy?

Well, yes applescript, as well as objectiveC, can copy, but you’re not copying in this example. After the first 2 lines you just have 2 different variables that point to the same object (the string “hello”). When you then do “set b to “world”” you are just reassigning what b points to. There isn’t any copying going on here – you would use “copy” if you want to copy, and then you would have 2 string objects with the value of “hello”.

In any case, NSString does conform to NSCopying, so you can copy strings in ASOC or objective C.

Ric

So again, subclassing in Objective-C is the only clean solution? That means, if you will copy something not conforming to NSCopying (and that means all view objects) you must subclass it? Big deal. I suppose there is a good reason Apple didn’t make a NSObject’s clone() method.

Even not a sort of NSMoveBlock_(objectA, objectB, nBytes) I suppose. :confused:

I think that’s true if you define the problem the way you did in the first post. But why do you want to copy a view in the first place? How do you want the user to be able to change a view? What is it that they are changing? You might be able to solve the problem in a wholly different way.

Ric

You’re right, I’ll reconsider the design.

Thanks!

I wander again.

Is it possible to load/reload individual .nib objects (from another .nib belonging to the main bundle) using CreateWindowFromNib or is this strictly reserved to Carbon applications?

You use initWithWindowNibName:. But I wonder if what you’re really after is a subclass that you can alloc()'s initWithFrame_

What I want is very similar as what NSDocument does when it reloads a new document window, with all its subviews” controls, text strings and so on.

In my app this is not a document window, however, but an auxiliary window (a panel) associated with a document. Each of my documents has one panel to define some options which are not set from the main window; in fact, as these settings are optional, I want to load a default settings window if the options are not yet defined, and load them from file if they are defined.

The problem is, when a user closes a file which have defined options, and then opens a new file, it seems more convenient to reload a fresh default panel (defined in IB) than to replace options by defaults programmatically: some of the options are colorwells, not really simple to encode or to manipulate with a controller.

Is it doable or not? At which cost?

So what you’re saying is that each document has two windows. You can do that.

You make the windows in separate xib files, and you create NSWindowController classes for each; you set th file’s owner for each nib to the relevant controller class. Then in your NSDocument class you override makeWindowControllers to create the two window controller instances, using alloc and initWithWindowNibName_, and add them to the doc’s list using addWindowController_.

Using the standard document-based approach makes this stuff a bit easier.

My

returns NIL for my window (stored in a “MapWindow.xib” in the bundle)

so of course

or

show nothing (but I get no error)

So what class is file’s owner of MapWindow.xib?

I tried

without success

But you didn’t answer the question…

No, you’re right.
There is no WindowController in IB, so I declared if programmatically.
When I open a new xib file, I have new File’s Owner, Application cubes, and no way to drag anything from one file to the other.
Must I set the file’s owner of MapWindow.xib to my main script’s class?

if you want more than one window per document, you really need to make window controller subclasses for each.

My app is not a document application as NSDocument defines it – maybe it was an error from the beginning, but it opens a single window and work on one “document” (it is a folder in fact) at a time.

I suppose there is a default window controller created by the application somethere, but how to be sure? I’ve always been sending messages to my main window directly, and it has worked so far.

Do you mean I have to create explicitly a NSWindowController for my main window, and then another for my auxiliary window? Something like:

set gWindowController to current application’s NSWindowController’s alloc’s initWithWindowNibName_(“MainMenu”)

set gMapWindowController to current application’s NSWindowController’s alloc’s initWithWindowNibName_(“MapWindow”)

I’ve done so. My Map Window is always NIL.

When the solution becomes more complicated than the problem, it’s time to find another way to solve it. Visibly, Cocoa is fine when you strictly stick on Apple’s trail, like doing Temperature Converters. :confused:

I have another idea: I define a view with a set of colors and legends, save them as a view in IB (with no superview) and then install it later in my window’s content view using

and after saving I send

So I get exactly what I wanted and it works. A legend remains the default for the whole session. Finally not more complicated than Temperature Converters. :wink: