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"];
精彩评论