1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 13:17:43 +00:00

MacPDF: Start converting to document architecture

Cmd-O now produces an Open... dialog, and opening a PDF file reads it
(and then creates the old LagomPDFView object, which then reads
a hardcoded PDF again and displays that. One thing at a time.)

"Open Recent>" is also populated and seems to work.

See the guide:
https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/DocBasedAppProgrammingGuideForOSX/Introduction/Introduction.html
This commit is contained in:
Nico Weber 2023-09-21 14:04:52 -04:00 committed by Andreas Kling
parent 77b311f00a
commit 0a01a2c82b
7 changed files with 181 additions and 25 deletions

View file

@ -29,9 +29,4 @@
return YES;
}
- (IBAction)openDocument:(id)sender
{
NSLog(@"open");
}
@end

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -12,11 +12,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate">
<connections>
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
@ -680,16 +676,5 @@
</items>
<point key="canvasLocation" x="200" y="121"/>
</menu>
<window title="SerenityPDF" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="335" y="390" width="705" height="1017"/>
<rect key="screenRect" x="0.0" y="0.0" width="1728" height="1079"/>
<view key="contentView" id="EiT-Mj-1SZ" customClass="LagomPDFView">
<rect key="frame" x="0.0" y="0.0" width="705" height="1017"/>
<autoresizingMask key="autoresizingMask"/>
</view>
<point key="canvasLocation" x="312.5" y="728.5"/>
</window>
</objects>
</document>

View file

@ -0,0 +1,23 @@
<?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>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>PDF</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>com.adobe.pdf</string>
</array>
<key>NSDocumentClass</key>
<string>LagomPDFDocument</string>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,19 @@
//
// LagomPDFDocument.h
// SerenityPDF
//
// Created by Nico Weber on 9/21/23.
//
// Several AK types conflict with MacOS types.
#define FixedPoint FixedPointMacOS
#import <Cocoa/Cocoa.h>
#undef FixedPoint
NS_ASSUME_NONNULL_BEGIN
@interface LagomPDFDocument : NSDocument
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,99 @@
//
// LagomPDFDocument.m
// SerenityPDF
//
// Created by Nico Weber on 9/21/23.
//
#import "LagomPDFDocument.h"
// Several AK types conflict with MacOS types.
#define FixedPoint FixedPointMacOS
#import <Cocoa/Cocoa.h>
#undef FixedPoint
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#include <LibCore/File.h>
#include <LibCore/MappedFile.h>
#include <LibGfx/Bitmap.h>
#include <LibPDF/Document.h>
#include <LibPDF/Renderer.h>
@interface LagomPDFDocument ()
{
NSData* _data; // Strong, _doc refers to it.
RefPtr<PDF::Document> _doc;
}
@end
@implementation LagomPDFDocument
- (PDF::PDFErrorOr<NonnullRefPtr<PDF::Document>>)load:(NSData*)data
{
auto document = TRY(PDF::Document::create(ReadonlyBytes { [data bytes], [data length] }));
TRY(document->initialize());
return document;
}
- (NSString*)windowNibName
{
// Override to return the nib file name of the document.
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"LagomPDFDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController*)aController
{
[super windowControllerDidLoadNib:aController];
// Add any code here that needs to be executed once the windowController has loaded the document's window.
}
- (NSData*)dataOfType:(NSString*)typeName error:(NSError**)outError
{
// Insert code here to write your document to data of the specified type. If outError != NULL, ensure that you create and set an appropriate error if you return nil.
// Alternatively, you could remove this method and override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
if (outError) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:nil];
}
return nil;
}
- (BOOL)readFromData:(NSData*)data ofType:(NSString*)typeName error:(NSError**)outError
{
// Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error if you return NO.
// Alternatively, you could remove this method and override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
// If you do, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded.
if (![[UTType typeWithIdentifier:typeName] conformsToType:UTTypePDF]) {
if (outError) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain
code:unimpErr
userInfo:nil];
}
return NO;
}
if (auto doc_or = [self load:data]; !doc_or.is_error()) {
_doc = doc_or.value();
_data = data;
// [self pageChanged];
return YES;
} else {
NSLog(@"failed to load: %@", @(doc_or.error().message().characters()));
if (outError) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain
code:unimpErr
userInfo:nil];
}
return NO;
}
}
+ (BOOL)autosavesInPlace
{
return YES;
}
@end

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="LagomPDFDocument">
<connections>
<outlet property="window" destination="xOd-HO-29H" id="JIz-fz-R2o"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="133" y="235" width="507" height="413"/>
<rect key="screenRect" x="0.0" y="0.0" width="1728" height="1079"/>
<value key="minSize" type="size" width="94" height="86"/>
<view key="contentView" id="gIp-Ho-8D9" customClass="LagomPDFView">
<rect key="frame" x="0.0" y="0.0" width="507" height="413"/>
<autoresizingMask key="autoresizingMask"/>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-x8E"/>
</connections>
<point key="canvasLocation" x="80" y="126"/>
</window>
</objects>
</document>

View file

@ -69,6 +69,9 @@ static NSBitmapImageRep* ns_from_gfx(NonnullRefPtr<Gfx::Bitmap> bitmap_p)
Gfx::FontDatabase::set_default_fonts_lookup_path(DeprecatedString::formatted("{}/Base/res/fonts", source_root));
_file = TRY(Core::MappedFile::map("/Users/thakis/Downloads/pdf_reference_1-7.pdf"sv));
// _file = TRY(Core::MappedFile::map("/Users/thakis/Downloads/DC-008-Translation-2023-E.pdf"sv));
// _file = TRY(Core::MappedFile::map("/Users/thakis/Downloads/ISO_32000-2-2020_sponsored.pdf"sv));
// _file = TRY(Core::MappedFile::map("/Users/thakis/Downloads/Text.pdf"sv));
auto document = TRY(PDF::Document::create(_file->bytes()));
TRY(document->initialize());
return document;
@ -87,7 +90,7 @@ static NSBitmapImageRep* ns_from_gfx(NonnullRefPtr<Gfx::Bitmap> bitmap_p)
{
static bool did_load = false;
if (!did_load) {
_page_index = 0;
_page_index = 24 - 1;
did_load = true;
if (auto doc_or = [self load]; !doc_or.is_error()) {
_doc = doc_or.value();