├── .gitignore ├── LICENSE ├── QLNetcdf.xcodeproj └── project.pbxproj ├── QLnetcdf ├── GeneratePreviewForURL.m ├── GenerateThumbnailForURL.m ├── QLNetcdf-Info.plist ├── QLNetcdf-Prefix.pch ├── en.lproj │ └── InfoPlist.strings └── main.c ├── README.md └── images └── example0.png /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.DS_Store 3 | 4 | 5 | # user specific xcode files 6 | QLNetcdf.xcodeproj/project.xcworkspace/* 7 | QLNetcdf.xcodeproj/xcuserdata/* 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 tobey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /QLNetcdf.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E18D106D19C0FC5D00C893D1 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = E18D106B19C0FC5D00C893D1 /* LICENSE */; }; 11 | E18D106E19C0FC5D00C893D1 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = E18D106C19C0FC5D00C893D1 /* README.md */; }; 12 | E1A1603419BF9FCA00306185 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1A1603319BF9FCA00306185 /* QuickLook.framework */; }; 13 | E1A1603619BF9FCA00306185 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1A1603519BF9FCA00306185 /* ApplicationServices.framework */; }; 14 | E1A1603819BF9FCA00306185 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1A1603719BF9FCA00306185 /* CoreServices.framework */; }; 15 | E1A1603A19BF9FCA00306185 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1A1603919BF9FCA00306185 /* CoreFoundation.framework */; }; 16 | E1A1604019BF9FCA00306185 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E1A1603E19BF9FCA00306185 /* InfoPlist.strings */; }; 17 | E1A1604219BF9FCA00306185 /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A1604119BF9FCA00306185 /* GenerateThumbnailForURL.m */; }; 18 | E1A1604419BF9FCA00306185 /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A1604319BF9FCA00306185 /* GeneratePreviewForURL.m */; }; 19 | E1A1604619BF9FCA00306185 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = E1A1604519BF9FCA00306185 /* main.c */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | E18D103E19BFABB700C893D1 /* CopyFiles */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 1; 28 | files = ( 29 | ); 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXCopyFilesBuildPhase section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | E18D106B19C0FC5D00C893D1 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = SOURCE_ROOT; }; 36 | E18D106C19C0FC5D00C893D1 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = SOURCE_ROOT; }; 37 | E1A1603019BF9FCA00306185 /* QLNetcdf.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QLNetcdf.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | E1A1603319BF9FCA00306185 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; }; 39 | E1A1603519BF9FCA00306185 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; 40 | E1A1603719BF9FCA00306185 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; 41 | E1A1603919BF9FCA00306185 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 42 | E1A1603D19BF9FCA00306185 /* QLNetcdf-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QLNetcdf-Info.plist"; sourceTree = ""; }; 43 | E1A1603F19BF9FCA00306185 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 44 | E1A1604119BF9FCA00306185 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = ""; }; 45 | E1A1604319BF9FCA00306185 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; }; 46 | E1A1604519BF9FCA00306185 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 47 | E1A1604719BF9FCA00306185 /* QLNetcdf-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QLNetcdf-Prefix.pch"; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | E1A1602B19BF9FCA00306185 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | E1A1603A19BF9FCA00306185 /* CoreFoundation.framework in Frameworks */, 56 | E1A1603419BF9FCA00306185 /* QuickLook.framework in Frameworks */, 57 | E1A1603819BF9FCA00306185 /* CoreServices.framework in Frameworks */, 58 | E1A1603619BF9FCA00306185 /* ApplicationServices.framework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | E1A1602519BF9FCA00306185 = { 66 | isa = PBXGroup; 67 | children = ( 68 | E1A1603B19BF9FCA00306185 /* QLNetcdf */, 69 | E1A1603219BF9FCA00306185 /* Frameworks */, 70 | E1A1603119BF9FCA00306185 /* Products */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | E1A1603119BF9FCA00306185 /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | E1A1603019BF9FCA00306185 /* QLNetcdf.qlgenerator */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | E1A1603219BF9FCA00306185 /* Frameworks */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | E1A1603319BF9FCA00306185 /* QuickLook.framework */, 86 | E1A1603519BF9FCA00306185 /* ApplicationServices.framework */, 87 | E1A1603719BF9FCA00306185 /* CoreServices.framework */, 88 | E1A1603919BF9FCA00306185 /* CoreFoundation.framework */, 89 | ); 90 | name = Frameworks; 91 | sourceTree = ""; 92 | }; 93 | E1A1603B19BF9FCA00306185 /* QLNetcdf */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | E1A1604119BF9FCA00306185 /* GenerateThumbnailForURL.m */, 97 | E1A1604319BF9FCA00306185 /* GeneratePreviewForURL.m */, 98 | E1A1604519BF9FCA00306185 /* main.c */, 99 | E1A1603C19BF9FCA00306185 /* Supporting Files */, 100 | ); 101 | path = QLNetcdf; 102 | sourceTree = ""; 103 | }; 104 | E1A1603C19BF9FCA00306185 /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | E18D106B19C0FC5D00C893D1 /* LICENSE */, 108 | E18D106C19C0FC5D00C893D1 /* README.md */, 109 | E1A1603D19BF9FCA00306185 /* QLNetcdf-Info.plist */, 110 | E1A1603E19BF9FCA00306185 /* InfoPlist.strings */, 111 | E1A1604719BF9FCA00306185 /* QLNetcdf-Prefix.pch */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | /* End PBXGroup section */ 117 | 118 | /* Begin PBXHeadersBuildPhase section */ 119 | E1A1602C19BF9FCA00306185 /* Headers */ = { 120 | isa = PBXHeadersBuildPhase; 121 | buildActionMask = 2147483647; 122 | files = ( 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | /* End PBXHeadersBuildPhase section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | E1A1602F19BF9FCA00306185 /* QLNetcdf */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = E1A1604A19BF9FCA00306185 /* Build configuration list for PBXNativeTarget "QLNetcdf" */; 132 | buildPhases = ( 133 | E1A1602A19BF9FCA00306185 /* Sources */, 134 | E1A1602B19BF9FCA00306185 /* Frameworks */, 135 | E1A1602C19BF9FCA00306185 /* Headers */, 136 | E1A1602D19BF9FCA00306185 /* Resources */, 137 | E1A1602E19BF9FCA00306185 /* Rez */, 138 | E18D103E19BFABB700C893D1 /* CopyFiles */, 139 | ); 140 | buildRules = ( 141 | ); 142 | dependencies = ( 143 | ); 144 | name = QLNetcdf; 145 | productName = QLNetcdf; 146 | productReference = E1A1603019BF9FCA00306185 /* QLNetcdf.qlgenerator */; 147 | productType = "com.apple.product-type.bundle"; 148 | }; 149 | /* End PBXNativeTarget section */ 150 | 151 | /* Begin PBXProject section */ 152 | E1A1602619BF9FCA00306185 /* Project object */ = { 153 | isa = PBXProject; 154 | attributes = { 155 | LastUpgradeCheck = 0510; 156 | ORGANIZATIONNAME = tbc; 157 | }; 158 | buildConfigurationList = E1A1602919BF9FCA00306185 /* Build configuration list for PBXProject "QLNetcdf" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = English; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | en, 164 | ); 165 | mainGroup = E1A1602519BF9FCA00306185; 166 | productRefGroup = E1A1603119BF9FCA00306185 /* Products */; 167 | projectDirPath = ""; 168 | projectRoot = ""; 169 | targets = ( 170 | E1A1602F19BF9FCA00306185 /* QLNetcdf */, 171 | ); 172 | }; 173 | /* End PBXProject section */ 174 | 175 | /* Begin PBXResourcesBuildPhase section */ 176 | E1A1602D19BF9FCA00306185 /* Resources */ = { 177 | isa = PBXResourcesBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | E18D106E19C0FC5D00C893D1 /* README.md in Resources */, 181 | E18D106D19C0FC5D00C893D1 /* LICENSE in Resources */, 182 | E1A1604019BF9FCA00306185 /* InfoPlist.strings in Resources */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | /* End PBXResourcesBuildPhase section */ 187 | 188 | /* Begin PBXRezBuildPhase section */ 189 | E1A1602E19BF9FCA00306185 /* Rez */ = { 190 | isa = PBXRezBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXRezBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | E1A1602A19BF9FCA00306185 /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | E1A1604219BF9FCA00306185 /* GenerateThumbnailForURL.m in Sources */, 204 | E1A1604419BF9FCA00306185 /* GeneratePreviewForURL.m in Sources */, 205 | E1A1604619BF9FCA00306185 /* main.c in Sources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXSourcesBuildPhase section */ 210 | 211 | /* Begin PBXVariantGroup section */ 212 | E1A1603E19BF9FCA00306185 /* InfoPlist.strings */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | E1A1603F19BF9FCA00306185 /* en */, 216 | ); 217 | name = InfoPlist.strings; 218 | sourceTree = ""; 219 | }; 220 | /* End PBXVariantGroup section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | E1A1604819BF9FCA00306185 /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = YES; 227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 228 | CLANG_CXX_LIBRARY = "libc++"; 229 | CLANG_ENABLE_MODULES = YES; 230 | CLANG_ENABLE_OBJC_ARC = YES; 231 | CLANG_WARN_BOOL_CONVERSION = YES; 232 | CLANG_WARN_CONSTANT_CONVERSION = YES; 233 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 234 | CLANG_WARN_EMPTY_BODY = YES; 235 | CLANG_WARN_ENUM_CONVERSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 238 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 239 | CODE_SIGN_IDENTITY = ""; 240 | COPY_PHASE_STRIP = NO; 241 | GCC_C_LANGUAGE_STANDARD = gnu99; 242 | GCC_DYNAMIC_NO_PIC = NO; 243 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 244 | GCC_OPTIMIZATION_LEVEL = 0; 245 | GCC_PREPROCESSOR_DEFINITIONS = ( 246 | "DEBUG=1", 247 | "$(inherited)", 248 | ); 249 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 250 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 252 | GCC_WARN_UNDECLARED_SELECTOR = YES; 253 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 254 | GCC_WARN_UNUSED_FUNCTION = YES; 255 | GCC_WARN_UNUSED_VARIABLE = YES; 256 | MACOSX_DEPLOYMENT_TARGET = 10.6; 257 | ONLY_ACTIVE_ARCH = YES; 258 | SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; 259 | SDKROOT = macosx; 260 | }; 261 | name = Debug; 262 | }; 263 | E1A1604919BF9FCA00306185 /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = YES; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 268 | CLANG_CXX_LIBRARY = "libc++"; 269 | CLANG_ENABLE_MODULES = YES; 270 | CLANG_ENABLE_OBJC_ARC = YES; 271 | CLANG_WARN_BOOL_CONVERSION = YES; 272 | CLANG_WARN_CONSTANT_CONVERSION = YES; 273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 274 | CLANG_WARN_EMPTY_BODY = YES; 275 | CLANG_WARN_ENUM_CONVERSION = YES; 276 | CLANG_WARN_INT_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 279 | CODE_SIGN_IDENTITY = ""; 280 | COPY_PHASE_STRIP = YES; 281 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 282 | ENABLE_NS_ASSERTIONS = NO; 283 | GCC_C_LANGUAGE_STANDARD = gnu99; 284 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 287 | GCC_WARN_UNDECLARED_SELECTOR = YES; 288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 289 | GCC_WARN_UNUSED_FUNCTION = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | MACOSX_DEPLOYMENT_TARGET = 10.6; 292 | SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; 293 | SDKROOT = macosx; 294 | }; 295 | name = Release; 296 | }; 297 | E1A1604B19BF9FCA00306185 /* Debug */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | COMBINE_HIDPI_IMAGES = YES; 301 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 302 | GCC_PREFIX_HEADER = "QLNetcdf/QLNetcdf-Prefix.pch"; 303 | INFOPLIST_FILE = "QLNetcdf/QLNetcdf-Info.plist"; 304 | INSTALL_PATH = /Library/QuickLook; 305 | PRODUCT_NAME = "$(TARGET_NAME)"; 306 | WRAPPER_EXTENSION = qlgenerator; 307 | }; 308 | name = Debug; 309 | }; 310 | E1A1604C19BF9FCA00306185 /* Release */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | COMBINE_HIDPI_IMAGES = YES; 314 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 315 | GCC_PREFIX_HEADER = "QLNetcdf/QLNetcdf-Prefix.pch"; 316 | INFOPLIST_FILE = "QLNetcdf/QLNetcdf-Info.plist"; 317 | INSTALL_PATH = /Library/QuickLook; 318 | PRODUCT_NAME = "$(TARGET_NAME)"; 319 | WRAPPER_EXTENSION = qlgenerator; 320 | }; 321 | name = Release; 322 | }; 323 | /* End XCBuildConfiguration section */ 324 | 325 | /* Begin XCConfigurationList section */ 326 | E1A1602919BF9FCA00306185 /* Build configuration list for PBXProject "QLNetcdf" */ = { 327 | isa = XCConfigurationList; 328 | buildConfigurations = ( 329 | E1A1604819BF9FCA00306185 /* Debug */, 330 | E1A1604919BF9FCA00306185 /* Release */, 331 | ); 332 | defaultConfigurationIsVisible = 0; 333 | defaultConfigurationName = Release; 334 | }; 335 | E1A1604A19BF9FCA00306185 /* Build configuration list for PBXNativeTarget "QLNetcdf" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | E1A1604B19BF9FCA00306185 /* Debug */, 339 | E1A1604C19BF9FCA00306185 /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | /* End XCConfigurationList section */ 345 | }; 346 | rootObject = E1A1602619BF9FCA00306185 /* Project object */; 347 | } 348 | -------------------------------------------------------------------------------- /QLnetcdf/GeneratePreviewForURL.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #import 6 | 7 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 8 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 9 | 10 | void handle_error(int status); 11 | 12 | 13 | /* ----------------------------------------------------------------------------- 14 | Generate a preview for file 15 | 16 | This function's job is to create preview for designated file 17 | ----------------------------------------------------------------------------- */ 18 | 19 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) 20 | { 21 | // To complete your generator please implement the function GeneratePreviewForURL in GeneratePreviewForURL.c 22 | @autoreleasepool { 23 | NSString* filepath = (__bridge NSString*)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); 24 | 25 | //NSLog(@"This will print to the system.log..."); 26 | 27 | /* pretty much directly copied from here: 28 | http://stackoverflow.com/questions/412562/execute-a-terminal-command-from-a-cocoa-app/696942#696942 29 | */ 30 | NSTask *task; 31 | task = [[NSTask alloc] init]; 32 | [task setLaunchPath: @"/usr/local/bin/ncdump"]; 33 | 34 | NSArray *arguments; 35 | arguments = [NSArray arrayWithObjects: @"-h", filepath, nil]; 36 | [task setArguments: arguments]; 37 | 38 | NSPipe *pipe; 39 | pipe = [NSPipe pipe]; 40 | [task setStandardOutput: pipe]; 41 | 42 | NSFileHandle *file; 43 | file = [pipe fileHandleForReading]; 44 | 45 | [task launch]; 46 | 47 | NSData *data; 48 | data = [file readDataToEndOfFile]; 49 | 50 | NSString *ncdump_result; 51 | ncdump_result = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 52 | //NSLog (@"ncdump returned:\n%@", ncdump_result); 53 | 54 | NSData* ncdumpdata = [ncdump_result dataUsingEncoding:NSUTF8StringEncoding]; 55 | 56 | // Pass preview data to QuickLook 57 | QLPreviewRequestSetDataRepresentation(preview, 58 | (__bridge CFDataRef)ncdumpdata, 59 | kUTTypePlainText, 60 | NULL); 61 | 62 | } 63 | 64 | return noErr; 65 | } 66 | 67 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview) 68 | { 69 | // Implement only if supported 70 | } 71 | -------------------------------------------------------------------------------- /QLnetcdf/GenerateThumbnailForURL.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //#include 5 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 6 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail); 7 | 8 | /* ----------------------------------------------------------------------------- 9 | Generate a thumbnail for file 10 | 11 | This function's job is to create thumbnail for designated file as fast as possible 12 | ----------------------------------------------------------------------------- */ 13 | 14 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) 15 | { 16 | // To complete your generator please implement the function GenerateThumbnailForURL in GenerateThumbnailForURL.c 17 | return noErr; 18 | } 19 | 20 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail) 21 | { 22 | // Implement only if supported 23 | } 24 | -------------------------------------------------------------------------------- /QLnetcdf/QLNetcdf-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeRole 11 | QLGenerator 12 | LSItemContentTypes 13 | 14 | public.data 15 | public.item 16 | 17 | 18 | 19 | CFBundleExecutable 20 | ${EXECUTABLE_NAME} 21 | CFBundleIconFile 22 | 23 | CFBundleIdentifier 24 | tbc.${PRODUCT_NAME:rfc1034identifier} 25 | CFBundleInfoDictionaryVersion 26 | 6.0 27 | CFBundleName 28 | ${PRODUCT_NAME} 29 | CFBundleShortVersionString 30 | 0.0.3 31 | CFBundleVersion 32 | 0.0.3 33 | CFPlugInDynamicRegisterFunction 34 | 35 | CFPlugInDynamicRegistration 36 | NO 37 | CFPlugInFactories 38 | 39 | 02CF0A68-C9C0-4401-ADB2-C56749124887 40 | QuickLookGeneratorPluginFactory 41 | 42 | CFPlugInTypes 43 | 44 | 5E2D9680-5022-40FA-B806-43349622E5B9 45 | 46 | 02CF0A68-C9C0-4401-ADB2-C56749124887 47 | 48 | 49 | CFPlugInUnloadFunction 50 | 51 | NSHumanReadableCopyright 52 | Copyright © 2014 tbc. All rights reserved. 53 | QLNeedsToBeRunInMainThread 54 | 55 | QLPreviewHeight 56 | 600 57 | QLPreviewWidth 58 | 800 59 | QLSupportsConcurrentRequests 60 | 61 | QLThumbnailMinimumSize 62 | 17 63 | 64 | 65 | -------------------------------------------------------------------------------- /QLnetcdf/QLNetcdf-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | -------------------------------------------------------------------------------- /QLnetcdf/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /QLnetcdf/main.c: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // 3 | // DO NO MODIFY THE CONTENT OF THIS FILE 4 | // 5 | // This file contains the generic CFPlug-in code necessary for your generator 6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c 7 | // 8 | //============================================================================== 9 | 10 | 11 | 12 | 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // ----------------------------------------------------------------------------- 21 | // constants 22 | // ----------------------------------------------------------------------------- 23 | 24 | // Don't modify this line 25 | #define PLUGIN_ID "02CF0A68-C9C0-4401-ADB2-C56749124887" 26 | 27 | // 28 | // Below is the generic glue code for all plug-ins. 29 | // 30 | // You should not have to modify this code aside from changing 31 | // names if you decide to change the names defined in the Info.plist 32 | // 33 | 34 | 35 | // ----------------------------------------------------------------------------- 36 | // typedefs 37 | // ----------------------------------------------------------------------------- 38 | 39 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c 40 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 41 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); 42 | 43 | // The preview generation function to be implemented in GeneratePreviewForURL.c 44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 45 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 46 | 47 | // The layout for an instance of QuickLookGeneratorPlugIn 48 | typedef struct __QuickLookGeneratorPluginType 49 | { 50 | void *conduitInterface; 51 | CFUUIDRef factoryID; 52 | UInt32 refCount; 53 | } QuickLookGeneratorPluginType; 54 | 55 | // ----------------------------------------------------------------------------- 56 | // prototypes 57 | // ----------------------------------------------------------------------------- 58 | // Forward declaration for the IUnknown implementation. 59 | // 60 | 61 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); 62 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); 63 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); 64 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); 65 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); 66 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance); 67 | 68 | // ----------------------------------------------------------------------------- 69 | // myInterfaceFtbl definition 70 | // ----------------------------------------------------------------------------- 71 | // The QLGeneratorInterfaceStruct function table. 72 | // 73 | static QLGeneratorInterfaceStruct myInterfaceFtbl = { 74 | NULL, 75 | QuickLookGeneratorQueryInterface, 76 | QuickLookGeneratorPluginAddRef, 77 | QuickLookGeneratorPluginRelease, 78 | NULL, 79 | NULL, 80 | NULL, 81 | NULL 82 | }; 83 | 84 | 85 | // ----------------------------------------------------------------------------- 86 | // AllocQuickLookGeneratorPluginType 87 | // ----------------------------------------------------------------------------- 88 | // Utility function that allocates a new instance. 89 | // You can do some initial setup for the generator here if you wish 90 | // like allocating globals etc... 91 | // 92 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) 93 | { 94 | QuickLookGeneratorPluginType *theNewInstance; 95 | 96 | theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); 97 | memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); 98 | 99 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ 100 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); 101 | memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); 102 | 103 | /* Retain and keep an open instance refcount for each factory. */ 104 | theNewInstance->factoryID = CFRetain(inFactoryID); 105 | CFPlugInAddInstanceForFactory(inFactoryID); 106 | 107 | /* This function returns the IUnknown interface so set the refCount to one. */ 108 | theNewInstance->refCount = 1; 109 | return theNewInstance; 110 | } 111 | 112 | // ----------------------------------------------------------------------------- 113 | // DeallocQuickLookGeneratorPluginType 114 | // ----------------------------------------------------------------------------- 115 | // Utility function that deallocates the instance when 116 | // the refCount goes to zero. 117 | // In the current implementation generator interfaces are never deallocated 118 | // but implement this as this might change in the future 119 | // 120 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) 121 | { 122 | CFUUIDRef theFactoryID; 123 | 124 | theFactoryID = thisInstance->factoryID; 125 | /* Free the conduitInterface table up */ 126 | free(thisInstance->conduitInterface); 127 | 128 | /* Free the instance structure */ 129 | free(thisInstance); 130 | if (theFactoryID){ 131 | CFPlugInRemoveInstanceForFactory(theFactoryID); 132 | CFRelease(theFactoryID); 133 | } 134 | } 135 | 136 | // ----------------------------------------------------------------------------- 137 | // QuickLookGeneratorQueryInterface 138 | // ----------------------------------------------------------------------------- 139 | // Implementation of the IUnknown QueryInterface function. 140 | // 141 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) 142 | { 143 | CFUUIDRef interfaceID; 144 | 145 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); 146 | 147 | if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ 148 | /* If the Right interface was requested, bump the ref count, 149 | * set the ppv parameter equal to the instance, and 150 | * return good status. 151 | */ 152 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; 153 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; 154 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; 155 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; 156 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); 157 | *ppv = thisInstance; 158 | CFRelease(interfaceID); 159 | return S_OK; 160 | }else{ 161 | /* Requested interface unknown, bail with error. */ 162 | *ppv = NULL; 163 | CFRelease(interfaceID); 164 | return E_NOINTERFACE; 165 | } 166 | } 167 | 168 | // ----------------------------------------------------------------------------- 169 | // QuickLookGeneratorPluginAddRef 170 | // ----------------------------------------------------------------------------- 171 | // Implementation of reference counting for this type. Whenever an interface 172 | // is requested, bump the refCount for the instance. NOTE: returning the 173 | // refcount is a convention but is not required so don't rely on it. 174 | // 175 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) 176 | { 177 | ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; 178 | return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; 179 | } 180 | 181 | // ----------------------------------------------------------------------------- 182 | // QuickLookGeneratorPluginRelease 183 | // ----------------------------------------------------------------------------- 184 | // When an interface is released, decrement the refCount. 185 | // If the refCount goes to zero, deallocate the instance. 186 | // 187 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance) 188 | { 189 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; 190 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ 191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); 192 | return 0; 193 | }else{ 194 | return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; 195 | } 196 | } 197 | 198 | // ----------------------------------------------------------------------------- 199 | // QuickLookGeneratorPluginFactory 200 | // ----------------------------------------------------------------------------- 201 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) 202 | { 203 | QuickLookGeneratorPluginType *result; 204 | CFUUIDRef uuid; 205 | 206 | /* If correct type is being requested, allocate an 207 | * instance of kQLGeneratorTypeID and return the IUnknown interface. 208 | */ 209 | if (CFEqual(typeID,kQLGeneratorTypeID)){ 210 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); 211 | result = AllocQuickLookGeneratorPluginType(uuid); 212 | CFRelease(uuid); 213 | return result; 214 | } 215 | /* If the requested type is incorrect, return NULL. */ 216 | return NULL; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QLNetcdf 2 | ======== 3 | A QuickLook Plugin for previewing 4 | [NetCDF](http://www.unidata.ucar.edu/software/netcdf/) files. Use 'spacebar' 5 | when navigating in OSX Finder to view the "header" (info ouput by `ncdump -h`) 6 | for NetCDF files. 7 | 8 | __Requires that `ncdump` is installed at `/usr/local/bin` !__ 9 | 10 | Fortunately if you installed `netcdf` using [Homebrew](http://brew.sh) (with 11 | the default settings) then `ncdump` should exist in the correct location 12 | already. 13 | 14 | Example 15 | ------- 16 | Here is an example. 17 | 18 | ![Screen shot](/images/example0.png?raw=true "QLNetcdf generator in action") 19 | 20 | Installing 21 | ----------- 22 | Download one of the releases and copy the QLNetcdf.qlgenerator file to your 23 | `~/Library/QuickLook/` directory (or `/Library/QuickLook/` to make the plugin 24 | available to all users). 25 | 26 | You may have to force the QuickLook Server to reload so it picks up the new 27 | generator: 28 | 29 | $ qlmnange -r 30 | 31 | Known Issues 32 | ------------ 33 | Sometimes the plugin fails to work (no preview is rendered). The best fix I 34 | have found is to force-relaunch Finder (`cmd+option+esc`) 35 | 36 | Building 37 | -------- 38 | The xcode project file is supplied with the project. The project has been built 39 | with xcode 4.6 and xcode 5.1 40 | -------------------------------------------------------------------------------- /images/example0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobeycarman/QLNetcdf/aa8620f775262dc52e8e9bbde323494b77007ae2/images/example0.png --------------------------------------------------------------------------------