mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 00:50:38 +00:00
Major revision of services - all menu services stuff in place now.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@3363 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
558b6da8c2
commit
141a4d603a
11 changed files with 1434 additions and 861 deletions
|
@ -738,177 +738,3 @@ NSGetFileTypes(NSArray *pboardTypes)
|
|||
return nil;
|
||||
}
|
||||
|
||||
|
||||
extern NSDictionary* GSAllServicesDictionary();
|
||||
extern NSDictionary* GSApplicationsDictionary();
|
||||
|
||||
static NSConnection *listener = nil;
|
||||
|
||||
void
|
||||
NSRegisterServicesProvider(id provider, NSString *name)
|
||||
{
|
||||
if (listener)
|
||||
{
|
||||
/*
|
||||
* Ensure there is no previous listener and nothing else using
|
||||
* the given port name.
|
||||
*/
|
||||
[[NSPortNameServer defaultPortNameServer] removePortForName: name];
|
||||
[listener release];
|
||||
}
|
||||
listener = [NSConnection newRegisteringAtName: name
|
||||
withRootObject: provider];
|
||||
[listener retain];
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSPerformService(NSString *serviceItem, NSPasteboard *pboard)
|
||||
{
|
||||
NSUserDefaults *defs;
|
||||
NSArray *languages;
|
||||
NSDictionary *services;
|
||||
NSDictionary *byLanguage;
|
||||
NSDictionary *service;
|
||||
NSString *port;
|
||||
unsigned end;
|
||||
unsigned pos;
|
||||
NSString *timeout;
|
||||
double seconds;
|
||||
NSDate *finishBy;
|
||||
NSString *appPath;
|
||||
id provider;
|
||||
NSConnection *connection;
|
||||
NSString *message;
|
||||
NSString *selName;
|
||||
SEL msgSel;
|
||||
NSString *userData;
|
||||
IMP msgImp;
|
||||
NSString *error = nil;
|
||||
NSDictionary *allServices;
|
||||
|
||||
/*
|
||||
* Get language preference array.
|
||||
*/
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
languages = [defs arrayForKey: @"Languages"];
|
||||
|
||||
/*
|
||||
* Get dictionary of menu services from workspace manager.
|
||||
*/
|
||||
allServices = GSAllServicesDictionary();
|
||||
|
||||
services = [allServices objectForKey: @"ByService"];
|
||||
|
||||
/*
|
||||
* Find service information for a service matching the given menu item
|
||||
* Search in language preference order.
|
||||
*/
|
||||
if (languages)
|
||||
end = [languages count];
|
||||
else
|
||||
end = 0;
|
||||
byLanguage = nil;
|
||||
for (pos = 0; pos < end; pos++)
|
||||
{
|
||||
NSString *language = [languages objectAtIndex: pos];
|
||||
|
||||
byLanguage = [services objectForKey: language];
|
||||
if (byLanguage != nil)
|
||||
break;
|
||||
}
|
||||
if (byLanguage == nil)
|
||||
byLanguage = [services objectForKey: @"default"];
|
||||
service = [byLanguage objectForKey: serviceItem];
|
||||
|
||||
if (service == nil)
|
||||
return NO; /* No matching service. */
|
||||
|
||||
port = [service objectForKey: @"NSPortName"];
|
||||
timeout = [service objectForKey: @"NSTimeout"];
|
||||
if (timeout && [timeout floatValue] > 100)
|
||||
{
|
||||
seconds = [timeout floatValue] / 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
seconds = 30.0;
|
||||
}
|
||||
finishBy = [NSDate dateWithTimeIntervalSinceNow: seconds];
|
||||
appPath = [service objectForKey: @"ServicePath"];
|
||||
userData = [service objectForKey: @"NSUserData"];
|
||||
message = [service objectForKey: @"NSMessage"];
|
||||
selName = [message stringByAppendingString: @":userData:error:"];
|
||||
msgSel = NSSelectorFromString(selName);
|
||||
|
||||
/*
|
||||
* If there is no selector - we need to generate one with the
|
||||
* appropriate types.
|
||||
*/
|
||||
if (msgSel == 0)
|
||||
{
|
||||
NSMethodSignature *sig;
|
||||
const char *name;
|
||||
const char *type;
|
||||
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: "v@:@@^@"];
|
||||
type = [sig methodType];
|
||||
name = [selName cString];
|
||||
msgSel = sel_register_typed_name(name, type);
|
||||
}
|
||||
|
||||
provider = [NSConnection rootProxyForConnectionWithRegisteredName: port
|
||||
host: @""];
|
||||
if (provider == nil)
|
||||
{
|
||||
if ([[NSWorkspace sharedWorkspace] launchApplication: appPath] == NO)
|
||||
{
|
||||
return NO; /* Unable to launch. */
|
||||
}
|
||||
|
||||
provider = [NSConnection rootProxyForConnectionWithRegisteredName: port
|
||||
host: @""];
|
||||
while (provider == nil && [finishBy timeIntervalSinceNow] > 1.0)
|
||||
{
|
||||
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
||||
NSDate *next;
|
||||
|
||||
[NSTimer scheduledTimerWithTimeInterval: 1.0
|
||||
invocation: nil
|
||||
repeats: NO];
|
||||
next = [NSDate dateWithTimeIntervalSinceNow: 5.0];
|
||||
[loop runUntilDate: next];
|
||||
provider = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName: port
|
||||
host: @""];
|
||||
}
|
||||
}
|
||||
|
||||
if (provider == nil)
|
||||
{
|
||||
return NO; /* Unable to contact. */
|
||||
}
|
||||
connection = [(NSDistantObject*)provider connectionForProxy];
|
||||
seconds = [finishBy timeIntervalSinceNow];
|
||||
[connection setRequestTimeout: seconds];
|
||||
[connection setReplyTimeout: seconds];
|
||||
|
||||
msgImp = get_imp(fastClass(provider), msgSel);
|
||||
NS_DURING
|
||||
{
|
||||
(*msgImp)(provider, msgSel, pboard, userData, &error);
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
[NSException raise: NSPasteboardCommunicationException
|
||||
format: @"%s", [[localException reason] cString]];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
if (error != nil)
|
||||
{
|
||||
NSLog(error);
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue