开发者

Cocoa: Plugin Cannot Open App Window

I am developing an plugin for OsiriX.

In that app i have 3-4 nib files. Also in for plugin there are files (.h & .m) called PluginFilter where method called - (long) filterImage:(NSString) menuName is present from which the plugin start execution. Now my problem is 开发者_StackOverflowthat, I have return the code to launch main window is in some other .m file and I have to call that file using the method mentioned above.

The app has multiple nib files. I have a plugin name PluginFilter called by:

- (long) filterImage:(NSString*) menuName

The plugin should open a window when called by this method. The code that defines the window controller is in another nib. When I call the filterimage method in the plugin, the window never appears.

Here is my filterImage: method.

#import "XGridInOsiriXFilter.h"
#import "MainWindowController.h"

@implementation XGridInOsiriXFilter

- (void) initPlugin
{

}

- (long) filterImage:(NSString*) menuName
{

    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init];
    [mainWindowController showWindow:self ];
    [mainWindowController release];

    return 0;
}

@end

Calling the method produces not warnings or errors, the window simply fails to appear.


I recognize this may be coming a little too late but I was looking for a way to do the same thing you are asking for and found it. You can use NSBundle to load the desired nib and point it to an instantiated controller. Like:

@implementation YourPluginFilter

- (void) initPlugin
{
yourWindowController = [[YourWindowController alloc] init];
NSLog(@"Initialized YourWindowController");
}

- (long) filterImage:(NSString*) menuName
{
if (yourWindowController && [NSBundle loadNibNamed:@"YourNibName" owner:yourWindowController]) {
        NSLog(@"Activated yourWindowController");
    return 0;
} else {
    return -1;
}
}

@end


You would normally not open the app's main window from a plugin. Plugins by definition my not always be present so you should not put critical code in them. Neither would you want multiple plugins opening the same logical window.

Instead, the main window should be displayed by the app delegate as normal but the content of the window can be processed by a plugin if the plugin is available.

The main application should load and configure the main window and only call the plugin to process the contents of the window.

Even so it is technically possible to open a window from a plugin so either (1) the plugin is not being loaded and the method is not being called (insert breakpoint/log to confirm) or (2) the window controller is misconfigured so that it does not open the window. Test the controller outside the plugin to confirm it works. Better yet, move the window opening code outside the plugin.

Edit01:

From comment:

I have made some changes in the above code as follows

- (long) filterImage:(NSString*) menuName { 
    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];            
    [mainWindowController showWindow:self ]; 
    [mainWindowController release]; 
    return 0; 
}

but it is showing wanring that no -init method found. Why it is showing like this because -init method is der in the MainWindowController.m file

Well, you have two problems here.

(1) You set define mainWindowController as of class MainWindowController but you initialize it with class GridSampleMainWindowController. If MainWindowController is a subclass of GridSampleMainWindowController this will work but will generate warnings. You should instead initialize it like

GridSampleMainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];  

or

MainWindowController *mainWindowController = [[MainWindowController alloc] init:self]; 

(2) You release the controller without any other object retaining it which will kill it. When a window controller dies it deallocates the windows it controls. This is most likely why you see nothing.

You should sort out what class you want the controller to be and then set it as a retained property of the plugin class so you can keep it an its window around.

Which init method is it complaining about? Your initPlugin does nothing and returns a void if that is the plugin's actual initialization method then the plugin will never load. It should at least look like this:

- (id) initPlugin
{
    self=[super init];
    return self;
}

It looks like you come from a pure C background which is great for this environment but you need to learn about the object oriented parts of the Objective-C language. You're still writing methods as if they were old school C functions and there are important and oft times subtle differences.

Sorry I missed all this yesterday. I saw "plugin" and focused on the wrong aspect of the problem.

Edit02:

No i m not talking about my initPlugin method. I am talking about my init method which is there in MainWindowController.m file

- (id)init { 
      self = [super initWithWindowNibName:@"MainWindow"]; 
      return self; 
}

This will return an instance of the MainWindowController's super class. If you're not doing any customization you have no need to override the init method in you subclass. Just use the inherited version thusly:

MainWindowController *mainWindowController = [[MainWindowController alloc] initWithWindowNibName:@"MainWindow"]; 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