Preliminary services support.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@3307 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1998-11-23 21:39:58 +00:00
parent 528ae2a9e0
commit 407d404c80
2 changed files with 408 additions and 29 deletions

View file

@ -30,6 +30,7 @@
#include <gnustep/gui/config.h>
#include <AppKit/NSPasteboard.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSWorkspace.h>
#include "../Tools/PasteboardServer.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSData.h>
@ -43,6 +44,10 @@
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSSerialization.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSMethodSignature.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSTimer.h>
#include <Foundation/fast.x>
#define stringify_it(X) #X
#define prog_path(X,Y) \
@ -123,8 +128,15 @@ static id<PasteboardServer> the_server = nil;
}
else
{
NSRunLoop *loop = [NSRunLoop currentRunLoop];
NSDate *next;
system(prog_path(GNUSTEP_INSTALL_PREFIX, "/gpbs &"));
sleep(5);
[NSTimer scheduledTimerWithTimeInterval: 5.0
invocation: nil
repeats: NO];
next = [NSDate dateWithTimeIntervalSinceNow: 5.0];
[loop runUntilDate: next];
recursion = YES;
[self _pbs];
recursion = NO;
@ -383,8 +395,8 @@ static id<PasteboardServer> the_server = nil;
- (void) releaseGlobally
{
[target releaseGlobally];
[pasteboards removeObjectForKey: name];
[target releaseGlobally];
[pasteboards removeObjectForKey: name];
}
//
@ -726,12 +738,9 @@ NSGetFileTypes(NSArray *pboardTypes)
return nil;
}
void
NSUpdateDynamicServices()
{
system(prog_path(GNUSTEP_INSTALL_PREFIX, "/make_services"));
}
extern NSDictionary* GSAllServicesDictionary();
extern NSDictionary* GSApplicationsDictionary();
static NSConnection *listener = nil;
@ -752,3 +761,154 @@ NSRegisterServicesProvider(id provider, NSString *name)
[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;
}

View file

