]> git.lyx.org Git - lyx.git/blobdiff - src/support/linkback/LinkBackServer.m
#6961 correct the big-endian conversion of UInt32
[lyx.git] / src / support / linkback / LinkBackServer.m
index 4ca9e6bca53e90d5f692529d61c1e84c42a98371..d089fca7715b126c19f4830a111c4cff4315a12b 100644 (file)
@@ -6,30 +6,30 @@
 //  Copyright (c) 2004, Nisus Software, Inc.
 //  All rights reserved.
 
-//  Redistribution and use in source and binary forms, with or without 
+//  Redistribution and use in source and binary forms, with or without
 //  modification, are permitted provided that the following conditions are met:
 //
-//  Redistributions of source code must retain the above copyright notice, 
+//  Redistributions of source code must retain the above copyright notice,
 //  this list of conditions and the following disclaimer.
 //
-//  Redistributions in binary form must reproduce the above copyright notice, 
-//  this list of conditions and the following disclaimer in the documentation 
+//  Redistributions in binary form must reproduce the above copyright notice,
+//  this list of conditions and the following disclaimer in the documentation
 //  and/or other materials provided with the distribution.
 //
-//  Neither the name of the Nisus Software, Inc. nor the names of its 
-//  contributors may be used to endorse or promote products derived from this 
+//  Neither the name of the Nisus Software, Inc. nor the names of its
+//  contributors may be used to endorse or promote products derived from this
 //  software without specific prior written permission.
 //
-//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
-//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
+//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 //  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
-//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
-//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
-//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 //  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
@@ -50,18 +50,18 @@ NSMutableDictionary* LinkBackServers = nil ;
     static BOOL inited = NO ;
     if (inited) return ;
 
-    [super initialize] ; 
+    [super initialize] ;
     inited = YES ;
-    
+
     if (!LinkBackServers) LinkBackServers = [[NSMutableDictionary alloc] init];
 }
 
-+ (LinkBackServer*)LinkBackServerWithName:(NSString*)aName  
++ (LinkBackServer*)LinkBackServerWithName:(NSString*)aName
 {
     return [LinkBackServers objectForKey: aName] ;
 }
 
