tdf#35361 Add a Quick Look plugins for .od* files on macOS

Implement simple Quick Look plugins that generate a preview and/or
thumbnail image using Apple's latest Quick Look APIs. The approach
is to load and render any thumbnail images that may have been
embedded in .od* files when they were last saved.

Fortunately, LibreOffice, OpenOffice, and NeoOffice have been
saving thumbnail images by default in .od* files since at least
the mid-2000s so this approach should work with most unencrypted
.od* files.

Note: the plugins appear to work in unsigned builds using the
following steps to enable them:

1. Install LibreOfficeDev.app from an unsigned .dmg (e.g. nightly
   master builds) but the plugins in instdir/LibreOfficeDev.app
   in a local build are not usable.

2. Launch LibreOfficeDev.app to register the plugins.

3. Launch the System Preferences application, navigate to the
   Login Items & Extensions panel, and in the Extensions section,
   click on the icon next to the Quick Look entry to see a list of
   installed extensions.

4. If macOS has successfully found and loaded the plugins, there
   should be two extensions listed under LibreOfficeDev. If they
   are disabled, enable both.

5. Press Command-Option-Escape, select the Finder in the dialog
   that appears, and press the Relaunch button.

The Finder should now display the thumbnail images in .od* files.

Change-Id: I094afbc56b684cc85b12ed996e060818bfe8ad46
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178393
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
Tested-by: Jenkins
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
This commit is contained in:
Patrick Luby
2025-01-10 21:19:33 +01:00
committed by Christian Lohmaier
parent a47ee4efce
commit 3eb7cdd6ec
30 changed files with 823 additions and 32 deletions
+6
View File
@@ -86,6 +86,8 @@ $(eval $(call gb_Helper_register_executables,NONE, \
listglyphs \
$(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \
$(if $(and $(ENABLE_GTKTILEDVIEWER), $(filter WNT,$(OS))), gtktiledviewer) \
$(if $(filter MACOSX,$(OS)),QuickLookPreview) \
$(if $(filter MACOSX,$(OS)),QuickLookThumbnail) \
))
$(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \
@@ -956,6 +958,10 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo,\
$(if $(filter $(OS),MACOSX), \
extensions_mdibundle \
extensions_OOoSpotlightImporter \
extensions_quicklookpreviewappex \
extensions_QuickLookPreview \
extensions_quicklookthumbnailappex \
extensions_QuickLookThumbnail \
) \
extras_autocorr \
extras_autotext \
+38
View File
@@ -0,0 +1,38 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#
$(eval $(call gb_Executable_Executable,QuickLookPreview))
$(eval $(call gb_Executable_set_include,QuickLookPreview,\
-I$(SRCDIR)/extensions/source/macosx/common \
$$(INCLUDE) \
))
$(eval $(call gb_Executable_add_ldflags,QuickLookPreview,\
-e _NSExtensionMain -fobjc-link-runtime -fapplication-extension \
))
$(eval $(call gb_Executable_add_objcobjects,QuickLookPreview,\
extensions/source/macosx/quicklookpreview/PreviewViewController \
))
$(eval $(call gb_Executable_use_system_darwin_frameworks,QuickLookPreview,\
AppKit \
Quartz \
))
$(eval $(call gb_Executable_use_static_libraries,QuickLookPreview,\
extensions_macosx_common \
))
$(eval $(call gb_Executable_use_external,QuickLookPreview,zlib))
# vim:set noet sw=4 ts=4:
@@ -0,0 +1,38 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#
$(eval $(call gb_Executable_Executable,QuickLookThumbnail))
$(eval $(call gb_Executable_set_include,QuickLookThumbnail,\
-I$(SRCDIR)/extensions/source/macosx/common \
$$(INCLUDE) \
))
$(eval $(call gb_Executable_add_ldflags,QuickLookThumbnail,\
-e _NSExtensionMain -fobjc-link-runtime -fapplication-extension \
))
$(eval $(call gb_Executable_add_objcobjects,QuickLookThumbnail,\
extensions/source/macosx/quicklookthumbnail/ThumbnailProvider \
))
$(eval $(call gb_Executable_use_system_darwin_frameworks,QuickLookThumbnail,\
AppKit \
QuickLookThumbnailing \
))
$(eval $(call gb_Executable_use_static_libraries,QuickLookThumbnail,\
extensions_macosx_common \
))
$(eval $(call gb_Executable_use_external,QuickLookThumbnail,zlib))
# vim:set noet sw=4 ts=4:
+10 -6
View File
@@ -11,18 +11,22 @@
$(eval $(call gb_Library_Bundle,OOoSpotlightImporter))
$(eval $(call gb_Library_set_include,OOoSpotlightImporter,\
-I$(SRCDIR)/extensions/source/macosx/common \
$$(INCLUDE) \
))
$(eval $(call gb_Library_add_objcobjects,OOoSpotlightImporter,\
extensions/source/macosx/spotlight/GetMetadataForFile \
extensions/source/macosx/spotlight/OOoContentDataParser \
extensions/source/macosx/spotlight/OOoMetaDataParser \
extensions/source/macosx/spotlight/OOoSpotlightImporter \
extensions/source/macosx/spotlight/main \
))
$(eval $(call gb_Library_use_static_libraries,OOoSpotlightImporter,\
extensions_macosx_common \
))
$(eval $(call gb_Library_use_system_darwin_frameworks,OOoSpotlightImporter,\
CoreFoundation \
Foundation \
CoreServices \
AppKit \
))
$(eval $(call gb_Library_use_external,OOoSpotlightImporter,zlib))
+7
View File
@@ -104,9 +104,16 @@ endif # WNT
ifeq ($(OS),MACOSX)
$(eval $(call gb_Module_add_targets,extensions,\
StaticLibrary_extensions_macosx_common \
Library_OOoSpotlightImporter \
Executable_QuickLookPreview \
Executable_QuickLookThumbnail \
Package_mdibundle \
Package_OOoSpotlightImporter \
Package_quicklookpreviewappex \
Package_QuickLookPreview \
Package_quicklookthumbnailappex \
Package_QuickLookThumbnail \
))
endif # OS=MACOSX
+14
View File
@@ -0,0 +1,14 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_Package_Package,extensions_QuickLookPreview,$(gb_Executable_BINDIR)))
$(eval $(call gb_Package_add_file,extensions_QuickLookPreview,PlugIns/QuickLookPreview.appex/Contents/MacOS/QuickLookPreview,QuickLookPreview))
# vim: set noet sw=4 ts=4:
+14
View File
@@ -0,0 +1,14 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_Package_Package,extensions_QuickLookThumbnail,$(gb_Executable_BINDIR)))
$(eval $(call gb_Package_add_file,extensions_QuickLookThumbnail,PlugIns/QuickLookThumbnail.appex/Contents/MacOS/QuickLookThumbnail,QuickLookThumbnail))
# vim: set noet sw=4 ts=4:
@@ -0,0 +1,19 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_Package_Package,extensions_quicklookpreviewappex,$(SRCDIR)/extensions/source/macosx/quicklookpreview/appex))
$(eval $(call gb_Package_add_files,extensions_quicklookpreviewappex,PlugIns/QuickLookPreview.appex/Contents,\
Info.plist \
))
$(eval $(call gb_Package_add_files,extensions_quicklookpreviewappex,PlugIns/QuickLookPreview.appex/Contents/Resources,\
))
# vim: set noet sw=4 ts=4:
@@ -0,0 +1,19 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_Package_Package,extensions_quicklookthumbnailappex,$(SRCDIR)/extensions/source/macosx/quicklookthumbnail/appex))
$(eval $(call gb_Package_add_files,extensions_quicklookthumbnailappex,PlugIns/QuickLookThumbnail.appex/Contents,\
Info.plist \
))
$(eval $(call gb_Package_add_files,extensions_quicklookthumbnailappex,PlugIns/QuickLookThumbnail.appex/Contents/Resources,\
))
# vim: set noet sw=4 ts=4:
@@ -0,0 +1,20 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_StaticLibrary_StaticLibrary,extensions_macosx_common))
$(eval $(call gb_StaticLibrary_add_objcobjects,extensions_macosx_common,\
extensions/source/macosx/common/OOoContentDataParser \
extensions/source/macosx/common/OOoManifestParser \
extensions/source/macosx/common/OOoMetaDataParser \
extensions/source/macosx/common/OOoSpotlightAndQuickLookImporter \
))
# vim: set noet sw=4 ts=4:
@@ -19,32 +19,40 @@
#import <Cocoa/Cocoa.h>
@interface OOoContentDataParser : NSObject <NSXMLParserDelegate> {
@interface OOoContentDataParser : NSObject <NSXMLParserDelegate>
{
// indicates if we are interested in an element's content
BOOL shouldReadCharacters;
// the MD importer's values
NSMutableDictionary *mdiValues;
NSMutableDictionary* mdiValues;
// all of the text inside a document
NSMutableString *textContent;
NSMutableString* textContent;
// the current element's content
NSMutableString *runningTextContent;
NSMutableString* runningTextContent;
}
- (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict;
// delegates
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser*)parser
didStartElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
attributes:(NSDictionary*)attributeDict;
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser*)parser
didEndElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
- (void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)string;
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError;
- (void)parserDidEndDocument:(NSXMLParser *)parser;
- (void)parserDidEndDocument:(NSXMLParser*)parser;
@end
@@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#import <Cocoa/Cocoa.h>
#define MEDIA_TYPE_PDF @"application/pdf"
#define MEDIA_TYPE_PNG @"image/png"
@interface OOoManifestParser : NSObject <NSXMLParserDelegate>
{
NSMutableDictionary* metaValues;
}
- (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict;
//delegates
- (void)parser:(NSXMLParser*)parser
didStartElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
attributes:(NSDictionary*)attributeDict;
- (void)parser:(NSXMLParser*)parser
didEndElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qName;
- (void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)string;
- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError;
@end
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#import "OOoManifestParser.h"
@implementation OOoManifestParser
- (id)init
{
if ((self = [super init]) != nil) {
metaValues = nil;
return self;
}
return nil;
}
- (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict
{
metaValues = dict;
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
[parser release];
metaValues = nil;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
(void) parser; // unused
(void) namespaceURI; // unused
(void) qualifiedName; // unused
if ([@"manifest:file-entry" isEqualToString:elementName]) {
NSString *mediaType = [attributeDict objectForKey:@"manifest:media-type"];
NSString *path = [attributeDict objectForKey:@"manifest:full-path"];
if (mediaType && path && [path length]) {
NSString *key = nil;
NSArray *mediaComponents = [mediaType componentsSeparatedByString:@"/"];
if (mediaComponents && [mediaComponents count] && [[mediaComponents objectAtIndex:0] isEqualToString:@"image"]) {
key = mediaType;
}
else if ([mediaType isEqualToString:MEDIA_TYPE_PDF]) {
key = MEDIA_TYPE_PDF;
}
else if (![mediaType length]) {
// NeoOffice sometimes adds PDF thumbnails with an emopty mime type
if ([path hasSuffix:@".pdf"])
key = MEDIA_TYPE_PDF;
// Just to be safe, add any PNG thumbnails
else if ([path hasSuffix:@".png"])
key = MEDIA_TYPE_PNG;
}
// OpenOffice, NeoOffice, and LibreOffice appear to only insert a
// single thumbnail per media type so ignore duplicate thumbnails
if (key && ![metaValues objectForKey:key])
[metaValues setObject:path forKey:key];
}
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
(void) parser; // unused
(void) namespaceURI; // unused
(void) qName; // unused
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
(void) parser; // unused
(void) string; // unused
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
//NSLog(@"parsing finished with error");
NSLog(@"Error %li, Description: %@, Line: %li, Column: %li", (long) [parseError code],
[[parser parserError] localizedDescription], (long) [parser lineNumber],
(long) [parser columnNumber]);
}
@end
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -19,28 +19,35 @@
#import <Cocoa/Cocoa.h>
@interface OOoMetaDataParser : NSObject <NSXMLParserDelegate> {
@interface OOoMetaDataParser : NSObject <NSXMLParserDelegate>
{
//indicates if content should be read
BOOL shouldReadCharacters;
//indicates if the current element is a custom metadata tag
BOOL isCustom;
NSMutableDictionary *metaValues;
NSMutableString *textCurrentElement;
NSString *customAttribute;
NSMutableDictionary* metaValues;
NSMutableString* textCurrentElement;
NSString* customAttribute;
}
- (void)parseXML:(NSData*)data intoDictionary:(NSMutableDictionary*)dict;
//delegates
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser*)parser
didStartElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
attributes:(NSDictionary*)attributeDict;
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser*)parser
didEndElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
- (void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)string;
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError;
@end
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -19,7 +19,7 @@
#import <Cocoa/Cocoa.h>
@interface OOoSpotlightImporter : NSObject
@interface OOoSpotlightAndQuickLookImporter : NSObject
{
}
@@ -27,11 +27,16 @@
contentType:(NSString*)contentTypeUTI
attributes:(NSMutableDictionary*)attributes;
- (NSImage*)importDocumentThumbnail:(NSString*)pathToFile;
- (NSFileHandle*)openZipFileAtPath:(NSString*)pathToFile;
- (NSData*)metaDataFileFromZip:(NSFileHandle*)unzipFile;
- (NSData*)contentDataFileFromZip:(NSFileHandle*)unzipFile;
- (NSData*)manifestFileFromZip:(NSFileHandle*)unzipFile;
@end
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -19,9 +19,10 @@
#import <zlib.h>
#import "OOoSpotlightImporter.h"
#import "OOoSpotlightAndQuickLookImporter.h"
#import "OOoMetaDataParser.h"
#import "OOoContentDataParser.h"
#import "OOoManifestParser.h"
/* a dictionary to hold the UTIs */
static NSDictionary *uti2kind;
@@ -338,7 +339,7 @@ static NSData *getUncompressedData(NSFileHandle *file, NSString *name)
}
}
@implementation OOoSpotlightImporter
@implementation OOoSpotlightAndQuickLookImporter
/* initialize is only called once the first time this class is loaded */
+ (void)initialize
@@ -437,6 +438,69 @@ static NSData *getUncompressedData(NSFileHandle *file, NSString *name)
return YES;
}
- (NSImage*)importDocumentThumbnail:(NSString*)pathToFile {
if (!pathToFile || ![pathToFile length])
return nil;
NSFileHandle *unzipFile = [self openZipFileAtPath:pathToFile];
if (!unzipFile)
return nil;
NSData *manifest = [self manifestFileFromZip:unzipFile];
if (!manifest) {
[unzipFile closeFile];
return nil;
}
[manifest retain];
NSMutableDictionary *attributes = [NSMutableDictionary new];
OOoManifestParser *parser = [OOoManifestParser new];
[parser parseXML:manifest intoDictionary:attributes];
[parser release];
NSMutableArray<NSString *> *pathArray = [NSMutableArray arrayWithCapacity:[attributes count]];
// NeoOffice files have a low resolution .pdf thumbnail so if there is a .pdf
// thumbnail available, use that
NSString *path = [attributes objectForKey:MEDIA_TYPE_PDF];
if (path && [path length])
[pathArray addObject:path];
// OpenOffice, NeoOffice, and LibreOffice files normally have a .png thumbnail
path = [attributes objectForKey:MEDIA_TYPE_PNG];
if (path && [path length])
[pathArray addObject:path];
for (NSString *key in [attributes allKeys]) {
if (![key length] || [key isEqualToString:MEDIA_TYPE_PDF] || [key isEqualToString:MEDIA_TYPE_PNG])
continue;
path = [attributes objectForKey:key];
if (path && [path length])
[pathArray addObject:path];
}
[attributes release];
[manifest release];
NSImage *image = nil;
for (path in pathArray) {
NSData *imageData = getUncompressedData(unzipFile, path);
if (imageData) {
image = [[NSImage alloc] initWithData:imageData];
if (image) {
[image autorelease];
break;
}
}
}
[unzipFile closeFile];
return image;
}
/* openZipFileAtPath returns the file as a valid data structure or nil otherwise*/
- (NSFileHandle*)openZipFileAtPath:(NSString*)pathToFile
{
@@ -481,6 +545,12 @@ static NSData *getUncompressedData(NSFileHandle *file, NSString *name)
return getUncompressedData(unzipFile, @"content.xml");
}
- (NSData*) manifestFileFromZip:(NSFileHandle*)unzipFile
{
if (unzipFile == nil)
return nil;
return getUncompressedData(unzipFile, @"META-INF/manifest.xml");
}
@end
@@ -0,0 +1,17 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>
@interface PreviewViewController : NSViewController <QLPreviewingController>
@end
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#import <Quartz/Quartz.h>
#import "PreviewViewController.h"
#import "OOoSpotlightAndQuickLookImporter.h"
@implementation PreviewViewController
- (void)preparePreviewOfFileAtURL:(NSURL *)url completionHandler:(void (^)(NSError * _Nullable))handler {
if (!url || ![url isFileURL]) {
handler([[NSError alloc] initWithDomain:NSURLErrorDomain code:NSURLErrorUnsupportedURL userInfo:nil]);
return;
}
NSAutoreleasePool *pool = [NSAutoreleasePool new];
OOoSpotlightAndQuickLookImporter *importer = [OOoSpotlightAndQuickLookImporter new];
NSImage *image = nil;
@try {
image = [importer importDocumentThumbnail:[url path]];
}
@catch (NSException *exception) {
NSLog(@"preparePreviewOfFileAtURL: Caught %@: %@", [exception name], [exception reason]);
}
[importer release];
if (!image) {
handler([[NSError alloc] initWithDomain:NSURLErrorDomain code:NSURLErrorUnsupportedURL userInfo:nil]);
[pool release];
return;
}
// Make image automatic scale to the size of the view while preserving the
// image's aspect ratio by using a CALayer to handle image drawing:
// https://stackoverflow.com/questions/23002653/nsimageview-image-aspect-fill
self.view.layer = [CALayer layer];
self.view.layer.contentsGravity = kCAGravityResizeAspect;
self.view.layer.contents = image;
self.view.wantsLayer = YES;
handler(nil);
[pool release];
}
@end
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -0,0 +1,75 @@
<?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">
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>LibreOffice Quick Look Preview</string>
<key>CFBundleExecutable</key>
<string>QuickLookPreview</string>
<key>CFBundleIdentifier</key>
<string>org.libreoffice.quicklookpreview</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>QuickLookPreview</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>QLIsDataBasedPreview</key>
<false/>
<key>QLSupportedContentTypes</key>
<array>
<string>org.openoffice.text</string>
<string>org.oasis-open.opendocument.text</string>
<string>org.openoffice.spreadsheet</string>
<string>org.oasis-open.opendocument.spreadsheet</string>
<string>org.openoffice.presentation</string>
<string>org.oasis-open.opendocument.presentation</string>
<string>org.openoffice.graphics</string>
<string>org.oasis-open.opendocument.graphics</string>
<string>org.openoffice.text-master</string>
<string>org.oasis-open.opendocument.text-master</string>
<string>org.openoffice.formula</string>
<string>org.oasis-open.opendocument.formula</string>
<string>org.openoffice.text-template</string>
<string>org.oasis-open.opendocument.text-template</string>
<string>org.openoffice.spreadsheet-template</string>
<string>org.oasis-open.opendocument.spreadsheet-template</string>
<string>org.openoffice.presentation-template</string>
<string>org.oasis-open.opendocument.presentation-template</string>
<string>org.openoffice.graphics-template</string>
<string>org.oasis-open.opendocument.graphics-template</string>
<string>org.oasis-open.opendocument.database</string>
</array>
<key>QLSupportsSearchableItems</key>
<false/>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.preview</string>
<key>NSExtensionPrincipalClass</key>
<string>PreviewViewController</string>
</dict>
</dict>
</plist>
@@ -0,0 +1,18 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#import <QuickLookThumbnailing/QuickLookThumbnailing.h>
NS_ASSUME_NONNULL_BEGIN
@interface ThumbnailProvider : QLThumbnailProvider
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#import <Quartz/Quartz.h>
#import "ThumbnailProvider.h"
#import "OOoSpotlightAndQuickLookImporter.h"
@implementation ThumbnailProvider
- (void)provideThumbnailForFileRequest:(QLFileThumbnailRequest *)request completionHandler:(void (^)(QLThumbnailReply * _Nullable, NSError * _Nullable))handler {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSImage *image = nil;
NSRect drawRect = NSMakeRect(0, 0, floorf(request.maximumSize.width), floorf(request.maximumSize.height));
if (request.fileURL && [request.fileURL isFileURL] && drawRect.size.width > 0 && drawRect.size.height > 0) {
OOoSpotlightAndQuickLookImporter *importer = [OOoSpotlightAndQuickLookImporter new];
@try {
image = [importer importDocumentThumbnail:[request.fileURL path]];
}
@catch (NSException *exception) {
NSLog(@"provideThumbnailForFileRequest: Caught %@: %@", [exception name], [exception reason]);
}
[importer release];
if (image) {
// The handler() function appears to run the drwaing block asyncronously
// so retain the image and release it in the drawing block.
[image retain];
NSSize imageSize = [image size];
CGFloat widthRatio = imageSize.width / request.maximumSize.width;
CGFloat heightRatio = imageSize.height / request.maximumSize.height;
// Eliminate an undrawn white edge in thumbnail by rounding down any
// scaling to the nearest integer.
if (widthRatio > heightRatio)
drawRect.size.height = floorf(imageSize.height / widthRatio);
else
drawRect.size.width = floorf(imageSize.width / heightRatio);
}
}
handler([QLThumbnailReply replyWithContextSize:drawRect.size currentContextDrawingBlock:^BOOL {
if (!image)
return NO;
[image drawInRect:drawRect];
[image release];
return YES;
}], nil);
[pool release];
}
@end
@@ -0,0 +1,73 @@
<?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">
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>LibreOffice Quick Look Thumbnail</string>
<key>CFBundleExecutable</key>
<string>QuickLookThumbnail</string>
<key>CFBundleIdentifier</key>
<string>org.libreoffice.quicklookthumbnail</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>QuickLookThumbnail</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>QLSupportedContentTypes</key>
<array>
<string>org.openoffice.text</string>
<string>org.oasis-open.opendocument.text</string>
<string>org.openoffice.spreadsheet</string>
<string>org.oasis-open.opendocument.spreadsheet</string>
<string>org.openoffice.presentation</string>
<string>org.oasis-open.opendocument.presentation</string>
<string>org.openoffice.graphics</string>
<string>org.oasis-open.opendocument.graphics</string>
<string>org.openoffice.text-master</string>
<string>org.oasis-open.opendocument.text-master</string>
<string>org.openoffice.formula</string>
<string>org.oasis-open.opendocument.formula</string>
<string>org.openoffice.text-template</string>
<string>org.oasis-open.opendocument.text-template</string>
<string>org.openoffice.spreadsheet-template</string>
<string>org.oasis-open.opendocument.spreadsheet-template</string>
<string>org.openoffice.presentation-template</string>
<string>org.oasis-open.opendocument.presentation-template</string>
<string>org.openoffice.graphics-template</string>
<string>org.oasis-open.opendocument.graphics-template</string>
<string>org.oasis-open.opendocument.database</string>
</array>
<key>QLThumbnailMinimumDimension</key>
<integer>0</integer>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.thumbnail</string>
<key>NSExtensionPrincipalClass</key>
<string>ThumbnailProvider</string>
</dict>
</dict>
</plist>
@@ -22,7 +22,7 @@
#include <Foundation/Foundation.h>
#include "GetMetadataForFile.h"
#import "OOoSpotlightImporter.h"
#import "OOoSpotlightAndQuickLookImporter.h"
/* -----------------------------------------------------------------------------
Get metadata attributes from file
@@ -42,7 +42,7 @@ Boolean GetMetadataForFile(void* thisInterface,
/* Return TRUE if successful, FALSE if there was no data provided */
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
OOoSpotlightImporter *importer = [OOoSpotlightImporter new];
OOoSpotlightAndQuickLookImporter *importer = [OOoSpotlightAndQuickLookImporter new];
Boolean importOK = NO;
@try {
+35
View File
@@ -65,6 +65,41 @@ Directory gid_Dir_Bundle_Contents_Library_Spotlight_Bundle_Contents
End
#endif
#ifdef MACOSX
Directory gid_Dir_Bundle_Contents_PlugIns
ParentID = gid_Dir_Bundle_Contents;
HostName = "PlugIns";
End
#endif
#ifdef MACOSX
Directory gid_Dir_Bundle_Contents_PlugIns_Preview
ParentID = gid_Dir_Bundle_Contents_PlugIns;
HostName = "QuickLookPreview.appex";
End
#endif
#ifdef MACOSX
Directory gid_Dir_Bundle_Contents_PlugIns_Preview_Contents
ParentID = gid_Dir_Bundle_Contents_PlugIns_Preview;
HostName = "Contents";
End
#endif
#ifdef MACOSX
Directory gid_Dir_Bundle_Contents_PlugIns_Thumbnail
ParentID = gid_Dir_Bundle_Contents_PlugIns;
HostName = "QuickLookThumbnail.appex";
End
#endif
#ifdef MACOSX
Directory gid_Dir_Bundle_Contents_PlugIns_Thumbnail_Contents
ParentID = gid_Dir_Bundle_Contents_PlugIns_Thumbnail;
HostName = "Contents";
End
#endif
#if defined MACOSX
Unixlink gid_Unixlink_Applications
BIN_FILE_BODY;
+14
View File
@@ -25,6 +25,7 @@ done
APP_BUNDLE="$1"
entitlements=
entitlements_helper=
entitlements_quicklookappex="--entitlements $SRCDIR/sysui/desktop/macosx/quicklookappex.entitlements"
application_identifier=
if test -n "$ENABLE_MACOSX_SANDBOX"; then
# In a sandboxed build executables need the entitlements
@@ -48,6 +49,12 @@ if test -z "$MACOSX_CODESIGNING_IDENTITY"; then
exit 1
fi
# Quick Look plugins will only load if with sandbox entitlements
find "$APP_BUNDLE" -name 'QuickLook*.appex' -type d |
while read appex; do
codesign --force --prefix=$MACOSX_BUNDLE_IDENTIFIER. --sign - $entitlements_quicklookappex "$appex" || exit 1
done
# Skip codesigning for non-release builds if there is no identity set but
# set entitlements to allow Xcode's Instruments application to connect to
# the application. Note: the following command fails on some Mac Intel
@@ -65,6 +72,7 @@ if test -z "$MACOSX_CODESIGNING_IDENTITY"; then
else
rm "$APP_BUNDLE/Contents/MacOS/soffice.withentitlements"
fi
exit 0
fi
@@ -117,6 +125,12 @@ while read bundle; do
codesign --force --prefix=$MACOSX_BUNDLE_IDENTIFIER. --sign "$MACOSX_CODESIGNING_IDENTITY" "$bundle" || exit 1
done
# Quick Look plugins will only load if with sandbox entitlements
find "$APP_BUNDLE" -name 'QuickLook*.appex' -type d |
while read appex; do
codesign --force --prefix=$MACOSX_BUNDLE_IDENTIFIER. --sign "$MACOSX_CODESIGNING_IDENTITY" $entitlements_quicklookappex "$appex" || exit 1
done
# Sign executables
find "$APP_BUNDLE/Contents/MacOS" -type f |
-3
View File
@@ -3538,9 +3538,6 @@ extensions/source/logging/logrecord.cxx
extensions/source/logging/logrecord.hxx
extensions/source/logging/methodguard.hxx
extensions/source/logging/plaintextformatter.cxx
extensions/source/macosx/spotlight/GetMetadataForFile.h
extensions/source/macosx/spotlight/OOoContentDataParser.h
extensions/source/macosx/spotlight/OOoMetaDataParser.h
extensions/source/ole/comifaces.hxx
extensions/source/ole/jscriptclasses.cxx
extensions/source/ole/jscriptclasses.hxx
+2
View File
@@ -66,6 +66,8 @@ endef
gb_StaticLibrary_add_cobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_cobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_cxxobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_objcobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_objcobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_cxxobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_objcxxobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
gb_StaticLibrary_add_objcxxobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
@@ -0,0 +1,10 @@
<?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.files.user-selected.read-only</key>
<true/>
</dict>
</plist>