@ -7,6 +7,8 @@
Author: Scott Christley <scottc@net-community.com>
Date: 1996
Implementation: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: 1998
This file is part of the GNUstep GUI Library.
@ -28,8 +30,74 @@
#include <gnustep/gui/config.h>
#include <AppKit/NSWorkspace.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSTask.h>
#include <Foundation/NSException.h>
@implementation NSWorkspace
#define stringify_it(X) #X
#define prog_path(X,Y) \
stringify_it(X) "/Tools/" GNUSTEP_TARGET_DIR "/" LIBRARY_COMBO Y
static NSDictionary *allServices = nil;
static NSDictionary *applications = nil;
NSDictionary*
GSAllServicesDictionary()
{
if (allServices == nil)
[[NSWorkspace sharedWorkspace] findApplications];
return allServices;
}
NSDictionary*
GSApplicationsDictionary()
{
if (applications == nil)
[[NSWorkspace sharedWorkspace] findApplications];
return applications;
}
void
NSUpdateDynamicServices()
{
[[NSWorkspace sharedWorkspace] findApplications];
}
@implementation NSWorkspace
static NSWorkspace *sharedWorkspace = nil;
static NSNotificationCenter *workspaceCenter = nil;
static BOOL userDefaultsChanged = NO;
static NSString *cacheName = @".GNUstepServices";
static NSString *servicesPath = nil;
static NSString* gnustep_target_dir =
#ifdef GNUSTEP_TARGET_DIR
@GNUSTEP_TARGET_DIR;
#else
nil;
#endif
static NSString* gnustep_target_cpu =
#ifdef GNUSTEP_TARGET_CPU
@GNUSTEP_TARGET_CPU;
#else
nil;
#endif
static NSString* gnustep_target_os =
#ifdef GNUSTEP_TARGET_OS
@GNUSTEP_TARGET_OS;
#else
nil;
#endif
static NSString* library_combo =
#ifdef LIBRARY_COMBO
@LIBRARY_COMBO;
#else
nil;
#endif
//
// Class methods
@ -38,22 +106,96 @@
{
if (self == [NSWorkspace class])
{
static BOOL beenHere;
NSDictionary *env;
// Initial version
[self setVersion:1];
[gnustep_global_lock lock];
if (beenHere == YES)
{
[gnustep_global_lock unlock];
return;
}
beenHere = YES;
workspaceCenter = [NSNotificationCenter new];
env = [[NSProcessInfo processInfo] environment];
if (env)
{
NSString *str;
str = [env objectForKey: @"GNUSTEP_USER_ROOT"];
if (str == nil)
str = [NSString stringWithFormat: @"%@/GNUstep", NSHomeDirectory()];
str = [str stringByAppendingPathComponent: cacheName];
servicesPath = [str retain];
if ((str = [env objectForKey: @"GNUSTEP_TARGET_DIR"]) != nil)
gnustep_target_dir = [str retain];
else if ((str = [env objectForKey: @"GNUSTEP_HOST_DIR"]) != nil)
gnustep_target_dir = [str retain];
if ((str = [env objectForKey: @"GNUSTEP_TARGET_CPU"]) != nil)
gnustep_target_cpu = [str retain];
else if ((str = [env objectForKey: @"GNUSTEP_HOST_CPU"]) != nil)
gnustep_target_cpu = [str retain];
if ((str = [env objectForKey: @"GNUSTEP_TARGET_OS"]) != nil)
gnustep_target_os = [str retain];
else if ((str = [env objectForKey: @"GNUSTEP_HOST_OS"]) != nil)
gnustep_target_os = [str retain];
if ((str = [env objectForKey: @"LIBRARY_COMBO"]) != nil)
library_combo = [str retain];
[gnustep_global_lock unlock];
}
}
}
+ (id) allocWithZone: (NSZone*)zone
{
[NSException raise: NSInvalidArgumentException
format: @"You may not allocate a workspace directly"];
return nil;
}
//
// Creating a Workspace
//
+ (NSWorkspace *)sharedWorkspace
{
return nil;
if (sharedWorkspace == nil)
{
[gnustep_global_lock lock];
if (sharedWorkspace == nil)
{
sharedWorkspace =
(NSWorkspace*)NSAllocateObject(self, 0, NSDefaultMallocZone());
}
[gnustep_global_lock unlock];
}
return sharedWorkspace;
}
//
// Instance methods
//
- (void) dealloc
{
[NSException raise: NSInvalidArgumentException
format: @"Attempt to call dealloc for shared worksapace"];
}
- (id) init
{
[NSException raise: NSInvalidArgumentException
format: @"Attempt to call init for shared worksapace"];
return nil;
}
//
// Opening Files
@ -65,8 +207,8 @@
- (BOOL)openFile:(NSString *)fullPath
fromImage:(NSImage *)anImage
at:(NSPoint)point
inView:(NSView *)aView
at:(NSPoint)point
inView:(NSView *)aView
{
return NO;
}
@ -79,7 +221,7 @@ at:(NSPoint)point
- (BOOL)openFile:(NSString *)fullPath
withApplication:(NSString *)appName
andDeactivate:(BOOL)flag
andDeactivate:(BOOL)flag
{
return NO;
}
@ -94,9 +236,9 @@ andDeactivate:(BOOL)flag
//
- (BOOL)performFileOperation:(NSString *)operation
source:(NSString *)source
destination:(NSString *)destination
files:(NSArray *)files
tag:(int *)tag
destination:(NSString *)destination
files:(NSArray *)files
tag:(int *)tag
{
return NO;
}
@ -112,22 +254,37 @@ inFileViewerRootedAtPath:(NSString *)rootFullpath
//
- (NSString *)fullPathForApplication:(NSString *)appName
{
NSString *last = [appName lastPathComponent];
if (applications == nil)
NSUpdateDynamicServices();
if ([appName isEqual: last])
{
NSString *ext = [appName pathExtension];
if (ext == nil)
{
appName = [appName stringByAppendingPathExtension: @"app"];
}
return [applications objectForKey: appName];
}
return nil;
}
- (BOOL)getFileSystemInfoForPath:(NSString *)fullPath
isRemovable:(BOOL *)removableFlag
isWritable:(BOOL *)writableFlag
isUnmountable:(BOOL *)unmountableFlag
description:(NSString **)description
type:(NSString **)fileSystemType
isWritable:(BOOL *)writableFlag
isUnmountable:(BOOL *)unmountableFlag
description:(NSString **)description
type:(NSString **)fileSystemType
{
return NO;
}
- (BOOL)getInfoForFile:(NSString *)fullPath
application:(NSString **)appName
type:(NSString **)type
type:(NSString **)type
{
return NO;
}
@ -162,7 +319,20 @@ type:(NSString **)type
// Updating Registered Services and File Types
//
- (void)findApplications
{}
{
NSData *data;
NSDictionary *newServices;
NSDictionary *dict;
system(prog_path(GNUSTEP_INSTALL_PREFIX, "/make_services"));
data = [NSData dataWithContentsOfFile: servicesPath];
newServices = [NSDeserializer deserializePropertyListFromData: data
mutableContainers: NO];
ASSIGN(allServices, newServices);
dict = [newServices objectForKey: @"Applications"];
ASSIGN(applications, dict);
}
//
// Launching and Manipulating Applications
@ -172,14 +342,59 @@ type:(NSString **)type
- (BOOL)launchApplication:(NSString *)appName
{
return NO;
return [self launchApplication: appName
showIcon: YES
autolaunch: NO];
}
- (BOOL)launchApplication:(NSString *)appName
showIcon:(BOOL)showIcon
autolaunch:(BOOL)autolaunch
autolaunch:(BOOL)autolaunch
{
return NO;
NSArray *args;
NSTask *task;
NSString *path;
NSString *file;
NSDictionary *info;
if (appName == nil)
return NO;
path = appName;
appName = [path lastPathComponent];
if ([appName isEqual: path])
{
path = [self fullPathForApplication: appName];
appName = [[path lastPathComponent] stringByDeletingPathExtension];
}
else if ([appName pathExtension] == nil)
{
path = [path stringByAppendingPathExtension: @"app"];
}
else
{
appName = [[path lastPathComponent] stringByDeletingPathExtension];
}
if (path == nil)
return NO;
file = [path stringByAppendingPathComponent: @"Resources/Info-gnustep.plist"];
info = [NSDictionary dictionaryWithContentsOfFile: file];
file = [info objectForKey: @"NSExecutable"];
if (file == nil)
{
file = appName;
}
path = [path stringByAppendingPathComponent: gnustep_target_dir];
path = [path stringByAppendingPathComponent: library_combo];
path = [path stringByAppendingPathComponent: appName];
args = [NSArray arrayWithObjects: nil];
task = [NSTask launchedTaskWithLaunchPath: path
arguments: args];
return YES;
}
//
@ -211,18 +426,22 @@ autolaunch:(BOOL)autolaunch
//
- (NSNotificationCenter *)notificationCenter
{
return nil;
return workspaceCenter;
}
//
// Tracking Changes to the User Defaults Database
//
- (void)noteUserDefaultsChanged
{}
{
userDefaultsChanged = YES;
}
- (BOOL)userDefaultsChanged
{
return NO;
BOOL hasChanged = userDefaultsChanged;
userDefaultsChanged = NO;
return hasChanged;
}
//
@ -230,7 +449,7 @@ autolaunch:(BOOL)autolaunch
//
- (void)slideImage:(NSImage *)image
from:(NSPoint)fromPoint
to:(NSPoint)toPoint
to:(NSPoint)toPoint
{}
//