Merge pull request #3347 from jturcotte/shell_integration_findersync
shell_i: Add a FinderSync-based implementation #2340
|
@ -118,6 +118,10 @@ if(OWNCLOUD_5XX_NO_BLACKLIST)
|
|||
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesigh key's TeamIdentifier/Organizational Unit" )
|
||||
endif()
|
||||
|
||||
#### find libs
|
||||
#find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest QtWebkit REQUIRED )
|
||||
#if( UNIX AND NOT APPLE ) # Fdo notifications
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
#!/bin/sh -xe
|
||||
|
||||
[ "$#" -lt 2 ] && echo "Usage: sign_app.sh <app> <identity>" && exit
|
||||
[ "$#" -lt 2 ] && echo "Usage: sign_app.sh <app> <identity> <team_identifier>" && exit
|
||||
|
||||
src_app="$1"
|
||||
identity="$2"
|
||||
team_identifier="$3"
|
||||
|
||||
codesign -s "$identity" --force --verbose=4 --deep "$src_app"
|
||||
codesign -s "$identity" --force --preserve-metadata=entitlements --verbose=4 --deep "$src_app"
|
||||
|
||||
# Verify the signature
|
||||
spctl -a -t exec -vv $src_app
|
||||
codesign -dv $src_app
|
||||
|
||||
# Validate that the key used for signing the binary matches the expected TeamIdentifier
|
||||
# needed to pass the SocketApi through the sandbox
|
||||
codesign -dv $src_app 2>&1 | grep "TeamIdentifier=$team_identifier"
|
||||
exit $?
|
|
@ -5,9 +5,8 @@
|
|||
#cmakedefine WITH_QTKEYCHAIN 1
|
||||
#cmakedefine WITH_CRASHREPORTER
|
||||
#cmakedefine CRASHREPORTER_EXECUTABLE "@CRASHREPORTER_EXECUTABLE@"
|
||||
#define SOCKETAPI_TEAM_IDENTIFIER_PREFIX "@SOCKETAPI_TEAM_IDENTIFIER_PREFIX@"
|
||||
|
||||
|
||||
#cmakedefine GIT_SHA1 "@GIT_SHA1@"
|
||||
#cmakedefine APPLICATION_DOMAIN @APPLICATION_DOMAIN@
|
||||
#cmakedefine THEME_CLASS @THEME_CLASS@
|
||||
#cmakedefine THEME_INCLUDE @THEME_INCLUDE@
|
||||
|
|
|
@ -1,11 +1,28 @@
|
|||
|
||||
if(APPLE)
|
||||
add_custom_target( mac_overlayplugin ALL
|
||||
xcodebuild -workspace ${CMAKE_SOURCE_DIR}/shell_integration/MacOSX/OwnCloud.xcworkspace
|
||||
-scheme SyncStateFinder.osax SYMROOT=${CMAKE_CURRENT_BINARY_DIR} archive
|
||||
COMMENT building Mac Overlay icons)
|
||||
add_custom_target( legacy_mac_overlayplugin ALL
|
||||
xcodebuild -workspace ${CMAKE_SOURCE_DIR}/shell_integration/MacOSX/OwnCloud.xcworkspace
|
||||
-scheme SyncStateFinder.osax -configuration Release SYMROOT=${CMAKE_CURRENT_BINARY_DIR}
|
||||
OC_APPLICATION_REV_DOMAIN=${APPLICATION_REV_DOMAIN}
|
||||
OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX=${SOCKETAPI_TEAM_IDENTIFIER_PREFIX}
|
||||
COMMENT building Legacy Mac Overlay icons)
|
||||
|
||||
# The bundle identifier and application group need to have compatible values with the client
|
||||
# to be able to open a Mach port across the extension's sandbox boundary.
|
||||
# Pass the info through the xcodebuild command line and make sure that the project uses
|
||||
# those user-defined settings to build the plist.
|
||||
add_custom_target( mac_overlayplugin ALL
|
||||
xcodebuild -project ${CMAKE_SOURCE_DIR}/shell_integration/MacOSX/OwnCloudFinderSync/OwnCloudFinderSync.xcodeproj
|
||||
-target FinderSyncExt -configuration Release SYMROOT=${CMAKE_CURRENT_BINARY_DIR}
|
||||
OC_APPLICATION_NAME=${APPLICATION_NAME}
|
||||
OC_APPLICATION_REV_DOMAIN=${APPLICATION_REV_DOMAIN}
|
||||
OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX=${SOCKETAPI_TEAM_IDENTIFIER_PREFIX}
|
||||
COMMENT building Mac Overlay icons)
|
||||
|
||||
INSTALL( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Release/SyncStateFinder.osax/Contents
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/Library/ScriptingAdditions/SyncStateFinder.osax/ )
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Release/FinderSyncExt.appex
|
||||
DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Plugins
|
||||
USE_SOURCE_PERMISSIONS)
|
||||
endif(APPLE)
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:OwnCloudFinderSync/OwnCloudFinderSync.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:OwnCloudFinder/OwnCloudFinder.xcodeproj">
|
||||
</FileRef>
|
||||
|
|
|
@ -10,29 +10,29 @@
|
|||
<string>OwnCloud</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>09EE94AA-F410-4594-AB26-5A0220DEAEC7</key>
|
||||
<key>D67321A19EF879CA55BF889202BA8C23AC9AA2B5</key>
|
||||
<string>ssh://github.com/owncloud/client.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>shell_integration/MacOSX/OwnCloud.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>09EE94AA-F410-4594-AB26-5A0220DEAEC7</key>
|
||||
<key>D67321A19EF879CA55BF889202BA8C23AC9AA2B5</key>
|
||||
<string>../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>ssh://github.com/owncloud/client.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>110</integer>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>09EE94AA-F410-4594-AB26-5A0220DEAEC7</string>
|
||||
<string>D67321A19EF879CA55BF889202BA8C23AC9AA2B5</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>09EE94AA-F410-4594-AB26-5A0220DEAEC7</string>
|
||||
<string>D67321A19EF879CA55BF889202BA8C23AC9AA2B5</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>client</string>
|
||||
</dict>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface ContentManager : NSObject
|
||||
@interface OwnCloudFinderContentManager : NSObject
|
||||
{
|
||||
NSMutableDictionary* _fileNamesCache;
|
||||
NSMutableDictionary* _oldFileNamesCache;
|
||||
|
@ -31,7 +31,7 @@
|
|||
NSNumber *_icnErrSwm;
|
||||
}
|
||||
|
||||
+ (ContentManager*)sharedInstance;
|
||||
+ (OwnCloudFinderContentManager*)sharedInstance;
|
||||
|
||||
- (void)enableFileIcons:(BOOL)enable;
|
||||
- (NSNumber*)iconByPath:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
|
@ -42,6 +42,6 @@
|
|||
- (void)reFetchFileNameCacheForPath:(NSString*)path;
|
||||
- (void)repaintAllWindows;
|
||||
|
||||
- (void)loadIconResourcePath:(NSString*)path;
|
||||
- (void)loadIconResources;
|
||||
|
||||
@end
|
|
@ -20,9 +20,9 @@
|
|||
#import "RequestManager.h"
|
||||
#import "IconCache.h"
|
||||
|
||||
static ContentManager* sharedInstance = nil;
|
||||
static OwnCloudFinderContentManager* sharedInstance = nil;
|
||||
|
||||
@implementation ContentManager
|
||||
@implementation OwnCloudFinderContentManager
|
||||
- init
|
||||
{
|
||||
self = [super init];
|
||||
|
@ -33,6 +33,7 @@ static ContentManager* sharedInstance = nil;
|
|||
_oldFileNamesCache = [[NSMutableDictionary alloc] init];
|
||||
_fileIconsEnabled = TRUE;
|
||||
_hasChangedContent = TRUE;
|
||||
[self loadIconResources];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -48,7 +49,7 @@ static ContentManager* sharedInstance = nil;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (ContentManager*)sharedInstance
|
||||
+ (OwnCloudFinderContentManager*)sharedInstance
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
|
@ -61,20 +62,20 @@ static ContentManager* sharedInstance = nil;
|
|||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (void)loadIconResourcePath:(NSString*)path
|
||||
- (void)loadIconResources
|
||||
{
|
||||
NSString *base = path;
|
||||
NSBundle *extBundle = [NSBundle bundleForClass:[self class]];
|
||||
|
||||
_icnOk = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"ok.icns"]];
|
||||
_icnSync = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"sync.icns"]];
|
||||
_icnWarn = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"warning.icns"]];
|
||||
_icnErr = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"error.icns"]];
|
||||
_icnOkSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"ok_swm.icns"]];
|
||||
_icnSyncSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"sync_swm.icns"]];
|
||||
_icnWarnSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"warning_swm.icns"]];
|
||||
_icnErrSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingPathComponent:@"error_swm.icns"]];
|
||||
_icnOk = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"ok.icns"]];
|
||||
_icnSync = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"sync.icns"]];
|
||||
_icnWarn = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"warning.icns"]];
|
||||
_icnErr = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"error.icns"]];
|
||||
_icnOkSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"ok_swm.icns"]];
|
||||
_icnSyncSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"sync_swm.icns"]];
|
||||
_icnWarnSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"warning_swm.icns"]];
|
||||
_icnErrSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"error_swm.icns"]];
|
||||
|
||||
// NSLog(@"Icon ok identifier: %d from %@", [_icnOk intValue], [base stringByAppendingString:@"ok.icns"]);
|
||||
// NSLog(@"Icon ok: %@ identifier: %d from bundle %@", [extBundle imageForResource:@"ok.icns"], [_icnOk intValue], extBundle);
|
||||
}
|
||||
|
||||
- (void)enableFileIcons:(BOOL)enable
|
||||
|
@ -141,7 +142,7 @@ static ContentManager* sharedInstance = nil;
|
|||
}
|
||||
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
|
||||
|
||||
if (![[RequestManager sharedInstance] isRegisteredPath:normalizedPath isDirectory:isDir]) {
|
||||
if (![[OwnCloudFinderRequestManager sharedInstance] isRegisteredPath:normalizedPath isDirectory:isDir]) {
|
||||
return [NSNumber numberWithInt:0];
|
||||
}
|
||||
|
||||
|
@ -149,11 +150,11 @@ static ContentManager* sharedInstance = nil;
|
|||
// NSLog(@"XXXXXXX Asking for icon for path %@ = %d",normalizedPath, [result intValue]);
|
||||
|
||||
if( result == nil ) {
|
||||
// start the async call
|
||||
[[RequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
|
||||
result = [NSNumber numberWithInt:0];
|
||||
// Set 0 into the cache, meaning "don't have an icon, but already requested it"
|
||||
[_fileNamesCache setObject:result forKey:normalizedPath];
|
||||
// start the async call
|
||||
[[OwnCloudFinderRequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
|
||||
}
|
||||
if ([result intValue] == 0) {
|
||||
// Show the old state while we wait for the new one
|
||||
|
@ -222,7 +223,7 @@ static ContentManager* sharedInstance = nil;
|
|||
}
|
||||
|
||||
MenuManager* menuManager = [MenuManager sharedInstance];
|
||||
RequestManager* requestManager = [RequestManager sharedInstance];
|
||||
OwnCloudFinderRequestManager* requestManager = [OwnCloudFinderRequestManager sharedInstance];
|
||||
|
||||
if ([[window className] isEqualToString:@"TBrowserWindow"])
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ static BOOL installed = NO;
|
|||
|
||||
// NSLog(@"SyncStateFinder: installing SyncState Shell extension");
|
||||
|
||||
[RequestManager sharedInstance];
|
||||
[OwnCloudFinderRequestManager sharedInstance];
|
||||
|
||||
// Icons
|
||||
[self hookMethod:@selector(drawImage:) inClass:@"IKImageBrowserCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_IKImageBrowserCell_drawImage:)]; // 10.7 & 10.8 & 10.9 (Icon View arrange by name)
|
||||
|
@ -95,11 +95,11 @@ static BOOL installed = NO;
|
|||
|
||||
// NSLog(@"SyncStateFinder: uninstalling");
|
||||
|
||||
[[ContentManager sharedInstance] dealloc];
|
||||
[[OwnCloudFinderContentManager sharedInstance] dealloc];
|
||||
|
||||
[[IconCache sharedInstance] dealloc];
|
||||
|
||||
[[RequestManager sharedInstance] dealloc];
|
||||
[[OwnCloudFinderRequestManager sharedInstance] dealloc];
|
||||
|
||||
// Icons
|
||||
[self hookMethod:@selector(OCIconOverlayHandlers_drawImage:) inClass:@"TIconViewCell" toCallToTheNewMethod:@selector(drawImage:)]; // 10.7 & 10.8 & 10.9
|
||||
|
|
|
@ -17,13 +17,11 @@
|
|||
@interface IconCache : NSObject {
|
||||
int _currentIconId;
|
||||
NSMutableDictionary* _iconIdDictionary;
|
||||
NSMutableDictionary* _iconPathDictionary;
|
||||
}
|
||||
|
||||
+ (IconCache*)sharedInstance;
|
||||
|
||||
- (NSImage*)getIcon:(NSNumber*)iconId;
|
||||
- (NSNumber*)registerIcon:(NSString*)path;
|
||||
- (void)unregisterIcon:(NSNumber*)iconId;
|
||||
- (NSNumber*)registerIcon:(NSImage*)image;
|
||||
|
||||
@end
|
|
@ -25,7 +25,6 @@ static IconCache* sharedInstance = nil;
|
|||
if (self)
|
||||
{
|
||||
_iconIdDictionary = [[NSMutableDictionary alloc] init];
|
||||
_iconPathDictionary = [[NSMutableDictionary alloc] init];
|
||||
_currentIconId = 0;
|
||||
}
|
||||
|
||||
|
@ -35,7 +34,6 @@ static IconCache* sharedInstance = nil;
|
|||
- (void)dealloc
|
||||
{
|
||||
[_iconIdDictionary release];
|
||||
[_iconPathDictionary release];
|
||||
sharedInstance = nil;
|
||||
|
||||
[super dealloc];
|
||||
|
@ -60,57 +58,15 @@ static IconCache* sharedInstance = nil;
|
|||
return image;
|
||||
}
|
||||
|
||||
- (NSNumber*)registerIcon:(NSString*)path
|
||||
- (NSNumber*)registerIcon:(NSImage*)image
|
||||
{
|
||||
if (path == nil)
|
||||
{
|
||||
return [NSNumber numberWithInt:-1];
|
||||
}
|
||||
_currentIconId++;
|
||||
|
||||
NSImage* image = [[NSImage alloc]initWithContentsOfFile:path];
|
||||
|
||||
if (image == nil)
|
||||
{
|
||||
NSLog(@"%@ Could not load %@", NSStringFromSelector(_cmd), path);
|
||||
return [NSNumber numberWithInt:-1];
|
||||
}
|
||||
|
||||
NSNumber* iconId = [_iconPathDictionary objectForKey:path];
|
||||
|
||||
if (iconId == nil)
|
||||
{
|
||||
_currentIconId++;
|
||||
|
||||
iconId = [NSNumber numberWithInt:_currentIconId];
|
||||
|
||||
[_iconPathDictionary setObject:iconId forKey:path];
|
||||
}
|
||||
NSNumber* iconId = [NSNumber numberWithInt:_currentIconId];
|
||||
|
||||
[_iconIdDictionary setObject:image forKey:iconId];
|
||||
[image release];
|
||||
|
||||
return iconId;
|
||||
}
|
||||
|
||||
- (void)unregisterIcon:(NSNumber*)iconId
|
||||
{
|
||||
NSString* path = @"";
|
||||
|
||||
for (NSString* key in _iconPathDictionary)
|
||||
{
|
||||
NSNumber* value = [_iconPathDictionary objectForKey:key];
|
||||
|
||||
if ([value isEqualToNumber:iconId])
|
||||
{
|
||||
path = key;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[_iconPathDictionary removeObjectForKey:path];
|
||||
|
||||
[_iconIdDictionary removeObjectForKey:iconId];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
isDir = NO;
|
||||
}
|
||||
|
||||
NSNumber* imageIndex = [[ContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
NSNumber* imageIndex = [[OwnCloudFinderContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
|
||||
//NSLog(@"1 The icon index is %d", [imageIndex intValue]);
|
||||
if ([imageIndex intValue] > 0)
|
||||
|
@ -76,7 +76,7 @@
|
|||
isDir = NO;
|
||||
}
|
||||
|
||||
NSNumber* imageIndex = [[ContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
NSNumber* imageIndex = [[OwnCloudFinderContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
//NSLog(@"2 The icon index is %d %@ %@", [imageIndex intValue], [url path], isDir ? @"isDir" : @"");
|
||||
|
||||
if ([imageIndex intValue] > 0)
|
||||
|
@ -157,7 +157,7 @@
|
|||
isDir = NO;
|
||||
}
|
||||
|
||||
NSNumber* imageIndex = [[ContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
NSNumber* imageIndex = [[OwnCloudFinderContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
//NSLog(@"3 The icon index is %d", [imageIndex intValue]);
|
||||
|
||||
if ([imageIndex intValue] > 0)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SocketApiPrefix</key>
|
||||
<string>$(OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX)$(OC_APPLICATION_REV_DOMAIN)</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
|
|
@ -73,7 +73,7 @@ static MenuManager* sharedInstance = nil;
|
|||
|
||||
- (void)addItemsToMenu:(TContextMenu*)menu forFiles:(NSArray*)files
|
||||
{
|
||||
RequestManager *requestManager = [RequestManager sharedInstance];
|
||||
OwnCloudFinderRequestManager *requestManager = [OwnCloudFinderRequestManager sharedInstance];
|
||||
NSString *shareItemTitle = [requestManager shareItemTitle];
|
||||
if (!shareItemTitle || shareItemTitle.length == 0) {
|
||||
return;
|
||||
|
@ -157,7 +157,7 @@ static MenuManager* sharedInstance = nil;
|
|||
|
||||
- (void)menuItemClicked:(id)param
|
||||
{
|
||||
[[RequestManager sharedInstance] menuItemClicked:[param representedObject]];
|
||||
[[OwnCloudFinderRequestManager sharedInstance] menuItemClicked:[param representedObject]];
|
||||
}
|
||||
|
||||
- (NSArray*)pathsForNodes:(const struct TFENodeVector*)nodes
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0B13ECAE173C687400548DA1 /* GCDAsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B13ECAD173C686A00548DA1 /* GCDAsyncSocket.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
|
||||
0B13ECAF173C687900548DA1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BFC9ACB173C57E400CDD329 /* Security.framework */; };
|
||||
5BB74A8719DBF9BB001BAAAC /* FinishedIconCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BB74A8619DBF9BB001BAAAC /* FinishedIconCache.m */; };
|
||||
692C18A516660C4700BF6A53 /* ContextMenuHandlers.m in Sources */ = {isa = PBXBuildFile; fileRef = 692C18A416660C4600BF6A53 /* ContextMenuHandlers.m */; };
|
||||
|
@ -21,13 +20,20 @@
|
|||
8C99F6941622D145002D2135 /* IconCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C99F6931622D145002D2135 /* IconCache.m */; };
|
||||
8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; };
|
||||
8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; };
|
||||
C220057B1B31B04C00A4FB37 /* error_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005731B31B04C00A4FB37 /* error_swm.icns */; };
|
||||
C220057C1B31B04C00A4FB37 /* error.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005741B31B04C00A4FB37 /* error.icns */; };
|
||||
C220057D1B31B04C00A4FB37 /* ok_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005751B31B04C00A4FB37 /* ok_swm.icns */; };
|
||||
C220057E1B31B04C00A4FB37 /* ok.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005761B31B04C00A4FB37 /* ok.icns */; };
|
||||
C220057F1B31B04C00A4FB37 /* sync_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005771B31B04C00A4FB37 /* sync_swm.icns */; };
|
||||
C22005801B31B04C00A4FB37 /* sync.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005781B31B04C00A4FB37 /* sync.icns */; };
|
||||
C22005811B31B04C00A4FB37 /* warning_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005791B31B04C00A4FB37 /* warning_swm.icns */; };
|
||||
C22005821B31B04C00A4FB37 /* warning.icns in Resources */ = {isa = PBXBuildFile; fileRef = C220057A1B31B04C00A4FB37 /* warning.icns */; };
|
||||
C2B573831B1CD5AE00303B36 /* SyncClientProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573821B1CD5AE00303B36 /* SyncClientProxy.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
|
||||
0B13ECAC173C686900548DA1 /* GCDAsyncSocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCDAsyncSocket.h; sourceTree = "<group>"; };
|
||||
0B13ECAD173C686A00548DA1 /* GCDAsyncSocket.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GCDAsyncSocket.m; sourceTree = "<group>"; };
|
||||
0B2BF60B176A43DB001246CD /* Finder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Finder.h; sourceTree = "<group>"; };
|
||||
0BFC9ACB173C57E400CDD329 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
5BB74A8519DBF9BB001BAAAC /* FinishedIconCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FinishedIconCache.h; sourceTree = "<group>"; };
|
||||
|
@ -50,6 +56,16 @@
|
|||
8C99F6931622D145002D2135 /* IconCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IconCache.m; sourceTree = "<group>"; };
|
||||
8D576316048677EA00EA77CD /* SyncStateFinder.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SyncStateFinder.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C22005731B31B04C00A4FB37 /* error_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = error_swm.icns; path = ../../icons/icns/error_swm.icns; sourceTree = "<group>"; };
|
||||
C22005741B31B04C00A4FB37 /* error.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = error.icns; path = ../../icons/icns/error.icns; sourceTree = "<group>"; };
|
||||
C22005751B31B04C00A4FB37 /* ok_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ok_swm.icns; path = ../../icons/icns/ok_swm.icns; sourceTree = "<group>"; };
|
||||
C22005761B31B04C00A4FB37 /* ok.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ok.icns; path = ../../icons/icns/ok.icns; sourceTree = "<group>"; };
|
||||
C22005771B31B04C00A4FB37 /* sync_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = sync_swm.icns; path = ../../icons/icns/sync_swm.icns; sourceTree = "<group>"; };
|
||||
C22005781B31B04C00A4FB37 /* sync.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = sync.icns; path = ../../icons/icns/sync.icns; sourceTree = "<group>"; };
|
||||
C22005791B31B04C00A4FB37 /* warning_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = warning_swm.icns; path = ../../icons/icns/warning_swm.icns; sourceTree = "<group>"; };
|
||||
C220057A1B31B04C00A4FB37 /* warning.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = warning.icns; path = ../../icons/icns/warning.icns; sourceTree = "<group>"; };
|
||||
C2B573811B1CD5AE00303B36 /* SyncClientProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncClientProxy.h; sourceTree = "<group>"; };
|
||||
C2B573821B1CD5AE00303B36 /* SyncClientProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncClientProxy.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -70,6 +86,7 @@
|
|||
089C166AFE841209C02AAC07 /* SyncStateFinder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573801B1CD5AE00303B36 /* common */,
|
||||
08FB77AFFE84173DC02AAC07 /* Source */,
|
||||
089C167CFE841241C02AAC07 /* Resources */,
|
||||
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */,
|
||||
|
@ -93,6 +110,14 @@
|
|||
089C167CFE841241C02AAC07 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C22005731B31B04C00A4FB37 /* error_swm.icns */,
|
||||
C22005741B31B04C00A4FB37 /* error.icns */,
|
||||
C22005751B31B04C00A4FB37 /* ok_swm.icns */,
|
||||
C22005761B31B04C00A4FB37 /* ok.icns */,
|
||||
C22005771B31B04C00A4FB37 /* sync_swm.icns */,
|
||||
C22005781B31B04C00A4FB37 /* sync.icns */,
|
||||
C22005791B31B04C00A4FB37 /* warning_swm.icns */,
|
||||
C220057A1B31B04C00A4FB37 /* warning.icns */,
|
||||
8D576317048677EA00EA77CD /* Info.plist */,
|
||||
8D5B49A704867FD3000E48DA /* InfoPlist.strings */,
|
||||
);
|
||||
|
@ -103,7 +128,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
0B2BF60A176A43DB001246CD /* Finder */,
|
||||
0B08BAC21759627700C8351E /* GCDAsyncSocket */,
|
||||
8C37DD99161593BD00016A95 /* FinderHook.h */,
|
||||
8C37DD9A161593BD00016A95 /* FinderHook.m */,
|
||||
692C18A316660C4600BF6A53 /* ContextMenuHandlers.h */,
|
||||
|
@ -124,15 +148,6 @@
|
|||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0B08BAC21759627700C8351E /* GCDAsyncSocket */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0B13ECAC173C686900548DA1 /* GCDAsyncSocket.h */,
|
||||
0B13ECAD173C686A00548DA1 /* GCDAsyncSocket.m */,
|
||||
);
|
||||
name = GCDAsyncSocket;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0B2BF60A176A43DB001246CD /* Finder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -149,6 +164,16 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573801B1CD5AE00303B36 /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573811B1CD5AE00303B36 /* SyncClientProxy.h */,
|
||||
C2B573821B1CD5AE00303B36 /* SyncClientProxy.m */,
|
||||
);
|
||||
name = common;
|
||||
path = ../common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -178,7 +203,7 @@
|
|||
attributes = {
|
||||
LastUpgradeCheck = 0460;
|
||||
};
|
||||
buildConfigurationList = 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "SyncStateFinder" */;
|
||||
buildConfigurationList = 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "OwnCloudFinder" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
|
@ -188,7 +213,7 @@
|
|||
French,
|
||||
German,
|
||||
);
|
||||
mainGroup = 089C166AFE841209C02AAC07 /* SyncStateFinder` */;
|
||||
mainGroup = 089C166AFE841209C02AAC07 /* SyncStateFinder */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
|
@ -202,7 +227,15 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C220057E1B31B04C00A4FB37 /* ok.icns in Resources */,
|
||||
C22005821B31B04C00A4FB37 /* warning.icns in Resources */,
|
||||
C220057F1B31B04C00A4FB37 /* sync_swm.icns in Resources */,
|
||||
C220057C1B31B04C00A4FB37 /* error.icns in Resources */,
|
||||
8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */,
|
||||
C22005801B31B04C00A4FB37 /* sync.icns in Resources */,
|
||||
C220057D1B31B04C00A4FB37 /* ok_swm.icns in Resources */,
|
||||
C220057B1B31B04C00A4FB37 /* error_swm.icns in Resources */,
|
||||
C22005811B31B04C00A4FB37 /* warning_swm.icns in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -213,10 +246,10 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0B13ECAE173C687400548DA1 /* GCDAsyncSocket.m in Sources */,
|
||||
8C37DD9F161593BD00016A95 /* FinderHook.m in Sources */,
|
||||
8C99F6941622D145002D2135 /* IconCache.m in Sources */,
|
||||
69948B361636D50E0093B6CE /* ContentManager.m in Sources */,
|
||||
C2B573831B1CD5AE00303B36 /* SyncClientProxy.m in Sources */,
|
||||
6993878616494C000044E4DF /* RequestManager.m in Sources */,
|
||||
5BB74A8719DBF9BB001BAAAC /* FinishedIconCache.m in Sources */,
|
||||
692C18A516660C4700BF6A53 /* ContextMenuHandlers.m in Sources */,
|
||||
|
@ -252,6 +285,8 @@
|
|||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "$(HOME)/Library/Bundles";
|
||||
OC_APPLICATION_REV_DOMAIN = com.owncloud.desktopclient;
|
||||
OC_TEAM_IDENTIFIER_PREFIX = "";
|
||||
PRODUCT_NAME = SyncStateFinder;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
|
@ -269,6 +304,8 @@
|
|||
GCC_MODEL_TUNING = G5;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "$(HOME)/Library/Bundles";
|
||||
OC_APPLICATION_REV_DOMAIN = com.owncloud.desktopclient;
|
||||
OC_TEAM_IDENTIFIER_PREFIX = "";
|
||||
PRODUCT_NAME = SyncStateFinder;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
|
@ -317,7 +354,7 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "SyncStateFinder" */ = {
|
||||
1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "OwnCloudFinder" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB911F08733D790010E9CD /* Debug */,
|
||||
|
|
|
@ -13,31 +13,27 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "GCDAsyncSocket.h"
|
||||
#import "RequestManager.h"
|
||||
#import "SyncClientProxy.h"
|
||||
|
||||
@interface RequestManager : NSObject
|
||||
@interface OwnCloudFinderRequestManager : NSObject <SyncClientProxyDelegate>
|
||||
{
|
||||
GCDAsyncSocket* _socket;
|
||||
SyncClientProxy *_syncClientProxy;
|
||||
|
||||
NSMutableArray* _requestQueue;
|
||||
NSMutableDictionary* _registeredPathes;
|
||||
NSMutableSet* _requestedPaths;
|
||||
|
||||
NSString *_shareMenuTitle;
|
||||
|
||||
BOOL _isConnected;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSString* filterFolder;
|
||||
|
||||
+ (RequestManager*)sharedInstance;
|
||||
+ (OwnCloudFinderRequestManager*)sharedInstance;
|
||||
|
||||
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)askOnSocket:(NSString*)path query:(NSString*)verb;
|
||||
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)menuItemClicked:(NSDictionary*)actionDictionary;
|
||||
- (void)start;
|
||||
|
||||
- (NSString*) shareItemTitle;
|
||||
|
||||
|
|
|
@ -16,26 +16,32 @@
|
|||
#import "IconCache.h"
|
||||
#import "RequestManager.h"
|
||||
|
||||
#define READ_TAG 2422
|
||||
static OwnCloudFinderRequestManager* sharedInstance = nil;
|
||||
|
||||
static RequestManager* sharedInstance = nil;
|
||||
|
||||
@implementation RequestManager
|
||||
@implementation OwnCloudFinderRequestManager
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
|
||||
// For the sake of allowing both the legacy and the FinderSync extensions to work with the same
|
||||
// client build, use the same server name including the Team ID even though we won't be sandboxed.
|
||||
NSBundle *extBundle = [NSBundle bundleForClass:[self class]];
|
||||
// This was added to the bundle's Info.plist to get it from the build system
|
||||
NSString *socketApiPrefix = [extBundle objectForInfoDictionaryKey:@"SocketApiPrefix"];
|
||||
NSString *serverName = [socketApiPrefix stringByAppendingString:@".socketApi"];
|
||||
// NSLog(@"OwnCloudFinderRequestManager serverName %@", serverName);
|
||||
|
||||
_isConnected = NO;
|
||||
_syncClientProxy = [[SyncClientProxy alloc] initWithDelegate:self serverName:serverName];
|
||||
|
||||
_registeredPathes = [[NSMutableDictionary alloc] init];
|
||||
_requestedPaths = [[NSMutableSet alloc] init];
|
||||
|
||||
_shareMenuTitle = nil;
|
||||
|
||||
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(start) userInfo:nil repeats:YES];
|
||||
// The NSConnection will block until the distant object came back and this creates a loop hanging Finder.
|
||||
// Start from a timer to have time to unwind the stack first.
|
||||
[NSTimer scheduledTimerWithTimeInterval:0 target:_syncClientProxy selector:@selector(start) userInfo:nil repeats:NO];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -43,16 +49,14 @@ static RequestManager* sharedInstance = nil;
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_socket setDelegate:nil delegateQueue:NULL];
|
||||
[_socket disconnect];
|
||||
[_socket release];
|
||||
[_syncClientProxy release];
|
||||
|
||||
sharedInstance = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (RequestManager*)sharedInstance
|
||||
+ (OwnCloudFinderRequestManager*)sharedInstance
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
|
@ -65,20 +69,6 @@ static RequestManager* sharedInstance = nil;
|
|||
return sharedInstance;
|
||||
}
|
||||
|
||||
|
||||
- (void)askOnSocket:(NSString*)path query:(NSString*)verb
|
||||
{
|
||||
NSString *query = [NSString stringWithFormat:@"%@:%@\n", verb,path];
|
||||
// NSLog(@"Query: %@", query);
|
||||
|
||||
NSData* data = [query dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[_socket writeData:data withTimeout:5 tag:4711];
|
||||
|
||||
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[_socket readDataToData:stop withTimeout:-1 tag:READ_TAG];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir
|
||||
{
|
||||
// check if the file in question is underneath a registered directory
|
||||
|
@ -104,215 +94,71 @@ static RequestManager* sharedInstance = nil;
|
|||
|
||||
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
|
||||
{
|
||||
NSString *verb = @"RETRIEVE_FILE_STATUS";
|
||||
|
||||
if( [self isRegisteredPath:path isDirectory:isDir] ) {
|
||||
[_requestedPaths addObject:path];
|
||||
if( _isConnected ) {
|
||||
if(isDir) {
|
||||
verb = @"RETRIEVE_FOLDER_STATUS";
|
||||
}
|
||||
|
||||
[self askOnSocket:path query:verb];
|
||||
} else {
|
||||
[_requestQueue addObject:path];
|
||||
[self start]; // try again to connect
|
||||
}
|
||||
[_syncClientProxy askForIcon:path isDirectory:isDir];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)socket:(GCDAsyncSocket*)socket didReadData:(NSData*)data withTag:(long)tag
|
||||
- (void)setResultForPath:(NSString*)path result:(NSString*)result
|
||||
{
|
||||
NSString *answer = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
NSArray *chunks = nil;
|
||||
if (answer != nil && [answer length] > 0) {
|
||||
// cut a trailing newline
|
||||
answer = [answer substringToIndex:[answer length] - 1];
|
||||
chunks = [answer componentsSeparatedByString: @":"];
|
||||
// The client will broadcast all changes, do not fill the cache for paths that Finder didn't ask for.
|
||||
if ([_requestedPaths containsObject:path]) {
|
||||
[[OwnCloudFinderContentManager sharedInstance] setResultForPath:path result:result];
|
||||
}
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
|
||||
if( chunks && [chunks count] > 0 && tag == READ_TAG ) {
|
||||
// NSLog(@"READ from socket (%ld): <%@>", tag, answer);
|
||||
if( [[chunks objectAtIndex:0] isEqualToString:@"STATUS"] ) {
|
||||
NSString *path = [chunks objectAtIndex:2];
|
||||
if( [chunks count] > 3 ) {
|
||||
for( int i = 2; i < [chunks count]-1; i++ ) {
|
||||
path = [NSString stringWithFormat:@"%@:%@",
|
||||
path, [chunks objectAtIndex:i+1] ];
|
||||
}
|
||||
}
|
||||
// The client will broadcast all changes, do not fill the cache for paths that Finder didn't ask for.
|
||||
if ([_requestedPaths containsObject:path]) {
|
||||
[contentman setResultForPath:path result:[chunks objectAtIndex:1]];
|
||||
}
|
||||
} else if( [[chunks objectAtIndex:0] isEqualToString:@"UPDATE_VIEW"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_requestedPaths removeAllObjects];
|
||||
[contentman reFetchFileNameCacheForPath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
|
||||
NSNumber *one = [NSNumber numberWithInt:1];
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
// NSLog(@"Registering path: %@", path);
|
||||
[_registeredPathes setObject:one forKey:path];
|
||||
|
||||
[contentman repaintAllWindows];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"UNREGISTER_PATH"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_registeredPathes removeObjectForKey:path];
|
||||
|
||||
[contentman repaintAllWindows];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"ICON_PATH"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[[ContentManager sharedInstance] loadIconResourcePath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"SHARE_MENU_TITLE"] ) {
|
||||
_shareMenuTitle = [[chunks objectAtIndex:1] copy];
|
||||
// NSLog(@"Received shar menu title: %@", _shareMenuTitle);
|
||||
} else {
|
||||
NSLog(@"SyncState: Unknown command %@", [chunks objectAtIndex:0]);
|
||||
}
|
||||
} else if (tag != READ_TAG) {
|
||||
NSLog(@"SyncState: Received unknown tag %ld <%@>", tag, answer);
|
||||
}
|
||||
// Read on and on
|
||||
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[_socket readDataToData:stop withTimeout:-1 tag:READ_TAG];
|
||||
|
||||
}
|
||||
|
||||
- (NSTimeInterval)socket:(GCDAsyncSocket*)socket shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path
|
||||
{
|
||||
// Called if a read operation has reached its timeout without completing.
|
||||
return 0.0;
|
||||
[_requestedPaths removeAllObjects];
|
||||
[[OwnCloudFinderContentManager sharedInstance] reFetchFileNameCacheForPath:path];
|
||||
}
|
||||
|
||||
-(void)socket:(GCDAsyncSocket*)socket didConnectToUrl:(NSURL *)url {
|
||||
// NSLog( @"Connected to sync client successfully on %@", url);
|
||||
_isConnected = YES;
|
||||
|
||||
[self askOnSocket:@"" query:@"SHARE_MENU_TITLE"];
|
||||
|
||||
if( [_requestQueue count] > 0 ) {
|
||||
// NSLog( @"We have to empty the queue");
|
||||
for( NSString *path in _requestQueue ) {
|
||||
[self askOnSocket:path query:@"RETRIEVE_FILE_STATUS"];
|
||||
}
|
||||
[_requestQueue removeAllObjects];
|
||||
}
|
||||
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
[contentman clearFileNameCache];
|
||||
[contentman repaintAllWindows];
|
||||
|
||||
// Read for the UPDATE_VIEW requests
|
||||
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[_socket readDataToData:stop withTimeout:-1 tag:READ_TAG];
|
||||
- (void)registerPath:(NSString*)path
|
||||
{
|
||||
NSNumber *one = [NSNumber numberWithInt:1];
|
||||
[_registeredPathes setObject:one forKey:path];
|
||||
[[OwnCloudFinderContentManager sharedInstance] repaintAllWindows];
|
||||
}
|
||||
|
||||
- (void)socketDidDisconnect:(GCDAsyncSocket*)socket withError:(NSError*)err
|
||||
- (void)unregisterPath:(NSString*)path
|
||||
{
|
||||
[_registeredPathes removeObjectForKey:path];
|
||||
[[OwnCloudFinderContentManager sharedInstance] repaintAllWindows];
|
||||
}
|
||||
|
||||
- (void)setShareMenuTitle:(NSString*)title
|
||||
{
|
||||
_shareMenuTitle = title;
|
||||
}
|
||||
|
||||
- (void)connectionDidDie
|
||||
{
|
||||
// NSLog(@"Socket DISconnected! %@", [err localizedDescription]);
|
||||
|
||||
_isConnected = NO;
|
||||
|
||||
// clear the registered pathes.
|
||||
[_registeredPathes release];
|
||||
_registeredPathes = [[NSMutableDictionary alloc] init];
|
||||
[_requestedPaths removeAllObjects];
|
||||
|
||||
// clear the caches in conent manager
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
OwnCloudFinderContentManager *contentman = [OwnCloudFinderContentManager sharedInstance];
|
||||
[contentman clearFileNameCache];
|
||||
[contentman repaintAllWindows];
|
||||
}
|
||||
|
||||
- (NSDate*)fileDate:(NSString*)fn
|
||||
{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error = 0;
|
||||
NSDictionary *oneAttributes = [fileManager attributesOfItemAtPath:fn error:&error];
|
||||
if (!error) {
|
||||
return [oneAttributes valueForKey:NSFileModificationDate];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString*) getNewerFileOne:(NSString*)one two:(NSString*)two
|
||||
{
|
||||
if (!one) {
|
||||
return two;
|
||||
}
|
||||
NSDate *oneDate = [self fileDate:one];
|
||||
NSDate *twoDate = [self fileDate:two];
|
||||
if (oneDate && twoDate) {
|
||||
if ([oneDate compare:twoDate] == NSOrderedDescending) {
|
||||
return one;
|
||||
} else if ([oneDate compare:twoDate] == NSOrderedAscending) {
|
||||
return two;
|
||||
} else {
|
||||
return two;
|
||||
}
|
||||
}
|
||||
return one;
|
||||
}
|
||||
|
||||
|
||||
- (void)start
|
||||
{
|
||||
if (!_isConnected && ![_socket isConnected])
|
||||
{
|
||||
NSError *err = nil;
|
||||
NSURL *url = nil;
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count])
|
||||
{
|
||||
// e.g file:///Users/guruz/Library/Caches/SyncStateHelper/ownCloud.socket
|
||||
NSString *syncStateHelperDir = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SyncStateHelper"];
|
||||
NSError *pnsError = NULL;
|
||||
NSArray *paths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:syncStateHelperDir error:&pnsError];
|
||||
if (!pnsError && paths && [paths count] > 0) {
|
||||
NSString *currentLatestPath = nil;
|
||||
if (paths.count > 1) {
|
||||
// NSLog(@"Possible paths: %@", paths);
|
||||
}
|
||||
for (int i = 0; i < paths.count; i++) {
|
||||
NSString *currentPath = [syncStateHelperDir stringByAppendingPathComponent:[paths objectAtIndex:i]];
|
||||
if (![currentPath hasSuffix:@".socket"]) {
|
||||
continue;
|
||||
}
|
||||
currentLatestPath = [self getNewerFileOne:currentLatestPath two:currentPath];
|
||||
}
|
||||
// FIXME Instead of connecting to the newest socket we could go multi-socket to support multiple instances
|
||||
if (currentLatestPath) {
|
||||
url = [NSURL fileURLWithPath:currentLatestPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (url) {
|
||||
// NSLog(@"Connect Socket to %@", url);
|
||||
[_socket connectToUrl:url withTimeout:1 error:&err];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)menuItemClicked:(NSDictionary*)actionDictionary
|
||||
{
|
||||
// NSLog(@"RequestManager menuItemClicked %@", actionDictionary);
|
||||
NSArray *filePaths = [actionDictionary valueForKey:@"files"];
|
||||
for (int i = 0; i < filePaths.count; i++) {
|
||||
[self askOnSocket:[filePaths objectAtIndex:i] query:@"SHARE"];
|
||||
[_syncClientProxy askOnSocket:[filePaths objectAtIndex:i] query:@"SHARE"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString*) shareItemTitle
|
||||
{
|
||||
if (_socket && _socket.isConnected && _shareMenuTitle) {
|
||||
return _shareMenuTitle;
|
||||
}
|
||||
return nil;
|
||||
return _shareMenuTitle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) by Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <FinderSync/FinderSync.h>
|
||||
#import "SyncClientProxy.h"
|
||||
|
||||
@interface FinderSync : FIFinderSync <SyncClientProxyDelegate>
|
||||
{
|
||||
SyncClientProxy *_syncClientProxy;
|
||||
NSMutableSet *_registeredDirectories;
|
||||
NSMutableSet *_requestedUrls;
|
||||
NSString *_shareMenuTitle;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (C) by Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#import "FinderSync.h"
|
||||
|
||||
|
||||
@implementation FinderSync
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
FIFinderSyncController *syncController = [FIFinderSyncController defaultController];
|
||||
NSBundle *extBundle = [NSBundle bundleForClass:[self class]];
|
||||
// This was added to the bundle's Info.plist to get it from the build system
|
||||
NSString *socketApiPrefix = [extBundle objectForInfoDictionaryKey:@"SocketApiPrefix"];
|
||||
|
||||
NSImage *ok = [extBundle imageForResource:@"ok.icns"];
|
||||
NSImage *ok_swm = [extBundle imageForResource:@"ok_swm.icns"];
|
||||
NSImage *sync = [extBundle imageForResource:@"sync.icns"];
|
||||
NSImage *warning = [extBundle imageForResource:@"warning.icns"];
|
||||
NSImage *error = [extBundle imageForResource:@"error.icns"];
|
||||
|
||||
[syncController setBadgeImage:ok label:@"Up to date" forBadgeIdentifier:@"OK"];
|
||||
[syncController setBadgeImage:sync label:@"Synchronizing" forBadgeIdentifier:@"SYNC"];
|
||||
[syncController setBadgeImage:sync label:@"Synchronizing" forBadgeIdentifier:@"NEW"];
|
||||
[syncController setBadgeImage:warning label:@"Ignored" forBadgeIdentifier:@"IGNORE"];
|
||||
[syncController setBadgeImage:error label:@"Error" forBadgeIdentifier:@"ERROR"];
|
||||
[syncController setBadgeImage:ok_swm label:@"Shared" forBadgeIdentifier:@"OK+SWM"];
|
||||
[syncController setBadgeImage:sync label:@"Synchronizing" forBadgeIdentifier:@"SYNC+SWM"];
|
||||
[syncController setBadgeImage:sync label:@"Synchronizing" forBadgeIdentifier:@"NEW+SWM"];
|
||||
[syncController setBadgeImage:warning label:@"Ignored" forBadgeIdentifier:@"IGNORE+SWM"];
|
||||
[syncController setBadgeImage:error label:@"Error" forBadgeIdentifier:@"ERROR+SWM"];
|
||||
|
||||
// The Mach port name needs to:
|
||||
// - Be prefixed with the code signing Team ID
|
||||
// - Then infixed with the sandbox App Group
|
||||
// - The App Group itself must be a prefix of (or equal to) the application bundle identifier
|
||||
// We end up in the official signed client with: 9B5WD74GWJ.com.owncloud.desktopclient.socketApi
|
||||
// With ad-hoc signing (the '-' signing identity) we must drop the Team ID.
|
||||
// When the code isn't sandboxed (e.g. the OC client or the legacy overlay icon extension)
|
||||
// the OS doesn't seem to put any restriction on the port name, so we just follow what
|
||||
// the sandboxed App Extension needs.
|
||||
// https://developer.apple.com/library/mac/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW24
|
||||
NSString *serverName = [socketApiPrefix stringByAppendingString:@".socketApi"];
|
||||
// NSLog(@"FinderSync serverName %@", serverName);
|
||||
|
||||
_syncClientProxy = [[SyncClientProxy alloc] initWithDelegate:self serverName:serverName];
|
||||
_registeredDirectories = [[NSMutableSet alloc] init];
|
||||
_requestedUrls = [[NSMutableSet alloc] init];
|
||||
_shareMenuTitle = nil;
|
||||
|
||||
[_syncClientProxy start];
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Primary Finder Sync protocol methods
|
||||
|
||||
- (void)endObservingDirectoryAtURL:(NSURL *)url
|
||||
{
|
||||
// The user is no longer seeing the container's contents.
|
||||
// At this point we know that the status of any file as a direct child of url.filePathURL
|
||||
// won't be displayed. Filter our _requestedUrls to get rid of them.
|
||||
NSString *observedDirectoryPath = [url.filePathURL path];
|
||||
[_requestedUrls filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
||||
NSURL *requestedUrl = (NSURL *)evaluatedObject;
|
||||
NSString *parentDir = [[requestedUrl path] stringByDeletingLastPathComponent];
|
||||
return [parentDir isEqualToString:observedDirectoryPath];
|
||||
}]];
|
||||
}
|
||||
|
||||
- (void)requestBadgeIdentifierForURL:(NSURL *)url
|
||||
{
|
||||
[_requestedUrls addObject:url.filePathURL];
|
||||
|
||||
BOOL isDir;
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory: &isDir] == NO) {
|
||||
NSLog(@"ERROR: Could not determine file type of %@", [url path]);
|
||||
isDir = NO;
|
||||
}
|
||||
|
||||
NSString* normalizedPath = [[url path] decomposedStringWithCanonicalMapping];
|
||||
[_syncClientProxy askForIcon:normalizedPath isDirectory:isDir];
|
||||
}
|
||||
|
||||
#pragma mark - Menu and toolbar item support
|
||||
|
||||
- (NSMenu *)menuForMenuKind:(FIMenuKind)whichMenu
|
||||
{
|
||||
if (_shareMenuTitle) {
|
||||
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
|
||||
[menu addItemWithTitle:_shareMenuTitle action:@selector(shareMenuAction:) keyEquivalent:@"title"];
|
||||
|
||||
return menu;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (IBAction)shareMenuAction:(id)sender
|
||||
{
|
||||
NSArray* items = [[FIFinderSyncController defaultController] selectedItemURLs];
|
||||
|
||||
[items enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
|
||||
NSString* normalizedPath = [[obj path] decomposedStringWithCanonicalMapping];
|
||||
[_syncClientProxy askOnSocket:normalizedPath query:@"SHARE"];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - SyncClientProxyDelegate implementation
|
||||
|
||||
- (void)setResultForPath:(NSString*)path result:(NSString*)result
|
||||
{
|
||||
NSString *normalizedPath = [path decomposedStringWithCanonicalMapping];
|
||||
[[FIFinderSyncController defaultController] setBadgeIdentifier:result forURL:[NSURL fileURLWithPath:normalizedPath]];
|
||||
}
|
||||
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path
|
||||
{
|
||||
// This shouldn't be necessary, and will be a problem when we
|
||||
// filter values of _requestedUrls even though Finder might still
|
||||
// have an old status in its cache (and therefore won't re-request it)
|
||||
// but will do OK until we get the socket API to re-push the status of everything needed.
|
||||
[_requestedUrls enumerateObjectsUsingBlock: ^(id url, BOOL *stop) {
|
||||
if ([[url path] hasPrefix:path])
|
||||
[self requestBadgeIdentifierForURL: url];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)registerPath:(NSString*)path
|
||||
{
|
||||
assert(_registeredDirectories);
|
||||
[_registeredDirectories addObject:[NSURL fileURLWithPath:path]];
|
||||
[FIFinderSyncController defaultController].directoryURLs = _registeredDirectories;
|
||||
}
|
||||
|
||||
- (void)unregisterPath:(NSString*)path
|
||||
{
|
||||
[_registeredDirectories removeObject:[NSURL fileURLWithPath:path]];
|
||||
[FIFinderSyncController defaultController].directoryURLs = _registeredDirectories;
|
||||
}
|
||||
|
||||
- (void)setShareMenuTitle:(NSString*)title
|
||||
{
|
||||
_shareMenuTitle = title;
|
||||
}
|
||||
|
||||
- (void)connectionDidDie
|
||||
{
|
||||
_shareMenuTitle = nil;
|
||||
|
||||
// This will tell Finder that this extension isn't attached to any directory
|
||||
// until we can reconnect to the sync client.
|
||||
[_registeredDirectories removeAllObjects];
|
||||
[FIFinderSyncController defaultController].directoryURLs = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>$(OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX)$(OC_APPLICATION_REV_DOMAIN)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SocketApiPrefix</key>
|
||||
<string>$(OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX)$(OC_APPLICATION_REV_DOMAIN)</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>$(OC_APPLICATION_NAME) Extensions</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(OC_APPLICATION_REV_DOMAIN).$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict/>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.FinderSync</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>FinderSync</string>
|
||||
</dict>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,520 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
C2B573BA1B1CD91E00303B36 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573B91B1CD91E00303B36 /* main.m */; };
|
||||
C2B573D21B1CD94B00303B36 /* main.m in Resources */ = {isa = PBXBuildFile; fileRef = C2B573B91B1CD91E00303B36 /* main.m */; };
|
||||
C2B573DE1B1CD9CE00303B36 /* FinderSync.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573DD1B1CD9CE00303B36 /* FinderSync.m */; };
|
||||
C2B573E21B1CD9CE00303B36 /* FinderSyncExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = C2B573D71B1CD9CE00303B36 /* FinderSyncExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
C2B573E91B1DA1FB00303B36 /* SyncClientProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573E81B1DA1FB00303B36 /* SyncClientProxy.m */; };
|
||||
C2B573F31B1DAD6400303B36 /* error.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573EB1B1DAD6400303B36 /* error.iconset */; };
|
||||
C2B573F41B1DAD6400303B36 /* ok_swm.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573EC1B1DAD6400303B36 /* ok_swm.iconset */; };
|
||||
C2B573F51B1DAD6400303B36 /* ok.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573ED1B1DAD6400303B36 /* ok.iconset */; };
|
||||
C2B573F71B1DAD6400303B36 /* sync.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573EF1B1DAD6400303B36 /* sync.iconset */; };
|
||||
C2B573F91B1DAD6400303B36 /* warning.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573F11B1DAD6400303B36 /* warning.iconset */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
C2B573DF1B1CD9CE00303B36 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = C2B573951B1CD88000303B36 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = C2B573D61B1CD9CE00303B36;
|
||||
remoteInfo = FinderSyncExt;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
C2B573E11B1CD9CE00303B36 /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
C2B573E21B1CD9CE00303B36 /* FinderSyncExt.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
C2B573B11B1CD91E00303B36 /* desktopclient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = desktopclient.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C2B573B51B1CD91E00303B36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C2B573B91B1CD91E00303B36 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
C2B573D71B1CD9CE00303B36 /* FinderSyncExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FinderSyncExt.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C2B573DA1B1CD9CE00303B36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C2B573DB1B1CD9CE00303B36 /* FinderSyncExt.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = FinderSyncExt.entitlements; sourceTree = "<group>"; };
|
||||
C2B573DC1B1CD9CE00303B36 /* FinderSync.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FinderSync.h; sourceTree = "<group>"; };
|
||||
C2B573DD1B1CD9CE00303B36 /* FinderSync.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FinderSync.m; sourceTree = "<group>"; };
|
||||
C2B573E71B1DA1FB00303B36 /* SyncClientProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncClientProxy.h; sourceTree = "<group>"; };
|
||||
C2B573E81B1DA1FB00303B36 /* SyncClientProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncClientProxy.m; sourceTree = "<group>"; };
|
||||
C2B573EB1B1DAD6400303B36 /* error.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = error.iconset; path = ../../icons/nopadding/error.iconset; sourceTree = SOURCE_ROOT; };
|
||||
C2B573EC1B1DAD6400303B36 /* ok_swm.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = ok_swm.iconset; path = ../../icons/nopadding/ok_swm.iconset; sourceTree = SOURCE_ROOT; };
|
||||
C2B573ED1B1DAD6400303B36 /* ok.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = ok.iconset; path = ../../icons/nopadding/ok.iconset; sourceTree = SOURCE_ROOT; };
|
||||
C2B573EF1B1DAD6400303B36 /* sync.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = sync.iconset; path = ../../icons/nopadding/sync.iconset; sourceTree = SOURCE_ROOT; };
|
||||
C2B573F11B1DAD6400303B36 /* warning.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = warning.iconset; path = ../../icons/nopadding/warning.iconset; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
C2B573AE1B1CD91E00303B36 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
C2B573D41B1CD9CE00303B36 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
C2B573941B1CD88000303B36 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573E61B1DA1FB00303B36 /* common */,
|
||||
C2B573B31B1CD91E00303B36 /* desktopclient */,
|
||||
C2B573D81B1CD9CE00303B36 /* FinderSyncExt */,
|
||||
C2B573B21B1CD91E00303B36 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573B21B1CD91E00303B36 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573B11B1CD91E00303B36 /* desktopclient.app */,
|
||||
C2B573D71B1CD9CE00303B36 /* FinderSyncExt.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573B31B1CD91E00303B36 /* desktopclient */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573B41B1CD91E00303B36 /* Supporting Files */,
|
||||
);
|
||||
path = desktopclient;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573B41B1CD91E00303B36 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573B51B1CD91E00303B36 /* Info.plist */,
|
||||
C2B573B91B1CD91E00303B36 /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573D81B1CD9CE00303B36 /* FinderSyncExt */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573DC1B1CD9CE00303B36 /* FinderSync.h */,
|
||||
C2B573DD1B1CD9CE00303B36 /* FinderSync.m */,
|
||||
C2B573D91B1CD9CE00303B36 /* Supporting Files */,
|
||||
);
|
||||
path = FinderSyncExt;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573D91B1CD9CE00303B36 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573EB1B1DAD6400303B36 /* error.iconset */,
|
||||
C2B573EC1B1DAD6400303B36 /* ok_swm.iconset */,
|
||||
C2B573ED1B1DAD6400303B36 /* ok.iconset */,
|
||||
C2B573EF1B1DAD6400303B36 /* sync.iconset */,
|
||||
C2B573F11B1DAD6400303B36 /* warning.iconset */,
|
||||
C2B573DA1B1CD9CE00303B36 /* Info.plist */,
|
||||
C2B573DB1B1CD9CE00303B36 /* FinderSyncExt.entitlements */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C2B573E61B1DA1FB00303B36 /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C2B573E71B1DA1FB00303B36 /* SyncClientProxy.h */,
|
||||
C2B573E81B1DA1FB00303B36 /* SyncClientProxy.m */,
|
||||
);
|
||||
name = common;
|
||||
path = ../common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
C2B573B01B1CD91E00303B36 /* desktopclient */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C2B573CC1B1CD91E00303B36 /* Build configuration list for PBXNativeTarget "desktopclient" */;
|
||||
buildPhases = (
|
||||
C2B573AD1B1CD91E00303B36 /* Sources */,
|
||||
C2B573AE1B1CD91E00303B36 /* Frameworks */,
|
||||
C2B573AF1B1CD91E00303B36 /* Resources */,
|
||||
C2B573E11B1CD9CE00303B36 /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
C2B573E01B1CD9CE00303B36 /* PBXTargetDependency */,
|
||||
);
|
||||
name = desktopclient;
|
||||
productName = desktopclient;
|
||||
productReference = C2B573B11B1CD91E00303B36 /* desktopclient.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
C2B573D61B1CD9CE00303B36 /* FinderSyncExt */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = C2B573E31B1CD9CE00303B36 /* Build configuration list for PBXNativeTarget "FinderSyncExt" */;
|
||||
buildPhases = (
|
||||
C2B573D31B1CD9CE00303B36 /* Sources */,
|
||||
C2B573D41B1CD9CE00303B36 /* Frameworks */,
|
||||
C2B573D51B1CD9CE00303B36 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = FinderSyncExt;
|
||||
productName = FinderSyncExt;
|
||||
productReference = C2B573D71B1CD9CE00303B36 /* FinderSyncExt.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
C2B573951B1CD88000303B36 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0630;
|
||||
TargetAttributes = {
|
||||
C2B573B01B1CD91E00303B36 = {
|
||||
CreatedOnToolsVersion = 6.3.1;
|
||||
DevelopmentTeam = 9B5WD74GWJ;
|
||||
};
|
||||
C2B573D61B1CD9CE00303B36 = {
|
||||
CreatedOnToolsVersion = 6.3.1;
|
||||
DevelopmentTeam = 9B5WD74GWJ;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.Mac = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = C2B573981B1CD88000303B36 /* Build configuration list for PBXProject "OwnCloudFinderSync" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = C2B573941B1CD88000303B36;
|
||||
productRefGroup = C2B573B21B1CD91E00303B36 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
C2B573B01B1CD91E00303B36 /* desktopclient */,
|
||||
C2B573D61B1CD9CE00303B36 /* FinderSyncExt */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
C2B573AF1B1CD91E00303B36 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C2B573D21B1CD94B00303B36 /* main.m in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
C2B573D51B1CD9CE00303B36 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C2B573F91B1DAD6400303B36 /* warning.iconset in Resources */,
|
||||
C2B573F31B1DAD6400303B36 /* error.iconset in Resources */,
|
||||
C2B573F71B1DAD6400303B36 /* sync.iconset in Resources */,
|
||||
C2B573F41B1DAD6400303B36 /* ok_swm.iconset in Resources */,
|
||||
C2B573F51B1DAD6400303B36 /* ok.iconset in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
C2B573AD1B1CD91E00303B36 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C2B573BA1B1CD91E00303B36 /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
C2B573D31B1CD9CE00303B36 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C2B573E91B1DA1FB00303B36 /* SyncClientProxy.m in Sources */,
|
||||
C2B573DE1B1CD9CE00303B36 /* FinderSync.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
C2B573E01B1CD9CE00303B36 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = C2B573D61B1CD9CE00303B36 /* FinderSyncExt */;
|
||||
targetProxy = C2B573DF1B1CD9CE00303B36 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
C2B573991B1CD88000303B36 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C2B5739A1B1CD88000303B36 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C2B573CD1B1CD91E00303B36 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = desktopclient/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C2B573CE1B1CD91E00303B36 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = desktopclient/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C2B573E41B1CD9CE00303B36 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = FinderSyncExt/FinderSyncExt.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = FinderSyncExt/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
OC_APPLICATION_NAME = ownCloud;
|
||||
OC_APPLICATION_REV_DOMAIN = com.owncloud.desktopclient;
|
||||
OC_TEAM_IDENTIFIER_PREFIX = "";
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C2B573E51B1CD9CE00303B36 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = FinderSyncExt/FinderSyncExt.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = FinderSyncExt/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OC_APPLICATION_NAME = ownCloud;
|
||||
OC_APPLICATION_REV_DOMAIN = com.owncloud.desktopclient;
|
||||
OC_TEAM_IDENTIFIER_PREFIX = "";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
C2B573981B1CD88000303B36 /* Build configuration list for PBXProject "OwnCloudFinderSync" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C2B573991B1CD88000303B36 /* Debug */,
|
||||
C2B5739A1B1CD88000303B36 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C2B573CC1B1CD91E00303B36 /* Build configuration list for PBXNativeTarget "desktopclient" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C2B573CD1B1CD91E00303B36 /* Debug */,
|
||||
C2B573CE1B1CD91E00303B36 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C2B573E31B1CD9CE00303B36 /* Build configuration list for PBXNativeTarget "FinderSyncExt" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C2B573E41B1CD9CE00303B36 /* Debug */,
|
||||
C2B573E51B1CD9CE00303B36 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = C2B573951B1CD88000303B36 /* Project object */;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C2B573D61B1CD9CE00303B36"
|
||||
BuildableName = "FinderSyncExt.appex"
|
||||
BlueprintName = "FinderSyncExt"
|
||||
ReferencedContainer = "container:OwnCloudFinderSync.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C2B573B01B1CD91E00303B36"
|
||||
BuildableName = "desktopclient.app"
|
||||
BlueprintName = "desktopclient"
|
||||
ReferencedContainer = "container:OwnCloudFinderSync.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C2B573D61B1CD9CE00303B36"
|
||||
BuildableName = "FinderSyncExt.appex"
|
||||
BlueprintName = "FinderSyncExt"
|
||||
ReferencedContainer = "container:OwnCloudFinderSync.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C2B573B01B1CD91E00303B36"
|
||||
BuildableName = "desktopclient.app"
|
||||
BlueprintName = "desktopclient"
|
||||
ReferencedContainer = "container:OwnCloudFinderSync.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "C2B573B01B1CD91E00303B36"
|
||||
BuildableName = "desktopclient.app"
|
||||
BlueprintName = "desktopclient"
|
||||
ReferencedContainer = "container:OwnCloudFinderSync.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.owncloud.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// main.m
|
||||
// desktopclient
|
||||
//
|
||||
// Created by Jocelyn Turcotte on 01/06/15.
|
||||
//
|
||||
//
|
||||
|
||||
// This is fake application bundle with the same bundle ID as the real desktop client.
|
||||
// Xcode needs a wrapping application to allow the extension to be debugged.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) by Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@protocol SyncClientProxyDelegate <NSObject>
|
||||
- (void)setResultForPath:(NSString*)path result:(NSString*)result;
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path;
|
||||
- (void)registerPath:(NSString*)path;
|
||||
- (void)unregisterPath:(NSString*)path;
|
||||
- (void)setShareMenuTitle:(NSString*)title;
|
||||
- (void)connectionDidDie;
|
||||
@end
|
||||
|
||||
@protocol ChannelProtocol <NSObject>
|
||||
- (void)sendMessage:(NSData*)msg;
|
||||
@end
|
||||
|
||||
@interface SyncClientProxy : NSObject <ChannelProtocol>
|
||||
{
|
||||
NSString *_serverName;
|
||||
NSDistantObject <ChannelProtocol> *_remoteEnd;
|
||||
}
|
||||
|
||||
@property (weak) id <SyncClientProxyDelegate> delegate;
|
||||
|
||||
- (instancetype)initWithDelegate:(id)arg1 serverName:(NSString*)serverName;
|
||||
- (void)start;
|
||||
- (void)askOnSocket:(NSString*)path query:(NSString*)verb;
|
||||
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
@end
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) by Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#import "SyncClientProxy.h"
|
||||
|
||||
@protocol ServerProtocol <NSObject>
|
||||
- (void)registerClient:(id)client;
|
||||
@end
|
||||
|
||||
@interface SyncClientProxy ()
|
||||
- (void)registerTransmitter:(id)tx;
|
||||
@end
|
||||
|
||||
@implementation SyncClientProxy
|
||||
|
||||
- (instancetype)initWithDelegate:(id)arg1 serverName:(NSString*)serverName
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
self.delegate = arg1;
|
||||
_serverName = serverName;
|
||||
_remoteEnd = nil;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Connection setup
|
||||
|
||||
- (void)start
|
||||
{
|
||||
if (_remoteEnd)
|
||||
return;
|
||||
|
||||
// Lookup the server connection
|
||||
NSConnection *conn = [NSConnection connectionWithRegisteredName:_serverName host:nil];
|
||||
|
||||
if (!conn) {
|
||||
// Could not connect to the sync client
|
||||
[self scheduleRetry];
|
||||
return;
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification
|
||||
object:conn];
|
||||
|
||||
NSDistantObject <ServerProtocol> *server = (NSDistantObject <ServerProtocol> *)[conn rootProxy];
|
||||
assert(server);
|
||||
|
||||
// This saves a few Mach messages, enable "Distributed Objects" in the scheme's Run diagnostics to watch
|
||||
[server setProtocolForProxy:@protocol(ServerProtocol)];
|
||||
|
||||
// Send an object to the server to act as the channel rx, we'll receive the tx through registerTransmitter
|
||||
[server registerClient:self];
|
||||
}
|
||||
|
||||
- (void)registerTransmitter:(id)tx;
|
||||
{
|
||||
// The server replied with the distant object that we will use for tx
|
||||
_remoteEnd = (NSDistantObject <ChannelProtocol> *)tx;
|
||||
[_remoteEnd setProtocolForProxy:@protocol(ChannelProtocol)];
|
||||
|
||||
// Everything is set up, start querrying
|
||||
[self askOnSocket:@"" query:@"SHARE_MENU_TITLE"];
|
||||
}
|
||||
|
||||
- (void)scheduleRetry
|
||||
{
|
||||
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(start) userInfo:nil repeats:NO];
|
||||
}
|
||||
|
||||
- (void)connectionDidDie:(NSNotification*)notification
|
||||
{
|
||||
#pragma unused(notification)
|
||||
_remoteEnd = nil;
|
||||
[_delegate connectionDidDie];
|
||||
|
||||
[self scheduleRetry];
|
||||
}
|
||||
|
||||
#pragma mark - Communication logic
|
||||
|
||||
- (void)sendMessage:(NSData*)msg
|
||||
{
|
||||
NSString *answer = [[NSString alloc] initWithData:msg encoding:NSUTF8StringEncoding];
|
||||
|
||||
// Cut the trailing newline
|
||||
answer = [answer substringToIndex:[answer length] - 1];
|
||||
NSArray *chunks = [answer componentsSeparatedByString: @":"];
|
||||
|
||||
if( [[chunks objectAtIndex:0] isEqualToString:@"STATUS"] ) {
|
||||
NSString *result = [chunks objectAtIndex:1];
|
||||
NSString *path = [chunks objectAtIndex:2];
|
||||
if( [chunks count] > 3 ) {
|
||||
for( int i = 2; i < [chunks count]-1; i++ ) {
|
||||
path = [NSString stringWithFormat:@"%@:%@",
|
||||
path, [chunks objectAtIndex:i+1] ];
|
||||
}
|
||||
}
|
||||
[_delegate setResultForPath:path result:result];
|
||||
} else if( [[chunks objectAtIndex:0] isEqualToString:@"UPDATE_VIEW"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_delegate reFetchFileNameCacheForPath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_delegate registerPath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"UNREGISTER_PATH"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_delegate unregisterPath:path];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"SHARE_MENU_TITLE"] ) {
|
||||
[_delegate setShareMenuTitle:[chunks objectAtIndex:1]];
|
||||
} else {
|
||||
NSLog(@"SyncState: Unknown command %@", [chunks objectAtIndex:0]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)askOnSocket:(NSString*)path query:(NSString*)verb
|
||||
{
|
||||
NSString *query = [NSString stringWithFormat:@"%@:%@\n", verb,path];
|
||||
|
||||
@try {
|
||||
[_remoteEnd sendMessage:[query dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
} @catch(NSException* e) {
|
||||
// Do nothing and wait for connectionDidDie
|
||||
}
|
||||
}
|
||||
|
||||
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
|
||||
{
|
||||
NSString *verb = isDir ? @"RETRIEVE_FOLDER_STATUS" : @"RETRIEVE_FILE_STATUS";
|
||||
[self askOnSocket:path query:verb];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,4 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "Not used anymore, please do (from build dir) (this is <= 10.9 only)"
|
||||
echo sudo cp -r ./shell_integration/MacOSX/Release/SyncStateFinder.osax /Library/ScriptingAdditions/
|
||||
echo killall Finder
|
||||
exit 1
|
||||
|
||||
SELFPATH=`dirname $0`
|
||||
# osascript $SELFPATH/unload.scpt
|
||||
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
|
||||
# Install the Mac icon container into the Mac Bundle.
|
||||
if( BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY )
|
||||
set (ICON_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/icons)
|
||||
|
||||
file(GLOB mac_icons "icns/*icns")
|
||||
install(FILES ${mac_icons} DESTINATION ${ICON_DIR})
|
||||
endif()
|
||||
|
||||
if( UNIX AND NOT APPLE )
|
||||
|
||||
SET(ICON_DIR ${DATADIR}/icons/hicolor)
|
||||
|
@ -22,6 +13,3 @@ if( UNIX AND NOT APPLE )
|
|||
ENDFOREACH(size)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Sync" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<circle fill="#E0D92D" cx="64" cy="64" r="61.9"/>
|
||||
<path fill="#8E7409" d="M64,128C28.7,128,0,99.3,0,64S28.7,0,64,0s64,28.7,64,64S99.3,128,64,128z M64,4.1C31,4.1,4.1,31,4.1,64
|
||||
c0,33,26.9,59.9,59.9,59.9c33,0,59.9-26.9,59.9-59.9C123.9,31,97,4.1,64,4.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M64,107.4c-5.6,0-10.2-4.6-10.2-10.2C53.8,91.6,58.4,87,64,87c5.6,0,10.2,4.6,10.2,10.2
|
||||
C74.2,102.8,69.6,107.4,64,107.4z M64,81.3c-8.3,0-8.3-7.3-8.3-10.2L52,30.9v-0.1c0-5.6,5.4-10.2,12-10.2c6.6,0,12,4.6,12,10.2
|
||||
v0.1l-3.7,40.3C72.3,74,72.3,81.3,64,81.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#8E7409" d="M64,21.9c5.9,0,10.7,4,10.7,8.8l-3.7,40.3c0,4.9-1.1,8.8-7,8.8c-5.9,0-6.9-4-6.9-8.8l-3.7-40.3
|
||||
C53.3,25.9,58.1,21.9,64,21.9 M64,88.3c4.9,0,8.9,4,8.9,8.8c0,4.9-4,8.9-8.9,8.9c-4.9,0-8.9-4-8.9-8.9
|
||||
C55.1,92.3,59.1,88.3,64,88.3 M64,19.2c-3.5,0-6.8,1.1-9.3,3.2c-2.7,2.2-4.1,5.2-4.1,8.4v0.1l0,0.1l3.7,40.1
|
||||
c0,2.3,0.2,5.2,1.7,7.6c1.6,2.6,4.3,3.9,8,3.9c3.7,0,6.4-1.3,8-3.9c1.5-2.3,1.7-5.3,1.7-7.6L77.4,31l0-0.1v-0.1
|
||||
c0-3.2-1.5-6.2-4.1-8.4C70.8,20.3,67.5,19.2,64,19.2L64,19.2z M64,85.6c-6.4,0-11.6,5.2-11.6,11.6c0,6.4,5.2,11.6,11.6,11.6
|
||||
c6.4,0,11.6-5.2,11.6-11.6C75.6,90.8,70.4,85.6,64,85.6L64,85.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Sync" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<circle fill="#B23015" cx="64" cy="64" r="61.9"/>
|
||||
<path fill="#981D05" d="M64,128C28.7,128,0,99.3,0,64S28.7,0,64,0s64,28.7,64,64S99.3,128,64,128z M64,4.1C31,4.1,4.1,31,4.1,64
|
||||
S31,123.9,64,123.9c33,0,59.9-26.9,59.9-59.9S97,4.1,64,4.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M41.8,95.2c-2.4,0-4.4-0.9-6.2-2.6c-1.7-1.7-2.7-3.9-2.8-6.4c-0.1-2.6,0.7-4.8,2.5-6.8L50.8,64L35.4,48.6
|
||||
c-1.9-1.9-2.7-4-2.5-6.5c0.2-2.3,1.1-4.5,2.7-6.3l0,0l0,0c1.9-1.9,4-2.9,6.3-2.9c0.2,0,0.4,0,0.6,0c2.4,0.2,4.5,1.1,6.4,2.8l0,0
|
||||
L64,50.7l15.4-15.2c1.8-1.8,3.9-2.7,6.3-2.7c0.1,0,0.1,0,0.2,0c2.4,0.1,4.6,1,6.5,2.8l0,0c1.7,1.7,2.6,3.9,2.6,6.5
|
||||
c0,2.6-0.9,4.8-2.6,6.6L77.4,64l15.1,15.2c1.7,1.7,2.6,3.9,2.7,6.5c0.1,2.6-0.8,5-2.7,6.9c-1.7,1.7-4,2.6-6.6,2.6
|
||||
c-2.6,0-4.9-1-6.8-3L64,77.4L48.9,92.6l0,0c-1.7,1.5-3.8,2.4-6.4,2.6C42.3,95.2,42,95.2,41.8,95.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#981D05" d="M41.9,34.1c0.2,0,0.3,0,0.5,0c2,0.2,3.9,1,5.5,2.5l16,16l16.4-16.2c1.5-1.5,3.3-2.3,5.3-2.3
|
||||
c0.1,0,0.1,0,0.2,0c2.1,0,4,0.8,5.6,2.4c1.5,1.5,2.2,3.3,2.2,5.6c0,2.2-0.7,4.1-2.2,5.7L75.4,64l16,16.2c1.5,1.5,2.3,3.3,2.3,5.6
|
||||
c0.1,2.3-0.7,4.2-2.3,5.9c-1.5,1.5-3.3,2.2-5.6,2.2c-2.3,0-4.2-0.9-5.9-2.6L64,75.5l-16,16.2c-1.5,1.3-3.3,2.1-5.5,2.2
|
||||
c-0.2,0-0.4,0-0.6,0c-2,0-3.7-0.7-5.2-2.2c-1.5-1.5-2.3-3.3-2.4-5.5c-0.1-2.2,0.6-4.1,2.2-5.7L52.7,64L36.3,47.6
|
||||
c-1.6-1.6-2.3-3.4-2.1-5.4c0.2-2.1,0.9-3.9,2.3-5.6C38.3,35,40,34.1,41.9,34.1 M41.9,31.4c-2.6,0-5,1.1-7.2,3.3l-0.1,0.1
|
||||
l-0.1,0.1c-1.8,2.1-2.8,4.5-3,7.1c-0.2,2.9,0.8,5.5,2.9,7.6L48.9,64L34.4,78.5l0,0l0,0c-2.1,2.2-3.1,4.8-2.9,7.8
|
||||
c0.2,2.9,1.2,5.3,3.2,7.3c2,2,4.4,3,7.2,3c0.3,0,0.5,0,0.8,0c2.8-0.2,5.2-1.2,7.2-2.9l0.1-0.1l0.1-0.1L64,79.4L78,93.2
|
||||
c2.2,2.3,4.8,3.4,7.8,3.4c3,0,5.6-1,7.6-3c2.2-2.2,3.3-4.9,3.1-7.9c-0.1-3-1.2-5.5-3.1-7.5L79.3,64l14.1-14.2l0,0l0,0
|
||||
c2-2.1,3-4.6,3-7.6c0-3-1-5.5-3-7.5l0,0l0,0c-2.2-2-4.7-3.1-7.4-3.2c-0.1,0-0.1,0-0.2,0c-2.8,0-5.2,1-7.3,3.1L64,48.8L49.9,34.7
|
||||
l0-0.1l-0.1-0.1c-2.1-1.9-4.5-2.9-7.2-3.2C42.4,31.4,42.1,31.4,41.9,31.4L41.9,31.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 2.5 KiB |
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Sync" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#5EB220" d="M64,2.1c34.2,0,61.9,27.7,61.9,61.9S98.2,125.9,64,125.9C29.8,125.9,2.1,98.2,2.1,64S29.8,2.1,64,2.1z"/>
|
||||
<path fill="#3A9804" d="M64,128C28.7,128,0,99.3,0,64S28.7,0,64,0s64,28.7,64,64S99.3,128,64,128z M64,4.1C31,4.1,4.1,31,4.1,64
|
||||
S31,123.9,64,123.9c33,0,59.9-26.9,59.9-59.9S97,4.1,64,4.1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon fill="#FFFFFF" points="25.7,76.8 35.9,63.8 53,77.3 87.1,31 100.3,40.7 61.3,93.9 56.2,100.7 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#3A9804" d="M87.3,32.4L98.9,41l-4.3,5.8L60.4,93.2l-4.4,6l-5.8-4.6L32.8,81.1l-5.7-4.4L36,65.3l5.7,4.4l11.5,9
|
||||
L83,38.2L87.3,32.4 M86.8,29.5l-1.2,1.7L81.3,37L52.8,75.8L43,68.1l-5.7-4.4l-1.6-1.3L34.4,64l-8.9,11.4L24.3,77l1.6,1.3l5.7,4.4
|
||||
l17.4,13.6l5.8,4.6l1.7,1.3l1.3-1.7l4.4-6L96.3,48l4.3-5.8l1.2-1.7l-1.7-1.2l-11.6-8.5L86.8,29.5L86.8,29.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.3 KiB |
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Sync" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#5EB220" d="M64,2.1c34.2,0,61.9,27.7,61.9,61.9S98.2,125.9,64,125.9C29.8,125.9,2.1,98.2,2.1,64S29.8,2.1,64,2.1z"
|
||||
/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#3A9804" d="M64,128C28.7,128,0,99.3,0,64S28.7,0,64,0s64,28.7,64,64S99.3,128,64,128z M64,4.1C31,4.1,4.1,31,4.1,64
|
||||
S31,123.9,64,123.9c33,0,59.9-26.9,59.9-59.9S97,4.1,64,4.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="translate(0 -1036.4)">
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M83.9,1059.9c-7.9,0-14.2,6.4-14.2,14.2c0,0.4,0,0.9,0.1,1.3l-27.4,14c-2.5-2.1-5.7-3.4-9.2-3.4
|
||||
c-7.9,0-14.2,6.4-14.2,14.2c0,7.9,6.4,14.2,14.2,14.2c3.2,0,6.1-1,8.5-2.8l28.2,14.3c0,0.2-0.1,0.5-0.1,0.8
|
||||
c0,7.9,6.4,14.2,14.2,14.2c7.8,0,14.2-6.4,14.2-14.2c0-7.9-6.4-14.2-14.2-14.2c-3.7,0-7.1,1.4-9.6,3.7l-27.2-13.9
|
||||
c0.1-0.7,0.2-1.4,0.2-2.2c0-0.4-0.1-0.8-0.1-1.2l27.5-14c2.5,2.1,5.7,3.4,9.2,3.4c7.9,0,14.2-6.4,14.2-14.2
|
||||
C98.1,1066.2,91.7,1059.8,83.9,1059.9L83.9,1059.9z"/>
|
||||
<path fill="#3A9804" d="M83.9,1141.9c-8.4,0-15.2-6.8-15.2-15.1c0-0.1,0-0.2,0-0.2l-27.1-13.8c-2.5,1.7-5.4,2.6-8.5,2.6
|
||||
c-8.3,0-15.1-6.8-15.1-15.1c0-8.3,6.8-15.1,15.1-15.1c3.4,0,6.7,1.1,9.4,3.2l26.3-13.4c0-0.3,0-0.5,0-0.8
|
||||
c0-8,6.2-14.6,14.1-15.1l0,0l1-0.1c8.3,0,15.1,6.8,15.1,15.1c0,8.4-6.8,15.2-15.1,15.2c-3.4,0-6.7-1.1-9.3-3.2l-26.4,13.4
|
||||
c0,0.2,0,0.5,0,0.7c0,0.6-0.1,1.1-0.1,1.7l26.1,13.3c2.7-2.3,6.2-3.5,9.7-3.5c8.3,0,15.1,6.8,15.1,15.2
|
||||
C99,1135.1,92.2,1141.9,83.9,1141.9z M41.4,1110.6l29.2,14.9l-0.1,0.9c0,0.1,0,0.3,0,0.4c0,7.3,6,13.3,13.3,13.3
|
||||
c7.3,0,13.3-6,13.3-13.3c0-7.3-6-13.3-13.3-13.3c-3.3,0-6.5,1.2-9,3.5l-0.5,0.4l-28.3-14.5l0.1-0.6c0.1-0.7,0.2-1.4,0.2-2.1
|
||||
c0-0.3,0-0.5,0-0.8l-0.1-1l28.5-14.5l0.5,0.4c2.4,2,5.5,3.2,8.6,3.2c7.3,0,13.3-6,13.3-13.3c0-7.1-5.6-12.9-12.6-13.3l-0.7,0
|
||||
c-7.3,0-13.3,6-13.3,13.3c0,0.4,0,0.7,0.1,1.1l0.1,0.6l-0.5,0.4l-28,14.3l-0.5-0.4c-2.4-2-5.5-3.2-8.6-3.2
|
||||
c-7.3,0-13.3,6-13.3,13.3c0,7.3,6,13.3,13.3,13.3c2.9,0,5.6-0.9,7.9-2.6L41.4,1110.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M83.9,1141.2c-8,0-14.4-6.5-14.4-14.4c0-0.2,0-0.3,0-0.5c0-0.1,0-0.1,0-0.2l-28-14.2
|
||||
c-2.4,1.8-5.4,2.7-8.5,2.7c-7.9,0-14.4-6.5-14.4-14.4c0-7.9,6.5-14.4,14.4-14.4c3.4,0,6.7,1.2,9.3,3.4l27.2-13.9l0-0.1
|
||||
c0-0.4-0.1-0.7-0.1-1.1c0-7.9,6.4-14.3,14.2-14.4l0-0.1h0.2c7.9,0,14.4,6.5,14.4,14.4c0,8-6.5,14.4-14.4,14.4
|
||||
c-3.4,0-6.6-1.2-9.2-3.3L47.4,1099l0,0.2c0,0.3,0.1,0.6,0.1,0.9c0,0.7-0.1,1.4-0.2,2.1l27,13.8c2.6-2.4,6.1-3.7,9.6-3.7
|
||||
c7.9,0,14.4,6.5,14.4,14.4C98.3,1134.7,91.8,1141.2,83.9,1141.2z M41.5,1111.4L41.5,1111.4l28.4,14.4l0,0.1c0,0.1,0,0.2,0,0.3
|
||||
c0,0.2,0,0.3,0,0.5c0,7.7,6.3,14,14.1,14c7.7,0,14-6.3,14-14c0-7.8-6.3-14.1-14-14.1c-3.5,0-6.9,1.3-9.5,3.7l-0.1,0.1l-0.1-0.1
|
||||
l-27.3-14l0-0.1c0.1-0.7,0.2-1.4,0.2-2.2c0-0.3,0-0.6-0.1-0.9c0-0.1,0-0.2,0-0.3l0-0.1l0.1-0.1l27.6-14l0.1,0.1
|
||||
c2.5,2.1,5.8,3.3,9.1,3.3c7.7,0,14-6.3,14-14.1c0-7.7-6.2-13.9-13.8-14l0,0.1h-0.2c-7.8,0-14.1,6.3-14.1,14c0,0.4,0,0.7,0.1,1
|
||||
l0,0.3l-0.1,0.1l-27.5,14l-0.1-0.1c-2.5-2.2-5.8-3.3-9.1-3.3c-7.7,0-14,6.3-14,14c0,7.7,6.3,14,14,14
|
||||
C36.1,1114.2,39,1113.3,41.5,1111.4L41.5,1111.4z"/>
|
||||
<path fill="#3A9804" d="M83.9,1142.1c-8.5,0-15.3-6.9-15.3-15.3c0,0,0-0.1,0-0.1l-26.9-13.7c-2.5,1.7-5.5,2.6-8.6,2.6
|
||||
c-8.4,0-15.3-6.9-15.3-15.3c0-8.4,6.9-15.3,15.3-15.3c3.4,0,6.7,1.1,9.4,3.2l26.1-13.3c0-0.2,0-0.4,0-0.7
|
||||
c0-8,6.2-14.6,14.1-15.3l0,0l1-0.1c8.6,0,15.5,6.9,15.5,15.3c0,8.5-6.9,15.3-15.3,15.3c-3.4,0-6.7-1.1-9.3-3.2l-26.2,13.3
|
||||
c0,0.2,0,0.4,0,0.6c0,0.5,0,1-0.1,1.6l25.8,13.2c2.7-2.3,6.2-3.5,9.7-3.5c8.4,0,15.3,6.9,15.3,15.3
|
||||
C99.2,1135.2,92.3,1142.1,83.9,1142.1z M41.3,1110.4l0.7,0.3l28.8,14.7l-0.1,1.1c0,0.1,0,0.2,0,0.4c0,7.2,5.9,13.1,13.1,13.1
|
||||
c7.2,0,13.1-5.9,13.1-13.1c0-7.2-5.9-13.1-13.1-13.1c-3.3,0-6.4,1.2-8.8,3.4l-0.5,0.4l-0.6-0.2l-28-14.3l0.1-0.6
|
||||
c0.1-0.8,0.2-1.5,0.2-2.2c0-0.3,0-0.5,0-0.8l-0.1-1l0.5-0.4l28.2-14.4l0.5,0.4c2.5,2.1,5.5,3.2,8.6,3.2
|
||||
c7.2,0,13.1-5.9,13.1-13.1c0-6.9-5.5-12.7-12.3-13.1l-0.6,0c-7.5,0-13.4,5.9-13.4,13.1c0,0.3,0,0.7,0.1,1l0.1,1l-0.5,0.3
|
||||
l-28.2,14.4l-0.5-0.4c-2.4-2.1-5.5-3.2-8.6-3.2c-7.2,0-13.1,5.9-13.1,13.1c0,7.2,5.9,13.1,13.1,13.1c2.9,0,5.6-0.9,7.8-2.5
|
||||
L41.3,1110.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 4.6 KiB |
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Sync" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<circle fill="#2268AB" cx="64" cy="64" r="61.934"/>
|
||||
<path fill="#114999" d="M64,128C28.711,128,0,99.289,0,64S28.711,0,64,0s64,28.711,64,64S99.289,128,64,128z M64,4.132
|
||||
C30.989,4.132,4.132,30.987,4.132,64S30.989,123.868,64,123.868S123.868,97.013,123.868,64S97.011,4.132,64,4.132z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M85.311,53.564c-3.957-8.111-12.221-13.307-21.264-13.307c-1.375,0-2.764,0.121-4.125,0.364
|
||||
c-8.236,1.448-15.172,7.237-18.111,15.105l-0.264,0.705l-14.818,2.616l0.346-1.871c2.836-15.363,15.068-27.507,30.436-30.216
|
||||
c2.164-0.38,4.361-0.575,6.543-0.575c12.025,0,23.222,5.73,30.3,15.411l4.771-6.193l1.889,21.721l0.325,1.479l-0.046,0.004
|
||||
v0.007l-23.129,4.048L85.311,53.564z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#114999" d="M64.053,27.711c12.314,0,23.643,6.318,30.25,16.325l3.8-4.938l1.6,18.411
|
||||
c0.007,0.048,0.025,0.111,0.036,0.159l-0.025,0.003l0.014,0.074l-18.446,3.232l5.568-7.243
|
||||
c-3.996-8.916-12.936-14.798-22.803-14.798c-1.436,0-2.889,0.125-4.353,0.38c-9.054,1.595-16.114,7.893-19.121,15.948
|
||||
l-12.197,2.152c2.672-14.457,14.061-26.452,29.368-29.152C59.861,27.891,61.971,27.711,64.053,27.711 M64.053,25.064
|
||||
c-2.257,0-4.536,0.2-6.768,0.595c-7.957,1.405-15.164,5.177-20.846,10.911c-5.55,5.605-9.239,12.65-10.664,20.368l-0.693,3.745
|
||||
l3.754-0.661l12.196-2.152l1.49-0.264l0.528-1.415c1.343-3.602,3.6-6.819,6.525-9.307c3.014-2.557,6.668-4.273,10.575-4.962
|
||||
c1.289-0.225,2.596-0.343,3.896-0.343c8.264,0,15.839,4.602,19.704,11.845l-4.564,5.941l-4.143,5.386l6.697-1.168l18.443-3.232
|
||||
l1.371-0.24l1.393-0.173l-0.625-2.82l-1.582-18.248l-0.593-6.761l-4.143,5.377l-1.65,2.145
|
||||
c-3.222-3.998-7.236-7.363-11.775-9.832C76.9,26.702,70.489,25.064,64.053,25.064L64.053,25.064z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M64.032,101.541c-11.982,0-23.157-5.701-30.254-15.341l-4.825,6.289l-1.918-21.98
|
||||
c-0.007-0.032-0.011-0.063-0.014-0.087l-0.147-1.245l13.597-2.398l0.018,0.096l9.422-1.653l-7.093,9.234
|
||||
c3.979,8.048,12.221,13.207,21.211,13.207c1.368,0,2.761-0.12,4.125-0.362c8.154-1.439,15.068-7.148,18.036-14.902l0.268-0.704
|
||||
l14.857-2.62l-0.361,1.884C99.543,78.37,95.968,85.127,90.618,90.5c-5.475,5.498-12.411,9.121-20.057,10.466
|
||||
C68.404,101.348,66.207,101.541,64.032,101.541z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#114999" d="M46.793,67.111l-5.518,7.182c4.021,8.855,12.918,14.691,22.754,14.691c1.432,0,2.89-0.123,4.353-0.384
|
||||
c8.975-1.581,15.997-7.784,19.043-15.732l12.232-2.159c-2.743,14.366-14.086,26.268-29.325,28.957
|
||||
c-2.118,0.37-4.221,0.554-6.3,0.554c-12.278,0-23.582-6.291-30.204-16.255l-3.85,5.019l-1.632-18.652
|
||||
c-0.007-0.025-0.007-0.052-0.011-0.073l11.054-1.948c0.004,0.029,0.018,0.059,0.025,0.095L46.793,67.111 M53.032,63.332
|
||||
l-6.697,1.173l-4.764,0.834l-0.014-0.093l-2.629,0.463l-11.05,1.948l-2.471,0.432l0.304,2.487
|
||||
c0.004,0.029,0.007,0.059,0.011,0.095l1.622,18.545l0.589,6.779l4.143-5.398l1.711-2.23c3.225,3.986,7.239,7.329,11.761,9.784
|
||||
c5.675,3.084,12.068,4.713,18.486,4.713c2.25,0,4.525-0.2,6.761-0.591c7.914-1.398,15.097-5.145,20.765-10.841
|
||||
c5.535-5.559,9.232-12.555,10.696-20.223l0.718-3.768l-3.775,0.668l-12.232,2.156l-1.475,0.259l-0.536,1.402
|
||||
c-1.361,3.55-3.618,6.723-6.529,9.173c-2.996,2.522-6.629,4.218-10.503,4.902c-1.29,0.225-2.6,0.343-3.893,0.343
|
||||
c-8.214,0-15.764-4.564-19.65-11.746l4.511-5.872L53.032,63.332L53.032,63.332z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 3.8 KiB |
После Ширина: | Высота: | Размер: 5.4 KiB |
После Ширина: | Высота: | Размер: 12 KiB |
После Ширина: | Высота: | Размер: 603 B |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 11 KiB |
После Ширина: | Высота: | Размер: 25 KiB |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 2.4 KiB |
После Ширина: | Высота: | Размер: 6.5 KiB |
После Ширина: | Высота: | Размер: 14 KiB |
После Ширина: | Высота: | Размер: 615 B |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 14 KiB |
После Ширина: | Высота: | Размер: 31 KiB |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 2.7 KiB |
После Ширина: | Высота: | Размер: 7.3 KiB |
Двоичные данные
shell_integration/icons/nopadding/ok_swm.iconset/icon_128x128@2x.png
Executable file
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 647 B |
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 16 KiB |
Двоичные данные
shell_integration/icons/nopadding/ok_swm.iconset/icon_256x256@2x.png
Executable file
После Ширина: | Высота: | Размер: 34 KiB |
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 7.5 KiB |
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 694 B |
После Ширина: | Высота: | Размер: 1.5 KiB |
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 35 KiB |
После Ширина: | Высота: | Размер: 1.5 KiB |
После Ширина: | Высота: | Размер: 3.4 KiB |
После Ширина: | Высота: | Размер: 5.9 KiB |
Двоичные данные
shell_integration/icons/nopadding/warning.iconset/icon_128x128@2x.png
Executable file
После Ширина: | Высота: | Размер: 13 KiB |
После Ширина: | Высота: | Размер: 523 B |
После Ширина: | Высота: | Размер: 1.1 KiB |
После Ширина: | Высота: | Размер: 13 KiB |
Двоичные данные
shell_integration/icons/nopadding/warning.iconset/icon_256x256@2x.png
Executable file
После Ширина: | Высота: | Размер: 27 KiB |
После Ширина: | Высота: | Размер: 1.1 KiB |
После Ширина: | Высота: | Размер: 2.5 KiB |
|
@ -34,7 +34,6 @@
|
|||
#include "theme.h"
|
||||
#include "netrcparser.h"
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
|
|
@ -94,6 +94,7 @@ set(updater_SRCS
|
|||
IF( APPLE )
|
||||
list(APPEND client_SRCS cocoainitializer_mac.mm)
|
||||
list(APPEND client_SRCS settingsdialogmac.cpp)
|
||||
list(APPEND client_SRCS socketapisocket_mac.mm)
|
||||
list(APPEND client_SRCS systray.mm)
|
||||
|
||||
if(SPARKLE_FOUND)
|
||||
|
|
|
@ -569,6 +569,7 @@ void Folder::slotWatchedPathChanged(const QString& path)
|
|||
// the sync is doing to filter out our own changes.
|
||||
bool ownChange = false;
|
||||
#ifdef Q_OS_MAC
|
||||
Q_UNUSED(path)
|
||||
// On OSX the folder watcher does not report changes done by our
|
||||
// own process. Therefore nothing needs to be done here!
|
||||
#else
|
||||
|
|
|
@ -47,11 +47,15 @@ static void callback(
|
|||
const FSEventStreamEventFlags eventFlags[],
|
||||
const FSEventStreamEventId eventIds[])
|
||||
{
|
||||
Q_UNUSED(streamRef)
|
||||
Q_UNUSED(eventFlags)
|
||||
Q_UNUSED(eventIds)
|
||||
|
||||
qDebug() << "FolderWatcherPrivate::callback by OS X";
|
||||
|
||||
QStringList paths;
|
||||
CFArrayRef eventPaths = (CFArrayRef)eventPathsVoid;
|
||||
for (int i = 0; i < numEvents; ++i) {
|
||||
for (int i = 0; i < static_cast<int>(numEvents); ++i) {
|
||||
CFStringRef path = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(eventPaths, i));
|
||||
|
||||
QString qstring;
|
||||
|
|
|
@ -107,29 +107,33 @@ ownCloudGui::ownCloudGui(Application *parent) :
|
|||
void ownCloudGui::setupOverlayIcons()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
const QLatin1String finderExtension("/Library/ScriptingAdditions/SyncStateFinder.osax");
|
||||
if(QFile::exists(finderExtension) ) {
|
||||
QString aScript = QString::fromUtf8("tell application \"Finder\"\n"
|
||||
" try\n"
|
||||
" «event OWNCload»\n"
|
||||
" end try\n"
|
||||
"end tell\n");
|
||||
// Make sure that we only send the load event to the legacy plugin when
|
||||
// using OS X <= 10.9 since 10.10 starts using the new FinderSync one.
|
||||
if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_10) {
|
||||
const QLatin1String finderExtension("/Library/ScriptingAdditions/SyncStateFinder.osax");
|
||||
if (QFile::exists(finderExtension)) {
|
||||
QString aScript = QString::fromUtf8("tell application \"Finder\"\n"
|
||||
" try\n"
|
||||
" «event OWNCload»\n"
|
||||
" end try\n"
|
||||
"end tell\n");
|
||||
|
||||
QString osascript = "/usr/bin/osascript";
|
||||
QStringList processArguments;
|
||||
// processArguments << "-l" << "AppleScript";
|
||||
QString osascript = "/usr/bin/osascript";
|
||||
QStringList processArguments;
|
||||
// processArguments << "-l" << "AppleScript";
|
||||
|
||||
QProcess p;
|
||||
p.start(osascript, processArguments);
|
||||
p.write(aScript.toUtf8());
|
||||
p.closeWriteChannel();
|
||||
p.waitForReadyRead(-1);
|
||||
QByteArray result = p.readAll();
|
||||
QString resultAsString(result); // if appropriate
|
||||
qDebug() << "Laod Finder Overlay-Plugin: " << resultAsString << ": " << p.exitCode()
|
||||
<< (p.exitCode() != 0 ? p.errorString() : QString::null);
|
||||
} else {
|
||||
qDebug() << finderExtension << "does not exist! Finder Overlay Plugin loading failed";
|
||||
QProcess p;
|
||||
p.start(osascript, processArguments);
|
||||
p.write(aScript.toUtf8());
|
||||
p.closeWriteChannel();
|
||||
p.waitForReadyRead(-1);
|
||||
QByteArray result = p.readAll();
|
||||
QString resultAsString(result); // if appropriate
|
||||
qDebug() << "Laod Finder Overlay-Plugin: " << resultAsString << ": " << p.exitCode()
|
||||
<< (p.exitCode() != 0 ? p.errorString() : QString::null);
|
||||
} else {
|
||||
qDebug() << finderExtension << "does not exist! Finder Overlay Plugin loading failed";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "socketapi.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "configfile.h"
|
||||
#include "folderman.h"
|
||||
#include "folder.h"
|
||||
|
@ -84,13 +85,10 @@ SocketApi::SocketApi(QObject* parent)
|
|||
// See issue #2388
|
||||
// + Theme::instance()->appName();
|
||||
} else if (Utility::isMac()) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
// Always using Qt5 on OS X
|
||||
QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
|
||||
socketPath = runtimeDir + "/SyncStateHelper/" + Theme::instance()->appName() + ".socket";
|
||||
// We use the generic SyncStateHelper name on OS X since the different branded clients
|
||||
// should unfortunately not mention that they are ownCloud :-)
|
||||
#endif
|
||||
// This must match the code signing Team setting of the extension
|
||||
// Example for developer builds (with ad-hoc signing identity): "" "com.owncloud.desktopclient" ".socketApi"
|
||||
// Example for official signed packages: "9B5WD74GWJ." "com.owncloud.desktopclient" ".socketApi"
|
||||
socketPath = SOCKETAPI_TEAM_IDENTIFIER_PREFIX APPLICATION_REV_DOMAIN ".socketApi";
|
||||
} else if( Utility::isLinux() || Utility::isBSD() ) {
|
||||
QString runtimeDir;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
|
@ -108,7 +106,7 @@ SocketApi::SocketApi(QObject* parent)
|
|||
DEBUG << "An unexpected system detected";
|
||||
}
|
||||
|
||||
QLocalServer::removeServer(socketPath);
|
||||
SocketApiServer::removeServer(socketPath);
|
||||
QFileInfo info(socketPath);
|
||||
if (!info.dir().exists()) {
|
||||
bool result = info.dir().mkpath(".");
|
||||
|
@ -167,7 +165,7 @@ void SocketApi::slotReadExcludes()
|
|||
|
||||
void SocketApi::slotNewConnection()
|
||||
{
|
||||
QLocalSocket* socket = _localServer.nextPendingConnection();
|
||||
QIODevice* socket = _localServer.nextPendingConnection();
|
||||
|
||||
if( ! socket ) {
|
||||
return;
|
||||
|
@ -179,16 +177,6 @@ void SocketApi::slotNewConnection()
|
|||
|
||||
_listeners.append(socket);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// We want to tell our location so it can load the icons
|
||||
// e.g. "/Users/guruz/woboq/owncloud/client/buildmirall/owncloud.app/Contents/MacOS/"
|
||||
QString iconPath = qApp->applicationDirPath() + "/../Resources/icons/";
|
||||
if (!QDir(iconPath).exists()) {
|
||||
DEBUG << "Icon path " << iconPath << " does not exist, did you forget make install?";
|
||||
}
|
||||
broadcastMessage(QLatin1String("ICON_PATH"), iconPath );
|
||||
#endif
|
||||
|
||||
foreach( Folder *f, FolderMan::instance()->map() ) {
|
||||
QString message = buildRegisterPathMessage(f->path());
|
||||
sendMessage(socket, message);
|
||||
|
@ -199,7 +187,7 @@ void SocketApi::onLostConnection()
|
|||
{
|
||||
DEBUG << "Lost connection " << sender();
|
||||
|
||||
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
|
||||
QIODevice* socket = qobject_cast<QIODevice*>(sender());
|
||||
_listeners.removeAll(socket);
|
||||
socket->deleteLater();
|
||||
}
|
||||
|
@ -207,7 +195,7 @@ void SocketApi::onLostConnection()
|
|||
|
||||
void SocketApi::slotReadSocket()
|
||||
{
|
||||
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
|
||||
QIODevice* socket = qobject_cast<QIODevice*>(sender());
|
||||
Q_ASSERT(socket);
|
||||
|
||||
while(socket->canReadLine()) {
|
||||
|
@ -215,12 +203,12 @@ void SocketApi::slotReadSocket()
|
|||
QString command = line.split(":").first();
|
||||
QString function = QString(QLatin1String("command_")).append(command);
|
||||
|
||||
QString functionWithArguments = function + QLatin1String("(QString,QLocalSocket*)");
|
||||
QString functionWithArguments = function + QLatin1String("(QString,QIODevice*)");
|
||||
int indexOfMethod = this->metaObject()->indexOfMethod(functionWithArguments.toAscii());
|
||||
|
||||
QString argument = line.remove(0, command.length()+1).trimmed();
|
||||
if(indexOfMethod != -1) {
|
||||
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(QLocalSocket*, socket));
|
||||
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(QIODevice*, socket));
|
||||
} else {
|
||||
DEBUG << "The command is not supported by this version of the client:" << command << "with argument:" << argument;
|
||||
}
|
||||
|
@ -232,7 +220,7 @@ void SocketApi::slotRegisterPath( const QString& alias )
|
|||
Folder *f = FolderMan::instance()->folder(alias);
|
||||
if (f) {
|
||||
QString message = buildRegisterPathMessage(f->path());
|
||||
foreach(QLocalSocket *socket, _listeners) {
|
||||
foreach(QIODevice *socket, _listeners) {
|
||||
sendMessage(socket, message);
|
||||
}
|
||||
}
|
||||
|
@ -336,7 +324,7 @@ void SocketApi::slotSyncItemDiscovered(const QString &folder, const SyncFileItem
|
|||
|
||||
|
||||
|
||||
void SocketApi::sendMessage(QLocalSocket *socket, const QString& message, bool doWait)
|
||||
void SocketApi::sendMessage(QIODevice *socket, const QString& message, bool doWait)
|
||||
{
|
||||
DEBUG << "Sending message: " << message;
|
||||
QString localMessage = message;
|
||||
|
@ -369,14 +357,12 @@ void SocketApi::broadcastMessage( const QString& verb, const QString& path, cons
|
|||
msg.append(QDir::toNativeSeparators(fi.absoluteFilePath()));
|
||||
}
|
||||
|
||||
// sendMessage already has a debug output
|
||||
//DEBUG << "Broadcasting to" << _listeners.count() << "listeners: " << msg;
|
||||
foreach(QLocalSocket *socket, _listeners) {
|
||||
foreach(QIODevice *socket, _listeners) {
|
||||
sendMessage(socket, msg, doWait);
|
||||
}
|
||||
}
|
||||
|
||||
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket)
|
||||
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevice* socket)
|
||||
{
|
||||
// This command is the same as RETRIEVE_FILE_STATUS
|
||||
|
||||
|
@ -384,7 +370,7 @@ void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSo
|
|||
command_RETRIEVE_FILE_STATUS(argument, socket);
|
||||
}
|
||||
|
||||
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSocket* socket)
|
||||
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket)
|
||||
{
|
||||
if( !socket ) {
|
||||
qDebug() << "No valid socket object.";
|
||||
|
@ -412,7 +398,7 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSock
|
|||
sendMessage(socket, message);
|
||||
}
|
||||
|
||||
void SocketApi::command_SHARE(const QString& localFile, QLocalSocket* socket)
|
||||
void SocketApi::command_SHARE(const QString& localFile, QIODevice* socket)
|
||||
{
|
||||
if (!socket) {
|
||||
qDebug() << Q_FUNC_INFO << "No valid socket object.";
|
||||
|
@ -450,12 +436,12 @@ void SocketApi::command_SHARE(const QString& localFile, QLocalSocket* socket)
|
|||
}
|
||||
}
|
||||
|
||||
void SocketApi::command_VERSION(const QString&, QLocalSocket* socket)
|
||||
void SocketApi::command_VERSION(const QString&, QIODevice* socket)
|
||||
{
|
||||
sendMessage(socket, QLatin1String("VERSION:" MIRALL_VERSION_STRING ":" MIRALL_SOCKET_API_VERSION));
|
||||
}
|
||||
|
||||
void SocketApi::command_SHARE_MENU_TITLE(const QString &, QLocalSocket* socket)
|
||||
void SocketApi::command_SHARE_MENU_TITLE(const QString &, QIODevice* socket)
|
||||
{
|
||||
sendMessage(socket, QLatin1String("SHARE_MENU_TITLE:") + tr("Share with %1", "parameter is ownCloud").arg(Theme::instance()->appNameGUI()));
|
||||
}
|
||||
|
|
|
@ -20,17 +20,17 @@ extern "C" {
|
|||
#include <std/c_string.h>
|
||||
}
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <QWeakPointer>
|
||||
#include <QTcpSocket>
|
||||
#include <QTcpServer>
|
||||
#include <QLocalServer>
|
||||
|
||||
#include "syncfileitem.h"
|
||||
#include "syncjournalfilerecord.h"
|
||||
#include "ownsql.h"
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include "socketapisocket_mac.h"
|
||||
#else
|
||||
#include <QLocalServer>
|
||||
typedef QLocalServer SocketApiServer;
|
||||
#endif
|
||||
|
||||
class QUrl;
|
||||
class QLocalSocket;
|
||||
class QStringList;
|
||||
|
@ -74,20 +74,20 @@ private:
|
|||
SyncJournalFileRecord dbFileRecord_capi( Folder *folder, QString fileName );
|
||||
SqlQuery *getSqlQuery( Folder *folder );
|
||||
|
||||
void sendMessage(QLocalSocket* socket, const QString& message, bool doWait = false);
|
||||
void sendMessage(QIODevice* socket, const QString& message, bool doWait = false);
|
||||
void broadcastMessage(const QString& verb, const QString &path, const QString &status = QString::null, bool doWait = false);
|
||||
|
||||
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_SHARE(const QString& localFile, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevice* socket);
|
||||
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket);
|
||||
Q_INVOKABLE void command_SHARE(const QString& localFile, QIODevice* socket);
|
||||
|
||||
Q_INVOKABLE void command_VERSION(const QString& argument, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_VERSION(const QString& argument, QIODevice* socket);
|
||||
|
||||
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QLocalSocket* socket);
|
||||
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QIODevice* socket);
|
||||
QString buildRegisterPathMessage(const QString& path);
|
||||
|
||||
QList<QLocalSocket*> _listeners;
|
||||
QLocalServer _localServer;
|
||||
QList<QIODevice*> _listeners;
|
||||
SocketApiServer _localServer;
|
||||
c_strlist_t *_excludes;
|
||||
QHash<Folder*, QSharedPointer<SqlQuery>> _dbQueries;
|
||||
QHash<Folder*, QSharedPointer<SqlDatabase>> _openDbs;
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) by Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef SOCKETAPISOCKET_OSX_H
|
||||
#define SOCKETAPISOCKET_OSX_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QIODevice>
|
||||
|
||||
class SocketApiServerPrivate;
|
||||
class SocketApiSocketPrivate;
|
||||
|
||||
class SocketApiSocket : public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocketApiSocket(QObject *parent, SocketApiSocketPrivate *p);
|
||||
~SocketApiSocket();
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen) override;
|
||||
qint64 writeData(const char *data, qint64 len) override;
|
||||
|
||||
bool isSequential() const override { return true; }
|
||||
qint64 bytesAvailable() const override;
|
||||
bool canReadLine() const override;
|
||||
|
||||
signals:
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
// Use Qt's p-impl system to hide objective-c types from C++ code including this file
|
||||
Q_DECLARE_PRIVATE(SocketApiSocket)
|
||||
QScopedPointer<SocketApiSocketPrivate> d_ptr;
|
||||
friend class SocketApiServerPrivate;
|
||||
};
|
||||
|
||||
class SocketApiServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocketApiServer();
|
||||
~SocketApiServer();
|
||||
|
||||
void close();
|
||||
bool listen(const QString &name);
|
||||
SocketApiSocket *nextPendingConnection();
|
||||
|
||||
static bool removeServer(const QString &) { return false; }
|
||||
|
||||
signals:
|
||||
void newConnection();
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(SocketApiServer)
|
||||
QScopedPointer<SocketApiServerPrivate> d_ptr;
|
||||
};
|
||||
|
||||
#endif // SOCKETAPISOCKET_OSX_H
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* Copyright (C) by Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "socketapisocket_mac.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@protocol ChannelProtocol <NSObject>
|
||||
- (void)sendMessage:(NSData*)msg;
|
||||
@end
|
||||
|
||||
@protocol RemoteEndProtocol <NSObject, ChannelProtocol>
|
||||
- (void)registerTransmitter:(id)tx;
|
||||
@end
|
||||
|
||||
@interface LocalEnd : NSObject <ChannelProtocol>
|
||||
@property SocketApiSocketPrivate *wrapper;
|
||||
- (instancetype)initWithWrapper:(SocketApiSocketPrivate *)wrapper;
|
||||
@end
|
||||
|
||||
@interface Server : NSObject
|
||||
@property SocketApiServerPrivate *wrapper;
|
||||
- (instancetype)initWithWrapper:(SocketApiServerPrivate *)wrapper;
|
||||
- (void)registerClient:(NSDistantObject <RemoteEndProtocol> *)remoteEnd;
|
||||
@end
|
||||
|
||||
class SocketApiSocketPrivate
|
||||
{
|
||||
public:
|
||||
SocketApiSocket *q_ptr;
|
||||
|
||||
SocketApiSocketPrivate(NSDistantObject <ChannelProtocol> *remoteEnd);
|
||||
~SocketApiSocketPrivate();
|
||||
|
||||
NSDistantObject <ChannelProtocol> *remoteEnd;
|
||||
LocalEnd *localEnd;
|
||||
QByteArray inBuffer;
|
||||
};
|
||||
|
||||
class SocketApiServerPrivate
|
||||
{
|
||||
public:
|
||||
SocketApiServer *q_ptr;
|
||||
|
||||
SocketApiServerPrivate();
|
||||
~SocketApiServerPrivate();
|
||||
|
||||
QList<SocketApiSocket*> pendingConnections;
|
||||
NSConnection *connection;
|
||||
Server *server;
|
||||
};
|
||||
|
||||
|
||||
@implementation LocalEnd
|
||||
- (instancetype)initWithWrapper:(SocketApiSocketPrivate *)wrapper
|
||||
{
|
||||
self = [super init];
|
||||
self->_wrapper = wrapper;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sendMessage:(NSData*)msg
|
||||
{
|
||||
if (_wrapper) {
|
||||
_wrapper->inBuffer += QByteArray::fromRawNSData(msg);
|
||||
emit _wrapper->q_ptr->readyRead();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)connectionDidDie:(NSNotification*)notification
|
||||
{
|
||||
#pragma unused(notification)
|
||||
if (_wrapper)
|
||||
emit _wrapper->q_ptr->disconnected();
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Server
|
||||
- (instancetype)initWithWrapper:(SocketApiServerPrivate *)wrapper
|
||||
{
|
||||
self = [super init];
|
||||
self->_wrapper = wrapper;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerClient:(NSDistantObject <RemoteEndProtocol> *)remoteEnd
|
||||
{
|
||||
// This saves a few mach messages that would otherwise be needed to query the interface
|
||||
[remoteEnd setProtocolForProxy:@protocol(RemoteEndProtocol)];
|
||||
|
||||
SocketApiServer *server = _wrapper->q_ptr;
|
||||
SocketApiSocketPrivate *socketPrivate = new SocketApiSocketPrivate(remoteEnd);
|
||||
SocketApiSocket *socket = new SocketApiSocket(server, socketPrivate);
|
||||
_wrapper->pendingConnections.append(socket);
|
||||
emit server->newConnection();
|
||||
|
||||
[remoteEnd registerTransmitter:socketPrivate->localEnd];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
SocketApiSocket::SocketApiSocket(QObject *parent, SocketApiSocketPrivate *p)
|
||||
: QIODevice(parent)
|
||||
, d_ptr(p)
|
||||
{
|
||||
Q_D(SocketApiSocket);
|
||||
d->q_ptr = this;
|
||||
open(ReadWrite);
|
||||
}
|
||||
|
||||
SocketApiSocket::~SocketApiSocket()
|
||||
{
|
||||
}
|
||||
|
||||
qint64 SocketApiSocket::readData(char *data, qint64 maxlen)
|
||||
{
|
||||
Q_D(SocketApiSocket);
|
||||
qint64 len = std::min(maxlen, static_cast<qint64>(d->inBuffer.size()));
|
||||
memcpy(data, d->inBuffer.constData(), len);
|
||||
d->inBuffer.remove(0, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
qint64 SocketApiSocket::writeData(const char *data, qint64 len)
|
||||
{
|
||||
@try {
|
||||
Q_D(SocketApiSocket);
|
||||
// FIXME: The NSConnection will make this block unless the function is marked as "oneway"
|
||||
// in the protocol. This isn't async and reduces our performances but this currectly avoids
|
||||
// a Mach queue deadlock during requests bursts of the legacy OwnCloudFinder extension.
|
||||
// Since FinderSync already runs in a separate process, blocking isn't too critical.
|
||||
[d->remoteEnd sendMessage:[NSData dataWithBytesNoCopy:const_cast<char *>(data) length:len freeWhenDone:NO]];
|
||||
return len;
|
||||
} @catch(NSException* e) {
|
||||
// connectionDidDie can be notified too late, also interpret any sending exception as a disconnection.
|
||||
emit disconnected();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 SocketApiSocket::bytesAvailable() const
|
||||
{
|
||||
Q_D(const SocketApiSocket);
|
||||
return d->inBuffer.size() + QIODevice::bytesAvailable();
|
||||
}
|
||||
|
||||
bool SocketApiSocket::canReadLine() const
|
||||
{
|
||||
Q_D(const SocketApiSocket);
|
||||
return d->inBuffer.indexOf('\n', int(pos())) != -1 || QIODevice::canReadLine();
|
||||
}
|
||||
|
||||
SocketApiSocketPrivate::SocketApiSocketPrivate(NSDistantObject <ChannelProtocol> *remoteEnd)
|
||||
: remoteEnd(remoteEnd)
|
||||
, localEnd([[LocalEnd alloc] initWithWrapper:this])
|
||||
{
|
||||
[remoteEnd retain];
|
||||
// (Ab)use our objective-c object just to catch the notification
|
||||
[[NSNotificationCenter defaultCenter] addObserver:localEnd
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification
|
||||
object:[remoteEnd connectionForProxy]];
|
||||
}
|
||||
|
||||
SocketApiSocketPrivate::~SocketApiSocketPrivate()
|
||||
{
|
||||
[remoteEnd release];
|
||||
// The DO vended localEnd might still be referenced by the connection
|
||||
localEnd.wrapper = nil;
|
||||
[localEnd release];
|
||||
}
|
||||
|
||||
SocketApiServer::SocketApiServer()
|
||||
: d_ptr(new SocketApiServerPrivate)
|
||||
{
|
||||
Q_D(SocketApiServer);
|
||||
d->q_ptr = this;
|
||||
}
|
||||
|
||||
SocketApiServer::~SocketApiServer()
|
||||
{
|
||||
}
|
||||
|
||||
void SocketApiServer::close()
|
||||
{
|
||||
// Assume we'll be destroyed right after
|
||||
}
|
||||
|
||||
bool SocketApiServer::listen(const QString &name)
|
||||
{
|
||||
Q_D(SocketApiServer);
|
||||
// Set the name of the root object
|
||||
return [d->connection registerName:name.toNSString()];
|
||||
}
|
||||
|
||||
SocketApiSocket *SocketApiServer::nextPendingConnection()
|
||||
{
|
||||
Q_D(SocketApiServer);
|
||||
return d->pendingConnections.takeFirst();
|
||||
}
|
||||
|
||||
SocketApiServerPrivate::SocketApiServerPrivate()
|
||||
{
|
||||
// Create the connection and server object to vend over Disributed Objects
|
||||
connection = [[NSConnection alloc] init];
|
||||
server = [[Server alloc] initWithWrapper:this];
|
||||
[connection setRootObject:server];
|
||||
}
|
||||
|
||||
SocketApiServerPrivate::~SocketApiServerPrivate()
|
||||
{
|
||||
[connection release];
|
||||
server.wrapper = nil;
|
||||
[server release];
|
||||
}
|
|
@ -13,7 +13,6 @@
|
|||
*/
|
||||
|
||||
#include "theme.h"
|
||||
#include "version.h"
|
||||
#include "configfile.h"
|
||||
#include "utility.h"
|
||||
#include "accessmanager.h"
|
||||
|
|
|
@ -183,6 +183,7 @@ void Utility::setLaunchOnStartup(const QString &appName, const QString& guiName,
|
|||
qint64 Utility::freeDiskSpace(const QString &path, bool *ok)
|
||||
{
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD) || defined(Q_OS_FREEBSD_KERNEL) || defined(Q_OS_NETBSD)
|
||||
Q_UNUSED(ok)
|
||||
struct statvfs stat;
|
||||
statvfs(path.toUtf8().data(), &stat);
|
||||
return (qint64) stat.f_bavail * stat.f_frsize;
|
||||
|
|
|
@ -69,6 +69,7 @@ bool hasLaunchOnStartup_private(const QString &)
|
|||
|
||||
void setLaunchOnStartup_private(const QString &appName, const QString& guiName, bool enable)
|
||||
{
|
||||
Q_UNUSED(appName)
|
||||
Q_UNUSED(guiName)
|
||||
QString filePath = QDir(QCoreApplication::applicationDirPath()+QLatin1String("/../..")).absolutePath();
|
||||
CFStringRef folderCFStr = CFStringCreateWithCString(0, filePath.toUtf8().data(), kCFStringEncodingUTF8);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#cmakedefine GIT_SHA1 "@GIT_SHA1@"
|
||||
|
||||
#define MIRALL_STRINGIFY(s) MIRALL_TOSTRING(s)
|
||||
#define MIRALL_TOSTRING(s) #s
|
||||
|
||||
|
|