-+ (BOOL)publishServerWithName:(NSString*)aName delegate:(id<LinkBackServerDelegate>)del 
++ (BOOL)publishServerWithName:(NSString*)aName delegate:(id<LinkBackServerDelegate>)del
 {
     LinkBackServer* serv = [[LinkBackServer alloc] initWithName: aName delegate: del] ;
     BOOL ret = [serv publish] ; // retains if successful
@@ -72,20 +72,24 @@ NSMutableDictionary* LinkBackServers = nil ;
 BOOL LinkBackServerIsSupported(NSString* name, id supportedServers)
 {
        BOOL ret = NO ;
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
+       NSUInteger idx ;
+#else
        int idx ;
+#endif
        NSString* curServer = supportedServers ;
-       
+
        // NOTE: supportedServers may be nil, an NSArray, or NSString.
        if (supportedServers) {
                if ([supportedServers isKindOfClass: [NSArray class]]) {
                        idx = [supportedServers count] ;
-                       while((NO==ret) && (--idx >= 0)) {
-                               curServer = [supportedServers objectAtIndex: idx] ;
+                       while((NO==ret) && (idx > 0)) {
+                               curServer = [supportedServers objectAtIndex: --idx] ;
                                ret = [curServer isEqualToString: name] ;
                        }
-               } else ret = [curServer isEqualToString: name] ; 
+               } else ret = [curServer isEqualToString: name] ;
        }
-       
+
        return ret ;
 }
 
@@ -94,44 +98,49 @@ NSString* FindLinkBackServer(NSString* bundleIdentifier, NSString* serverName, N
        NSString* ret = nil ;
 
        NSFileManager* fm = [NSFileManager defaultManager] ;
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
        NSArray* contents = [fm contentsOfDirectoryAtPath: dir error: nil] ;
+       NSUInteger idx ;
+#else
+       NSArray* contents = [fm directoryContentsAtPath: dir] ;
        int idx ;
+#endif
 
-       NSLog(@"searching for %@ in folder: %@", serverName, dir) ;
-       
        // working info
        NSString* cpath ;
        NSBundle* cbundle ;
        NSString* cbundleIdentifier ;
        id supportedServers ;
 
+       NSLog(@"searching for %@ in folder: %@", serverName, dir) ;
+
        // resolve any symlinks, expand tildes.
        dir = [dir stringByStandardizingPath] ;
-       
+
        // find all .app bundles in the directory and test them.
        idx = (contents) ? [contents count] : 0 ;
-       while((nil==ret) && (--idx >= 0)) {
-               cpath = [contents objectAtIndex: idx] ;
-               
+       while((nil==ret) && (idx > 0)) {
+               cpath = [contents objectAtIndex: --idx] ;
+
                if ([[cpath pathExtension] isEqualToString: @"app"]) {
                        cpath = [dir stringByAppendingPathComponent: cpath] ;
                        cbundle = [NSBundle bundleWithPath: cpath] ;
                        cbundleIdentifier = [cbundle bundleIdentifier] ;
-                       
+
                        if ([cbundleIdentifier isEqualToString: bundleIdentifier]) {
                                supportedServers = [[cbundle infoDictionary] objectForKey: @"LinkBackServer"] ;
                                ret= (LinkBackServerIsSupported(serverName, supportedServers)) ? cpath : nil ;
                        }
                }
        }
-       
+
        // if the app was not found, descend into non-app dirs.  only descend 4 levels to avoid taking forever.
        if ((nil==ret) && (level<4)) {
                idx = (contents) ? [contents count] : 0 ;
-               while((nil==ret) && (--idx >= 0)) {
+               while((nil==ret) && (idx > 0)) {
                        BOOL isdir ;
-                       
-                       cpath = [contents objectAtIndex: idx] ;
+
+                       cpath = [contents objectAtIndex: --idx] ;
                        [fm fileExistsAtPath: cpath isDirectory: &isdir] ;
                        if (isdir && (![[cpath pathExtension] isEqualToString: @"app"])) {
                                cpath = [dir stringByAppendingPathComponent: cpath] ;
@@ -139,63 +148,68 @@ NSString* FindLinkBackServer(NSString* bundleIdentifier, NSString* serverName, N
                        }
                }
        }
-       
+
        return ret ;
 }
 
 void LinkBackRunAppNotFoundPanel(NSString* appName, NSURL* url)
 {
-       int result ;
-       
+
        // strings for panel
        NSBundle* b = [NSBundle bundleForClass: [LinkBack class]] ;
        NSString* title ;
        NSString* msg ;
        NSString* ok ;
        NSString* urlstr ;
-       
+
        title = NSLocalizedStringFromTableInBundle(@"_AppNotFoundTitle", @"Localized", b, @"app not found title") ;
        ok = NSLocalizedStringFromTableInBundle(@"_OK", @"Localized", b, @"ok") ;
 
        msg = (url) ? NSLocalizedStringFromTableInBundle(@"_AppNotFoundMessageWithURL", @"Localized", b, @"app not found msg") : NSLocalizedStringFromTableInBundle(@"_AppNotFoundMessageNoURL", @"Localized", b, @"app not found msg") ;
-       
+
        urlstr = (url) ? NSLocalizedStringFromTableInBundle(@"_GetApplication", @"Localized", b, @"Get application") : nil ;
 
        title = [NSString stringWithFormat: title, appName] ;
-       
-       result = NSRunCriticalAlertPanel(title, msg, ok, urlstr, nil) ;
-       if (NSAlertAlternateReturn == result) {
-               [[NSWorkspace sharedWorkspace] openURL: url] ;
-       }
+
+       NSAlert* alert = [[NSAlert alloc] init];
+       [alert setAlertStyle:NSAlertStyleCritical];
+       [alert setMessageText:title];
+       [alert setInformativeText:[NSString stringWithFormat:@"%@", msg]];
+       [alert addButtonWithTitle:ok];
+       [alert addButtonWithTitle:urlstr];
+       [alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(NSModalResponse returnCode) {
+               if (returnCode == NSAlertSecondButtonReturn)
+                               [[NSWorkspace sharedWorkspace] openURL: url] ;
+       }];
 }
 
-+ (LinkBackServer*)LinkBackServerWithName:(NSString*)aName inApplication:(NSString*)bundleIdentifier launchIfNeeded:(BOOL)flag fallbackURL:(NSURL*)url appName:(NSString*)appName ;
++ (LinkBackServer*)LinkBackServerWithName:(NSString*)aName inApplication:(NSString*)bundleIdentifier launchIfNeeded:(BOOL)flag fallbackURL:(NSURL*)url appName:(NSString*)appName
 {
        BOOL connect = YES ;
        NSString* serverName = MakeLinkBackServerName(bundleIdentifier, aName) ;
     id ret = nil ;
        NSTimeInterval tryMark ;
-       
+
        // Try to connect
        ret = [NSConnection rootProxyForConnectionWithRegisteredName: serverName host: nil] ;
-       
+
     // if launchIfNeeded, and the connection was not available, try to launch.
        if((!ret) && (flag)) {
                NSString* appPath ;
                id linkBackServers ;
-               
+
                // first, try to find the app with the bundle identifier
                appPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier: bundleIdentifier] ;
-               linkBackServers = [[[NSBundle bundleWithPath: appPath] infoDictionary] objectForKey: @"LinkBackServer"] ; 
+               linkBackServers = [[[NSBundle bundleWithPath: appPath] infoDictionary] objectForKey: @"LinkBackServer"] ;
                appPath = (LinkBackServerIsSupported(aName, linkBackServers)) ? appPath : nil ;
-               
+
                // if the found app is not supported, we will need to search for the app ourselves.
                if (nil==appPath) appPath = FindLinkBackServer(bundleIdentifier, aName, @"/Applications",0);
-               
+
                if (nil==appPath) appPath = FindLinkBackServer(bundleIdentifier, aName, @"~/Applications",0);
-               
+
                if (nil==appPath) appPath = FindLinkBackServer(bundleIdentifier, aName, @"/Network/Applications",0);
-               
+
                // if app path has been found, launch the app.
                if (appPath) {
                        [[NSWorkspace sharedWorkspace] launchApplication: appName] ;
@@ -204,15 +218,15 @@ void LinkBackRunAppNotFoundPanel(NSString* appName, NSURL* url)
                        connect = NO ;
                }
        }
-    
-    // if needed, try to connect.  
+
+    // if needed, try to connect.
        // retry connection for a while if we did not succeed at first.  This gives the app time to launch.
        if (connect && (nil==ret)) {
                tryMark = [NSDate timeIntervalSinceReferenceDate] ;
                do {
                        ret = [NSConnection rootProxyForConnectionWithRegisteredName: serverName host: nil] ;
                } while ((!ret) && (([NSDate timeIntervalSinceReferenceDate]-tryMark)<10)) ;
-               
+
        }
 
        // setup protocol and return
@@ -222,12 +236,13 @@ void LinkBackRunAppNotFoundPanel(NSString* appName, NSURL* url)
 
 - (id)initWithName:(NSString*)aName delegate:(id<LinkBackServerDelegate>)aDel
 {
-    if (self = [super init]) {
+    self = [super init];
+    if (self) {
         name = [aName copy] ;
         delegate = aDel ;
         listener = nil ;
     }
-    
+
     return self ;
 }
 
@@ -242,40 +257,40 @@ void LinkBackRunAppNotFoundPanel(NSString* appName, NSURL* url)
 {
     NSString* serverName = MakeLinkBackServerName([[NSBundle mainBundle] bundleIdentifier], name) ;
     BOOL ret = YES ;
-    
+
     // create listener and connect
     NSPort* port = [NSPort port] ;
     listener = [NSConnection connectionWithReceivePort: port sendPort:port] ;
     [listener setRootObject: self] ;
     ret = [listener registerName: serverName] ;
-    
+
     // if successful, retain connection and add self to list of servers.
     if (ret) {
         [listener retain] ;
         [LinkBackServers setObject: self forKey: name] ;
-    } else listener = nil ; // listener will dealloc on its own. 
-    
+    } else listener = nil ; // listener will dealloc on its own.
+
     return ret ;
 }
 
-- (void)retract 
+- (void)retract
 {
     if (listener) {
         [listener invalidate] ;
         [listener release] ;
         listener = nil ;
     }
-    
+
     [LinkBackServers removeObjectForKey: name] ;
 }
 
-- (LinkBack*)initiateLinkBackFromClient:(LinkBack*)clientLinkBack 
+- (LinkBack*)initiateLinkBackFromClient:(LinkBack*)clientLinkBack
 {
     LinkBack* ret = [[LinkBack alloc] initServerWithClient: clientLinkBack delegate: delegate] ;
-    
+
     // NOTE: we do not release because LinkBack will release itself when it the link closes. (caj)
-    
-    return ret ; 
+
+    return ret ;
 }
 
 @end