diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a2eb27a4eb..5b76900f44 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,7 +18,6 @@ if(BUILD_TEMPLATE)
add_subdirectory(Tools/_TEMPLATE_)
endif(BUILD_TEMPLATE)
+# "if" clause moved into local CMakeLists.txt file to support Conda and Homebrew builds
+add_subdirectory(MacAppBundle)
-if(FREECAD_CREATE_MAC_APP)
- add_subdirectory(MacAppBundle)
-endif(FREECAD_CREATE_MAC_APP)
diff --git a/src/Gui/Thumbnail.cpp b/src/Gui/Thumbnail.cpp
index 4bc2d3a9ad..620d801e8a 100644
--- a/src/Gui/Thumbnail.cpp
+++ b/src/Gui/Thumbnail.cpp
@@ -106,7 +106,7 @@ void Thumbnail::SaveDocFile (Base::Writer &writer) const
if (App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/Document")->GetBool("AddThumbnailLogo",true)) {
// only scale app icon if an offscreen image could be created
- appIcon = appIcon.scaled(this->size / 4, this->size /4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ appIcon = appIcon.scaled(this->size / 4, this->size /4, Qt::KeepAspectRatio, Qt::SmoothTransformation);
px = BitmapFactory().merge(QPixmap::fromImage(img), appIcon, BitmapFactoryInst::BottomRight);
}
else {
diff --git a/src/MacAppBundle/CMakeLists.txt b/src/MacAppBundle/CMakeLists.txt
index 708821cf79..a6c72dcecd 100644
--- a/src/MacAppBundle/CMakeLists.txt
+++ b/src/MacAppBundle/CMakeLists.txt
@@ -1,3 +1,27 @@
+
+#
+# Build and install QuickLook for FCStd files (org.freecad.fcstd)
+# This is used by Homebrew and Conda/Mamba scripts alike.
+#
+if(FREECAD_CREATE_MAC_APP OR (APPLE AND BUILD_WITH_CONDA))
+ add_subdirectory(QuickLook)
+ install(
+ DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/QuickLook/QuicklookFCStd.qlgenerator"
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/Library/QuickLook"
+ )
+ install(
+ PROGRAMS "${PROJECT_BINARY_DIR}/src/MacAppBundle/QuickLook/QuicklookFCStd.framework/Versions/A/QuicklookFCStd"
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/Library/QuickLook/QuicklookFCStd.qlgenerator/Contents/MacOS/"
+ )
+endif()
+
+
+#
+# Build a Bundle in Homebrew.
+# This is ignored by Conda/Mamba build scripts.
+#
+if(FREECAD_CREATE_MAC_APP)
+
set(PYTHON_DIR_BASENAME python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
if(PYTHON_LIBRARY MATCHES "(.*Python\\.framework).*")
@@ -122,8 +146,8 @@ file(GLOB CONFIG_GCC "${HOMEBREW_PREFIX}/opt/gcc/lib/gcc/current")
execute_process(
COMMAND find -L /usr/local/Cellar/nglib -name MacOS
OUTPUT_VARIABLE CONFIG_NGLIB)
-
-install(CODE
+
+install(CODE
"message(STATUS \"Making bundle relocatable...\")
# The top-level CMakeLists.txt should prevent multiple package manager
# prefixes from being set, so the lib path will resolve correctly...
@@ -133,3 +157,5 @@ install(CODE
${APP_PATH} ${HOMEBREW_PREFIX}${MACPORTS_PREFIX}/lib ${CONFIG_ICU} ${CONFIG_LLVM} ${CONFIG_GCC} /usr/local/opt ${CONFIG_NGLIB} ${Qt5Core_DIR}/../../.. ${XCTEST_PATH} ${WEBKIT_FRAMEWORK_DIR}
)"
)
+
+endif(FREECAD_CREATE_MAC_APP)
diff --git a/src/MacAppBundle/FreeCAD.app/Contents/Info.plist b/src/MacAppBundle/FreeCAD.app/Contents/Info.plist
index c8683067e7..504a70123a 100644
--- a/src/MacAppBundle/FreeCAD.app/Contents/Info.plist
+++ b/src/MacAppBundle/FreeCAD.app/Contents/Info.plist
@@ -2,6 +2,56 @@
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleTypeExtensions
+
+ FCStd
+ FCMat
+ FCParam
+
+ CFBundleTypeIconFile
+ freecad-doc.icns
+ LSIsAppleDefaultForType
+
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleTypeExtensions
+
+ FCMacro
+ FCScript
+
+ CFBundleTypeIconFile
+ freecad-script.icns
+ LSIsAppleDefaultForType
+
+
+
+ UTExportedTypeDeclarations
+
+
+ UTTypeConformsTo
+
+ public.data
+
+ UTTypeDescription
+ FreeCAD Document
+ UTTypeIdentifier
+ org.freecad.fcstd
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ FCStd
+
+
+
+
CFBundleDevelopmentRegion
English
CFBundleExecutable
@@ -31,23 +81,8 @@
NSHumanReadableCopyright
NSPrincipalClass
- NSApplication
+ NSApplication
NSHighResolutionCapable
True
- CFBundleDocumentTypes
-
-
- CFBundleTypeRole
- Editor
- CFBundleTypeExtensions
-
- FCStd
-
- CFBundleTypeIconFile
- freecad-doc.icns
- LSIsAppleDefaultForType
-
-
-
diff --git a/src/MacAppBundle/FreeCAD.app/Contents/Resources/freecad-script.icns b/src/MacAppBundle/FreeCAD.app/Contents/Resources/freecad-script.icns
new file mode 100644
index 0000000000..377cafe86a
Binary files /dev/null and b/src/MacAppBundle/FreeCAD.app/Contents/Resources/freecad-script.icns differ
diff --git a/src/MacAppBundle/QuickLook/CMakeLists.txt b/src/MacAppBundle/QuickLook/CMakeLists.txt
new file mode 100644
index 0000000000..7ded90b6a8
--- /dev/null
+++ b/src/MacAppBundle/QuickLook/CMakeLists.txt
@@ -0,0 +1,35 @@
+
+#cmake_minimum_required(VERSION 3.23)
+#project(FCQuickLook)
+
+add_library(
+ QuicklookFCStd
+ SHARED
+ GeneratePreviewForURL.m
+ GenerateThumbnailForURL.m
+ main.c
+)
+
+set_target_properties(
+ QuicklookFCStd
+ PROPERTIES
+ FRAMEWORK TRUE
+ MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/QuicklookFCStd.qlgenerator/Contents/Info.plist"
+ #SUFFIX .qlgenerator
+)
+
+target_link_libraries(
+ QuicklookFCStd
+ "-framework AppKit"
+ "-framework ApplicationServices"
+ "-framework CoreData"
+ "-framework CoreFoundation"
+ "-framework CoreServices"
+ "-framework Foundation"
+ "-framework QuickLook"
+)
+
+set_target_properties(
+ QuicklookFCStd
+ PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks"
+)
diff --git a/src/MacAppBundle/QuickLook/GeneratePreviewForURL.m b/src/MacAppBundle/QuickLook/GeneratePreviewForURL.m
new file mode 100644
index 0000000000..2c0827e3a4
--- /dev/null
+++ b/src/MacAppBundle/QuickLook/GeneratePreviewForURL.m
@@ -0,0 +1,74 @@
+#include
+#include
+#include
+#include
+#include
+
+/* -----------------------------------------------------------------------------
+ Generate a preview for file
+
+ This function's job is to create preview for designated file
+ ----------------------------------------------------------------------------- */
+
+
+OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
+{
+ OSStatus ret = coreFoundationUnknownErr;
+
+ @autoreleasepool {
+
+ // unzip -qq -o -j -d /tmp ~/test.FCStd thumbnails/Thumbnail.png
+ // -qq : be really quiet
+ // -o : overwrite without prompt
+ // -j : don't create archive paths
+ // -d : destination path (create this path)
+ // extracts thumbnails/Thumbnail.png to /tmp/Thumbnail.png .
+ // We add a UUID and use a system temp directory here.
+
+ // TODO: do we need to release any of these resources?
+ NSUUID *uuid = [NSUUID UUID];
+ NSString *uuidPath = [uuid UUIDString];
+ NSString *unzipDstPath = [NSString stringWithFormat:@"%@/%@/", NSTemporaryDirectory(), uuidPath];
+ NSString *unzipDstFile = [NSString stringWithFormat:@"%@%@", unzipDstPath, @"Thumbnail.png"];
+ NSURL *zipFile = (__bridge NSURL *)url;
+ NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/unzip"
+ arguments:@[@"-qq", @"-o", @"-j", @"-d", unzipDstPath, [zipFile path], @"thumbnails/Thumbnail.png"]];
+ [task waitUntilExit];
+// NSLog(@"%@", unzipDstPath);
+// NSLog(@"%@", unzipDstFile);
+
+ if ( [[NSFileManager defaultManager] fileExistsAtPath:unzipDstFile] )
+ {
+ // Preview will be drawn in a vectorized context
+ CGSize canvasSize = CGSizeMake(512, 512);
+ CGContextRef cgContext = QLPreviewRequestCreateContext(preview, canvasSize, true, NULL);
+ if(cgContext)
+ {
+ CGDataProviderRef pngDP = CGDataProviderCreateWithFilename([unzipDstFile fileSystemRepresentation]);
+ CGImageRef image = CGImageCreateWithPNGDataProvider(pngDP, NULL, true, kCGRenderingIntentDefault);
+
+ CGContextDrawImage(cgContext,CGRectMake(0, 0, 512, 512), image);
+
+ QLPreviewRequestFlushContext(preview, cgContext);
+ ret = noErr;
+
+ CFRelease(cgContext);
+ CFRelease(image);
+ }
+ }
+
+ if ( [[NSFileManager defaultManager] fileExistsAtPath:unzipDstFile] )
+ [[NSFileManager defaultManager] removeItemAtPath:unzipDstFile error:nil];
+
+ if ( [[NSFileManager defaultManager] fileExistsAtPath:unzipDstPath] )
+ [[NSFileManager defaultManager] removeItemAtPath:unzipDstPath error:nil];
+ }
+
+ return ret;
+}
+
+
+void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
+{
+ // implement only if supported
+}
diff --git a/src/MacAppBundle/QuickLook/GenerateThumbnailForURL.m b/src/MacAppBundle/QuickLook/GenerateThumbnailForURL.m
new file mode 100644
index 0000000000..336c0d4f99
--- /dev/null
+++ b/src/MacAppBundle/QuickLook/GenerateThumbnailForURL.m
@@ -0,0 +1,72 @@
+#include
+#include
+#include
+#include
+#include
+
+/* -----------------------------------------------------------------------------
+ Generate a thumbnail for file
+
+ This function's job is to create thumbnail for designated file as fast as possible
+ ----------------------------------------------------------------------------- */
+
+OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
+{
+ OSStatus ret = coreFoundationUnknownErr;
+
+ @autoreleasepool {
+
+ // unzip -qq -o -j -d /tmp ~/test.FCStd thumbnails/Thumbnail.png
+ // -qq : be really quiet
+ // -o : overwrite without prompt
+ // -j : don't create archive paths
+ // -d : destination path (create this path)
+ // extracts thumbnails/Thumbnail.png to /tmp/Thumbnail.png .
+ // We add a UUID and use a system temp directory here.
+
+ NSUUID *uuid = [NSUUID UUID];
+ NSString *uuidPath = [uuid UUIDString];
+ NSString *unzipDstPath = [NSString stringWithFormat:@"%@/%@/", NSTemporaryDirectory(), uuidPath];
+ NSString *unzipDstFile = [NSString stringWithFormat:@"%@%@", unzipDstPath, @"Thumbnail.png"];
+ NSURL *zipFile = (__bridge NSURL *)url;
+ NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/unzip"
+ arguments:@[@"-qq", @"-o", @"-j", @"-d", unzipDstPath, [zipFile path], @"thumbnails/Thumbnail.png"]];
+ [task waitUntilExit];
+ // NSLog(@"%@", unzipDstPath);
+ // NSLog(@"%@", unzipDstFile);
+
+ if ( [[NSFileManager defaultManager] fileExistsAtPath:unzipDstFile] )
+ {
+ CGSize canvasSize = CGSizeMake(128, 128);
+ CGContextRef cgContext = QLThumbnailRequestCreateContext(thumbnail, /*maxSize*/canvasSize, true, NULL);
+ if(cgContext)
+ {
+ CGDataProviderRef pngDP = CGDataProviderCreateWithFilename([unzipDstFile fileSystemRepresentation]);
+ CGImageRef image = CGImageCreateWithPNGDataProvider(pngDP, NULL, true, kCGRenderingIntentDefault);
+ CGDataProviderRelease(pngDP);
+
+ CGContextDrawImage(cgContext,CGRectMake(0, 0, 128, 128), image);
+
+ QLThumbnailRequestFlushContext(thumbnail, cgContext);
+ ret = noErr;
+
+ CFRelease(cgContext);
+ CFRelease(image);
+ }
+ }
+
+ if ( [[NSFileManager defaultManager] isDeletableFileAtPath:unzipDstFile] )
+ [[NSFileManager defaultManager] removeItemAtPath:unzipDstFile error:nil];
+
+ if ( [[NSFileManager defaultManager] isDeletableFileAtPath:unzipDstPath] )
+ [[NSFileManager defaultManager] removeItemAtPath:unzipDstPath error:nil];
+ }
+
+ return ret;
+}
+
+
+void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail)
+{
+ // implement only if supported
+}
diff --git a/src/MacAppBundle/QuickLook/QuicklookFCStd.qlgenerator/Contents/Info.plist b/src/MacAppBundle/QuickLook/QuicklookFCStd.qlgenerator/Contents/Info.plist
new file mode 100644
index 0000000000..c7e5a51687
--- /dev/null
+++ b/src/MacAppBundle/QuickLook/QuicklookFCStd.qlgenerator/Contents/Info.plist
@@ -0,0 +1,106 @@
+
+
+
+
+ BuildMachineOSBuild
+ 21G83
+ CFBundleDevelopmentRegion
+ English
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeRole
+ QLGenerator
+ LSItemContentTypes
+
+ org.freecad.fcstd
+
+
+
+ CFBundleExecutable
+ QuicklookFCStd
+ CFBundleIdentifier
+ org.freecad.qlgenerator.QuicklookFCStd
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ QuicklookFCStd
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSupportedPlatforms
+
+ MacOSX
+
+ CFBundleVersion
+ 0
+ CFPlugInDynamicRegisterFunction
+
+ CFPlugInDynamicRegistration
+ YES
+ CFPlugInFactories
+
+ F70BD796-FE76-450B-83CC-609688F17873
+ QuickLookGeneratorPluginFactory
+
+ CFPlugInTypes
+
+ 5E2D9680-5022-40FA-B806-43349622E5B9
+
+ F70BD796-FE76-450B-83CC-609688F17873
+
+
+ CFPlugInUnloadFunction
+
+ DTCompiler
+ com.apple.compilers.llvm.clang.1_0
+ DTPlatformBuild
+ 13F100
+ DTPlatformName
+ macosx
+ DTPlatformVersion
+ 12.3
+ DTSDKBuild
+ 21E226
+ DTSDKName
+ macosx12.3
+ DTXcode
+ 1341
+ DTXcodeBuild
+ 13F100
+ LSMinimumSystemVersion
+ 12.3
+ QLNeedsToBeRunInMainThread
+
+ QLPreviewHeight
+ 512
+ QLPreviewWidth
+ 512
+ QLSupportsConcurrentRequests
+
+ QLThumbnailMinimumSize
+ 17
+ UTImportedTypeDeclarations
+
+
+ UTTypeConformsTo
+
+ public.data
+ public.archive
+
+ UTTypeDescription
+ FreeCAD document
+ UTTypeIdentifier
+ org.freecad.fcstd
+ UTTypeReferenceURL
+ https://wiki.freecad.org/File_Format_FCStd/id
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ FCStd
+
+
+
+
+
+
diff --git a/src/MacAppBundle/QuickLook/main.c b/src/MacAppBundle/QuickLook/main.c
new file mode 100644
index 0000000000..aa320bf0f8
--- /dev/null
+++ b/src/MacAppBundle/QuickLook/main.c
@@ -0,0 +1,212 @@
+//==============================================================================
+//
+// DO NO MODIFY THE CONTENT OF THIS FILE
+//
+// This file contains the generic CFPlug-in code necessary for your generator
+// To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c
+//
+//==============================================================================
+
+#include
+#include
+#include
+#include
+
+// -----------------------------------------------------------------------------
+// constants
+// -----------------------------------------------------------------------------
+
+// Don't modify this line
+#define PLUGIN_ID "F70BD796-FE76-450B-83CC-609688F17873"
+
+//
+// Below is the generic glue code for all plug-ins.
+//
+// You should not have to modify this code aside from changing
+// names if you decide to change the names defined in the Info.plist
+//
+
+// -----------------------------------------------------------------------------
+// typedefs
+// -----------------------------------------------------------------------------
+
+// The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
+OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
+void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
+
+// The preview generation function to be implemented in GeneratePreviewForURL.c
+OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
+void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
+
+// The layout for an instance of QuickLookGeneratorPlugIn
+typedef struct __QuickLookGeneratorPluginType
+{
+ void *conduitInterface;
+ CFUUIDRef factoryID;
+ UInt32 refCount;
+} QuickLookGeneratorPluginType;
+
+// -----------------------------------------------------------------------------
+// prototypes
+// -----------------------------------------------------------------------------
+// Forward declaration for the IUnknown implementation.
+//
+
+QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
+void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance);
+HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
+void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
+ULONG QuickLookGeneratorPluginAddRef(void *thisInstance);
+ULONG QuickLookGeneratorPluginRelease(void *thisInstance);
+
+// -----------------------------------------------------------------------------
+// myInterfaceFtbl definition
+// -----------------------------------------------------------------------------
+// The QLGeneratorInterfaceStruct function table.
+//
+static QLGeneratorInterfaceStruct myInterfaceFtbl = {
+ NULL,
+ QuickLookGeneratorQueryInterface,
+ QuickLookGeneratorPluginAddRef,
+ QuickLookGeneratorPluginRelease,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+// -----------------------------------------------------------------------------
+// AllocQuickLookGeneratorPluginType
+// -----------------------------------------------------------------------------
+// Utility function that allocates a new instance.
+// You can do some initial setup for the generator here if you wish
+// like allocating globals etc...
+//
+QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)
+{
+ QuickLookGeneratorPluginType *theNewInstance;
+
+ theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType));
+ memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType));
+
+ /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */
+ theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct));
+ memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct));
+
+ /* Retain and keep an open instance refcount for each factory. */
+ theNewInstance->factoryID = CFRetain(inFactoryID);
+ CFPlugInAddInstanceForFactory(inFactoryID);
+
+ /* This function returns the IUnknown interface so set the refCount to one. */
+ theNewInstance->refCount = 1;
+ return theNewInstance;
+}
+
+// -----------------------------------------------------------------------------
+// DeallocQuickLookGeneratorPluginType
+// -----------------------------------------------------------------------------
+// Utility function that deallocates the instance when
+// the refCount goes to zero.
+// In the current implementation generator interfaces are never deallocated
+// but implement this as this might change in the future
+//
+void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance)
+{
+ CFUUIDRef theFactoryID;
+
+ theFactoryID = thisInstance->factoryID;
+ /* Free the conduitInterface table up */
+ free(thisInstance->conduitInterface);
+
+ /* Free the instance structure */
+ free(thisInstance);
+ if (theFactoryID){
+ CFPlugInRemoveInstanceForFactory(theFactoryID);
+ CFRelease(theFactoryID);
+ }
+}
+
+// -----------------------------------------------------------------------------
+// QuickLookGeneratorQueryInterface
+// -----------------------------------------------------------------------------
+// Implementation of the IUnknown QueryInterface function.
+//
+HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
+{
+ CFUUIDRef interfaceID;
+
+ interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
+
+ if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){
+ /* If the Right interface was requested, bump the ref count,
+ * set the ppv parameter equal to the instance, and
+ * return good status.
+ */
+ ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL;
+ ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration;
+ ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL;
+ ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration;
+ ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance);
+ *ppv = thisInstance;
+ CFRelease(interfaceID);
+ return S_OK;
+ }else{
+ /* Requested interface unknown, bail with error. */
+ *ppv = NULL;
+ CFRelease(interfaceID);
+ return E_NOINTERFACE;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// QuickLookGeneratorPluginAddRef
+// -----------------------------------------------------------------------------
+// Implementation of reference counting for this type. Whenever an interface
+// is requested, bump the refCount for the instance. NOTE: returning the
+// refcount is a convention but is not required so don't rely on it.
+//
+ULONG QuickLookGeneratorPluginAddRef(void *thisInstance)
+{
+ ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1;
+ return ((QuickLookGeneratorPluginType*) thisInstance)->refCount;
+}
+
+// -----------------------------------------------------------------------------
+// QuickLookGeneratorPluginRelease
+// -----------------------------------------------------------------------------
+// When an interface is released, decrement the refCount.
+// If the refCount goes to zero, deallocate the instance.
+//
+ULONG QuickLookGeneratorPluginRelease(void *thisInstance)
+{
+ ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1;
+ if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){
+ DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance );
+ return 0;
+ }else{
+ return ((QuickLookGeneratorPluginType*) thisInstance )->refCount;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// QuickLookGeneratorPluginFactory
+// -----------------------------------------------------------------------------
+void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
+{
+ QuickLookGeneratorPluginType *result;
+ CFUUIDRef uuid;
+
+ /* If correct type is being requested, allocate an
+ * instance of kQLGeneratorTypeID and return the IUnknown interface.
+ */
+ if (CFEqual(typeID,kQLGeneratorTypeID)){
+ uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
+ result = AllocQuickLookGeneratorPluginType(uuid);
+ CFRelease(uuid);
+ return result;
+ }
+ /* If the requested type is incorrect, return NULL. */
+ return NULL;
+}
+