Add files via upload

This commit is contained in:
Norbert Schmidt
2018-05-15 12:31:48 +02:00
committed by GitHub
parent 2921a8f4e4
commit 89c0c04881
84 changed files with 9532 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,530 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
F09BBB9717B7C6C400900F01 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F09BBB9617B7C6C300900F01 /* UIKit.framework */; };
F09BBB9917B7C6C400900F01 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F09BBB9817B7C6C400900F01 /* Foundation.framework */; };
F09BBB9B17B7C6C400900F01 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F09BBB9A17B7C6C400900F01 /* CoreGraphics.framework */; };
F09BBBA117B7C6C400900F01 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F09BBB9F17B7C6C400900F01 /* InfoPlist.strings */; };
F09BBBA317B7C6C400900F01 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBA217B7C6C400900F01 /* main.m */; };
F09BBBA717B7C6C400900F01 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBA617B7C6C400900F01 /* AppDelegate.m */; };
F09BBBA917B7C6C400900F01 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBBA817B7C6C400900F01 /* Default.png */; };
F09BBBAB17B7C6C400900F01 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBBAA17B7C6C400900F01 /* Default@2x.png */; };
F09BBBAD17B7C6C400900F01 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBBAC17B7C6C400900F01 /* Default-568h@2x.png */; };
F09BBBBD17B7C6DC00900F01 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F09BBBBC17B7C6DC00900F01 /* QuartzCore.framework */; };
F09BBBBF17B7C6E600900F01 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F09BBBBE17B7C6E600900F01 /* ImageIO.framework */; };
F09BBBC117B7C6F100900F01 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F09BBBC017B7C6F100900F01 /* MessageUI.framework */; };
F09BBBF417B7C8BC00900F01 /* CGPDFDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBCD17B7C8BC00900F01 /* CGPDFDocument.m */; };
F09BBBF517B7C8BC00900F01 /* ReaderConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBCF17B7C8BC00900F01 /* ReaderConstants.m */; };
F09BBBF617B7C8BC00900F01 /* ReaderContentPage.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBD117B7C8BC00900F01 /* ReaderContentPage.m */; };
F09BBBF717B7C8BC00900F01 /* ReaderContentTile.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBD317B7C8BC00900F01 /* ReaderContentTile.m */; };
F09BBBF817B7C8BC00900F01 /* ReaderContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBD517B7C8BC00900F01 /* ReaderContentView.m */; };
F09BBBF917B7C8BC00900F01 /* ReaderDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBD717B7C8BC00900F01 /* ReaderDocument.m */; };
F09BBBFA17B7C8BC00900F01 /* ReaderDocumentOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBD917B7C8BC00900F01 /* ReaderDocumentOutline.m */; };
F09BBBFB17B7C8BC00900F01 /* ReaderMainPagebar.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBDB17B7C8BC00900F01 /* ReaderMainPagebar.m */; };
F09BBBFC17B7C8BC00900F01 /* ReaderMainToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBDD17B7C8BC00900F01 /* ReaderMainToolbar.m */; };
F09BBBFD17B7C8BC00900F01 /* ReaderThumbCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBDF17B7C8BC00900F01 /* ReaderThumbCache.m */; };
F09BBBFE17B7C8BC00900F01 /* ReaderThumbFetch.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBE117B7C8BC00900F01 /* ReaderThumbFetch.m */; };
F09BBBFF17B7C8BC00900F01 /* ReaderThumbQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBE317B7C8BC00900F01 /* ReaderThumbQueue.m */; };
F09BBC0017B7C8BC00900F01 /* ReaderThumbRender.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBE517B7C8BC00900F01 /* ReaderThumbRender.m */; };
F09BBC0117B7C8BC00900F01 /* ReaderThumbRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBE717B7C8BC00900F01 /* ReaderThumbRequest.m */; };
F09BBC0217B7C8BC00900F01 /* ReaderThumbsView.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBE917B7C8BC00900F01 /* ReaderThumbsView.m */; };
F09BBC0317B7C8BC00900F01 /* ReaderThumbView.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBEB17B7C8BC00900F01 /* ReaderThumbView.m */; };
F09BBC0417B7C8BC00900F01 /* ReaderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBED17B7C8BC00900F01 /* ReaderViewController.m */; };
F09BBC0517B7C8BC00900F01 /* ThumbsMainToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBEF17B7C8BC00900F01 /* ThumbsMainToolbar.m */; };
F09BBC0617B7C8BC00900F01 /* ThumbsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBF117B7C8BC00900F01 /* ThumbsViewController.m */; };
F09BBC0717B7C8BC00900F01 /* UIXToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBBF317B7C8BC00900F01 /* UIXToolbarView.m */; };
F09BBC0E17B7C8EA00900F01 /* ReaderAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBC0917B7C8EA00900F01 /* ReaderAppDelegate.m */; };
F09BBC0F17B7C8EA00900F01 /* ReaderBookDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBC0B17B7C8EA00900F01 /* ReaderBookDelegate.m */; };
F09BBC1017B7C8EA00900F01 /* ReaderDemoController.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBC0D17B7C8EA00900F01 /* ReaderDemoController.m */; };
F09BBC1D17B7D62B00900F01 /* NightReaderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F09BBC1B17B7D62A00900F01 /* NightReaderViewController.m */; };
F09BBC1E17B7D62B00900F01 /* NightReaderViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC1C17B7D62B00900F01 /* NightReaderViewController.xib */; };
F09BBC2317B8D4EB00900F01 /* NightReaderViewController-ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2117B8D4EB00900F01 /* NightReaderViewController-ipad.xib */; };
F09BBC2717B8DA2900900F01 /* 84-lightbulb.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2417B8DA2900900F01 /* 84-lightbulb.png */; };
F09BBC2817B8DA2900900F01 /* 84-lightbulb@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2517B8DA2900900F01 /* 84-lightbulb@2x.png */; };
F09BBC2917B8DA2900900F01 /* redslider2.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2617B8DA2900900F01 /* redslider2.png */; };
F09BBC3417B8E34100900F01 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2A17B8E34000900F01 /* Icon-72.png */; };
F09BBC3517B8E34100900F01 /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2B17B8E34000900F01 /* Icon-72@2x.png */; };
F09BBC3617B8E34100900F01 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2C17B8E34000900F01 /* Icon-Small-50.png */; };
F09BBC3717B8E34100900F01 /* Icon-Small-50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2D17B8E34000900F01 /* Icon-Small-50@2x.png */; };
F09BBC3817B8E34100900F01 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2E17B8E34000900F01 /* Icon-Small.png */; };
F09BBC3917B8E34100900F01 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC2F17B8E34000900F01 /* Icon-Small@2x.png */; };
F09BBC3A17B8E34100900F01 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC3017B8E34000900F01 /* Icon.png */; };
F09BBC3B17B8E34100900F01 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC3117B8E34100900F01 /* Icon@2x.png */; };
F09BBC3C17B8E34100900F01 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC3217B8E34100900F01 /* iTunesArtwork */; };
F09BBC3D17B8E34100900F01 /* iTunesArtwork@2x in Resources */ = {isa = PBXBuildFile; fileRef = F09BBC3317B8E34100900F01 /* iTunesArtwork@2x */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F09BBB9317B7C6C300900F01 /* Night Reader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Night Reader.app"; sourceTree = BUILT_PRODUCTS_DIR; };
F09BBB9617B7C6C300900F01 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
F09BBB9817B7C6C400900F01 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
F09BBB9A17B7C6C400900F01 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
F09BBB9E17B7C6C400900F01 /* Night Reader-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Night Reader-Info.plist"; sourceTree = "<group>"; };
F09BBBA017B7C6C400900F01 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F09BBBA217B7C6C400900F01 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
F09BBBA417B7C6C400900F01 /* Night Reader-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Night Reader-Prefix.pch"; sourceTree = "<group>"; };
F09BBBA517B7C6C400900F01 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
F09BBBA617B7C6C400900F01 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
F09BBBA817B7C6C400900F01 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
F09BBBAA17B7C6C400900F01 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; };
F09BBBAC17B7C6C400900F01 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
F09BBBBC17B7C6DC00900F01 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
F09BBBBE17B7C6E600900F01 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
F09BBBC017B7C6F100900F01 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
F09BBBCC17B7C8BC00900F01 /* CGPDFDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGPDFDocument.h; sourceTree = "<group>"; };
F09BBBCD17B7C8BC00900F01 /* CGPDFDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGPDFDocument.m; sourceTree = "<group>"; };
F09BBBCE17B7C8BC00900F01 /* ReaderConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderConstants.h; sourceTree = "<group>"; };
F09BBBCF17B7C8BC00900F01 /* ReaderConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderConstants.m; sourceTree = "<group>"; };
F09BBBD017B7C8BC00900F01 /* ReaderContentPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderContentPage.h; sourceTree = "<group>"; };
F09BBBD117B7C8BC00900F01 /* ReaderContentPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderContentPage.m; sourceTree = "<group>"; };
F09BBBD217B7C8BC00900F01 /* ReaderContentTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderContentTile.h; sourceTree = "<group>"; };
F09BBBD317B7C8BC00900F01 /* ReaderContentTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderContentTile.m; sourceTree = "<group>"; };
F09BBBD417B7C8BC00900F01 /* ReaderContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderContentView.h; sourceTree = "<group>"; };
F09BBBD517B7C8BC00900F01 /* ReaderContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderContentView.m; sourceTree = "<group>"; };
F09BBBD617B7C8BC00900F01 /* ReaderDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderDocument.h; sourceTree = "<group>"; };
F09BBBD717B7C8BC00900F01 /* ReaderDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderDocument.m; sourceTree = "<group>"; };
F09BBBD817B7C8BC00900F01 /* ReaderDocumentOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderDocumentOutline.h; sourceTree = "<group>"; };
F09BBBD917B7C8BC00900F01 /* ReaderDocumentOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderDocumentOutline.m; sourceTree = "<group>"; };
F09BBBDA17B7C8BC00900F01 /* ReaderMainPagebar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderMainPagebar.h; sourceTree = "<group>"; };
F09BBBDB17B7C8BC00900F01 /* ReaderMainPagebar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderMainPagebar.m; sourceTree = "<group>"; };
F09BBBDC17B7C8BC00900F01 /* ReaderMainToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderMainToolbar.h; sourceTree = "<group>"; };
F09BBBDD17B7C8BC00900F01 /* ReaderMainToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderMainToolbar.m; sourceTree = "<group>"; };
F09BBBDE17B7C8BC00900F01 /* ReaderThumbCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbCache.h; sourceTree = "<group>"; };
F09BBBDF17B7C8BC00900F01 /* ReaderThumbCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbCache.m; sourceTree = "<group>"; };
F09BBBE017B7C8BC00900F01 /* ReaderThumbFetch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbFetch.h; sourceTree = "<group>"; };
F09BBBE117B7C8BC00900F01 /* ReaderThumbFetch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbFetch.m; sourceTree = "<group>"; };
F09BBBE217B7C8BC00900F01 /* ReaderThumbQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbQueue.h; sourceTree = "<group>"; };
F09BBBE317B7C8BC00900F01 /* ReaderThumbQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbQueue.m; sourceTree = "<group>"; };
F09BBBE417B7C8BC00900F01 /* ReaderThumbRender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbRender.h; sourceTree = "<group>"; };
F09BBBE517B7C8BC00900F01 /* ReaderThumbRender.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbRender.m; sourceTree = "<group>"; };
F09BBBE617B7C8BC00900F01 /* ReaderThumbRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbRequest.h; sourceTree = "<group>"; };
F09BBBE717B7C8BC00900F01 /* ReaderThumbRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbRequest.m; sourceTree = "<group>"; };
F09BBBE817B7C8BC00900F01 /* ReaderThumbsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbsView.h; sourceTree = "<group>"; };
F09BBBE917B7C8BC00900F01 /* ReaderThumbsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbsView.m; sourceTree = "<group>"; };
F09BBBEA17B7C8BC00900F01 /* ReaderThumbView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderThumbView.h; sourceTree = "<group>"; };
F09BBBEB17B7C8BC00900F01 /* ReaderThumbView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderThumbView.m; sourceTree = "<group>"; };
F09BBBEC17B7C8BC00900F01 /* ReaderViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderViewController.h; sourceTree = "<group>"; };
F09BBBED17B7C8BC00900F01 /* ReaderViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderViewController.m; sourceTree = "<group>"; };
F09BBBEE17B7C8BC00900F01 /* ThumbsMainToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThumbsMainToolbar.h; sourceTree = "<group>"; };
F09BBBEF17B7C8BC00900F01 /* ThumbsMainToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThumbsMainToolbar.m; sourceTree = "<group>"; };
F09BBBF017B7C8BC00900F01 /* ThumbsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThumbsViewController.h; sourceTree = "<group>"; };
F09BBBF117B7C8BC00900F01 /* ThumbsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThumbsViewController.m; sourceTree = "<group>"; };
F09BBBF217B7C8BC00900F01 /* UIXToolbarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIXToolbarView.h; sourceTree = "<group>"; };
F09BBBF317B7C8BC00900F01 /* UIXToolbarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIXToolbarView.m; sourceTree = "<group>"; };
F09BBC0817B7C8EA00900F01 /* ReaderAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderAppDelegate.h; sourceTree = "<group>"; };
F09BBC0917B7C8EA00900F01 /* ReaderAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderAppDelegate.m; sourceTree = "<group>"; };
F09BBC0A17B7C8EA00900F01 /* ReaderBookDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderBookDelegate.h; sourceTree = "<group>"; };
F09BBC0B17B7C8EA00900F01 /* ReaderBookDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderBookDelegate.m; sourceTree = "<group>"; };
F09BBC0C17B7C8EA00900F01 /* ReaderDemoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaderDemoController.h; sourceTree = "<group>"; };
F09BBC0D17B7C8EA00900F01 /* ReaderDemoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderDemoController.m; sourceTree = "<group>"; };
F09BBC1A17B7D62A00900F01 /* NightReaderViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NightReaderViewController.h; sourceTree = "<group>"; };
F09BBC1B17B7D62A00900F01 /* NightReaderViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NightReaderViewController.m; sourceTree = "<group>"; };
F09BBC1C17B7D62B00900F01 /* NightReaderViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NightReaderViewController.xib; sourceTree = "<group>"; };
F09BBC2117B8D4EB00900F01 /* NightReaderViewController-ipad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "NightReaderViewController-ipad.xib"; sourceTree = "<group>"; };
F09BBC2417B8DA2900900F01 /* 84-lightbulb.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "84-lightbulb.png"; path = "Night Reader/84-lightbulb.png"; sourceTree = "<group>"; };
F09BBC2517B8DA2900900F01 /* 84-lightbulb@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "84-lightbulb@2x.png"; path = "Night Reader/84-lightbulb@2x.png"; sourceTree = "<group>"; };
F09BBC2617B8DA2900900F01 /* redslider2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = redslider2.png; path = "Night Reader/redslider2.png"; sourceTree = "<group>"; };
F09BBC2A17B8E34000900F01 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = "<group>"; };
F09BBC2B17B8E34000900F01 /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72@2x.png"; sourceTree = "<group>"; };
F09BBC2C17B8E34000900F01 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = "<group>"; };
F09BBC2D17B8E34000900F01 /* Icon-Small-50@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50@2x.png"; sourceTree = "<group>"; };
F09BBC2E17B8E34000900F01 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = "<group>"; };
F09BBC2F17B8E34000900F01 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small@2x.png"; sourceTree = "<group>"; };
F09BBC3017B8E34000900F01 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; };
F09BBC3117B8E34100900F01 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = "<group>"; };
F09BBC3217B8E34100900F01 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = "<group>"; };
F09BBC3317B8E34100900F01 /* iTunesArtwork@2x */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iTunesArtwork@2x"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F09BBB9017B7C6C300900F01 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F09BBBC117B7C6F100900F01 /* MessageUI.framework in Frameworks */,
F09BBBBF17B7C6E600900F01 /* ImageIO.framework in Frameworks */,
F09BBBBD17B7C6DC00900F01 /* QuartzCore.framework in Frameworks */,
F09BBB9717B7C6C400900F01 /* UIKit.framework in Frameworks */,
F09BBB9917B7C6C400900F01 /* Foundation.framework in Frameworks */,
F09BBB9B17B7C6C400900F01 /* CoreGraphics.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F09BBB8A17B7C6C300900F01 = {
isa = PBXGroup;
children = (
F09BBC3E17B8E6B700900F01 /* Artwork */,
F09BBB9C17B7C6C400900F01 /* Night Reader */,
F09BBB9517B7C6C300900F01 /* Frameworks */,
F09BBB9417B7C6C300900F01 /* Products */,
);
sourceTree = "<group>";
};
F09BBB9417B7C6C300900F01 /* Products */ = {
isa = PBXGroup;
children = (
F09BBB9317B7C6C300900F01 /* Night Reader.app */,
);
name = Products;
sourceTree = "<group>";
};
F09BBB9517B7C6C300900F01 /* Frameworks */ = {
isa = PBXGroup;
children = (
F09BBBC017B7C6F100900F01 /* MessageUI.framework */,
F09BBBBE17B7C6E600900F01 /* ImageIO.framework */,
F09BBBBC17B7C6DC00900F01 /* QuartzCore.framework */,
F09BBB9617B7C6C300900F01 /* UIKit.framework */,
F09BBB9817B7C6C400900F01 /* Foundation.framework */,
F09BBB9A17B7C6C400900F01 /* CoreGraphics.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
F09BBB9C17B7C6C400900F01 /* Night Reader */ = {
isa = PBXGroup;
children = (
F09BBBCB17B7C8A300900F01 /* Sources */,
F09BBBA517B7C6C400900F01 /* AppDelegate.h */,
F09BBBA617B7C6C400900F01 /* AppDelegate.m */,
F09BBC1A17B7D62A00900F01 /* NightReaderViewController.h */,
F09BBC1B17B7D62A00900F01 /* NightReaderViewController.m */,
F09BBC1C17B7D62B00900F01 /* NightReaderViewController.xib */,
F09BBC2117B8D4EB00900F01 /* NightReaderViewController-ipad.xib */,
F09BBB9D17B7C6C400900F01 /* Supporting Files */,
);
path = "Night Reader";
sourceTree = "<group>";
};
F09BBB9D17B7C6C400900F01 /* Supporting Files */ = {
isa = PBXGroup;
children = (
F09BBB9E17B7C6C400900F01 /* Night Reader-Info.plist */,
F09BBB9F17B7C6C400900F01 /* InfoPlist.strings */,
F09BBBA217B7C6C400900F01 /* main.m */,
F09BBBA417B7C6C400900F01 /* Night Reader-Prefix.pch */,
F09BBBA817B7C6C400900F01 /* Default.png */,
F09BBBAA17B7C6C400900F01 /* Default@2x.png */,
F09BBBAC17B7C6C400900F01 /* Default-568h@2x.png */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
F09BBBCB17B7C8A300900F01 /* Sources */ = {
isa = PBXGroup;
children = (
F09BBC0817B7C8EA00900F01 /* ReaderAppDelegate.h */,
F09BBC0917B7C8EA00900F01 /* ReaderAppDelegate.m */,
F09BBC0A17B7C8EA00900F01 /* ReaderBookDelegate.h */,
F09BBC0B17B7C8EA00900F01 /* ReaderBookDelegate.m */,
F09BBC0C17B7C8EA00900F01 /* ReaderDemoController.h */,
F09BBC0D17B7C8EA00900F01 /* ReaderDemoController.m */,
F09BBBCC17B7C8BC00900F01 /* CGPDFDocument.h */,
F09BBBCD17B7C8BC00900F01 /* CGPDFDocument.m */,
F09BBBCE17B7C8BC00900F01 /* ReaderConstants.h */,
F09BBBCF17B7C8BC00900F01 /* ReaderConstants.m */,
F09BBBD017B7C8BC00900F01 /* ReaderContentPage.h */,
F09BBBD117B7C8BC00900F01 /* ReaderContentPage.m */,
F09BBBD217B7C8BC00900F01 /* ReaderContentTile.h */,
F09BBBD317B7C8BC00900F01 /* ReaderContentTile.m */,
F09BBBD417B7C8BC00900F01 /* ReaderContentView.h */,
F09BBBD517B7C8BC00900F01 /* ReaderContentView.m */,
F09BBBD617B7C8BC00900F01 /* ReaderDocument.h */,
F09BBBD717B7C8BC00900F01 /* ReaderDocument.m */,
F09BBBD817B7C8BC00900F01 /* ReaderDocumentOutline.h */,
F09BBBD917B7C8BC00900F01 /* ReaderDocumentOutline.m */,
F09BBBDA17B7C8BC00900F01 /* ReaderMainPagebar.h */,
F09BBBDB17B7C8BC00900F01 /* ReaderMainPagebar.m */,
F09BBBDC17B7C8BC00900F01 /* ReaderMainToolbar.h */,
F09BBBDD17B7C8BC00900F01 /* ReaderMainToolbar.m */,
F09BBBDE17B7C8BC00900F01 /* ReaderThumbCache.h */,
F09BBBDF17B7C8BC00900F01 /* ReaderThumbCache.m */,
F09BBBE017B7C8BC00900F01 /* ReaderThumbFetch.h */,
F09BBBE117B7C8BC00900F01 /* ReaderThumbFetch.m */,
F09BBBE217B7C8BC00900F01 /* ReaderThumbQueue.h */,
F09BBBE317B7C8BC00900F01 /* ReaderThumbQueue.m */,
F09BBBE417B7C8BC00900F01 /* ReaderThumbRender.h */,
F09BBBE517B7C8BC00900F01 /* ReaderThumbRender.m */,
F09BBBE617B7C8BC00900F01 /* ReaderThumbRequest.h */,
F09BBBE717B7C8BC00900F01 /* ReaderThumbRequest.m */,
F09BBBE817B7C8BC00900F01 /* ReaderThumbsView.h */,
F09BBBE917B7C8BC00900F01 /* ReaderThumbsView.m */,
F09BBBEA17B7C8BC00900F01 /* ReaderThumbView.h */,
F09BBBEB17B7C8BC00900F01 /* ReaderThumbView.m */,
F09BBBEC17B7C8BC00900F01 /* ReaderViewController.h */,
F09BBBED17B7C8BC00900F01 /* ReaderViewController.m */,
F09BBBEE17B7C8BC00900F01 /* ThumbsMainToolbar.h */,
F09BBBEF17B7C8BC00900F01 /* ThumbsMainToolbar.m */,
F09BBBF017B7C8BC00900F01 /* ThumbsViewController.h */,
F09BBBF117B7C8BC00900F01 /* ThumbsViewController.m */,
F09BBBF217B7C8BC00900F01 /* UIXToolbarView.h */,
F09BBBF317B7C8BC00900F01 /* UIXToolbarView.m */,
);
name = Sources;
sourceTree = "<group>";
};
F09BBC3E17B8E6B700900F01 /* Artwork */ = {
isa = PBXGroup;
children = (
F09BBC2417B8DA2900900F01 /* 84-lightbulb.png */,
F09BBC2517B8DA2900900F01 /* 84-lightbulb@2x.png */,
F09BBC2617B8DA2900900F01 /* redslider2.png */,
F09BBC2A17B8E34000900F01 /* Icon-72.png */,
F09BBC2B17B8E34000900F01 /* Icon-72@2x.png */,
F09BBC2C17B8E34000900F01 /* Icon-Small-50.png */,
F09BBC2D17B8E34000900F01 /* Icon-Small-50@2x.png */,
F09BBC2E17B8E34000900F01 /* Icon-Small.png */,
F09BBC2F17B8E34000900F01 /* Icon-Small@2x.png */,
F09BBC3017B8E34000900F01 /* Icon.png */,
F09BBC3117B8E34100900F01 /* Icon@2x.png */,
F09BBC3217B8E34100900F01 /* iTunesArtwork */,
F09BBC3317B8E34100900F01 /* iTunesArtwork@2x */,
);
name = Artwork;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F09BBB9217B7C6C300900F01 /* Night Reader */ = {
isa = PBXNativeTarget;
buildConfigurationList = F09BBBB917B7C6C400900F01 /* Build configuration list for PBXNativeTarget "Night Reader" */;
buildPhases = (
F09BBB8F17B7C6C300900F01 /* Sources */,
F09BBB9017B7C6C300900F01 /* Frameworks */,
F09BBB9117B7C6C300900F01 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Night Reader";
productName = "Night Reader";
productReference = F09BBB9317B7C6C300900F01 /* Night Reader.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F09BBB8B17B7C6C300900F01 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "Norbert Schmidt";
};
buildConfigurationList = F09BBB8E17B7C6C300900F01 /* Build configuration list for PBXProject "Night Reader" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = F09BBB8A17B7C6C300900F01;
productRefGroup = F09BBB9417B7C6C300900F01 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F09BBB9217B7C6C300900F01 /* Night Reader */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F09BBB9117B7C6C300900F01 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F09BBBA117B7C6C400900F01 /* InfoPlist.strings in Resources */,
F09BBBA917B7C6C400900F01 /* Default.png in Resources */,
F09BBBAB17B7C6C400900F01 /* Default@2x.png in Resources */,
F09BBBAD17B7C6C400900F01 /* Default-568h@2x.png in Resources */,
F09BBC1E17B7D62B00900F01 /* NightReaderViewController.xib in Resources */,
F09BBC2317B8D4EB00900F01 /* NightReaderViewController-ipad.xib in Resources */,
F09BBC2717B8DA2900900F01 /* 84-lightbulb.png in Resources */,
F09BBC2817B8DA2900900F01 /* 84-lightbulb@2x.png in Resources */,
F09BBC2917B8DA2900900F01 /* redslider2.png in Resources */,
F09BBC3417B8E34100900F01 /* Icon-72.png in Resources */,
F09BBC3517B8E34100900F01 /* Icon-72@2x.png in Resources */,
F09BBC3617B8E34100900F01 /* Icon-Small-50.png in Resources */,
F09BBC3717B8E34100900F01 /* Icon-Small-50@2x.png in Resources */,
F09BBC3817B8E34100900F01 /* Icon-Small.png in Resources */,
F09BBC3917B8E34100900F01 /* Icon-Small@2x.png in Resources */,
F09BBC3A17B8E34100900F01 /* Icon.png in Resources */,
F09BBC3B17B8E34100900F01 /* Icon@2x.png in Resources */,
F09BBC3C17B8E34100900F01 /* iTunesArtwork in Resources */,
F09BBC3D17B8E34100900F01 /* iTunesArtwork@2x in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F09BBB8F17B7C6C300900F01 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F09BBBA317B7C6C400900F01 /* main.m in Sources */,
F09BBBA717B7C6C400900F01 /* AppDelegate.m in Sources */,
F09BBBF417B7C8BC00900F01 /* CGPDFDocument.m in Sources */,
F09BBBF517B7C8BC00900F01 /* ReaderConstants.m in Sources */,
F09BBBF617B7C8BC00900F01 /* ReaderContentPage.m in Sources */,
F09BBBF717B7C8BC00900F01 /* ReaderContentTile.m in Sources */,
F09BBBF817B7C8BC00900F01 /* ReaderContentView.m in Sources */,
F09BBBF917B7C8BC00900F01 /* ReaderDocument.m in Sources */,
F09BBBFA17B7C8BC00900F01 /* ReaderDocumentOutline.m in Sources */,
F09BBBFB17B7C8BC00900F01 /* ReaderMainPagebar.m in Sources */,
F09BBBFC17B7C8BC00900F01 /* ReaderMainToolbar.m in Sources */,
F09BBBFD17B7C8BC00900F01 /* ReaderThumbCache.m in Sources */,
F09BBBFE17B7C8BC00900F01 /* ReaderThumbFetch.m in Sources */,
F09BBBFF17B7C8BC00900F01 /* ReaderThumbQueue.m in Sources */,
F09BBC0017B7C8BC00900F01 /* ReaderThumbRender.m in Sources */,
F09BBC0117B7C8BC00900F01 /* ReaderThumbRequest.m in Sources */,
F09BBC0217B7C8BC00900F01 /* ReaderThumbsView.m in Sources */,
F09BBC0317B7C8BC00900F01 /* ReaderThumbView.m in Sources */,
F09BBC0417B7C8BC00900F01 /* ReaderViewController.m in Sources */,
F09BBC0517B7C8BC00900F01 /* ThumbsMainToolbar.m in Sources */,
F09BBC0617B7C8BC00900F01 /* ThumbsViewController.m in Sources */,
F09BBC0717B7C8BC00900F01 /* UIXToolbarView.m in Sources */,
F09BBC0E17B7C8EA00900F01 /* ReaderAppDelegate.m in Sources */,
F09BBC0F17B7C8EA00900F01 /* ReaderBookDelegate.m in Sources */,
F09BBC1017B7C8EA00900F01 /* ReaderDemoController.m in Sources */,
F09BBC1D17B7D62B00900F01 /* NightReaderViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F09BBB9F17B7C6C400900F01 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
F09BBBA017B7C6C400900F01 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F09BBBB717B7C6C400900F01 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F09BBBB817B7C6C400900F01 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F09BBBBA17B7C6C400900F01 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Distribution: Stichting Klinisch Wetenschappelijk Onderzoek Slotervaartziekenhuis (94KAKB756Z)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Stichting Klinisch Wetenschappelijk Onderzoek Slotervaartziekenhuis (94KAKB756Z)";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Night Reader/Night Reader-Prefix.pch";
INFOPLIST_FILE = "Night Reader/Night Reader-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "A2DA4094-40CD-40A9-8FDA-5A589F41622C";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "A2DA4094-40CD-40A9-8FDA-5A589F41622C";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
F09BBBBB17B7C6C400900F01 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Distribution: Stichting Klinisch Wetenschappelijk Onderzoek Slotervaartziekenhuis (94KAKB756Z)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Stichting Klinisch Wetenschappelijk Onderzoek Slotervaartziekenhuis (94KAKB756Z)";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Night Reader/Night Reader-Prefix.pch";
INFOPLIST_FILE = "Night Reader/Night Reader-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "A2DA4094-40CD-40A9-8FDA-5A589F41622C";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "A2DA4094-40CD-40A9-8FDA-5A589F41622C";
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F09BBB8E17B7C6C300900F01 /* Build configuration list for PBXProject "Night Reader" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F09BBBB717B7C6C400900F01 /* Debug */,
F09BBBB817B7C6C400900F01 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F09BBBB917B7C6C400900F01 /* Build configuration list for PBXNativeTarget "Night Reader" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F09BBBBA17B7C6C400900F01 /* Debug */,
F09BBBBB17B7C6C400900F01 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F09BBB8B17B7C6C300900F01 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Night Reader.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -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>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "1.0">
<FileBreakpoints>
<FileBreakpoint
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Night Reader/NightReaderViewController.m"
timestampString = "399385334.697816"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "86"
endingLineNumber = "86"
landmarkName = "-tableView:cellForRowAtIndexPath:"
landmarkType = "5">
</FileBreakpoint>
</FileBreakpoints>
</Bucket>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Night Reader/NightReaderViewController.m"
timestampString = "399385334.697816"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "86"
endingLineNumber = "86"
landmarkName = "-tableView:cellForRowAtIndexPath:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,22 @@
<?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>SchemeUserState</key>
<dict>
<key>Night Reader.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>F09BBB9217B7C6C300900F01</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F09BBB9217B7C6C300900F01"
BuildableName = "Night Reader.app"
BlueprintName = "Night Reader"
ReferencedContainer = "container:Night Reader.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,22 @@
<?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>SchemeUserState</key>
<dict>
<key>Night Reader.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>F09BBB9217B7C6C300900F01</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,19 @@
//
// AppDelegate.h
// Night Reader
//
// Created by Norbert Schmidt on 11-08-13.
// Copyright (c) 2013 Norbert Schmidt. All rights reserved.
//
#import <UIKit/UIKit.h>
@class NightReaderViewController;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NightReaderViewController *viewController;
@end

View File

@@ -0,0 +1,56 @@
//
// AppDelegate.m
// Night Reader
//
// Created by Norbert Schmidt on 11-08-13.
// Copyright (c) 2013 Norbert Schmidt. All rights reserved.
//
#import "AppDelegate.h"
#import "NightReaderViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[NightReaderViewController alloc] initWithNibName:@"NightReaderViewController" bundle:nil];
} else {
self.viewController = [[NightReaderViewController alloc] initWithNibName:@"NightReaderViewController-ipad" bundle:nil];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

View File

@@ -0,0 +1,35 @@
//
// CGPDFDocument.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
//
// Custom CGPDFDocument[...] functions
//
CGPDFDocumentRef CGPDFDocumentCreateX(CFURLRef theURL, NSString *password);
BOOL CGPDFDocumentNeedsPassword(CFURLRef theURL, NSString *password);

View File

@@ -0,0 +1,136 @@
//
// CGPDFDocument.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "CGPDFDocument.h"
//
// CGPDFDocumentRef CGPDFDocumentCreateX(CFURLRef, NSString *) function
//
// OF HIER DOEN NOP
CGPDFDocumentRef CGPDFDocumentCreateX(CFURLRef theURL, NSString *password)
{
CGPDFDocumentRef thePDFDocRef = NULL;
if (theURL != NULL) // Check for non-NULL CFURLRef
{
thePDFDocRef = CGPDFDocumentCreateWithURL(theURL);
if (thePDFDocRef != NULL) // Check for non-NULL CGPDFDocumentRef
{
if (CGPDFDocumentIsEncrypted(thePDFDocRef) == TRUE) // Encrypted
{
// Try a blank password first, per Apple's Quartz PDF example
if (CGPDFDocumentUnlockWithPassword(thePDFDocRef, "") == FALSE)
{
// Nope, now let's try the provided password to unlock the PDF
if ((password != nil) && ([password length] > 0)) // Not blank?
{
char text[128]; // char array buffer for the string conversion
[password getCString:text maxLength:126 encoding:NSUTF8StringEncoding];
if (CGPDFDocumentUnlockWithPassword(thePDFDocRef, text) == FALSE) // Log failure
{
#ifdef DEBUG
NSLog(@"CGPDFDocumentCreateX: Unable to unlock [%@] with [%@]", theURL, password);
#endif
}
}
}
if (CGPDFDocumentIsUnlocked(thePDFDocRef) == FALSE) // Cleanup unlock failure
{
CGPDFDocumentRelease(thePDFDocRef), thePDFDocRef = NULL;
}
}
}
}
else // Log an error diagnostic
{
#ifdef DEBUG
NSLog(@"CGPDFDocumentCreateX: theURL == NULL");
#endif
}
return thePDFDocRef;
}
//
// BOOL CGPDFDocumentNeedsPassword(CFURLRef, NSString *) function
//
BOOL CGPDFDocumentNeedsPassword(CFURLRef theURL, NSString *password)
{
BOOL needPassword = NO; // Default flag
if (theURL != NULL) // Check for non-NULL CFURLRef
{
CGPDFDocumentRef thePDFDocRef = CGPDFDocumentCreateWithURL(theURL);
if (thePDFDocRef != NULL) // Check for non-NULL CGPDFDocumentRef
{
if (CGPDFDocumentIsEncrypted(thePDFDocRef) == TRUE) // Encrypted
{
// Try a blank password first, per Apple's Quartz PDF example
if (CGPDFDocumentUnlockWithPassword(thePDFDocRef, "") == FALSE)
{
// Nope, now let's try the provided password to unlock the PDF
if ((password != nil) && ([password length] > 0)) // Not blank?
{
char text[128]; // char array buffer for the string conversion
[password getCString:text maxLength:126 encoding:NSUTF8StringEncoding];
if (CGPDFDocumentUnlockWithPassword(thePDFDocRef, text) == FALSE)
{
needPassword = YES;
}
}
else
{
needPassword = YES;
}
}
}
CGPDFDocumentRelease(thePDFDocRef); // Cleanup CGPDFDocumentRef
}
}
else // Log an error diagnostic
{
#ifdef DEBUG
NSLog(@"CGPDFDocumentNeedsPassword: theURL == NULL");
#endif
}
return needPassword;
}
// EOF

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>Night Reader</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon.png</string>
<string>Icon@2x.png</string>
</array>
<key>UIPrerenderedIcon</key>
<true/>
</dict>
</dict>
<key>CFBundleIdentifier</key>
<string>nl.slz.30minutes</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>
<key>UIPrerenderedIcon</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIStatusBarHidden</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,14 @@
//
// Prefix header for all source files of the 'Night Reader' target in the 'Night Reader' project
//
#import <Availability.h>
#ifndef __IPHONE_4_0
#warning "This project uses features only available in iOS SDK 4.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif

View File

@@ -0,0 +1,257 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1552</int>
<string key="IBDocument.SystemVersion">12E55</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.39</string>
<string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">2083</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIButton</string>
<string>IBUILabel</string>
<string>IBUITableView</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBProxyObject" id="606714003">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBUIView" id="766721923">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUITableView" id="52920729">
<reference key="NSNextResponder" ref="766721923"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{0, 49}, {768, 955}}</string>
<reference key="NSSuperview" ref="766721923"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<bool key="IBUIBounces">NO</bool>
<int key="IBUIIndicatorStyle">1</int>
<bool key="IBUIBouncesZoom">NO</bool>
<int key="IBUISeparatorStyle">1</int>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">44</float>
<float key="IBUISectionHeaderHeight">22</float>
<float key="IBUISectionFooterHeight">22</float>
</object>
<object class="IBUIButton" id="978391863">
<reference key="NSNextResponder" ref="766721923"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{730, 13}, {18, 19}}</string>
<reference key="NSSuperview" ref="766721923"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="52920729"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">4</int>
<bool key="IBUIShowsTouchWhenHighlighted">YES</bool>
<object class="NSColor" key="IBUIHighlightedTitleColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUILabel" id="963390438">
<reference key="NSNextResponder" ref="766721923"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{273, 11}, {222, 21}}</string>
<reference key="NSSuperview" ref="766721923"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="978391863"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<string key="IBUIText">Night Reader Documents</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC42NTA5ODA0MTMgMCAwAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC42NTA5ODA0MTMgMCAwAA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
</array>
<string key="NSFrameSize">{768, 1004}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="963390438"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xNTUwNzQxMzkgMC4xNTUwNzQxMzkgMC4xNTUwNzQxMzkAA</bytes>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="766721923"/>
</object>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">MaintableView</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="52920729"/>
</object>
<int key="connectionID">52</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="606714003"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="766721923"/>
<array class="NSMutableArray" key="children">
<reference ref="52920729"/>
<reference ref="963390438"/>
<reference ref="978391863"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">47</int>
<reference key="object" ref="52920729"/>
<reference key="parent" ref="766721923"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">48</int>
<reference key="object" ref="978391863"/>
<reference key="parent" ref="766721923"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">49</int>
<reference key="object" ref="963390438"/>
<reference key="parent" ref="766721923"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">NightReaderViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="47.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="48.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="49.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">52</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">NightReaderViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">MaintableView</string>
<string key="NS.object.0">UITableView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">MaintableView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">MaintableView</string>
<string key="candidateClassName">UITableView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/NightReaderViewController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">2083</string>
</data>
</archive>

View File

@@ -0,0 +1,21 @@
//
// ViewController.h
// FileSharingDemo
//
// Created by Kashif Jilani on 11/15/12.
// Copyright (c) 2012 Kashif Jilani. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ReaderViewController.h"
@interface NightReaderViewController : UIViewController <UIWebViewDelegate,UITabBarDelegate,UITableViewDataSource,ReaderViewControllerDelegate, UITableViewDelegate> {
IBOutlet UITableView *MaintableView;
NSArray *dataArray;
NSMutableArray *finalArray;
}
@property (nonatomic, retain) UITableView *MaintableView;
@end

View File

@@ -0,0 +1,173 @@
//
// ViewController.m
// FileSharingDemo
//
// Created by Kashif Jilani on 11/15/12.
// Copyright (c) 2012 Kashif Jilani. All rights reserved.
//
#import "NightReaderViewController.h"
@interface NightReaderViewController ()
@end
@implementation NightReaderViewController
@synthesize MaintableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[MaintableView
setBackgroundColor:[UIColor blackColor]];
[MaintableView setDelegate:self];
UIColor *NightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.8];
[MaintableView setSeparatorColor:NightColor];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *bundleDirectory = [fileManager contentsOfDirectoryAtPath:documentsPath error:nil];
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self ENDSWITH '.pdf'"];
dataArray = [bundleDirectory filteredArrayUsingPredicate:filter];
finalArray = [dataArray copy];
NSString *valueString = [[finalArray objectAtIndex:0] stringByDeletingPathExtension];
NSLog(@"Finalarray count %d", finalArray.count);
NSLog (@"Valuestring %@", valueString);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int x=[finalArray count];
// Return the number of rows in the section.
NSLog (@"x= %d", x);
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [MaintableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
// Configure the cell...
UIFont *myFont = [ UIFont fontWithName: @"System" size: 16.0 ];
cell.textLabel.font = myFont;
// Set up the cell...
UIColor *NightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.8];
UIColor *DarkNightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.3];
cell.textLabel.highlightedTextColor =DarkNightColor;
cell.textLabel.textColor=NightColor;
// [[cell textLabel] setText:contentForThisRow];
NSString *testje= [[finalArray objectAtIndex:indexPath.row] stringByDeletingPathExtension];
NSLog (@"Testje %@", testje);
cell.textLabel.text = testje;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
cell = [MaintableView cellForRowAtIndexPath:indexPath];
UIView *bgColorView = [[UIView alloc] init];
UIColor *DarkNightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.3];
UIColor *NightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.8];
[bgColorView setBackgroundColor:DarkNightColor];
[cell setSelectedBackgroundView:bgColorView];
cell.textLabel.textColor=NightColor;
NSString *valueString = [[finalArray objectAtIndex:indexPath.row] stringByDeletingPathExtension];
NSString *file = [[NSBundle mainBundle] pathForResource:valueString ofType:@"pdf"];
NSLog (@"Valuestring %@", file);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//Considering your pdf is stored in documents directory with name as "pdfFileName"
NSString *pdfPath = [[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",valueString]];
ReaderDocument *document = [ReaderDocument withDocumentFilePath:pdfPath password:nil];
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self;
[self presentViewController:readerViewController animated:YES completion:nil];
}
- (void)dismissReaderViewController:(ReaderViewController *)viewController {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

View File

@@ -0,0 +1,263 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1552</int>
<string key="IBDocument.SystemVersion">12E55</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.39</string>
<string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">2083</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIButton</string>
<string>IBUILabel</string>
<string>IBUITableView</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="843779117">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="774585933">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUITableView" id="649910150">
<reference key="NSNextResponder" ref="774585933"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{0, 32}, {320, 428}}</string>
<reference key="NSSuperview" ref="774585933"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIBounces">NO</bool>
<int key="IBUIIndicatorStyle">1</int>
<bool key="IBUIBouncesZoom">NO</bool>
<int key="IBUISeparatorStyle">1</int>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">44</float>
<float key="IBUISectionHeaderHeight">22</float>
<float key="IBUISectionFooterHeight">22</float>
</object>
<object class="IBUILabel" id="681285550">
<reference key="NSNextResponder" ref="774585933"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{49, 5}, {222, 21}}</string>
<reference key="NSSuperview" ref="774585933"/>
<reference key="NSNextKeyView" ref="236308457"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Night Reader Documents</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC42NTA5ODA0MTMgMCAwAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor">
<int key="NSColorSpace">2</int>
<bytes key="NSRGB">MC42NTA5ODA0MTMgMCAwAA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUIButton" id="236308457">
<reference key="NSNextResponder" ref="774585933"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{287, 6}, {18, 19}}</string>
<reference key="NSSuperview" ref="774585933"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">4</int>
<bool key="IBUIShowsTouchWhenHighlighted">YES</bool>
<object class="NSColor" key="IBUIHighlightedTitleColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="681285550"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xNTUwNzQxMzkgMC4xNTUwNzQxMzkgMC4xNTUwNzQxMzkAA</bytes>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<object class="IBUIScreenMetrics" key="IBUISimulatedDestinationMetrics">
<string key="IBUISimulatedSizeMetricsClass">IBUIScreenMetrics</string>
<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
<bool key="EncodedWithXMLCoder">YES</bool>
<array key="dict.sortedKeys">
<integer value="1"/>
<integer value="3"/>
</array>
<array key="dict.values">
<string>{320, 480}</string>
<string>{480, 320}</string>
</array>
</object>
<string key="IBUITargetRuntime">IBCocoaTouchFramework</string>
<string key="IBUIDisplayName">Retina 3.5 Full Screen</string>
<int key="IBUIType">0</int>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="774585933"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">MaintableView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="649910150"/>
</object>
<int key="connectionID">41</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="649910150"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">22</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="649910150"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">23</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="843779117"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="774585933"/>
<array class="NSMutableArray" key="children">
<reference ref="649910150"/>
<reference ref="681285550"/>
<reference ref="236308457"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="681285550"/>
<reference key="parent" ref="774585933"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">30</int>
<reference key="object" ref="236308457"/>
<reference key="parent" ref="774585933"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="649910150"/>
<reference key="parent" ref="774585933"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">NightReaderViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="20.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="30.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">41</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">2083</string>
</data>
</archive>

View File

@@ -0,0 +1,30 @@
//
// ReaderAppDelegate.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface ReaderAppDelegate : NSObject <UIApplicationDelegate>
@end

View File

@@ -0,0 +1,103 @@
//
// ReaderAppDelegate.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderAppDelegate.h"
#import "ReaderDemoController.h"
@implementation ReaderAppDelegate
{
UIWindow *mainWindow; // Main App Window
UINavigationController *navigationController;
ReaderDemoController *readerDemoController;
}
#pragma mark UIApplicationDelegate methods
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return NO;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
mainWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // Main application window
readerDemoController = [[ReaderDemoController alloc] initWithNibName:nil bundle:nil]; // Demo controller
navigationController = [[UINavigationController alloc] initWithRootViewController:readerDemoController];
mainWindow.backgroundColor = [UIColor blackColor]; // Window background color
navigationController.navigationBar.barStyle = UIBarStyleBlack; navigationController.navigationBar.translucent = YES;
mainWindow.rootViewController = navigationController; // Set the root view controller
[mainWindow makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of
// temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application
// and it begins the transition to the background state. Use this method to pause ongoing tasks, disable timers,
// and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough
// application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of transition from the background to the inactive state: here you can undo many
// of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive.
// If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate.
// See also applicationDidEnterBackground:.
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
// Free up as much memory as possible by purging cached data objects that can be recreated
// (or reloaded from disk) later.
}
@end

View File

@@ -0,0 +1,30 @@
//
// ReaderBookDelegate.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface ReaderBookDelegate : NSObject <UIApplicationDelegate>
@end

View File

@@ -0,0 +1,121 @@
//
// ReaderBookDelegate.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderBookDelegate.h"
#import "ReaderViewController.h"
@interface ReaderBookDelegate () <ReaderViewControllerDelegate>
@end
@implementation ReaderBookDelegate
{
UIWindow *mainWindow; // Main App Window
ReaderViewController *readerViewController;
}
#pragma mark UIApplicationDelegate methods
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return NO;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
mainWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // Main application window
mainWindow.backgroundColor = [UIColor blackColor]; // Window background color
NSString *phrase = nil; // Document password (for unlocking most encrypted PDF files)
NSArray *pdfs = [[NSBundle mainBundle] pathsForResourcesOfType:@"pdf" inDirectory:nil];
NSString *filePath = [pdfs lastObject]; assert(filePath != nil); // Path to last PDF file
ReaderDocument *document = [ReaderDocument withDocumentFilePath:filePath password:phrase];
if (document != nil) // Must have a valid ReaderDocument object in order to proceed
{
readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self; // Set the ReaderViewController delegate to self
mainWindow.rootViewController = readerViewController; // Set the root view controller
}
[mainWindow makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of
// temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application
// and it begins the transition to the background state. Use this method to pause ongoing tasks, disable timers,
// and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough
// application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of transition from the background to the inactive state: here you can undo many
// of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive.
// If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate.
// See also applicationDidEnterBackground:.
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
// Free up as much memory as possible by purging cached data objects that can be recreated
// (or reloaded from disk) later.
}
#pragma mark ReaderViewControllerDelegate methods
- (void)dismissReaderViewController:(ReaderViewController *)viewController
{
// Do nothing
}
@end

View File

@@ -0,0 +1,42 @@
//
// ReaderConstants.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !__has_feature(objc_arc)
#error ARC (-fobjc-arc) is required to build this code.
#endif
#import <Foundation/Foundation.h>
#define READER_BOOKMARKS FALSE
#define READER_ENABLE_MAIL FALSE
#define READER_ENABLE_PRINT FALSE
#define READER_ENABLE_THUMBS FALSE
#define READER_ENABLE_PREVIEW FALSE
#define READER_DISABLE_RETINA FALSE
#define READER_DISABLE_IDLE FALSE
#define READER_SHOW_SHADOWS FALSE
#define READER_STANDALONE FALSE
extern NSString *const kReaderCopyrightNotice;

View File

@@ -0,0 +1,28 @@
//
// ReaderConstants.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
NSString *const kReaderCopyrightNotice = @"Reader v2.x • Copyright © 2011-2013 Julius Oklamcak. All rights reserved.";

View File

@@ -0,0 +1,52 @@
//
// ReaderContentPage.h
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface ReaderContentPage : UIView
- (id)initWithURL:(NSURL *)fileURL page:(NSInteger)page password:(NSString *)phrase;
- (id)processSingleTap:(UITapGestureRecognizer *)recognizer;
@end
#pragma mark -
//
// ReaderDocumentLink class interface
//
@interface ReaderDocumentLink : NSObject <NSObject>
@property (nonatomic, assign, readonly) CGRect rect;
@property (nonatomic, assign, readonly) CGPDFDictionaryRef dictionary;
+ (id)newWithRect:(CGRect)linkRect dictionary:(CGPDFDictionaryRef)linkDictionary;
- (id)initWithRect:(CGRect)linkRect dictionary:(CGPDFDictionaryRef)linkDictionary;
@end

View File

@@ -0,0 +1,602 @@
//
// ReaderContentPage.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
#import "ReaderContentPage.h"
#import "ReaderContentTile.h"
#import "CGPDFDocument.h"
@implementation ReaderContentPage
{
NSMutableArray *_links;
CGPDFDocumentRef _PDFDocRef;
CGPDFPageRef _PDFPageRef;
NSInteger _pageAngle;
CGFloat _pageWidth;
CGFloat _pageHeight;
CGFloat _pageOffsetX;
CGFloat _pageOffsetY;
}
#pragma mark ReaderContentPage class methods
+ (Class)layerClass
{
return [ReaderContentTile class];
}
#pragma mark ReaderContentPage PDF link methods
- (void)highlightPageLinks
{
if (_links.count > 0) // Add highlight views over all links
{
UIColor *hilite = [UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.15f];
for (ReaderDocumentLink *link in _links) // Enumerate the links array
{
UIView *highlight = [[UIView alloc] initWithFrame:link.rect];
highlight.autoresizesSubviews = NO;
highlight.userInteractionEnabled = NO;
highlight.contentMode = UIViewContentModeRedraw;
highlight.autoresizingMask = UIViewAutoresizingNone;
highlight.backgroundColor = hilite; // Color
[self addSubview:highlight];
}
}
}
- (ReaderDocumentLink *)linkFromAnnotation:(CGPDFDictionaryRef)annotationDictionary
{
ReaderDocumentLink *documentLink = nil; // Document link object
CGPDFArrayRef annotationRectArray = NULL; // Annotation co-ordinates array
if (CGPDFDictionaryGetArray(annotationDictionary, "Rect", &annotationRectArray))
{
CGPDFReal ll_x = 0.0f; CGPDFReal ll_y = 0.0f; // PDFRect lower-left X and Y
CGPDFReal ur_x = 0.0f; CGPDFReal ur_y = 0.0f; // PDFRect upper-right X and Y
CGPDFArrayGetNumber(annotationRectArray, 0, &ll_x); // Lower-left X co-ordinate
CGPDFArrayGetNumber(annotationRectArray, 1, &ll_y); // Lower-left Y co-ordinate
CGPDFArrayGetNumber(annotationRectArray, 2, &ur_x); // Upper-right X co-ordinate
CGPDFArrayGetNumber(annotationRectArray, 3, &ur_y); // Upper-right Y co-ordinate
if (ll_x > ur_x) { CGPDFReal t = ll_x; ll_x = ur_x; ur_x = t; } // Normalize Xs
if (ll_y > ur_y) { CGPDFReal t = ll_y; ll_y = ur_y; ur_y = t; } // Normalize Ys
ll_x -= _pageOffsetX; ll_y -= _pageOffsetY; // Offset lower-left co-ordinate
ur_x -= _pageOffsetX; ur_y -= _pageOffsetY; // Offset upper-right co-ordinate
switch (_pageAngle) // Page rotation angle (in degrees)
{
case 90: // 90 degree page rotation
{
CGPDFReal swap;
swap = ll_y; ll_y = ll_x; ll_x = swap;
swap = ur_y; ur_y = ur_x; ur_x = swap;
break;
}
case 270: // 270 degree page rotation
{
CGPDFReal swap;
swap = ll_y; ll_y = ll_x; ll_x = swap;
swap = ur_y; ur_y = ur_x; ur_x = swap;
ll_x = ((0.0f - ll_x) + _pageWidth);
ur_x = ((0.0f - ur_x) + _pageWidth);
break;
}
case 0: // 0 degree page rotation
{
ll_y = ((0.0f - ll_y) + _pageHeight);
ur_y = ((0.0f - ur_y) + _pageHeight);
break;
}
}
NSInteger vr_x = ll_x; NSInteger vr_w = (ur_x - ll_x); // Integer X and width
NSInteger vr_y = ll_y; NSInteger vr_h = (ur_y - ll_y); // Integer Y and height
CGRect viewRect = CGRectMake(vr_x, vr_y, vr_w, vr_h); // View CGRect from PDFRect
documentLink = [ReaderDocumentLink newWithRect:viewRect dictionary:annotationDictionary];
}
return documentLink;
}
- (void)buildAnnotationLinksList
{
_links = [NSMutableArray new]; // Links list array
CGPDFArrayRef pageAnnotations = NULL; // Page annotations array
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(_PDFPageRef);
if (CGPDFDictionaryGetArray(pageDictionary, "Annots", &pageAnnotations) == true)
{
NSInteger count = CGPDFArrayGetCount(pageAnnotations); // Number of annotations
for (NSInteger index = 0; index < count; index++) // Iterate through all annotations
{
CGPDFDictionaryRef annotationDictionary = NULL; // PDF annotation dictionary
if (CGPDFArrayGetDictionary(pageAnnotations, index, &annotationDictionary) == true)
{
const char *annotationSubtype = NULL; // PDF annotation subtype string
if (CGPDFDictionaryGetName(annotationDictionary, "Subtype", &annotationSubtype) == true)
{
if (strcmp(annotationSubtype, "Link") == 0) // Found annotation subtype of 'Link'
{
ReaderDocumentLink *documentLink = [self linkFromAnnotation:annotationDictionary];
if (documentLink != nil) [_links insertObject:documentLink atIndex:0]; // Add link
}
}
}
}
//[self highlightPageLinks]; // Link support debugging
}
}
- (CGPDFArrayRef)destinationWithName:(const char *)destinationName inDestsTree:(CGPDFDictionaryRef)node
{
CGPDFArrayRef destinationArray = NULL;
CGPDFArrayRef limitsArray = NULL; // Limits array
if (CGPDFDictionaryGetArray(node, "Limits", &limitsArray) == true)
{
CGPDFStringRef lowerLimit = NULL; CGPDFStringRef upperLimit = NULL;
if (CGPDFArrayGetString(limitsArray, 0, &lowerLimit) == true) // Lower limit
{
if (CGPDFArrayGetString(limitsArray, 1, &upperLimit) == true) // Upper limit
{
const char *ll = (const char *)CGPDFStringGetBytePtr(lowerLimit); // Lower string
const char *ul = (const char *)CGPDFStringGetBytePtr(upperLimit); // Upper string
if ((strcmp(destinationName, ll) < 0) || (strcmp(destinationName, ul) > 0))
{
return NULL; // Destination name is outside this node's limits
}
}
}
}
CGPDFArrayRef namesArray = NULL; // Names array
if (CGPDFDictionaryGetArray(node, "Names", &namesArray) == true)
{
NSInteger namesCount = CGPDFArrayGetCount(namesArray);
for (NSInteger index = 0; index < namesCount; index += 2)
{
CGPDFStringRef destName; // Destination name string
if (CGPDFArrayGetString(namesArray, index, &destName) == true)
{
const char *dn = (const char *)CGPDFStringGetBytePtr(destName);
if (strcmp(dn, destinationName) == 0) // Found the destination name
{
if (CGPDFArrayGetArray(namesArray, (index + 1), &destinationArray) == false)
{
CGPDFDictionaryRef destinationDictionary = NULL; // Destination dictionary
if (CGPDFArrayGetDictionary(namesArray, (index + 1), &destinationDictionary) == true)
{
CGPDFDictionaryGetArray(destinationDictionary, "D", &destinationArray);
}
}
return destinationArray; // Return the destination array
}
}
}
}
CGPDFArrayRef kidsArray = NULL; // Kids array
if (CGPDFDictionaryGetArray(node, "Kids", &kidsArray) == true)
{
NSInteger kidsCount = CGPDFArrayGetCount(kidsArray);
for (NSInteger index = 0; index < kidsCount; index++)
{
CGPDFDictionaryRef kidNode = NULL; // Kid node dictionary
if (CGPDFArrayGetDictionary(kidsArray, index, &kidNode) == true) // Recurse into node
{
destinationArray = [self destinationWithName:destinationName inDestsTree:kidNode];
if (destinationArray != NULL) return destinationArray; // Return destination array
}
}
}
return NULL;
}
- (id)annotationLinkTarget:(CGPDFDictionaryRef)annotationDictionary
{
id linkTarget = nil; // Link target object
CGPDFStringRef destName = NULL; const char *destString = NULL;
CGPDFDictionaryRef actionDictionary = NULL; CGPDFArrayRef destArray = NULL;
if (CGPDFDictionaryGetDictionary(annotationDictionary, "A", &actionDictionary) == true)
{
const char *actionType = NULL; // Annotation action type string
if (CGPDFDictionaryGetName(actionDictionary, "S", &actionType) == true)
{
if (strcmp(actionType, "GoTo") == 0) // GoTo action type
{
if (CGPDFDictionaryGetArray(actionDictionary, "D", &destArray) == false)
{
CGPDFDictionaryGetString(actionDictionary, "D", &destName);
}
}
else // Handle other link action type possibility
{
if (strcmp(actionType, "URI") == 0) // URI action type
{
CGPDFStringRef uriString = NULL; // Action's URI string
if (CGPDFDictionaryGetString(actionDictionary, "URI", &uriString) == true)
{
const char *uri = (const char *)CGPDFStringGetBytePtr(uriString); // Destination URI string
linkTarget = [NSURL URLWithString:[NSString stringWithCString:uri encoding:NSASCIIStringEncoding]];
}
}
}
}
}
else // Handle other link target possibilities
{
if (CGPDFDictionaryGetArray(annotationDictionary, "Dest", &destArray) == false)
{
if (CGPDFDictionaryGetString(annotationDictionary, "Dest", &destName) == false)
{
CGPDFDictionaryGetName(annotationDictionary, "Dest", &destString);
}
}
}
if (destName != NULL) // Handle a destination name
{
CGPDFDictionaryRef catalogDictionary = CGPDFDocumentGetCatalog(_PDFDocRef);
CGPDFDictionaryRef namesDictionary = NULL; // Destination names in the document
if (CGPDFDictionaryGetDictionary(catalogDictionary, "Names", &namesDictionary) == true)
{
CGPDFDictionaryRef destsDictionary = NULL; // Document destinations dictionary
if (CGPDFDictionaryGetDictionary(namesDictionary, "Dests", &destsDictionary) == true)
{
const char *destinationName = (const char *)CGPDFStringGetBytePtr(destName); // Name
destArray = [self destinationWithName:destinationName inDestsTree:destsDictionary];
}
}
}
if (destString != NULL) // Handle a destination string
{
CGPDFDictionaryRef catalogDictionary = CGPDFDocumentGetCatalog(_PDFDocRef);
CGPDFDictionaryRef destsDictionary = NULL; // Document destinations dictionary
if (CGPDFDictionaryGetDictionary(catalogDictionary, "Dests", &destsDictionary) == true)
{
CGPDFDictionaryRef targetDictionary = NULL; // Destination target dictionary
if (CGPDFDictionaryGetDictionary(destsDictionary, destString, &targetDictionary) == true)
{
CGPDFDictionaryGetArray(targetDictionary, "D", &destArray);
}
}
}
if (destArray != NULL) // Handle a destination array
{
NSInteger targetPageNumber = 0; // The target page number
CGPDFDictionaryRef pageDictionaryFromDestArray = NULL; // Target reference
if (CGPDFArrayGetDictionary(destArray, 0, &pageDictionaryFromDestArray) == true)
{
NSInteger pageCount = CGPDFDocumentGetNumberOfPages(_PDFDocRef); // Pages
for (NSInteger pageNumber = 1; pageNumber <= pageCount; pageNumber++)
{
CGPDFPageRef pageRef = CGPDFDocumentGetPage(_PDFDocRef, pageNumber);
CGPDFDictionaryRef pageDictionaryFromPage = CGPDFPageGetDictionary(pageRef);
if (pageDictionaryFromPage == pageDictionaryFromDestArray) // Found it
{
targetPageNumber = pageNumber; break;
}
}
}
else // Try page number from array possibility
{
CGPDFInteger pageNumber = 0; // Page number in array
if (CGPDFArrayGetInteger(destArray, 0, &pageNumber) == true)
{
targetPageNumber = (pageNumber + 1); // 1-based
}
}
if (targetPageNumber > 0) // We have a target page number
{
linkTarget = [NSNumber numberWithInteger:targetPageNumber];
}
}
return linkTarget;
}
- (id)processSingleTap:(UITapGestureRecognizer *)recognizer
{
id result = nil; // Tap result object
if (recognizer.state == UIGestureRecognizerStateRecognized)
{
if (_links.count > 0) // Process the single tap
{
CGPoint point = [recognizer locationInView:self];
for (ReaderDocumentLink *link in _links) // Enumerate links
{
if (CGRectContainsPoint(link.rect, point) == true) // Found it
{
result = [self annotationLinkTarget:link.dictionary]; break;
}
}
}
}
return result;
}
#pragma mark ReaderContentPage instance methods
- (id)initWithFrame:(CGRect)frame
{
id view = nil; // UIView
if (CGRectIsEmpty(frame) == false)
{
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = NO;
self.userInteractionEnabled = NO;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingNone;
self.backgroundColor = [UIColor blackColor];
view = self; // Return self
}
}
else // Handle invalid frame size
{
self = nil;
}
return view;
}
// VOLGENS MIJ STAAT HIER DE CODE DIE JE MOET HEBBEN //NOP
- (id)initWithURL:(NSURL *)fileURL page:(NSInteger)page password:(NSString *)phrase
{
CGRect viewRect = CGRectZero; // View rect
if (fileURL != nil) // Check for non-nil file URL
{
_PDFDocRef = CGPDFDocumentCreateX((__bridge CFURLRef)fileURL, phrase);
if (_PDFDocRef != NULL) // Check for non-NULL CGPDFDocumentRef
{
if (page < 1) page = 1; // Check the lower page bounds
NSInteger pages = CGPDFDocumentGetNumberOfPages(_PDFDocRef);
if (page > pages) page = pages; // Check the upper page bounds
_PDFPageRef = CGPDFDocumentGetPage(_PDFDocRef, page); // Get page
if (_PDFPageRef != NULL) // Check for non-NULL CGPDFPageRef
{
CGPDFPageRetain(_PDFPageRef); // Retain the PDF page
CGRect cropBoxRect = CGPDFPageGetBoxRect(_PDFPageRef, kCGPDFCropBox);
CGRect mediaBoxRect = CGPDFPageGetBoxRect(_PDFPageRef, kCGPDFMediaBox);
CGRect effectiveRect = CGRectIntersection(cropBoxRect, mediaBoxRect);
_pageAngle = CGPDFPageGetRotationAngle(_PDFPageRef); // Angle
switch (_pageAngle) // Page rotation angle (in degrees)
{
default: // Default case
case 0: case 180: // 0 and 180 degrees
{
_pageWidth = effectiveRect.size.width;
_pageHeight = effectiveRect.size.height;
_pageOffsetX = effectiveRect.origin.x;
_pageOffsetY = effectiveRect.origin.y;
break;
}
case 90: case 270: // 90 and 270 degrees
{
_pageWidth = effectiveRect.size.height;
_pageHeight = effectiveRect.size.width;
_pageOffsetX = effectiveRect.origin.y;
_pageOffsetY = effectiveRect.origin.x;
break;
}
}
NSInteger page_w = _pageWidth; // Integer width
NSInteger page_h = _pageHeight; // Integer height
if (page_w % 2) page_w--; if (page_h % 2) page_h--; // Even
viewRect.size = CGSizeMake(page_w, page_h); // View size
}
else // Error out with a diagnostic
{
CGPDFDocumentRelease(_PDFDocRef), _PDFDocRef = NULL;
NSAssert(NO, @"CGPDFPageRef == NULL");
}
}
else // Error out with a diagnostic
{
NSAssert(NO, @"CGPDFDocumentRef == NULL");
}
}
else // Error out with a diagnostic
{
NSAssert(NO, @"fileURL == nil");
}
id view = [self initWithFrame:viewRect]; // UIView setup
if (view != nil) [self buildAnnotationLinksList]; // Links
return view;
}
- (void)removeFromSuperview
{
self.layer.delegate = nil;
//self.layer.contents = nil;
[super removeFromSuperview];
}
- (void)dealloc
{
CGPDFPageRelease(_PDFPageRef), _PDFPageRef = NULL;
CGPDFDocumentRelease(_PDFDocRef), _PDFDocRef = NULL;
}
#if (READER_DISABLE_RETINA == TRUE) // Option
- (void)didMoveToWindow
{
self.contentScaleFactor = 1.0f; // Override scale factor
}
#endif // end of READER_DISABLE_RETINA Option
#pragma mark CATiledLayer delegate methods
- (void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)context
{
ReaderContentPage *readerContentPage = self; // Retain self
CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // White
CGContextFillRect(context, CGContextGetClipBoundingBox(context)); // Fill
//NSLog(@"%s %@", __FUNCTION__, NSStringFromCGRect(CGContextGetClipBoundingBox(context)));
CGContextTranslateCTM(context, 0.0f, self.bounds.size.height); CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(_PDFPageRef, kCGPDFCropBox, self.bounds, 0, true));
//CGContextSetRenderingIntent(context, kCGRenderingIntentDefault); CGContextSetInterpolationQuality(context, kCGInterpolationDefault);
CGContextDrawPDFPage(context, _PDFPageRef); // Render the PDF page into the context
if (readerContentPage != nil) readerContentPage = nil; // Release self
}
@end
#pragma mark -
//
// ReaderDocumentLink class implementation
//
@implementation ReaderDocumentLink
{
CGPDFDictionaryRef _dictionary;
CGRect _rect;
}
#pragma mark Properties
@synthesize rect = _rect;
@synthesize dictionary = _dictionary;
#pragma mark ReaderDocumentLink class methods
+ (id)newWithRect:(CGRect)linkRect dictionary:(CGPDFDictionaryRef)linkDictionary
{
return [[ReaderDocumentLink alloc] initWithRect:linkRect dictionary:linkDictionary];
}
#pragma mark ReaderDocumentLink instance methods
- (id)initWithRect:(CGRect)linkRect dictionary:(CGPDFDictionaryRef)linkDictionary
{
if ((self = [super init]))
{
_dictionary = linkDictionary;
_rect = linkRect;
}
return self;
}
@end

View File

@@ -0,0 +1,31 @@
//
// ReaderContentTile.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ReaderContentTile : CATiledLayer
@end

View File

@@ -0,0 +1,72 @@
//
// ReaderContentTile.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderContentTile.h"
@implementation ReaderContentTile
#pragma mark Constants
#define LEVELS_OF_DETAIL 4
#define LEVELS_OF_DETAIL_BIAS 3
#pragma mark ReaderContentTile class methods
+ (CFTimeInterval)fadeDuration
{
return 0.001; // iOS bug (flickering tiles) workaround
}
#pragma mark ReaderContentTile instance methods
- (id)init
{
if ((self = [super init]))
{
self.levelsOfDetail = LEVELS_OF_DETAIL; // Zoom levels
UIScreen *mainScreen = [UIScreen mainScreen]; // Main screen
CGFloat screenScale = [mainScreen scale]; // Main screen scale
self.levelsOfDetailBias = (screenScale > 1.0f) ? 1 : LEVELS_OF_DETAIL_BIAS;
CGRect screenBounds = [mainScreen bounds]; // Main screen bounds
CGFloat w_pixels = (screenBounds.size.width * screenScale);
CGFloat h_pixels = (screenBounds.size.height * screenScale);
CGFloat max = ((w_pixels < h_pixels) ? h_pixels : w_pixels);
CGFloat sizeOfTiles = ((max < 512.0f) ? 512.0f : 1024.0f);
self.tileSize = CGSizeMake(sizeOfTiles, sizeOfTiles);
}
return self;
}
@end

View File

@@ -0,0 +1,66 @@
//
// ReaderContentView.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ReaderThumbView.h"
@class ReaderContentView;
@class ReaderContentPage;
@class ReaderContentThumb;
@protocol ReaderContentViewDelegate <NSObject>
@required // Delegate protocols
- (void)contentView:(ReaderContentView *)contentView touchesBegan:(NSSet *)touches;
@end
@interface ReaderContentView : UIScrollView <UIScrollViewDelegate>
@property (nonatomic, unsafe_unretained, readwrite) id <ReaderContentViewDelegate> message;
- (id)initWithFrame:(CGRect)frame fileURL:(NSURL *)fileURL page:(NSUInteger)page password:(NSString *)phrase;
- (void)showPageThumb:(NSURL *)fileURL page:(NSInteger)page password:(NSString *)phrase guid:(NSString *)guid;
- (id)processSingleTap:(UITapGestureRecognizer *)recognizer;
- (void)zoomIncrement;
- (void)zoomDecrement;
- (void)zoomReset;
@end
#pragma mark -
//
// ReaderContentThumb class interface
//
@interface ReaderContentThumb : ReaderThumbView
@end

View File

@@ -0,0 +1,332 @@
//
// ReaderContentView.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
#import "ReaderContentView.h"
#import "ReaderContentPage.h"
#import "ReaderThumbCache.h"
#import <QuartzCore/QuartzCore.h>
@implementation ReaderContentView
{
ReaderContentPage *theContentView;
ReaderContentThumb *theThumbView;
UIView *theContainerView;
CGFloat zoomAmount;
}
#pragma mark Constants
#define ZOOM_LEVELS 4
#if (READER_SHOW_SHADOWS == TRUE) // Option
#define CONTENT_INSET 4.0f
#else
#define CONTENT_INSET 2.0f
#endif // end of READER_SHOW_SHADOWS Option
#define PAGE_THUMB_LARGE 240
#define PAGE_THUMB_SMALL 144
static void *ReaderContentViewContext = &ReaderContentViewContext;
#pragma mark Properties
@synthesize message;
#pragma mark ReaderContentView functions
static inline CGFloat ZoomScaleThatFits(CGSize target, CGSize source)
{
CGFloat w_scale = (target.width / source.width);
CGFloat h_scale = (target.height / source.height);
return ((w_scale < h_scale) ? w_scale : h_scale);
}
#pragma mark ReaderContentView instance methods
- (void)updateMinimumMaximumZoom
{
CGRect targetRect = CGRectInset(self.bounds, CONTENT_INSET, CONTENT_INSET);
CGFloat zoomScale = ZoomScaleThatFits(targetRect.size, theContentView.bounds.size);
self.minimumZoomScale = zoomScale; // Set the minimum and maximum zoom scales
self.maximumZoomScale = (zoomScale * ZOOM_LEVELS); // Max number of zoom levels
zoomAmount = ((self.maximumZoomScale - self.minimumZoomScale) / ZOOM_LEVELS);
}
- (id)initWithFrame:(CGRect)frame fileURL:(NSURL *)fileURL page:(NSUInteger)page password:(NSString *)phrase
{
if ((self = [super initWithFrame:frame]))
{
self.scrollsToTop = NO;
self.delaysContentTouches = NO;
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.backgroundColor = [UIColor clearColor];
self.userInteractionEnabled = YES;
self.autoresizesSubviews = NO;
self.bouncesZoom = YES;
self.delegate = self;
theContentView = [[ReaderContentPage alloc] initWithURL:fileURL page:page password:phrase];
if (theContentView != nil) // Must have a valid and initialized content view
{
theContainerView = [[UIView alloc] initWithFrame:theContentView.bounds];
theContainerView.autoresizesSubviews = NO;
theContainerView.userInteractionEnabled = NO;
theContainerView.contentMode = UIViewContentModeRedraw;
theContainerView.autoresizingMask = UIViewAutoresizingNone;
theContainerView.backgroundColor = [UIColor blackColor];
#if (READER_SHOW_SHADOWS == TRUE) // Option
theContainerView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
theContainerView.layer.shadowRadius = 4.0f; theContainerView.layer.shadowOpacity = 1.0f;
theContainerView.layer.shadowPath = [UIBezierPath bezierPathWithRect:theContainerView.bounds].CGPath;
#endif // end of READER_SHOW_SHADOWS Option
self.contentSize = theContentView.bounds.size; // Content size same as view size
self.contentOffset = CGPointMake((0.0f - CONTENT_INSET), (0.0f - CONTENT_INSET)); // Offset
self.contentInset = UIEdgeInsetsMake(CONTENT_INSET, CONTENT_INSET, CONTENT_INSET, CONTENT_INSET);
#if (READER_ENABLE_PREVIEW == TRUE) // Option
theThumbView = [[ReaderContentThumb alloc] initWithFrame:theContentView.bounds]; // Page thumb view
[theContainerView addSubview:theThumbView]; // Add the thumb view to the container view
#endif // end of READER_ENABLE_PREVIEW Option
[theContainerView addSubview:theContentView]; // Add the content view to the container view
[self addSubview:theContainerView]; // Add the container view to the scroll view
[self updateMinimumMaximumZoom]; // Update the minimum and maximum zoom scales
self.zoomScale = self.minimumZoomScale; // Set zoom to fit page content
}
[self addObserver:self forKeyPath:@"frame" options:0 context:ReaderContentViewContext];
self.tag = page; // Tag the view with the page number
}
return self;
}
- (void)dealloc
{
// [self removeObserver:self forKeyPath:@"frame" context:ReaderContentViewContext];
[self removeObserver:self forKeyPath:@"frame"]; // Maintain iOS 4.x compatability
}
- (void)showPageThumb:(NSURL *)fileURL page:(NSInteger)page password:(NSString *)phrase guid:(NSString *)guid
{
#if (READER_ENABLE_PREVIEW == TRUE) // Option
BOOL large = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad); // Page thumb size
CGSize size = (large ? CGSizeMake(PAGE_THUMB_LARGE, PAGE_THUMB_LARGE) : CGSizeMake(PAGE_THUMB_SMALL, PAGE_THUMB_SMALL));
ReaderThumbRequest *request = [ReaderThumbRequest newForView:theThumbView fileURL:fileURL password:phrase guid:guid page:page size:size];
UIImage *image = [[ReaderThumbCache sharedInstance] thumbRequest:request priority:YES]; // Request the page thumb
if ([image isKindOfClass:[UIImage class]]) [theThumbView showImage:image]; // Show image from cache
#endif // end of READER_ENABLE_PREVIEW Option
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == ReaderContentViewContext) // Our context
{
if ((object == self) && [keyPath isEqualToString:@"frame"])
{
CGFloat oldMinimumZoomScale = self.minimumZoomScale;
[self updateMinimumMaximumZoom]; // Update zoom scale limits
if (self.zoomScale == oldMinimumZoomScale) // Old minimum
{
self.zoomScale = self.minimumZoomScale;
}
else // Check against minimum zoom scale
{
if (self.zoomScale < self.minimumZoomScale)
{
self.zoomScale = self.minimumZoomScale;
}
else // Check against maximum zoom scale
{
if (self.zoomScale > self.maximumZoomScale)
{
self.zoomScale = self.maximumZoomScale;
}
}
}
}
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize boundsSize = self.bounds.size;
CGRect viewFrame = theContainerView.frame;
if (viewFrame.size.width < boundsSize.width)
viewFrame.origin.x = (((boundsSize.width - viewFrame.size.width) / 2.0f) + self.contentOffset.x);
else
viewFrame.origin.x = 0.0f;
if (viewFrame.size.height < boundsSize.height)
viewFrame.origin.y = (((boundsSize.height - viewFrame.size.height) / 2.0f) + self.contentOffset.y);
else
viewFrame.origin.y = 0.0f;
theContainerView.frame = viewFrame;
}
- (id)processSingleTap:(UITapGestureRecognizer *)recognizer
{
return [theContentView processSingleTap:recognizer];
}
- (void)zoomIncrement
{
CGFloat zoomScale = self.zoomScale;
if (zoomScale < self.maximumZoomScale)
{
zoomScale += zoomAmount; // += value
if (zoomScale > self.maximumZoomScale)
{
zoomScale = self.maximumZoomScale;
}
[self setZoomScale:zoomScale animated:YES];
}
}
- (void)zoomDecrement
{
CGFloat zoomScale = self.zoomScale;
if (zoomScale > self.minimumZoomScale)
{
zoomScale -= zoomAmount; // -= value
if (zoomScale < self.minimumZoomScale)
{
zoomScale = self.minimumZoomScale;
}
[self setZoomScale:zoomScale animated:YES];
}
}
- (void)zoomReset
{
if (self.zoomScale > self.minimumZoomScale)
{
self.zoomScale = self.minimumZoomScale;
}
}
#pragma mark UIScrollViewDelegate methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return theContainerView;
}
#pragma mark UIResponder instance methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event]; // Message superclass
[message contentView:self touchesBegan:touches]; // Message delegate
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event]; // Message superclass
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event]; // Message superclass
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event]; // Message superclass
}
@end
#pragma mark -
//
// ReaderContentThumb class implementation
//
@implementation ReaderContentThumb
#pragma mark ReaderContentThumb instance methods
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) // Superclass init
{
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES; // Needed for aspect fill
}
return self;
}
@end

View File

@@ -0,0 +1,30 @@
//
// ReaderDemoController.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface ReaderDemoController : UIViewController
@end

View File

@@ -0,0 +1,217 @@
//
// ReaderDemoController.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderDemoController.h"
#import "ReaderViewController.h"
@interface ReaderDemoController () <ReaderViewControllerDelegate>
@end
@implementation ReaderDemoController
#pragma mark Constants
#define DEMO_VIEW_CONTROLLER_PUSH FALSE
#pragma mark UIViewController methods
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
{
// Custom initialization
}
return self;
}
*/
/*
- (void)loadView
{
// Implement loadView to create a view hierarchy programmatically, without using a nib.
}
*/
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor]; // Transparent
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *name = [infoDictionary objectForKey:@"CFBundleName"];
NSString *version = [infoDictionary objectForKey:@"CFBundleVersion"];
self.title = [NSString stringWithFormat:@"%@ v%@", name, version];
CGSize viewSize = self.view.bounds.size;
CGRect labelRect = CGRectMake(0.0f, 0.0f, 80.0f, 32.0f);
UILabel *tapLabel = [[UILabel alloc] initWithFrame:labelRect];
tapLabel.text = @"Tap";
tapLabel.textColor = [UIColor blackColor];
tapLabel.textAlignment = NSTextAlignmentCenter;
tapLabel.backgroundColor = [UIColor clearColor];
tapLabel.font = [UIFont systemFontOfSize:24.0f];
tapLabel.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
tapLabel.autoresizingMask |= UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
tapLabel.center = CGPointMake(viewSize.width / 2.0f, viewSize.height / 2.0f);
[self.view addSubview:tapLabel];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
//singleTap.numberOfTouchesRequired = 1; singleTap.numberOfTapsRequired = 1; //singleTap.delegate = self;
[self.view addGestureRecognizer:singleTap];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
#if (DEMO_VIEW_CONTROLLER_PUSH == TRUE)
[self.navigationController setNavigationBarHidden:NO animated:animated];
#endif // DEMO_VIEW_CONTROLLER_PUSH
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
#if (DEMO_VIEW_CONTROLLER_PUSH == TRUE)
[self.navigationController setNavigationBarHidden:YES animated:animated];
#endif // DEMO_VIEW_CONTROLLER_PUSH
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)viewDidUnload
{
#ifdef DEBUG
NSLog(@"%s", __FUNCTION__);
#endif
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) // See README
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
else
return YES;
}
/*
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//if (fromInterfaceOrientation == self.interfaceOrientation) return;
}
*/
- (void)didReceiveMemoryWarning
{
#ifdef DEBUG
NSLog(@"%s", __FUNCTION__);
#endif
[super didReceiveMemoryWarning];
}
#pragma mark UIGestureRecognizer methods
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
NSString *phrase = nil; // Document password (for unlocking most encrypted PDF files)
NSArray *pdfs = [[NSBundle mainBundle] pathsForResourcesOfType:@"pdf" inDirectory:nil];
NSString *filePath = [pdfs lastObject]; assert(filePath != nil); // Path to last PDF file
ReaderDocument *document = [ReaderDocument withDocumentFilePath:filePath password:phrase];
if (document != nil) // Must have a valid ReaderDocument object in order to proceed with things
{
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self; // Set the ReaderViewController delegate to self
#if (DEMO_VIEW_CONTROLLER_PUSH == TRUE)
[self.navigationController pushViewController:readerViewController animated:YES];
#else // present in a modal view controller
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:nil ];
#endif // DEMO_VIEW_CONTROLLER_PUSH
}
}
#pragma mark ReaderViewControllerDelegate methods
- (void)dismissReaderViewController:(ReaderViewController *)viewController
{
#if (DEMO_VIEW_CONTROLLER_PUSH == TRUE)
[self.navigationController popViewControllerAnimated:YES];
#else // dismiss the modal view controller
[self dismissViewControllerAnimated:YES completion:nil];
#endif // DEMO_VIEW_CONTROLLER_PUSH
}
@end

View File

@@ -0,0 +1,51 @@
//
// ReaderDocument.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@interface ReaderDocument : NSObject <NSObject, NSCoding>
@property (nonatomic, strong, readonly) NSString *guid;
@property (nonatomic, strong, readonly) NSDate *fileDate;
@property (nonatomic, strong, readwrite) NSDate *lastOpen;
@property (nonatomic, strong, readonly) NSNumber *fileSize;
@property (nonatomic, strong, readonly) NSNumber *pageCount;
@property (nonatomic, strong, readwrite) NSNumber *pageNumber;
@property (nonatomic, strong, readonly) NSMutableIndexSet *bookmarks;
@property (nonatomic, strong, readonly) NSString *fileName;
@property (nonatomic, strong, readonly) NSString *password;
@property (nonatomic, strong, readonly) NSURL *fileURL;
+ (ReaderDocument *)withDocumentFilePath:(NSString *)filename password:(NSString *)phrase;
+ (ReaderDocument *)unarchiveFromFileName:(NSString *)filename password:(NSString *)phrase;
- (id)initWithFilePath:(NSString *)fullFilePath password:(NSString *)phrase;
- (void)saveReaderDocument;
- (void)updateProperties;
@end

View File

@@ -0,0 +1,358 @@
//
// ReaderDocument.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderDocument.h"
#import "CGPDFDocument.h"
#import <fcntl.h>
@implementation ReaderDocument
{
NSString *_guid;
NSDate *_fileDate;
NSDate *_lastOpen;
NSNumber *_fileSize;
NSNumber *_pageCount;
NSNumber *_pageNumber;
NSMutableIndexSet *_bookmarks;
NSString *_fileName;
NSString *_password;
NSURL *_fileURL;
}
#pragma mark Properties
@synthesize guid = _guid;
@synthesize fileDate = _fileDate;
@synthesize fileSize = _fileSize;
@synthesize pageCount = _pageCount;
@synthesize pageNumber = _pageNumber;
@synthesize bookmarks = _bookmarks;
@synthesize lastOpen = _lastOpen;
@synthesize password = _password;
@dynamic fileName, fileURL;
#pragma mark ReaderDocument class methods
+ (NSString *)GUID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef theString = CFUUIDCreateString(NULL, theUUID);
NSString *unique = [NSString stringWithString:(__bridge id)theString];
CFRelease(theString); CFRelease(theUUID); // Cleanup CF objects
return unique;
}
+ (NSString *)documentsPath
{
NSArray *documentsPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [documentsPaths objectAtIndex:0]; // Path to the application's "~/Documents" directory
}
+ (NSString *)applicationPath
{
NSArray *documentsPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[documentsPaths objectAtIndex:0] stringByDeletingLastPathComponent]; // Strip "Documents" component
}
+ (NSString *)applicationSupportPath
{
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSURL *pathURL = [fileManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
return [pathURL path]; // Path to the application's "~/Library/Application Support" directory
}
+ (NSString *)relativeFilePath:(NSString *)fullFilePath
{
assert(fullFilePath != nil); // Ensure that the full file path is not nil
NSString *applicationPath = [ReaderDocument applicationPath]; // Get the application path
NSRange range = [fullFilePath rangeOfString:applicationPath]; // Look for the application path
assert(range.location != NSNotFound); // Ensure that the application path is in the full file path
return [fullFilePath stringByReplacingCharactersInRange:range withString:@""]; // Strip it out
}
+ (NSString *)archiveFilePath:(NSString *)filename
{
assert(filename != nil); // Ensure that the archive file name is not nil
//NSString *archivePath = [ReaderDocument documentsPath]; // Application's "~/Documents" path
NSString *archivePath = [ReaderDocument applicationSupportPath]; // Application's "~/Library/Application Support" path
NSString *archiveName = [[filename stringByDeletingPathExtension] stringByAppendingPathExtension:@"plist"];
return [archivePath stringByAppendingPathComponent:archiveName]; // "{archivePath}/'filename'.plist"
}
+ (ReaderDocument *)unarchiveFromFileName:(NSString *)filename password:(NSString *)phrase
{
ReaderDocument *document = nil; // ReaderDocument object
NSString *withName = [filename lastPathComponent]; // File name only
NSString *archiveFilePath = [ReaderDocument archiveFilePath:withName];
@try // Unarchive an archived ReaderDocument object from its property list
{
document = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
if ((document != nil) && (phrase != nil)) // Set the document password
{
[document setValue:[phrase copy] forKey:@"password"];
}
}
@catch (NSException *exception) // Exception handling (just in case O_o)
{
#ifdef DEBUG
NSLog(@"%s Caught %@: %@", __FUNCTION__, [exception name], [exception reason]);
#endif
}
return document;
}
+ (ReaderDocument *)withDocumentFilePath:(NSString *)filePath password:(NSString *)phrase
{
ReaderDocument *document = nil; // ReaderDocument object
document = [ReaderDocument unarchiveFromFileName:filePath password:phrase];
if (document == nil) // Unarchive failed so we create a new ReaderDocument object
{
document = [[ReaderDocument alloc] initWithFilePath:filePath password:phrase];
}
return document;
}
+ (BOOL)isPDF:(NSString *)filePath
{
BOOL state = NO;
if (filePath != nil) // Must have a file path
{
const char *path = [filePath fileSystemRepresentation];
int fd = open(path, O_RDONLY); // Open the file
if (fd > 0) // We have a valid file descriptor
{
const char sig[1024]; // File signature buffer
ssize_t len = read(fd, (void *)&sig, sizeof(sig));
state = (strnstr(sig, "%PDF", len) != NULL);
close(fd); // Close the file
}
}
return state;
}
#pragma mark ReaderDocument instance methods
- (id)initWithFilePath:(NSString *)fullFilePath password:(NSString *)phrase
{
id object = nil; // ReaderDocument object
if ([ReaderDocument isPDF:fullFilePath] == YES) // File must exist
{
if ((self = [super init])) // Initialize superclass object first
{
_guid = [ReaderDocument GUID]; // Create a document GUID
_password = [phrase copy]; // Keep copy of any document password
_bookmarks = [NSMutableIndexSet new]; // Bookmarked pages index set
_pageNumber = [NSNumber numberWithInteger:1]; // Start on page 1
_fileName = [ReaderDocument relativeFilePath:fullFilePath]; // File name
CFURLRef docURLRef = (__bridge CFURLRef)[self fileURL]; // CFURLRef from NSURL
CGPDFDocumentRef thePDFDocRef = CGPDFDocumentCreateX(docURLRef, _password);
if (thePDFDocRef != NULL) // Get the number of pages in the document
{
NSInteger pageCount = CGPDFDocumentGetNumberOfPages(thePDFDocRef);
_pageCount = [NSNumber numberWithInteger:pageCount];
CGPDFDocumentRelease(thePDFDocRef); // Cleanup
}
else // Cupertino, we have a problem with the document
{
NSAssert(NO, @"CGPDFDocumentRef == NULL");
}
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
_lastOpen = [NSDate dateWithTimeIntervalSinceReferenceDate:0.0]; // Last opened
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:fullFilePath error:NULL];
_fileDate = [fileAttributes objectForKey:NSFileModificationDate]; // File date
_fileSize = [fileAttributes objectForKey:NSFileSize]; // File size (bytes)
[self saveReaderDocument]; // Save the ReaderDocument object
object = self; // Return initialized ReaderDocument object
}
}
return object;
}
- (NSString *)fileName
{
return [_fileName lastPathComponent];
}
- (NSURL *)fileURL
{
if (_fileURL == nil) // Create and keep the file URL the first time it is requested
{
NSString *fullFilePath = [[ReaderDocument applicationPath] stringByAppendingPathComponent:_fileName];
_fileURL = [[NSURL alloc] initFileURLWithPath:fullFilePath isDirectory:NO]; // File URL from full file path
}
return _fileURL;
}
- (BOOL)archiveWithFileName:(NSString *)filename
{
NSString *archiveFilePath = [ReaderDocument archiveFilePath:filename];
return [NSKeyedArchiver archiveRootObject:self toFile:archiveFilePath];
}
- (void)saveReaderDocument
{
[self archiveWithFileName:[self fileName]];
}
- (void)updateProperties
{
CFURLRef docURLRef = (__bridge CFURLRef)self.fileURL; // File URL
CGPDFDocumentRef thePDFDocRef = CGPDFDocumentCreateWithURL(docURLRef);
if (thePDFDocRef != NULL) // Get the number of pages in the document
{
NSInteger pageCount = CGPDFDocumentGetNumberOfPages(thePDFDocRef);
_pageCount = [NSNumber numberWithInteger:pageCount];
CGPDFDocumentRelease(thePDFDocRef); // Cleanup
}
NSString *fullFilePath = [self.fileURL path]; // Full file path
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:fullFilePath error:NULL];
_fileDate = [fileAttributes objectForKey:NSFileModificationDate]; // File date
_fileSize = [fileAttributes objectForKey:NSFileSize]; // File size
}
#pragma mark NSCoding protocol methods
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:_guid forKey:@"FileGUID"];
[encoder encodeObject:_fileName forKey:@"FileName"];
[encoder encodeObject:_fileDate forKey:@"FileDate"];
[encoder encodeObject:_pageCount forKey:@"PageCount"];
[encoder encodeObject:_pageNumber forKey:@"PageNumber"];
[encoder encodeObject:_bookmarks forKey:@"Bookmarks"];
[encoder encodeObject:_fileSize forKey:@"FileSize"];
[encoder encodeObject:_lastOpen forKey:@"LastOpen"];
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [super init])) // Superclass init
{
_guid = [decoder decodeObjectForKey:@"FileGUID"];
_fileName = [decoder decodeObjectForKey:@"FileName"];
_fileDate = [decoder decodeObjectForKey:@"FileDate"];
_pageCount = [decoder decodeObjectForKey:@"PageCount"];
_pageNumber = [decoder decodeObjectForKey:@"PageNumber"];
_bookmarks = [decoder decodeObjectForKey:@"Bookmarks"];
_fileSize = [decoder decodeObjectForKey:@"FileSize"];
_lastOpen = [decoder decodeObjectForKey:@"LastOpen"];
if (_guid == nil) _guid = [ReaderDocument GUID];
if (_bookmarks != nil)
_bookmarks = [_bookmarks mutableCopy];
else
_bookmarks = [NSMutableIndexSet new];
}
return self;
}
@end

View File

@@ -0,0 +1,47 @@
//
// ReaderDocumentOutline.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2012-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@interface ReaderDocumentOutline : NSObject <NSObject>
+ (NSArray *)outlineFromFileURL:(NSURL *)fileURL password:(NSString *)phrase;
+ (void)logDocumentOutlineArray:(NSArray *)array;
@end
@interface DocumentOutlineEntry : NSObject <NSObject>
+ (id)newWithTitle:(NSString *)title target:(id)target level:(NSInteger)level;
- (id)initWithTitle:(NSString *)title target:(id)target level:(NSInteger)level;
@property (nonatomic, assign, readonly) NSInteger level;
@property (nonatomic, strong, readwrite) NSMutableArray *children;
@property (nonatomic, strong, readonly) NSString *title;
@property (nonatomic, strong, readonly) id target;
@end

View File

@@ -0,0 +1,467 @@
//
// ReaderDocumentOutline.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2012-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderDocumentOutline.h"
#import "CGPDFDocument.h"
@implementation ReaderDocumentOutline
#pragma mark Build option flags
#define HIERARCHICAL_OUTLINE TRUE
#pragma mark ReaderDocumentOutline functions
void logDictionaryEntry(const char *key, CGPDFObjectRef object, void *info)
{
//CGPDFDictionaryApplyFunction(dictionary, logDictionaryEntry, NULL);
NSString *kind = nil; // CGPDFObject type
CGPDFObjectType type = CGPDFObjectGetType(object);
switch (type) // CGPDFObjectTypes
{
case kCGPDFObjectTypeNull:
kind = @"CGPDFObjectTypeNull";
NSLog(@"%s %@", key, kind);
break;
case kCGPDFObjectTypeBoolean:
kind = @"CGPDFObjectTypeBoolean";
NSLog(@"%s %@", key, kind);
break;
case kCGPDFObjectTypeInteger:
kind = @"CGPDFObjectTypeInteger";
NSLog(@"%s %@", key, kind);
break;
case kCGPDFObjectTypeReal:
kind = @"CGPDFObjectTypeReal";
NSLog(@"%s %@", key, kind);
break;
case kCGPDFObjectTypeName:
{
kind = @"CGPDFObjectTypeName"; const char *pdfName = NULL;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeName, &pdfName))
{
if (pdfName != NULL) NSLog(@"%s %@ %s", key, kind, pdfName);
}
break;
}
case kCGPDFObjectTypeString:
{
kind = @"CGPDFObjectTypeString"; CGPDFStringRef pdfString = NULL;
if (CGPDFObjectGetValue(object, kCGPDFObjectTypeString, &pdfString))
{
const unsigned char *string = CGPDFStringGetBytePtr(pdfString);
if (string != NULL) NSLog(@"%s %@ %s", key, kind, string);
}
break;
}
case kCGPDFObjectTypeArray:
kind = @"CGPDFObjectTypeArray";
NSLog(@"%s %@", key, kind);
break;
case kCGPDFObjectTypeDictionary:
kind = @"CGPDFObjectTypeDictionary";
NSLog(@"%s %@", key, kind);
break;
case kCGPDFObjectTypeStream:
kind = @"CGPDFObjectTypeStream";
NSLog(@"%s %@", key, kind);
break;
}
}
#pragma mark ReaderDocumentOutline class methods
+ (void)logDocumentOutlineArray:(NSArray *)array
{
for (DocumentOutlineEntry *item in array) // Enumerate array entries
{
NSInteger indent = (item.level * 2); // Indent amount for NSLog output
NSLog(@"%@%@", [@"" stringByPaddingToLength:indent withString:@" " startingAtIndex:0], item);
[self logDocumentOutlineArray:item.children]; // Log any child entries
}
}
+ (CGPDFArrayRef)destinationWithName:(const char *)destinationName inDestsTree:(CGPDFDictionaryRef)node
{
CGPDFArrayRef destinationArray = NULL;
CGPDFArrayRef limitsArray = NULL; // Limits array
if (CGPDFDictionaryGetArray(node, "Limits", &limitsArray) == true)
{
CGPDFStringRef lowerLimit = NULL; CGPDFStringRef upperLimit = NULL;
if (CGPDFArrayGetString(limitsArray, 0, &lowerLimit) == true) // Lower limit
{
if (CGPDFArrayGetString(limitsArray, 1, &upperLimit) == true) // Upper limit
{
const char *ll = (const char *)CGPDFStringGetBytePtr(lowerLimit); // Lower string
const char *ul = (const char *)CGPDFStringGetBytePtr(upperLimit); // Upper string
if ((strcmp(destinationName, ll) < 0) || (strcmp(destinationName, ul) > 0))
{
return NULL; // Destination name is outside this node's limits
}
}
}
}
CGPDFArrayRef namesArray = NULL; // Names array
if (CGPDFDictionaryGetArray(node, "Names", &namesArray) == true)
{
NSInteger namesCount = CGPDFArrayGetCount(namesArray);
for (NSInteger index = 0; index < namesCount; index += 2)
{
CGPDFStringRef destName; // Destination name string
if (CGPDFArrayGetString(namesArray, index, &destName) == true)
{
const char *dn = (const char *)CGPDFStringGetBytePtr(destName);
if (strcmp(dn, destinationName) == 0) // Found the destination name
{
if (CGPDFArrayGetArray(namesArray, (index + 1), &destinationArray) == false)
{
CGPDFDictionaryRef destinationDictionary = NULL; // Destination dictionary
if (CGPDFArrayGetDictionary(namesArray, (index + 1), &destinationDictionary) == true)
{
CGPDFDictionaryGetArray(destinationDictionary, "D", &destinationArray);
}
}
return destinationArray; // Return the destination array
}
}
}
}
CGPDFArrayRef kidsArray = NULL; // Kids array
if (CGPDFDictionaryGetArray(node, "Kids", &kidsArray) == true)
{
NSInteger kidsCount = CGPDFArrayGetCount(kidsArray);
for (NSInteger index = 0; index < kidsCount; index++)
{
CGPDFDictionaryRef kidNode = NULL; // Kid node dictionary
if (CGPDFArrayGetDictionary(kidsArray, index, &kidNode) == true) // Recurse into node
{
destinationArray = [self destinationWithName:destinationName inDestsTree:kidNode];
if (destinationArray != NULL) return destinationArray; // Return destination array
}
}
}
return NULL;
}
+ (id)outlineEntryTarget:(CGPDFDictionaryRef)outlineDictionary document:(CGPDFDocumentRef)document
{
id entryTarget = nil; // Entry target object
CGPDFStringRef destName = NULL; const char *destString = NULL;
CGPDFDictionaryRef actionDictionary = NULL; CGPDFArrayRef destArray = NULL;
if (CGPDFDictionaryGetDictionary(outlineDictionary, "A", &actionDictionary) == true)
{
const char *actionType = NULL; // Outline entry action type string
if (CGPDFDictionaryGetName(actionDictionary, "S", &actionType) == true)
{
if (strcmp(actionType, "GoTo") == 0) // GoTo action type
{
if (CGPDFDictionaryGetArray(actionDictionary, "D", &destArray) == false)
{
CGPDFDictionaryGetString(actionDictionary, "D", &destName);
}
}
else // Handle other entry action type possibility
{
if (strcmp(actionType, "URI") == 0) // URI action type
{
CGPDFStringRef uriString = NULL; // Action's URI string
if (CGPDFDictionaryGetString(actionDictionary, "URI", &uriString) == true)
{
const char *uri = (const char *)CGPDFStringGetBytePtr(uriString); // Destination URI string
entryTarget = [NSURL URLWithString:[NSString stringWithCString:uri encoding:NSASCIIStringEncoding]];
}
}
}
}
}
else // Handle other entry target possibilities
{
if (CGPDFDictionaryGetArray(outlineDictionary, "Dest", &destArray) == false)
{
if (CGPDFDictionaryGetString(outlineDictionary, "Dest", &destName) == false)
{
CGPDFDictionaryGetName(outlineDictionary, "Dest", &destString);
}
}
}
if (destName != NULL) // Handle a destination name
{
CGPDFDictionaryRef catalogDictionary = CGPDFDocumentGetCatalog(document);
CGPDFDictionaryRef namesDictionary = NULL; // Destination names in the document
if (CGPDFDictionaryGetDictionary(catalogDictionary, "Names", &namesDictionary) == true)
{
CGPDFDictionaryRef destsDictionary = NULL; // Document destinations dictionary
if (CGPDFDictionaryGetDictionary(namesDictionary, "Dests", &destsDictionary) == true)
{
const char *destinationName = (const char *)CGPDFStringGetBytePtr(destName); // Name
destArray = [self destinationWithName:destinationName inDestsTree:destsDictionary];
}
}
}
if (destString != NULL) // Handle a destination string
{
CGPDFDictionaryRef catalogDictionary = CGPDFDocumentGetCatalog(document);
CGPDFDictionaryRef destsDictionary = NULL; // Document destinations dictionary
if (CGPDFDictionaryGetDictionary(catalogDictionary, "Dests", &destsDictionary) == true)
{
CGPDFDictionaryRef targetDictionary = NULL; // Destination target dictionary
if (CGPDFDictionaryGetDictionary(destsDictionary, destString, &targetDictionary) == true)
{
CGPDFDictionaryGetArray(targetDictionary, "D", &destArray);
}
}
}
if (destArray != NULL) // Handle a destination array
{
NSInteger targetPageNumber = 0; // The target page number
CGPDFDictionaryRef pageDictionaryFromDestArray = NULL; // Target reference
if (CGPDFArrayGetDictionary(destArray, 0, &pageDictionaryFromDestArray) == true)
{
NSInteger pageCount = CGPDFDocumentGetNumberOfPages(document); // Pages
for (NSInteger pageNumber = 1; pageNumber <= pageCount; pageNumber++)
{
CGPDFPageRef pageRef = CGPDFDocumentGetPage(document, pageNumber);
CGPDFDictionaryRef pageDictionaryFromPage = CGPDFPageGetDictionary(pageRef);
if (pageDictionaryFromPage == pageDictionaryFromDestArray) // Found it
{
targetPageNumber = pageNumber; break;
}
}
}
else // Try page number from array possibility
{
CGPDFInteger pageNumber = 0; // Page number in array
if (CGPDFArrayGetInteger(destArray, 0, &pageNumber) == true)
{
targetPageNumber = (pageNumber + 1); // 1-based
}
}
if (targetPageNumber > 0) // We have a target page number
{
entryTarget = [NSNumber numberWithInteger:targetPageNumber];
}
}
return entryTarget;
}
+ (void)outlineItems:(CGPDFDictionaryRef)outlineDictionary document:(CGPDFDocumentRef)document array:(NSMutableArray *)array level:(NSInteger)level
{
do // Loop through current level outline entries
{
DocumentOutlineEntry *outlineEntry = nil; // An entry
CGPDFStringRef string = NULL; // Outline entry title string
if (CGPDFDictionaryGetString(outlineDictionary, "Title", &string) == true)
{
CFStringRef title = NULL; // Actual outline title (CFObject) string
if ((title = CGPDFStringCopyTextString(string)) != NULL) // Copy of CFObject string
{
NSString *titleString = (__bridge NSString *)title; // CFString to NSString toll-free bridge cast
id entryTarget = [self outlineEntryTarget:outlineDictionary document:document]; // Get target object
NSString *trimmed = [titleString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
outlineEntry = [DocumentOutlineEntry newWithTitle:trimmed target:entryTarget level:level]; // New entry
[array addObject:outlineEntry]; CFRelease(title); // Add new entry and cleanup
}
}
if (outlineEntry != nil) // Must have a current outline entry
{
CGPDFDictionaryRef childItem = NULL; // First child outline item
if (CGPDFDictionaryGetDictionary(outlineDictionary, "First", &childItem) == true)
{
#if (HIERARCHICAL_OUTLINE == TRUE) // Option
NSMutableArray *childArray = [NSMutableArray array]; outlineEntry.children = childArray;
[self outlineItems:childItem document:document array:childArray level:(level + 1)];
#else // Flat
[self outlineItems:childItem document:document array:array level:(level + 1)];
#endif // end of HIERARCHICAL_OUTLINE Option
}
}
} while (CGPDFDictionaryGetDictionary(outlineDictionary, "Next", &outlineDictionary) == true);
}
+ (NSArray *)outlineFromFileURL:(NSURL *)fileURL password:(NSString *)phrase
{
NSMutableArray *outlineArray = nil; // Mutable outline array
if ((fileURL != nil) && [fileURL isFileURL]) // Check for valid file URL
{
CGPDFDocumentRef document = CGPDFDocumentCreateX((__bridge CFURLRef)fileURL, phrase);
if (document != NULL) // Check for non-NULL CGPDFDocumentRef
{
CGPDFDictionaryRef outlines = NULL; // Document's outlines
CGPDFDictionaryRef catalog = CGPDFDocumentGetCatalog(document);
if (CGPDFDictionaryGetDictionary(catalog, "Outlines", &outlines) == true)
{
CGPDFDictionaryRef firstItem = NULL; // First outline item entry
if (CGPDFDictionaryGetDictionary(outlines, "First", &firstItem) == true)
{
outlineArray = [NSMutableArray array]; // Top level outline entries array
[self outlineItems:firstItem document:document array:outlineArray level:0];
}
}
CGPDFDocumentRelease(document); // Cleanup
}
}
//[self logDocumentOutlineArray:outlineArray]; // Log it
return [outlineArray copy]; // NSArray
}
@end
#pragma mark -
//
// DocumentOutlineEntry class implementation
//
@interface DocumentOutlineEntry ()
@property (nonatomic, assign, readwrite) NSInteger level;
@property (nonatomic, strong, readwrite) NSString *title;
@property (nonatomic, strong, readwrite) id target;
@end
@implementation DocumentOutlineEntry
{
NSInteger _level;
NSMutableArray *_children;
NSString *_title;
id _target;
}
#pragma mark Properties
@synthesize level = _level;
@synthesize children = _children;
@synthesize target = _target;
@synthesize title = _title;
#pragma mark DocumentOutlineEntry class methods
+ (id)newWithTitle:(NSString *)title target:(id)target level:(NSInteger)level
{
return [[DocumentOutlineEntry alloc] initWithTitle:title target:target level:level];
}
#pragma mark DocumentOutlineEntry instance methods
- (id)initWithTitle:(NSString *)title target:(id)target level:(NSInteger)level
{
if ((self = [super init]))
{
self.title = title; self.target = target; self.level = level;
}
return self;
}
- (NSString *)description
{
NSString *format = @"%@ Title = '%@', Target = '%@', Level = (%i)";
return [NSString stringWithFormat:format, [super description], _title, _target, _level];
}
@end

View File

@@ -0,0 +1,88 @@
//
// ReaderMainPagebar.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ReaderThumbView.h"
@class ReaderMainPagebar;
@class ReaderTrackControl;
@class ReaderPagebarThumb;
@class ReaderDocument;
@protocol ReaderMainPagebarDelegate <NSObject>
@required // Delegate protocols
- (void)pagebar:(ReaderMainPagebar *)pagebar gotoPage:(NSInteger)page;
@end
@interface ReaderMainPagebar : UIView
@property (nonatomic, unsafe_unretained, readwrite) id <ReaderMainPagebarDelegate> delegate;
- (id)initWithFrame:(CGRect)frame document:(ReaderDocument *)object;
- (void)updatePagebar;
- (void)hidePagebar;
- (void)showPagebar;
@end
#pragma mark -
//
// ReaderTrackControl class interface
//
@interface ReaderTrackControl : UIControl
@property (nonatomic, assign, readonly) CGFloat value;
@end
#pragma mark -
//
// ReaderPagebarThumb class interface
//
@interface ReaderPagebarThumb : ReaderThumbView
- (id)initWithFrame:(CGRect)frame small:(BOOL)small;
@end
#pragma mark -
//
// ReaderPagebarShadow class interface
//
@interface ReaderPagebarShadow : UIView
@end

View File

@@ -0,0 +1,625 @@
//
// ReaderMainPagebar.m
// Reader v2.6.2
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderMainPagebar.h"
#import "ReaderThumbCache.h"
#import "ReaderDocument.h"
#import <QuartzCore/QuartzCore.h>
@implementation ReaderMainPagebar
{
ReaderDocument *document;
ReaderTrackControl *trackControl;
NSMutableDictionary *miniThumbViews;
ReaderPagebarThumb *pageThumbView;
UILabel *pageNumberLabel;
UIView *pageNumberView;
NSTimer *enableTimer;
NSTimer *trackTimer;
}
#pragma mark Constants
#define THUMB_SMALL_GAP 2
#define THUMB_SMALL_WIDTH 22
#define THUMB_SMALL_HEIGHT 28
#define THUMB_LARGE_WIDTH 32
#define THUMB_LARGE_HEIGHT 42
#define PAGE_NUMBER_WIDTH 96.0f
#define PAGE_NUMBER_HEIGHT 30.0f
#define PAGE_NUMBER_SPACE 20.0f
#pragma mark Properties
@synthesize delegate;
#pragma mark ReaderMainPagebar class methods
+ (Class)layerClass
{
return [CAGradientLayer class];
}
#pragma mark ReaderMainPagebar instance methods
- (id)initWithFrame:(CGRect)frame
{
return [self initWithFrame:frame document:nil];
}
- (void)updatePageThumbView:(NSInteger)page
{
NSInteger pages = [document.pageCount integerValue];
if (pages > 1) // Only update frame if more than one page
{
CGFloat controlWidth = trackControl.bounds.size.width;
CGFloat useableWidth = (controlWidth - THUMB_LARGE_WIDTH);
CGFloat stride = (useableWidth / (pages - 1)); // Page stride
NSInteger X = (stride * (page - 1)); CGFloat pageThumbX = X;
CGRect pageThumbRect = pageThumbView.frame; // Current frame
if (pageThumbX != pageThumbRect.origin.x) // Only if different
{
pageThumbRect.origin.x = pageThumbX; // The new X position
pageThumbView.frame = pageThumbRect; // Update the frame
}
}
if (page != pageThumbView.tag) // Only if page number changed
{
pageThumbView.tag = page; [pageThumbView reuse]; // Reuse the thumb view
CGSize size = CGSizeMake(THUMB_LARGE_WIDTH, THUMB_LARGE_HEIGHT); // Maximum thumb size
NSURL *fileURL = document.fileURL; NSString *guid = document.guid; NSString *phrase = document.password;
ReaderThumbRequest *request = [ReaderThumbRequest newForView:pageThumbView fileURL:fileURL password:phrase guid:guid page:page size:size];
UIImage *image = [[ReaderThumbCache sharedInstance] thumbRequest:request priority:YES]; // Request the thumb
UIImage *thumb = ([image isKindOfClass:[UIImage class]] ? image : nil); [pageThumbView showImage:thumb];
}
}
- (void)updatePageNumberText:(NSInteger)page
{
if (page != pageNumberLabel.tag) // Only if page number changed
{
NSInteger pages = [document.pageCount integerValue]; // Total pages
NSString *format = NSLocalizedString(@"%d of %d", @"format"); // Format
NSString *number = [NSString stringWithFormat:format, page, pages]; // Text
pageNumberLabel.text = number; // Update the page number label text
pageNumberLabel.tag = page; // Update the last page number tag
}
}
- (id)initWithFrame:(CGRect)frame document:(ReaderDocument *)object
{
assert(object != nil); // Must have a valid ReaderDocument
UIColor *DarkNightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.3];
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = YES;
self.userInteractionEnabled = YES;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
self.backgroundColor = [UIColor blackColor];
CAGradientLayer *layer = (CAGradientLayer *)self.layer;
UIColor *liteColor = DarkNightColor;
UIColor *darkColor = DarkNightColor;
layer.colors = [NSArray arrayWithObjects:(id)liteColor.CGColor, (id)darkColor.CGColor, nil];
// CGRect shadowRect = self.bounds; shadowRect.size.height = 4.0f; shadowRect.origin.y -= shadowRect.size.height;
// ReaderPagebarShadow *shadowView = [[ReaderPagebarShadow alloc] initWithFrame:shadowRect];
// [self addSubview:shadowView]; // Add the shadow to the view
CGFloat numberY = (0.0f - (PAGE_NUMBER_HEIGHT + PAGE_NUMBER_SPACE));
CGFloat numberX = ((self.bounds.size.width - PAGE_NUMBER_WIDTH) / 2.0f);
CGRect numberRect = CGRectMake(numberX, numberY, PAGE_NUMBER_WIDTH, PAGE_NUMBER_HEIGHT);
pageNumberView = [[UIView alloc] initWithFrame:numberRect]; // Page numbers view
pageNumberView.autoresizesSubviews = NO;
pageNumberView.userInteractionEnabled = NO;
pageNumberView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
pageNumberView.backgroundColor = [UIColor blackColor];
pageNumberView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
pageNumberView.layer.shadowColor = [UIColor colorWithWhite:0.0f alpha:0.6f].CGColor;
pageNumberView.layer.shadowPath = [UIBezierPath bezierPathWithRect:pageNumberView.bounds].CGPath;
pageNumberView.layer.shadowRadius = 2.0f; pageNumberView.layer.shadowOpacity = 1.0f;
CGRect textRect = CGRectInset(pageNumberView.bounds, 4.0f, 2.0f); // Inset the text a bit
pageNumberLabel = [[UILabel alloc] initWithFrame:textRect]; // Page numbers label
pageNumberLabel.autoresizesSubviews = NO;
pageNumberLabel.autoresizingMask = UIViewAutoresizingNone;
pageNumberLabel.textAlignment = NSTextAlignmentCenter;
pageNumberLabel.backgroundColor = [UIColor clearColor];
pageNumberLabel.textColor = [UIColor whiteColor];
pageNumberLabel.font = [UIFont systemFontOfSize:16.0f];
pageNumberLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
pageNumberLabel.shadowColor = [UIColor blackColor];
pageNumberLabel.adjustsFontSizeToFitWidth = YES;
pageNumberLabel.MinimumScaleFactor = 12.0f;
[pageNumberView addSubview:pageNumberLabel]; // Add label view
[self addSubview:pageNumberView]; // Add page numbers display view
trackControl = [[ReaderTrackControl alloc] initWithFrame:self.bounds]; // Track control view
[trackControl addTarget:self action:@selector(trackViewTouchDown:) forControlEvents:UIControlEventTouchDown];
[trackControl addTarget:self action:@selector(trackViewValueChanged:) forControlEvents:UIControlEventValueChanged];
[trackControl addTarget:self action:@selector(trackViewTouchUp:) forControlEvents:UIControlEventTouchUpOutside];
[trackControl addTarget:self action:@selector(trackViewTouchUp:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:trackControl]; // Add the track control and thumbs view
document = object; // Retain the document object for our use
[self updatePageNumberText:[document.pageNumber integerValue]];
miniThumbViews = [NSMutableDictionary new]; // Small thumbs
}
return self;
}
- (void)removeFromSuperview
{
[trackTimer invalidate]; [enableTimer invalidate];
[super removeFromSuperview];
}
- (void)layoutSubviews
{
CGRect controlRect = CGRectInset(self.bounds, 4.0f, 0.0f);
CGFloat thumbWidth = (THUMB_SMALL_WIDTH + THUMB_SMALL_GAP);
NSInteger thumbs = (controlRect.size.width / thumbWidth);
NSInteger pages = [document.pageCount integerValue]; // Pages
if (thumbs > pages) thumbs = pages; // No more than total pages
CGFloat controlWidth = ((thumbs * thumbWidth) - THUMB_SMALL_GAP);
controlRect.size.width = controlWidth; // Update control width
CGFloat widthDelta = (self.bounds.size.width - controlWidth);
NSInteger X = (widthDelta / 2.0f); controlRect.origin.x = X;
trackControl.frame = controlRect; // Update track control frame
if (pageThumbView == nil) // Create the page thumb view when needed
{
CGFloat heightDelta = (controlRect.size.height - THUMB_LARGE_HEIGHT);
NSInteger thumbY = (heightDelta / 2.0f); NSInteger thumbX = 0; // Thumb X, Y
CGRect thumbRect = CGRectMake(thumbX, thumbY, THUMB_LARGE_WIDTH, THUMB_LARGE_HEIGHT);
pageThumbView = [[ReaderPagebarThumb alloc] initWithFrame:thumbRect]; // Create the thumb view
pageThumbView.layer.zPosition = 1.0f; // Z position so that it sits on top of the small thumbs
[trackControl addSubview:pageThumbView]; // Add as the first subview of the track control
}
[self updatePageThumbView:[document.pageNumber integerValue]]; // Update page thumb view
NSInteger strideThumbs = (thumbs - 1); if (strideThumbs < 1) strideThumbs = 1;
CGFloat stride = ((CGFloat)pages / (CGFloat)strideThumbs); // Page stride
CGFloat heightDelta = (controlRect.size.height - THUMB_SMALL_HEIGHT);
NSInteger thumbY = (heightDelta / 2.0f); NSInteger thumbX = 0; // Initial X, Y
CGRect thumbRect = CGRectMake(thumbX, thumbY, THUMB_SMALL_WIDTH, THUMB_SMALL_HEIGHT);
NSMutableDictionary *thumbsToHide = [miniThumbViews mutableCopy];
for (NSInteger thumb = 0; thumb < thumbs; thumb++) // Iterate through needed thumbs
{
NSInteger page = ((stride * thumb) + 1); if (page > pages) page = pages; // Page
NSNumber *key = [NSNumber numberWithInteger:page]; // Page number key for thumb view
ReaderPagebarThumb *smallThumbView = [miniThumbViews objectForKey:key]; // Thumb view
if (smallThumbView == nil) // We need to create a new small thumb view for the page number
{
CGSize size = CGSizeMake(THUMB_SMALL_WIDTH, THUMB_SMALL_HEIGHT); // Maximum thumb size
NSURL *fileURL = document.fileURL; NSString *guid = document.guid; NSString *phrase = document.password;
smallThumbView = [[ReaderPagebarThumb alloc] initWithFrame:thumbRect small:YES]; // Create a small thumb view
ReaderThumbRequest *thumbRequest = [ReaderThumbRequest newForView:smallThumbView fileURL:fileURL password:phrase guid:guid page:page size:size];
UIImage *image = [[ReaderThumbCache sharedInstance] thumbRequest:thumbRequest priority:NO]; // Request the thumb
if ([image isKindOfClass:[UIImage class]]) [smallThumbView showImage:image]; // Use thumb image from cache
[trackControl addSubview:smallThumbView]; [miniThumbViews setObject:smallThumbView forKey:key];
}
else // Resue existing small thumb view for the page number
{
smallThumbView.hidden = NO; [thumbsToHide removeObjectForKey:key];
if (CGRectEqualToRect(smallThumbView.frame, thumbRect) == false)
{
smallThumbView.frame = thumbRect; // Update thumb frame
}
}
thumbRect.origin.x += thumbWidth; // Next thumb X position
}
[thumbsToHide enumerateKeysAndObjectsUsingBlock: // Hide unused thumbs
^(id key, id object, BOOL *stop)
{
ReaderPagebarThumb *thumb = object; thumb.hidden = YES;
}
];
}
- (void)updatePagebarViews
{
NSInteger page = [document.pageNumber integerValue]; // #
[self updatePageNumberText:page]; // Update page number text
[self updatePageThumbView:page]; // Update page thumb view
}
- (void)updatePagebar
{
if (self.hidden == NO) // Only if visible
{
[self updatePagebarViews]; // Update views
}
}
- (void)hidePagebar
{
if (self.hidden == NO) // Only if visible
{
[UIView animateWithDuration:0.25 delay:0.0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
self.alpha = 0.0f;
}
completion:^(BOOL finished)
{
self.hidden = YES;
}
];
}
}
- (void)showPagebar
{
if (self.hidden == YES) // Only if hidden
{
[self updatePagebarViews]; // Update views first
[UIView animateWithDuration:0.25 delay:0.0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
self.hidden = NO;
self.alpha = 1.0f;
}
completion:NULL
];
}
}
#pragma mark ReaderTrackControl action methods
- (void)trackTimerFired:(NSTimer *)timer
{
[trackTimer invalidate]; trackTimer = nil; // Cleanup timer
if (trackControl.tag != [document.pageNumber integerValue]) // Only if different
{
[delegate pagebar:self gotoPage:trackControl.tag]; // Go to document page
}
}
- (void)enableTimerFired:(NSTimer *)timer
{
[enableTimer invalidate]; enableTimer = nil; // Cleanup timer
trackControl.userInteractionEnabled = YES; // Enable track control interaction
}
- (void)restartTrackTimer
{
if (trackTimer != nil) { [trackTimer invalidate]; trackTimer = nil; } // Invalidate and release previous timer
trackTimer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(trackTimerFired:) userInfo:nil repeats:NO];
}
- (void)startEnableTimer
{
if (enableTimer != nil) { [enableTimer invalidate]; enableTimer = nil; } // Invalidate and release previous timer
enableTimer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(enableTimerFired:) userInfo:nil repeats:NO];
}
- (NSInteger)trackViewPageNumber:(ReaderTrackControl *)trackView
{
CGFloat controlWidth = trackView.bounds.size.width; // View width
CGFloat stride = (controlWidth / [document.pageCount integerValue]);
NSInteger page = (trackView.value / stride); // Integer page number
return (page + 1); // + 1
}
- (void)trackViewTouchDown:(ReaderTrackControl *)trackView
{
NSInteger page = [self trackViewPageNumber:trackView]; // Page
if (page != [document.pageNumber integerValue]) // Only if different
{
[self updatePageNumberText:page]; // Update page number text
[self updatePageThumbView:page]; // Update page thumb view
[self restartTrackTimer]; // Start the track timer
}
trackView.tag = page; // Start page tracking
}
- (void)trackViewValueChanged:(ReaderTrackControl *)trackView
{
NSInteger page = [self trackViewPageNumber:trackView]; // Page
if (page != trackView.tag) // Only if the page number has changed
{
[self updatePageNumberText:page]; // Update page number text
[self updatePageThumbView:page]; // Update page thumb view
trackView.tag = page; // Update the page tracking tag
[self restartTrackTimer]; // Restart the track timer
}
}
- (void)trackViewTouchUp:(ReaderTrackControl *)trackView
{
[trackTimer invalidate]; trackTimer = nil; // Cleanup
if (trackView.tag != [document.pageNumber integerValue]) // Only if different
{
trackView.userInteractionEnabled = NO; // Disable track control interaction
[delegate pagebar:self gotoPage:trackView.tag]; // Go to document page
[self startEnableTimer]; // Start track control enable timer
}
trackView.tag = 0; // Reset page tracking
}
@end
#pragma mark -
//
// ReaderTrackControl class implementation
//
@implementation ReaderTrackControl
{
CGFloat _value;
}
#pragma mark Properties
@synthesize value = _value;
#pragma mark ReaderTrackControl instance methods
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = NO;
self.userInteractionEnabled = YES;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingNone;
self.backgroundColor = [UIColor clearColor];
self.exclusiveTouch = YES;
}
return self;
}
- (CGFloat)limitValue:(CGFloat)valueX
{
CGFloat minX = self.bounds.origin.x; // 0.0f;
CGFloat maxX = (self.bounds.size.width - 1.0f);
if (valueX < minX) valueX = minX; // Minimum X
if (valueX > maxX) valueX = maxX; // Maximum X
return valueX;
}
#pragma mark UIControl subclass methods
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint point = [touch locationInView:self]; // Touch point
_value = [self limitValue:point.x]; // Limit control value
return YES;
}
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
if (self.touchInside == YES) // Only if inside the control
{
CGPoint point = [touch locationInView:touch.view]; // Touch point
CGFloat x = [self limitValue:point.x]; // Potential new control value
if (x != _value) // Only if the new value has changed since the last time
{
_value = x; [self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
return YES;
}
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint point = [touch locationInView:self]; // Touch point
_value = [self limitValue:point.x]; // Limit control value
}
@end
#pragma mark -
//
// ReaderPagebarThumb class implementation
//
@implementation ReaderPagebarThumb
#pragma mark ReaderPagebarThumb instance methods
- (id)initWithFrame:(CGRect)frame
{
return [self initWithFrame:frame small:NO];
}
- (id)initWithFrame:(CGRect)frame small:(BOOL)small
{
if ((self = [super initWithFrame:frame])) // Superclass init
{
CGFloat value = (small ? 0.6f : 0.7f); // Size based alpha value
UIColor *background = [UIColor colorWithWhite:0.8f alpha:value];
self.backgroundColor = background; imageView.backgroundColor = background;
imageView.layer.borderColor = [UIColor colorWithWhite:0.4f alpha:0.6f].CGColor;
imageView.layer.borderWidth = 1.0f; // Give the thumb image view a border
}
return self;
}
@end
#pragma mark -
//
// ReaderPagebarShadow class implementation
//
@implementation ReaderPagebarShadow
#pragma mark ReaderPagebarShadow class methods
+ (Class)layerClass
{
return [CAGradientLayer class];
}
#pragma mark ReaderPagebarShadow instance methods
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = NO;
self.userInteractionEnabled = NO;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = [UIColor clearColor];
CAGradientLayer *layer = (CAGradientLayer *)self.layer;
UIColor *blackColor = [UIColor colorWithWhite:0.42f alpha:1.0f];
UIColor *clearColor = [UIColor colorWithWhite:0.42f alpha:0.0f];
layer.colors = [NSArray arrayWithObjects:(id)clearColor.CGColor, (id)blackColor.CGColor, nil];
}
return self;
}
@end

View File

@@ -0,0 +1,56 @@
//
// ReaderMainToolbar.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "UIXToolbarView.h"
@class ReaderMainToolbar;
@class ReaderDocument;
@protocol ReaderMainToolbarDelegate <NSObject>
@required // Delegate protocols
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar doneButton:(UIButton *)button;
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar thumbsButton:(UIButton *)button;
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar printButton:(UIButton *)button;
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar emailButton:(UIButton *)button;
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar markButton:(UIButton *)button;
@end
@interface ReaderMainToolbar : UIXToolbarView
@property (nonatomic, unsafe_unretained, readwrite) id <ReaderMainToolbarDelegate> delegate;
- (id)initWithFrame:(CGRect)frame document:(ReaderDocument *)object;
- (void)setBookmarkState:(BOOL)state;
- (void)hideToolbar;
- (void)showToolbar;
@end

View File

@@ -0,0 +1,334 @@
//
// ReaderMainToolbar.m
// Reader v2.6.2
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
#import "ReaderMainToolbar.h"
#import "ReaderDocument.h"
#import <MessageUI/MessageUI.h>
@implementation ReaderMainToolbar
{
UIButton *markButton;
UIImage *markImageN;
UIImage *markImageY;
}
#pragma mark Constants
#define BUTTON_X 8.0f
#define BUTTON_Y 8.0f
#define BUTTON_SPACE 8.0f
#define BUTTON_HEIGHT 30.0f
#define DONE_BUTTON_WIDTH 56.0f
#define THUMBS_BUTTON_WIDTH 40.0f
#define PRINT_BUTTON_WIDTH 40.0f
#define EMAIL_BUTTON_WIDTH 40.0f
#define MARK_BUTTON_WIDTH 40.0f
#define TITLE_HEIGHT 28.0f
#pragma mark Properties
@synthesize delegate;
#pragma mark ReaderMainToolbar instance methods
- (id)initWithFrame:(CGRect)frame
{
return [self initWithFrame:frame document:nil];
}
- (id)initWithFrame:(CGRect)frame document:(ReaderDocument *)object
{
assert(object != nil); // Must have a valid ReaderDocument
if ((self = [super initWithFrame:frame]))
{
CGFloat viewWidth = self.bounds.size.width;
UIImage *imageH = [UIImage imageNamed:@"Reader-Button-H"];
UIImage *imageN = [UIImage imageNamed:@"Reader-Button-N"];
UIImage *buttonH = [imageH stretchableImageWithLeftCapWidth:5 topCapHeight:0];
UIImage *buttonN = [imageN stretchableImageWithLeftCapWidth:5 topCapHeight:0];
CGFloat titleX = BUTTON_X; CGFloat titleWidth = (viewWidth - (titleX + titleX));
CGFloat leftButtonX = BUTTON_X; // Left button start X position
#if (READER_STANDALONE == FALSE) // Option
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIColor *NightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.8];
// UIColor *DarkNightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.3];
doneButton.frame = CGRectMake(leftButtonX, BUTTON_Y, DONE_BUTTON_WIDTH, BUTTON_HEIGHT);
[doneButton setTitle:NSLocalizedString(@"Done", @"button") forState:UIControlStateNormal];
[doneButton setTitleColor:NightColor forState:UIControlStateNormal];
[doneButton setTitleColor:NightColor forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(doneButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[doneButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
[doneButton setBackgroundImage:buttonN forState:UIControlStateNormal];
doneButton.titleLabel.font = [UIFont systemFontOfSize:14.0f];
doneButton.autoresizingMask = UIViewAutoresizingNone;
doneButton.exclusiveTouch = YES;
[self addSubview:doneButton]; leftButtonX += (DONE_BUTTON_WIDTH + BUTTON_SPACE);
titleX += (DONE_BUTTON_WIDTH + BUTTON_SPACE); titleWidth -= (DONE_BUTTON_WIDTH + BUTTON_SPACE);
#endif // end of READER_STANDALONE Option
#if (READER_ENABLE_THUMBS == TRUE) // Option
UIButton *thumbsButton = [UIButton buttonWithType:UIButtonTypeCustom];
thumbsButton.frame = CGRectMake(leftButtonX, BUTTON_Y, THUMBS_BUTTON_WIDTH, BUTTON_HEIGHT);
[thumbsButton setImage:[UIImage imageNamed:@"Reader-Thumbs"] forState:UIControlStateNormal];
[thumbsButton addTarget:self action:@selector(thumbsButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[thumbsButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
[thumbsButton setBackgroundImage:buttonN forState:UIControlStateNormal];
thumbsButton.autoresizingMask = UIViewAutoresizingNone;
thumbsButton.exclusiveTouch = YES;
[self addSubview:thumbsButton]; //leftButtonX += (THUMBS_BUTTON_WIDTH + BUTTON_SPACE);
titleX += (THUMBS_BUTTON_WIDTH + BUTTON_SPACE); titleWidth -= (THUMBS_BUTTON_WIDTH + BUTTON_SPACE);
#endif // end of READER_ENABLE_THUMBS Option
#if (READER_BOOKMARKS == TRUE || READER_ENABLE_MAIL == TRUE || READER_ENABLE_PRINT == TRUE)
CGFloat rightButtonX = viewWidth; // Right button start X position
#endif // end of READER_BOOKMARKS || READER_ENABLE_MAIL || READER_ENABLE_PRINT Options
#if (READER_BOOKMARKS == TRUE) // Option
rightButtonX -= (MARK_BUTTON_WIDTH + BUTTON_SPACE);
UIButton *flagButton = [UIButton buttonWithType:UIButtonTypeCustom];
flagButton.frame = CGRectMake(rightButtonX, BUTTON_Y, MARK_BUTTON_WIDTH, BUTTON_HEIGHT);
//[flagButton setImage:[UIImage imageNamed:@"Reader-Mark-N"] forState:UIControlStateNormal];
[flagButton addTarget:self action:@selector(markButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[flagButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
[flagButton setBackgroundImage:buttonN forState:UIControlStateNormal];
flagButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
flagButton.exclusiveTouch = YES;
[self addSubview:flagButton]; titleWidth -= (MARK_BUTTON_WIDTH + BUTTON_SPACE);
markButton = flagButton; markButton.enabled = NO; markButton.tag = NSIntegerMin;
markImageN = [UIImage imageNamed:@"Reader-Mark-N"]; // N image
markImageY = [UIImage imageNamed:@"Reader-Mark-Y"]; // Y image
#endif // end of READER_BOOKMARKS Option
#if (READER_ENABLE_MAIL == TRUE) // Option
if ([MFMailComposeViewController canSendMail] == YES) // Can email
{
unsigned long long fileSize = [object.fileSize unsignedLongLongValue];
if (fileSize < (unsigned long long)15728640) // Check attachment size limit (15MB)
{
rightButtonX -= (EMAIL_BUTTON_WIDTH + BUTTON_SPACE);
UIButton *emailButton = [UIButton buttonWithType:UIButtonTypeCustom];
emailButton.frame = CGRectMake(rightButtonX, BUTTON_Y, EMAIL_BUTTON_WIDTH, BUTTON_HEIGHT);
[emailButton setImage:[UIImage imageNamed:@"Reader-Email"] forState:UIControlStateNormal];
[emailButton addTarget:self action:@selector(emailButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[emailButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
[emailButton setBackgroundImage:buttonN forState:UIControlStateNormal];
emailButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
emailButton.exclusiveTouch = YES;
[self addSubview:emailButton]; titleWidth -= (EMAIL_BUTTON_WIDTH + BUTTON_SPACE);
}
}
#endif // end of READER_ENABLE_MAIL Option
#if (READER_ENABLE_PRINT == TRUE) // Option
if (object.password == nil) // We can only print documents without passwords
{
Class printInteractionController = NSClassFromString(@"UIPrintInteractionController");
if ((printInteractionController != nil) && [printInteractionController isPrintingAvailable])
{
rightButtonX -= (PRINT_BUTTON_WIDTH + BUTTON_SPACE);
UIButton *printButton = [UIButton buttonWithType:UIButtonTypeCustom];
printButton.frame = CGRectMake(rightButtonX, BUTTON_Y, PRINT_BUTTON_WIDTH, BUTTON_HEIGHT);
[printButton setImage:[UIImage imageNamed:@"Reader-Print"] forState:UIControlStateNormal];
[printButton addTarget:self action:@selector(printButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[printButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
[printButton setBackgroundImage:buttonN forState:UIControlStateNormal];
printButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
printButton.exclusiveTouch = YES;
[self addSubview:printButton]; titleWidth -= (PRINT_BUTTON_WIDTH + BUTTON_SPACE);
}
}
#endif // end of READER_ENABLE_PRINT Option
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
CGRect titleRect = CGRectMake(titleX, BUTTON_Y, titleWidth, TITLE_HEIGHT);
UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleRect];
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.font = [UIFont systemFontOfSize:19.0f];
titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
titleLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
titleLabel.textColor = [UIColor colorWithWhite:0.0f alpha:1.0f];
titleLabel.shadowColor = [UIColor colorWithWhite:0.65f alpha:1.0f];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
titleLabel.adjustsFontSizeToFitWidth = YES;
titleLabel.MinimumScaleFactor = 14.0f;
titleLabel.text = [object.fileName stringByDeletingPathExtension];
[self addSubview:titleLabel];
}
}
return self;
}
- (void)setBookmarkState:(BOOL)state
{
#if (READER_BOOKMARKS == TRUE) // Option
if (state != markButton.tag) // Only if different state
{
if (self.hidden == NO) // Only if toolbar is visible
{
UIImage *image = (state ? markImageY : markImageN);
[markButton setImage:image forState:UIControlStateNormal];
}
markButton.tag = state; // Update bookmarked state tag
}
if (markButton.enabled == NO) markButton.enabled = YES;
#endif // end of READER_BOOKMARKS Option
}
- (void)updateBookmarkImage
{
#if (READER_BOOKMARKS == TRUE) // Option
if (markButton.tag != NSIntegerMin) // Valid tag
{
BOOL state = markButton.tag; // Bookmarked state
UIImage *image = (state ? markImageY : markImageN);
[markButton setImage:image forState:UIControlStateNormal];
}
if (markButton.enabled == NO) markButton.enabled = YES;
#endif // end of READER_BOOKMARKS Option
}
- (void)hideToolbar
{
if (self.hidden == NO)
{
[UIView animateWithDuration:0.25 delay:0.0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
self.alpha = 0.0f;
}
completion:^(BOOL finished)
{
self.hidden = YES;
}
];
}
}
- (void)showToolbar
{
if (self.hidden == YES)
{
[self updateBookmarkImage]; // First
[UIView animateWithDuration:0.25 delay:0.0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
self.hidden = NO;
self.alpha = 1.0f;
}
completion:NULL
];
}
}
#pragma mark UIButton action methods
- (void)doneButtonTapped:(UIButton *)button
{
[delegate tappedInToolbar:self doneButton:button];
}
- (void)thumbsButtonTapped:(UIButton *)button
{
[delegate tappedInToolbar:self thumbsButton:button];
}
- (void)printButtonTapped:(UIButton *)button
{
[delegate tappedInToolbar:self printButton:button];
}
- (void)emailButtonTapped:(UIButton *)button
{
[delegate tappedInToolbar:self emailButton:button];
}
- (void)markButtonTapped:(UIButton *)button
{
[delegate tappedInToolbar:self markButton:button];
}
@end

View File

@@ -0,0 +1,54 @@
//
// ReaderThumbCache.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ReaderThumbRequest.h"
@interface ReaderThumbCache : NSObject <NSObject>
+ (ReaderThumbCache *)sharedInstance;
+ (void)touchThumbCacheWithGUID:(NSString *)guid;
+ (void)createThumbCacheWithGUID:(NSString *)guid;
+ (void)removeThumbCacheWithGUID:(NSString *)guid;
+ (void)purgeThumbCachesOlderThan:(NSTimeInterval)age;
+ (NSString *)thumbCachePathForGUID:(NSString *)guid;
- (id)thumbRequest:(ReaderThumbRequest *)request priority:(BOOL)priority;
- (void)setObject:(UIImage *)image forKey:(NSString *)key;
- (void)removeObjectForKey:(NSString *)key;
- (void)removeNullForKey:(NSString *)key;
- (void)removeAllObjects;
@end

View File

@@ -0,0 +1,228 @@
//
// ReaderThumbCache.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbCache.h"
#import "ReaderThumbQueue.h"
#import "ReaderThumbFetch.h"
#import "ReaderThumbView.h"
@implementation ReaderThumbCache
{
NSCache *thumbCache;
}
#pragma mark Constants
#define CACHE_SIZE 2097152
#pragma mark ReaderThumbCache class methods
+ (ReaderThumbCache *)sharedInstance
{
static dispatch_once_t predicate = 0;
static ReaderThumbCache *object = nil; // Object
dispatch_once(&predicate, ^{ object = [self new]; });
return object; // ReaderThumbCache singleton
}
+ (NSString *)appCachesPath
{
static dispatch_once_t predicate = 0;
static NSString *theCachesPath = nil; // Application caches path string
dispatch_once(&predicate, // Save a copy of the application caches path the first time it is needed
^{
NSArray *cachesPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
theCachesPath = [[cachesPaths objectAtIndex:0] copy]; // Keep a copy for later abusage
});
return theCachesPath;
}
+ (NSString *)thumbCachePathForGUID:(NSString *)guid
{
NSString *cachesPath = [ReaderThumbCache appCachesPath]; // Caches path
return [cachesPath stringByAppendingPathComponent:guid]; // Append GUID
}
+ (void)createThumbCacheWithGUID:(NSString *)guid
{
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSString *cachePath = [ReaderThumbCache thumbCachePathForGUID:guid]; // Thumb cache path
[fileManager createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:NULL];
}
+ (void)removeThumbCacheWithGUID:(NSString *)guid
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSString *cachePath = [ReaderThumbCache thumbCachePathForGUID:guid]; // Thumb cache path
[fileManager removeItemAtPath:cachePath error:NULL]; // Remove thumb cache directory
});
}
+ (void)touchThumbCacheWithGUID:(NSString *)guid
{
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSString *cachePath = [ReaderThumbCache thumbCachePathForGUID:guid]; // Thumb cache path
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate];
[fileManager setAttributes:attributes ofItemAtPath:cachePath error:NULL]; // New modification date
}
+ (void)purgeThumbCachesOlderThan:(NSTimeInterval)age
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
NSDate *now = [NSDate date]; // Right about now time
NSString *cachesPath = [ReaderThumbCache appCachesPath]; // Caches path
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSArray *cachesList = [fileManager contentsOfDirectoryAtPath:cachesPath error:NULL];
if (cachesList != nil) // Process caches directory contents
{
for (NSString *cacheName in cachesList) // Enumerate directory contents
{
if (cacheName.length == 36) // This is a very hacky cache ident kludge
{
NSString *cachePath = [cachesPath stringByAppendingPathComponent:cacheName];
NSDictionary *attributes = [fileManager attributesOfItemAtPath:cachePath error:NULL];
NSDate *cacheDate = [attributes objectForKey:NSFileModificationDate]; // Cache date
NSTimeInterval seconds = [now timeIntervalSinceDate:cacheDate]; // Cache age
if (seconds > age) // Older than so remove the thumb cache
{
[fileManager removeItemAtPath:cachePath error:NULL];
#ifdef DEBUG
NSLog(@"%s purged %@", __FUNCTION__, cacheName);
#endif
}
}
}
}
});
}
#pragma mark ReaderThumbCache instance methods
- (id)init
{
if ((self = [super init])) // Initialize
{
thumbCache = [NSCache new]; // Cache
[thumbCache setName:@"ReaderThumbCache"];
[thumbCache setTotalCostLimit:CACHE_SIZE];
}
return self;
}
- (id)thumbRequest:(ReaderThumbRequest *)request priority:(BOOL)priority
{
@synchronized(thumbCache) // Mutex lock
{
id object = [thumbCache objectForKey:request.cacheKey];
if (object == nil) // Thumb object does not yet exist in the cache
{
object = [NSNull null]; // Return an NSNull thumb placeholder object
[thumbCache setObject:object forKey:request.cacheKey cost:2]; // Cache the placeholder object
ReaderThumbFetch *thumbFetch = [[ReaderThumbFetch alloc] initWithRequest:request]; // Create a thumb fetch operation
[thumbFetch setQueuePriority:(priority ? NSOperationQueuePriorityNormal : NSOperationQueuePriorityLow)]; // Queue priority
request.thumbView.operation = thumbFetch; [thumbFetch setThreadPriority:(priority ? 0.55 : 0.35)]; // Thread priority
[[ReaderThumbQueue sharedInstance] addLoadOperation:thumbFetch]; // Queue the operation
}
return object; // NSNull or UIImage
}
}
- (void)setObject:(UIImage *)image forKey:(NSString *)key
{
@synchronized(thumbCache) // Mutex lock
{
NSUInteger bytes = (image.size.width * image.size.height * 4.0f);
[thumbCache setObject:image forKey:key cost:bytes]; // Cache image
}
}
- (void)removeObjectForKey:(NSString *)key
{
@synchronized(thumbCache) // Mutex lock
{
[thumbCache removeObjectForKey:key];
}
}
- (void)removeNullForKey:(NSString *)key
{
@synchronized(thumbCache) // Mutex lock
{
id object = [thumbCache objectForKey:key];
if ([object isMemberOfClass:[NSNull class]])
{
[thumbCache removeObjectForKey:key];
}
}
}
- (void)removeAllObjects
{
@synchronized(thumbCache) // Mutex lock
{
[thumbCache removeAllObjects];
}
}
@end

View File

@@ -0,0 +1,36 @@
//
// ReaderThumbFetch.h
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
#import "ReaderThumbQueue.h"
@class ReaderThumbRequest;
@interface ReaderThumbFetch : ReaderThumbOperation
- (id)initWithRequest:(ReaderThumbRequest *)options;
@end

View File

@@ -0,0 +1,128 @@
//
// ReaderThumbFetch.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbFetch.h"
#import "ReaderThumbRender.h"
#import "ReaderThumbCache.h"
#import "ReaderThumbView.h"
#import <ImageIO/ImageIO.h>
@implementation ReaderThumbFetch
{
ReaderThumbRequest *request;
}
#pragma mark ReaderThumbFetch instance methods
- (id)initWithRequest:(ReaderThumbRequest *)options
{
if ((self = [super initWithGUID:options.guid]))
{
request = options;
}
return self;
}
- (void)cancel
{
[super cancel]; // Cancel the operation
request.thumbView.operation = nil; // Break retain loop
request.thumbView = nil; // Release target thumb view on cancel
[[ReaderThumbCache sharedInstance] removeNullForKey:request.cacheKey];
}
- (NSURL *)thumbFileURL
{
NSString *cachePath = [ReaderThumbCache thumbCachePathForGUID:request.guid]; // Thumb cache path
NSString *fileName = [NSString stringWithFormat:@"%@.png", request.thumbName]; // Thumb file name
return [NSURL fileURLWithPath:[cachePath stringByAppendingPathComponent:fileName]]; // File URL
}
- (void)main
{
CGImageRef imageRef = NULL; NSURL *thumbURL = [self thumbFileURL];
CGImageSourceRef loadRef = CGImageSourceCreateWithURL((__bridge CFURLRef)thumbURL, NULL);
if (loadRef != NULL) // Load the existing thumb image
{
imageRef = CGImageSourceCreateImageAtIndex(loadRef, 0, NULL); // Load it
CFRelease(loadRef); // Release CGImageSource reference
}
else // Existing thumb image not found - so create and queue up a thumb render operation on the work queue
{
ReaderThumbRender *thumbRender = [[ReaderThumbRender alloc] initWithRequest:request]; // Create a thumb render operation
[thumbRender setQueuePriority:self.queuePriority]; [thumbRender setThreadPriority:(self.threadPriority - 0.1)]; // Priority
if (self.isCancelled == NO) // We're not cancelled - so update things and add the render operation to the work queue
{
request.thumbView.operation = thumbRender; // Update the thumb view operation property to the new operation
[[ReaderThumbQueue sharedInstance] addWorkOperation:thumbRender]; return; // Queue the operation
}
}
if (imageRef != NULL) // Create a UIImage from a CGImage and show it
{
UIImage *image = [UIImage imageWithCGImage:imageRef scale:request.scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef); // Release the CGImage reference from the above thumb load code
UIGraphicsBeginImageContextWithOptions(image.size, YES, request.scale); // Graphics context
[image drawAtPoint:CGPointZero]; // Decode and draw the image on this background thread
UIImage *decoded = UIGraphicsGetImageFromCurrentImageContext(); // Newly decoded image
UIGraphicsEndImageContext(); // Cleanup after the bitmap-based graphics drawing context
[[ReaderThumbCache sharedInstance] setObject:decoded forKey:request.cacheKey]; // Cache it
if (self.isCancelled == NO) // Show the image in the target thumb view on the main thread
{
ReaderThumbView *thumbView = request.thumbView; // Target thumb view for image show
NSUInteger targetTag = request.targetTag; // Target reference tag for image show
dispatch_async(dispatch_get_main_queue(), // Queue image show on main thread
^{
if (thumbView.targetTag == targetTag) [thumbView showImage:decoded];
});
}
}
request.thumbView.operation = nil; // Break retain loop
}
@end

View File

@@ -0,0 +1,54 @@
//
// ReaderThumbQueue.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@interface ReaderThumbQueue : NSObject <NSObject>
+ (ReaderThumbQueue *)sharedInstance;
- (void)addLoadOperation:(NSOperation *)operation;
- (void)addWorkOperation:(NSOperation *)operation;
- (void)cancelOperationsWithGUID:(NSString *)guid;
- (void)cancelAllOperations;
@end
#pragma mark -
//
// ReaderThumbOperation class interface
//
@interface ReaderThumbOperation : NSOperation
@property (nonatomic, strong, readonly) NSString *guid;
- (id)initWithGUID:(NSString *)guid;
@end

View File

@@ -0,0 +1,141 @@
//
// ReaderThumbQueue.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbQueue.h"
@implementation ReaderThumbQueue
{
NSOperationQueue *loadQueue;
NSOperationQueue *workQueue;
}
#pragma mark ReaderThumbQueue class methods
+ (ReaderThumbQueue *)sharedInstance
{
static dispatch_once_t predicate = 0;
static ReaderThumbQueue *object = nil; // Object
dispatch_once(&predicate, ^{ object = [self new]; });
return object; // ReaderThumbQueue singleton
}
#pragma mark ReaderThumbQueue instance methods
- (id)init
{
if ((self = [super init])) // Initialize
{
loadQueue = [NSOperationQueue new];
[loadQueue setName:@"ReaderThumbLoadQueue"];
[loadQueue setMaxConcurrentOperationCount:1];
workQueue = [NSOperationQueue new];
[workQueue setName:@"ReaderThumbWorkQueue"];
[workQueue setMaxConcurrentOperationCount:1];
}
return self;
}
- (void)addLoadOperation:(NSOperation *)operation
{
if ([operation isKindOfClass:[ReaderThumbOperation class]])
{
[loadQueue addOperation:operation]; // Add to load queue
}
}
- (void)addWorkOperation:(NSOperation *)operation
{
if ([operation isKindOfClass:[ReaderThumbOperation class]])
{
[workQueue addOperation:operation]; // Add to work queue
}
}
- (void)cancelOperationsWithGUID:(NSString *)guid
{
[loadQueue setSuspended:YES]; [workQueue setSuspended:YES];
for (ReaderThumbOperation *operation in loadQueue.operations)
{
if ([operation isKindOfClass:[ReaderThumbOperation class]])
{
if ([operation.guid isEqualToString:guid]) [operation cancel];
}
}
for (ReaderThumbOperation *operation in workQueue.operations)
{
if ([operation isKindOfClass:[ReaderThumbOperation class]])
{
if ([operation.guid isEqualToString:guid]) [operation cancel];
}
}
[workQueue setSuspended:NO]; [loadQueue setSuspended:NO];
}
- (void)cancelAllOperations
{
[loadQueue cancelAllOperations]; [workQueue cancelAllOperations];
}
@end
#pragma mark -
//
// ReaderThumbOperation class implementation
//
@implementation ReaderThumbOperation
{
NSString *_guid;
}
@synthesize guid = _guid;
#pragma mark ReaderThumbOperation instance methods
- (id)initWithGUID:(NSString *)guid
{
if ((self = [super init]))
{
_guid = guid;
}
return self;
}
@end

View File

@@ -0,0 +1,36 @@
//
// ReaderThumbRender.h
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
#import "ReaderThumbQueue.h"
@class ReaderThumbRequest;
@interface ReaderThumbRender : ReaderThumbOperation
- (id)initWithRequest:(ReaderThumbRequest *)options;
@end

View File

@@ -0,0 +1,204 @@
//
// ReaderThumbRender.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbRender.h"
#import "ReaderThumbCache.h"
#import "ReaderThumbView.h"
#import "CGPDFDocument.h"
#import <ImageIO/ImageIO.h>
@implementation ReaderThumbRender
{
ReaderThumbRequest *request;
}
#pragma mark ReaderThumbRender instance methods
- (id)initWithRequest:(ReaderThumbRequest *)options
{
if ((self = [super initWithGUID:options.guid]))
{
request = options;
}
return self;
}
- (void)cancel
{
[super cancel]; // Cancel the operation
request.thumbView.operation = nil; // Break retain loop
request.thumbView = nil; // Release target thumb view on cancel
[[ReaderThumbCache sharedInstance] removeNullForKey:request.cacheKey];
}
- (NSURL *)thumbFileURL
{
NSFileManager *fileManager = [NSFileManager new]; // File manager instance
NSString *cachePath = [ReaderThumbCache thumbCachePathForGUID:request.guid]; // Thumb cache path
[fileManager createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:NULL];
NSString *fileName = [NSString stringWithFormat:@"%@.png", request.thumbName]; // Thumb file name
return [NSURL fileURLWithPath:[cachePath stringByAppendingPathComponent:fileName]]; // File URL
}
- (void)main
{
NSInteger page = request.thumbPage; NSString *password = request.password;
CGImageRef imageRef = NULL; CFURLRef fileURL = (__bridge CFURLRef)request.fileURL;
CGPDFDocumentRef thePDFDocRef = CGPDFDocumentCreateX(fileURL, password);
if (thePDFDocRef != NULL) // Check for non-NULL CGPDFDocumentRef
{
CGPDFPageRef thePDFPageRef = CGPDFDocumentGetPage(thePDFDocRef, page);
if (thePDFPageRef != NULL) // Check for non-NULL CGPDFPageRef
{
CGFloat thumb_w = request.thumbSize.width; // Maximum thumb width
CGFloat thumb_h = request.thumbSize.height; // Maximum thumb height
CGRect cropBoxRect = CGPDFPageGetBoxRect(thePDFPageRef, kCGPDFCropBox);
CGRect mediaBoxRect = CGPDFPageGetBoxRect(thePDFPageRef, kCGPDFMediaBox);
CGRect effectiveRect = CGRectIntersection(cropBoxRect, mediaBoxRect);
NSInteger pageRotate = CGPDFPageGetRotationAngle(thePDFPageRef); // Angle
CGFloat page_w = 0.0f; CGFloat page_h = 0.0f; // Rotated page size
switch (pageRotate) // Page rotation (in degrees)
{
default: // Default case
case 0: case 180: // 0 and 180 degrees
{
page_w = effectiveRect.size.width;
page_h = effectiveRect.size.height;
break;
}
case 90: case 270: // 90 and 270 degrees
{
page_h = effectiveRect.size.width;
page_w = effectiveRect.size.height;
break;
}
}
CGFloat scale_w = (thumb_w / page_w); // Width scale
CGFloat scale_h = (thumb_h / page_h); // Height scale
CGFloat scale = 0.0f; // Page to target thumb size scale
if (page_h > page_w)
scale = ((thumb_h > thumb_w) ? scale_w : scale_h); // Portrait
else
scale = ((thumb_h < thumb_w) ? scale_h : scale_w); // Landscape
NSInteger target_w = (page_w * scale); // Integer target thumb width
NSInteger target_h = (page_h * scale); // Integer target thumb height
if (target_w % 2) target_w--; if (target_h % 2) target_h--; // Even
target_w *= request.scale; target_h *= request.scale; // Screen scale
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); // RGB color space
CGBitmapInfo bmi = (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
CGContextRef context = CGBitmapContextCreate(NULL, target_w, target_h, 8, 0, rgb, bmi);
if (context != NULL) // Must have a valid custom CGBitmap context to draw into
{
CGRect thumbRect = CGRectMake(0.0f, 0.0f, target_w, target_h); // Target thumb rect
CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); CGContextFillRect(context, thumbRect); // White fill
CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(thePDFPageRef, kCGPDFCropBox, thumbRect, 0, true)); // Fit rect
//CGContextSetRenderingIntent(context, kCGRenderingIntentDefault); CGContextSetInterpolationQuality(context, kCGInterpolationDefault);
CGContextDrawPDFPage(context, thePDFPageRef); // Render the PDF page into the custom CGBitmap context
imageRef = CGBitmapContextCreateImage(context); // Create CGImage from custom CGBitmap context
CGContextRelease(context); // Release custom CGBitmap context reference
}
CGColorSpaceRelease(rgb); // Release device RGB color space reference
}
CGPDFDocumentRelease(thePDFDocRef); // Release CGPDFDocumentRef reference
}
if (imageRef != NULL) // Create UIImage from CGImage and show it, then save thumb as PNG
{
UIImage *image = [UIImage imageWithCGImage:imageRef scale:request.scale orientation:UIImageOrientationUp];
[[ReaderThumbCache sharedInstance] setObject:image forKey:request.cacheKey]; // Update cache
if (self.isCancelled == NO) // Show the image in the target thumb view on the main thread
{
ReaderThumbView *thumbView = request.thumbView; // Target thumb view for image show
NSUInteger targetTag = request.targetTag; // Target reference tag for image show
dispatch_async(dispatch_get_main_queue(), // Queue image show on main thread
^{
if (thumbView.targetTag == targetTag) [thumbView showImage:image];
});
}
CFURLRef thumbURL = (__bridge CFURLRef)[self thumbFileURL]; // Thumb cache path with PNG file name URL
CGImageDestinationRef thumbRef = CGImageDestinationCreateWithURL(thumbURL, (CFStringRef)@"public.png", 1, NULL);
if (thumbRef != NULL) // Write the thumb image file out to the thumb cache directory
{
CGImageDestinationAddImage(thumbRef, imageRef, NULL); // Add the image
CGImageDestinationFinalize(thumbRef); // Finalize the image file
CFRelease(thumbRef); // Release CGImageDestination reference
}
CGImageRelease(imageRef); // Release CGImage reference
}
else // No image - so remove the placeholder object from the cache
{
[[ReaderThumbCache sharedInstance] removeNullForKey:request.cacheKey];
}
request.thumbView.operation = nil; // Break retain loop
}
@end

View File

@@ -0,0 +1,47 @@
//
// ReaderThumbRequest.h
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@class ReaderThumbView;
@interface ReaderThumbRequest : NSObject <NSObject>
@property (nonatomic, strong, readonly) NSURL *fileURL;
@property (nonatomic, strong, readonly) NSString *guid;
@property (nonatomic, strong, readonly) NSString *password;
@property (nonatomic, strong, readonly) NSString *cacheKey;
@property (nonatomic, strong, readonly) NSString *thumbName;
@property (nonatomic, strong, readwrite) ReaderThumbView *thumbView;
@property (nonatomic, assign, readonly) NSUInteger targetTag;
@property (nonatomic, assign, readonly) NSInteger thumbPage;
@property (nonatomic, assign, readonly) CGSize thumbSize;
@property (nonatomic, assign, readonly) CGFloat scale;
+ (id)newForView:(ReaderThumbView *)view fileURL:(NSURL *)url password:(NSString *)phrase guid:(NSString *)guid page:(NSInteger)page size:(CGSize)size;
- (id)initWithView:(ReaderThumbView *)view fileURL:(NSURL *)url password:(NSString *)phrase guid:(NSString *)guid page:(NSInteger)page size:(CGSize)size;
@end

View File

@@ -0,0 +1,96 @@
//
// ReaderThumbRequest.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbRequest.h"
#import "ReaderThumbView.h"
@implementation ReaderThumbRequest
{
NSURL *_fileURL;
NSString *_guid;
NSString *_password;
NSString *_cacheKey;
NSString *_thumbName;
ReaderThumbView *_thumbView;
NSUInteger _targetTag;
NSInteger _thumbPage;
CGSize _thumbSize;
CGFloat _scale;
}
#pragma mark Properties
@synthesize guid = _guid;
@synthesize fileURL = _fileURL;
@synthesize password = _password;
@synthesize thumbView = _thumbView;
@synthesize thumbPage = _thumbPage;
@synthesize thumbSize = _thumbSize;
@synthesize thumbName = _thumbName;
@synthesize targetTag = _targetTag;
@synthesize cacheKey = _cacheKey;
@synthesize scale = _scale;
#pragma mark ReaderThumbRequest class methods
+ (id)newForView:(ReaderThumbView *)view fileURL:(NSURL *)url password:(NSString *)phrase guid:(NSString *)guid page:(NSInteger)page size:(CGSize)size
{
return [[ReaderThumbRequest alloc] initWithView:view fileURL:url password:phrase guid:guid page:page size:size];
}
#pragma mark ReaderThumbRequest instance methods
- (id)initWithView:(ReaderThumbView *)view fileURL:(NSURL *)url password:(NSString *)phrase guid:(NSString *)guid page:(NSInteger)page size:(CGSize)size
{
if ((self = [super init])) // Initialize object
{
NSInteger w = size.width; NSInteger h = size.height;
_thumbView = view; _thumbPage = page; _thumbSize = size;
_fileURL = [url copy]; _password = [phrase copy]; _guid = [guid copy];
_thumbName = [[NSString alloc] initWithFormat:@"%07d-%04dx%04d", page, w, h];
_cacheKey = [[NSString alloc] initWithFormat:@"%@+%@", _thumbName, _guid];
_targetTag = [_cacheKey hash]; _thumbView.targetTag = _targetTag;
_scale = [[UIScreen mainScreen] scale]; // Thumb screen scale
}
return self;
}
@end

View File

@@ -0,0 +1,45 @@
//
// ReaderThumbView.h
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface ReaderThumbView : UIView
{
@protected // Instance variables
UIImageView *imageView;
}
@property (atomic, strong, readwrite) NSOperation *operation;
@property (nonatomic, assign, readwrite) NSUInteger targetTag;
- (void)showImage:(UIImage *)image;
- (void)showTouched:(BOOL)touched;
- (void)reuse;
@end

View File

@@ -0,0 +1,93 @@
//
// ReaderThumbView.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbView.h"
@implementation ReaderThumbView
{
NSOperation *_operation;
NSUInteger _targetTag;
}
#pragma mark Properties
@synthesize operation = _operation;
@synthesize targetTag = _targetTag;
#pragma mark ReaderThumbView instance methods
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = NO;
self.userInteractionEnabled = NO;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingNone;
self.backgroundColor = [UIColor blackColor];
imageView = [[UIImageView alloc] initWithFrame:self.bounds];
imageView.autoresizesSubviews = NO;
imageView.userInteractionEnabled = NO;
imageView.autoresizingMask = UIViewAutoresizingNone;
imageView.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:imageView];
}
return self;
}
- (void)showImage:(UIImage *)image
{
imageView.image = image; // Show image
}
- (void)showTouched:(BOOL)touched
{
// Implemented by ReaderThumbView subclass
}
- (void)removeFromSuperview
{
_targetTag = 0; // Clear target tag
[self.operation cancel]; // Cancel operation
[super removeFromSuperview]; // Remove view
}
- (void)reuse
{
_targetTag = 0; // Clear target tag
[self.operation cancel]; // Cancel operation
imageView.image = nil; // Release image
}
@end

View File

@@ -0,0 +1,68 @@
//
// ReaderThumbsView.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ReaderThumbView.h"
@class ReaderThumbsView;
@protocol ReaderThumbsViewDelegate <NSObject, UIScrollViewDelegate>
@required // Delegate protocols
- (NSUInteger)numberOfThumbsInThumbsView:(ReaderThumbsView *)thumbsView;
- (id)thumbsView:(ReaderThumbsView *)thumbsView thumbCellWithFrame:(CGRect)frame;
- (void)thumbsView:(ReaderThumbsView *)thumbsView updateThumbCell:(id)thumbCell forIndex:(NSInteger)index;
- (void)thumbsView:(ReaderThumbsView *)thumbsView didSelectThumbWithIndex:(NSInteger)index;
@optional // Delegate protocols
- (void)thumbsView:(ReaderThumbsView *)thumbsView refreshThumbCell:(id)thumbCell forIndex:(NSInteger)index;
- (void)thumbsView:(ReaderThumbsView *)thumbsView didPressThumbWithIndex:(NSInteger)index;
@end
@interface ReaderThumbsView : UIScrollView
@property (nonatomic, unsafe_unretained, readwrite) id <ReaderThumbsViewDelegate> delegate;
- (void)setThumbSize:(CGSize)thumbSize;
- (void)reloadThumbsCenterOnIndex:(NSInteger)index;
- (void)reloadThumbsContentOffset:(CGPoint)newContentOffset;
- (void)refreshThumbWithIndex:(NSInteger)index;
- (void)refreshVisibleThumbs;
- (CGPoint)insetContentOffset;
@end

View File

@@ -0,0 +1,545 @@
//
// ReaderThumbsView.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderThumbsView.h"
@interface ReaderThumbsView () <UIScrollViewDelegate, UIGestureRecognizerDelegate>
@end
@implementation ReaderThumbsView
{
CGPoint lastContentOffset;
ReaderThumbView *touchedCell;
NSMutableArray *thumbCellsQueue;
NSMutableArray *thumbCellsVisible;
NSInteger _thumbsX, _thumbsY, _thumbX;
CGSize _thumbSize, _lastViewSize;
NSUInteger _thumbCount;
BOOL canUpdate;
}
#pragma mark Properties
@synthesize delegate;
#pragma mark ReaderThumbsView instance methods
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.scrollsToTop = NO;
self.autoresizesSubviews = NO;
self.delaysContentTouches = NO;
self.alwaysBounceVertical = YES;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.backgroundColor = [UIColor yellowColor];
[super setDelegate:self]; // Set the superclass UIScrollView delegate
thumbCellsQueue = [NSMutableArray new]; thumbCellsVisible = [NSMutableArray new]; // Cell management arrays
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
//tapGesture.numberOfTouchesRequired = 1; tapGesture.numberOfTapsRequired = 1; tapGesture.delegate = self;
[self addGestureRecognizer:tapGesture];
UILongPressGestureRecognizer *pressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePressGesture:)];
pressGesture.minimumPressDuration = 0.8; //pressGesture.numberOfTouchesRequired = 1; pressGesture.delegate = self;
[self addGestureRecognizer:pressGesture];
lastContentOffset = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN);
}
return self;
}
- (void)requeueThumbCell:(ReaderThumbView *)tvCell
{
[thumbCellsQueue addObject:tvCell];
[thumbCellsVisible removeObject:tvCell];
tvCell.tag = NSIntegerMin; tvCell.hidden = YES;
[tvCell reuse]; // Reuse the cell
}
- (void)requeueAllThumbCells
{
if (thumbCellsVisible.count > 0)
{
NSArray *visible = [thumbCellsVisible copy];
for (ReaderThumbView *tvCell in visible)
{
[self requeueThumbCell:tvCell];
}
}
}
- (ReaderThumbView *)dequeueThumbCellWithFrame:(CGRect)frame
{
ReaderThumbView *theCell = nil;
if (thumbCellsQueue.count > 0) // Reuse existing cell
{
theCell = [thumbCellsQueue objectAtIndex:0];
[thumbCellsQueue removeObjectAtIndex:0]; // Dequeue it
theCell.frame = frame; // Position the reused cell
}
else // Allocate a brand new thumb cell subclass for our use
{
theCell = [delegate thumbsView:self thumbCellWithFrame:frame];
//assert([theCell isKindOfClass:[ReaderThumbView class]]);
theCell.tag = NSIntegerMin; theCell.hidden = YES;
[self insertSubview:theCell atIndex:0]; // Add
}
[thumbCellsVisible addObject:theCell];
return theCell;
}
- (NSMutableIndexSet *)visibleIndexSetForContentOffset
{
CGFloat minY = self.contentOffset.y; // Content offset
CGFloat maxY = (minY + self.bounds.size.height - 1.0f);
NSInteger startRow = (minY / _thumbSize.height); // Start row
NSInteger finalRow = (maxY / _thumbSize.height); // Final row
NSInteger startIndex = (startRow * _thumbsX); // Start index
NSInteger finalIndex = (finalRow * _thumbsX); // Final index
finalIndex += (_thumbsX - 1); // Last index value in last row
NSInteger maximumIndex = (_thumbCount - 1); // Maximum index value
if (finalIndex > maximumIndex) finalIndex = maximumIndex; // Limit it
NSRange indexRange = NSMakeRange(startIndex, (finalIndex - startIndex + 1));
return [NSMutableIndexSet indexSetWithIndexesInRange:indexRange];
}
- (ReaderThumbView *)thumbCellContainingPoint:(CGPoint)point
{
ReaderThumbView *theCell = nil;
for (ReaderThumbView *tvCell in thumbCellsVisible)
{
if (CGRectContainsPoint(tvCell.frame, point) == true)
{
theCell = tvCell; break; // Found it
}
}
return theCell;
}
- (CGRect)thumbCellFrameForIndex:(NSInteger)index
{
CGRect thumbRect; thumbRect.size = _thumbSize;
NSInteger thumbY = ((index / _thumbsX) * _thumbSize.height); // X, Y
NSInteger thumbX = (((index % _thumbsX) * _thumbSize.width) + _thumbX);
thumbRect.origin.x = thumbX; thumbRect.origin.y = thumbY;
return thumbRect;
}
- (void)updateContentSize:(NSUInteger)thumbCount
{
canUpdate = NO; // Disable updates
if (thumbCount > 0) // Have some thumbs
{
CGFloat bw = self.bounds.size.width;
_thumbsX = (bw / _thumbSize.width);
if (_thumbsX < 1) _thumbsX = 1;
_thumbsY = (thumbCount / _thumbsX);
if ((_thumbsX * _thumbsY) < thumbCount) _thumbsY++;
CGFloat tw = (_thumbsX * _thumbSize.width);
CGFloat th = (_thumbsY * _thumbSize.height);
if (tw < bw)
_thumbX = ((bw - tw) / 2.0f);
else
_thumbX = 0; // Reset
if (tw < bw) tw = bw; // Limit
[self setContentSize:CGSizeMake(tw, th)];
}
else // Zero (0) thumbs
{
[self setContentSize:CGSizeZero];
}
canUpdate = YES; // Enable updates
}
- (void)layoutSubviews
{
if (CGSizeEqualToSize(_lastViewSize, CGSizeZero) == true)
{
_lastViewSize = self.bounds.size; // Initial view size
}
else
if (CGSizeEqualToSize(_lastViewSize, self.bounds.size) == false)
{
_lastViewSize = self.bounds.size; // Track the view size
[self updateContentSize:_thumbCount]; // Update the content size
NSMutableArray *requeueCells = [NSMutableArray array]; // Requeue cell list
NSMutableIndexSet *visibleIndexSet = [self visibleIndexSetForContentOffset];
for (ReaderThumbView *tvCell in thumbCellsVisible) // Enumerate visible cells
{
NSInteger index = tvCell.tag; // Get the cell's index value
if ([visibleIndexSet containsIndex:index] == YES) // Visible cell
{
tvCell.frame = [self thumbCellFrameForIndex:index]; // Frame
[visibleIndexSet removeIndex:index]; // Remove from set
}
else // Add it to the list of cells to requeue
{
[requeueCells addObject:tvCell];
}
}
for (ReaderThumbView *tvCell in requeueCells) // Enumerate requeue cells
{
[self requeueThumbCell:tvCell]; // Requeue the thumb cell
}
[visibleIndexSet enumerateIndexesUsingBlock: // Enumerate visible indexes
^(NSUInteger index, BOOL *stop)
{
CGRect thumbRect = [self thumbCellFrameForIndex:index]; // Frame
ReaderThumbView *tvCell = [self dequeueThumbCellWithFrame:thumbRect];
[delegate thumbsView:self updateThumbCell:tvCell forIndex:index];
tvCell.tag = index; tvCell.hidden = NO; // Tag and show it
}
];
}
}
- (void)setThumbSize:(CGSize)thumbSize
{
if (CGSizeEqualToSize(_thumbSize, CGSizeZero) == true)
{
if (CGSizeEqualToSize(thumbSize, CGSizeZero) == false)
{
_thumbSize = thumbSize; // Set the maximum thumb size
}
}
}
- (void)reloadThumbsCenterOnIndex:(NSInteger)index
{
assert(delegate != nil); // Check delegate
assert(CGSizeEqualToSize(_thumbSize, CGSizeZero) == false);
if (self.decelerating == YES) // Stop scroll view movement
{
[self setContentOffset:self.contentOffset animated:NO];
}
CGPoint newContentOffset = CGPointZero; // At top
lastContentOffset = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN);
[self requeueAllThumbCells]; // Start off fresh
_thumbCount = 0; // Reset the thumb count to zero
NSUInteger thumbCount = [delegate numberOfThumbsInThumbsView:self];
[self updateContentSize:thumbCount]; _thumbCount = thumbCount;
if (thumbCount > 0) // Have some thumbs
{
NSInteger boundsHeight = self.bounds.size.height;
NSInteger maxY = (self.contentSize.height - boundsHeight);
NSInteger minY = 0; maxY--; if (maxY < minY) maxY = minY; // Limits
if (index < 0) index = 0; else if (index > thumbCount) index = (thumbCount - 1);
NSInteger thumbY = ((index / _thumbsX) * _thumbSize.height); // Thumb Y
NSInteger offsetY = (thumbY - (boundsHeight / 2) + (_thumbSize.height / 2));
if (offsetY < minY) offsetY = minY; else if (offsetY > maxY) offsetY = maxY;
newContentOffset.y = offsetY; // Calculated content offset Y position
}
newContentOffset.y -= self.contentInset.top; // Content inset adjust
if (CGPointEqualToPoint(self.contentOffset, newContentOffset) == false)
[self setContentOffset:newContentOffset animated:NO];
else
[self scrollViewDidScroll:self];
[self flashScrollIndicators];
}
- (void)reloadThumbsContentOffset:(CGPoint)newContentOffset
{
assert(delegate != nil); // Check delegate
assert(CGSizeEqualToSize(_thumbSize, CGSizeZero) == false);
if (self.decelerating == YES) // Stop scroll view movement
{
[self setContentOffset:self.contentOffset animated:NO];
}
lastContentOffset = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN);
[self requeueAllThumbCells]; // Start off fresh
_thumbCount = 0; // Reset the thumb count to zero
NSUInteger thumbCount = [delegate numberOfThumbsInThumbsView:self];
[self updateContentSize:thumbCount]; _thumbCount = thumbCount;
if (thumbCount > 0) // Have some thumbs
{
NSInteger boundsHeight = self.bounds.size.height;
NSInteger maxY = (self.contentSize.height - boundsHeight);
NSInteger minY = 0; maxY--; if (maxY < minY) maxY = minY; // Limits
NSInteger offsetY = newContentOffset.y; // Requested content offset Y
if (offsetY < minY) offsetY = minY; else if (offsetY > maxY) offsetY = maxY;
newContentOffset.y = offsetY; newContentOffset.x = 0.0f; // Validated
}
else // Zero (0) thumbs
{
newContentOffset = CGPointZero;
}
newContentOffset.y -= self.contentInset.top; // Content inset adjust
if (CGPointEqualToPoint(self.contentOffset, newContentOffset) == false)
[self setContentOffset:newContentOffset animated:NO];
else
[self scrollViewDidScroll:self];
[self flashScrollIndicators];
}
- (void)refreshThumbWithIndex:(NSInteger)index
{
for (ReaderThumbView *tvCell in thumbCellsVisible) // Enumerate visible cells
{
if (tvCell.tag == index) // Found a visible thumb cell with the index value
{
if ([delegate respondsToSelector:@selector(thumbsView:refreshThumbCell:forIndex:)])
{
[delegate thumbsView:self refreshThumbCell:tvCell forIndex:index]; // Refresh
}
break;
}
}
}
- (void)refreshVisibleThumbs
{
for (ReaderThumbView *tvCell in thumbCellsVisible) // Enumerate visible cells
{
if ([delegate respondsToSelector:@selector(thumbsView:refreshThumbCell:forIndex:)])
{
[delegate thumbsView:self refreshThumbCell:tvCell forIndex:tvCell.tag]; // Refresh
}
}
}
- (CGPoint)insetContentOffset
{
CGPoint insetContentOffset = self.contentOffset; // Offset
insetContentOffset.y += self.contentInset.top; // Inset adjust
return insetContentOffset; // Adjusted content offset
}
#pragma mark UIGestureRecognizer action methods
- (void)handleTapGesture:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateRecognized) // Handle the tap
{
CGPoint point = [recognizer locationInView:recognizer.view]; // Tap location
ReaderThumbView *tvCell = [self thumbCellContainingPoint:point]; // Look for cell
if (tvCell != nil) [delegate thumbsView:self didSelectThumbWithIndex:tvCell.tag];
}
}
- (void)handlePressGesture:(UILongPressGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan) // Handle the press
{
if ([delegate respondsToSelector:@selector(thumbsView:didPressThumbWithIndex:)])
{
CGPoint point = [recognizer locationInView:recognizer.view]; // Press location
ReaderThumbView *tvCell = [self thumbCellContainingPoint:point]; // Look for cell
if (tvCell != nil) [delegate thumbsView:self didPressThumbWithIndex:tvCell.tag];
}
}
}
#pragma mark UIScrollViewDelegate methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if ((canUpdate == YES) && (_thumbCount > 0)) // Check flag and thumb count
{
if (CGPointEqualToPoint(scrollView.contentOffset, lastContentOffset) == false)
{
lastContentOffset = scrollView.contentOffset; // Work around a 'feature'
CGRect visibleBounds = self.bounds; // Visible bounds in the scroll view
NSMutableArray *requeueCells = [NSMutableArray array]; // Requeue cell list
NSMutableIndexSet *visibleCellSet = [NSMutableIndexSet indexSet]; // Visible set
for (ReaderThumbView *tvCell in thumbCellsVisible) // Enumerate visible cells
{
if (CGRectIntersectsRect(tvCell.frame, visibleBounds) == true)
[visibleCellSet addIndex:tvCell.tag];
else
[requeueCells addObject:tvCell];
}
for (ReaderThumbView *tvCell in requeueCells) // Enumerate requeue cells
{
[self requeueThumbCell:tvCell]; // Requeue the thumb cell
}
NSMutableIndexSet *visibleIndexSet = [self visibleIndexSetForContentOffset];
[visibleIndexSet enumerateIndexesUsingBlock: // Enumerate visible indexes
^(NSUInteger index, BOOL *stop)
{
if ([visibleCellSet containsIndex:index] == NO) // Index not visible
{
CGRect thumbRect = [self thumbCellFrameForIndex:index]; // Frame
ReaderThumbView *tvCell = [self dequeueThumbCellWithFrame:thumbRect];
[delegate thumbsView:self updateThumbCell:tvCell forIndex:index];
tvCell.tag = index; tvCell.hidden = NO; // Tag and show it
}
}
];
}
}
}
#pragma mark UIResponder instance methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event]; // Message superclass
if (touchedCell != nil) { [touchedCell showTouched:NO]; touchedCell = nil; }
if (touches.count == 1) // Show selection on single touch
{
UITouch *touch = [touches anyObject]; // Get touch from set
CGPoint point = [touch locationInView:touch.view]; // Touch location
ReaderThumbView *tvCell = [self thumbCellContainingPoint:point]; // Look for cell
if (tvCell != nil) { touchedCell = tvCell; [touchedCell showTouched:YES]; }
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event]; // Message superclass
if (touchedCell != nil) { [touchedCell showTouched:NO]; touchedCell = nil; }
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event]; // Message superclass
if (touchedCell != nil) { [touchedCell showTouched:NO]; touchedCell = nil; }
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event]; // Message superclass
}
@end

View File

@@ -0,0 +1,46 @@
//
// ReaderViewController.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ReaderDocument.h"
@class ReaderViewController;
@protocol ReaderViewControllerDelegate <NSObject>
@optional // Delegate protocols
- (void)dismissReaderViewController:(ReaderViewController *)viewController;
@end
@interface ReaderViewController : UIViewController
@property (nonatomic, unsafe_unretained, readwrite) id <ReaderViewControllerDelegate> delegate;
- (id)initWithReaderDocument:(ReaderDocument *)object;
@end

View File

@@ -0,0 +1,916 @@
//
// ReaderViewController.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-07-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
#import "ReaderViewController.h"
#import "ThumbsViewController.h"
#import "ReaderMainToolbar.h"
#import "ReaderMainPagebar.h"
#import "ReaderContentView.h"
#import "ReaderThumbCache.h"
#import "ReaderThumbQueue.h"
#import <MessageUI/MessageUI.h>
@interface ReaderViewController () <UIScrollViewDelegate, UIGestureRecognizerDelegate, MFMailComposeViewControllerDelegate,
ReaderMainToolbarDelegate, ReaderMainPagebarDelegate, ReaderContentViewDelegate, ThumbsViewControllerDelegate>
@end
@implementation ReaderViewController
{
ReaderDocument *document;
UIScrollView *theScrollView;
ReaderMainToolbar *mainToolbar;
ReaderMainPagebar *mainPagebar;
NSMutableDictionary *contentViews;
UIPrintInteractionController *printInteraction;
NSInteger currentPage;
CGSize lastAppearSize;
NSDate *lastHideTime;
BOOL isVisible;
}
#pragma mark Constants
#define PAGING_VIEWS 3
#define TOOLBAR_HEIGHT 44.0f
#define PAGEBAR_HEIGHT 48.0f
#define TAP_AREA_SIZE 48.0f
#pragma mark Properties
@synthesize delegate;
#pragma mark Support methods
- (void)updateScrollViewContentSize
{
NSInteger count = [document.pageCount integerValue];
if (count > PAGING_VIEWS) count = PAGING_VIEWS; // Limit
CGFloat contentHeight = theScrollView.bounds.size.height;
CGFloat contentWidth = (theScrollView.bounds.size.width * count);
theScrollView.contentSize = CGSizeMake(contentWidth, contentHeight);
}
- (void)updateScrollViewContentViews
{
[self updateScrollViewContentSize]; // Update the content size
NSMutableIndexSet *pageSet = [NSMutableIndexSet indexSet]; // Page set
[contentViews enumerateKeysAndObjectsUsingBlock: // Enumerate content views
^(id key, id object, BOOL *stop)
{
ReaderContentView *contentView = object; [pageSet addIndex:contentView.tag];
}
];
__block CGRect viewRect = CGRectZero; viewRect.size = theScrollView.bounds.size;
__block CGPoint contentOffset = CGPointZero; NSInteger page = [document.pageNumber integerValue];
[pageSet enumerateIndexesUsingBlock: // Enumerate page number set
^(NSUInteger number, BOOL *stop)
{
NSNumber *key = [NSNumber numberWithInteger:number]; // # key
ReaderContentView *contentView = [contentViews objectForKey:key];
contentView.frame = viewRect; if (page == number) contentOffset = viewRect.origin;
viewRect.origin.x += viewRect.size.width; // Next view frame position
}
];
if (CGPointEqualToPoint(theScrollView.contentOffset, contentOffset) == false)
{
theScrollView.contentOffset = contentOffset; // Update content offset
}
}
- (void)updateToolbarBookmarkIcon
{
NSInteger page = [document.pageNumber integerValue];
BOOL bookmarked = [document.bookmarks containsIndex:page];
[mainToolbar setBookmarkState:bookmarked]; // Update
}
- (void)showDocumentPage:(NSInteger)page
{
if (page != currentPage) // Only if different
{
NSInteger minValue; NSInteger maxValue;
NSInteger maxPage = [document.pageCount integerValue];
NSInteger minPage = 1;
if ((page < minPage) || (page > maxPage)) return;
if (maxPage <= PAGING_VIEWS) // Few pages
{
minValue = minPage;
maxValue = maxPage;
}
else // Handle more pages
{
minValue = (page - 1);
maxValue = (page + 1);
if (minValue < minPage)
{minValue++; maxValue++;}
else
if (maxValue > maxPage)
{minValue--; maxValue--;}
}
NSMutableIndexSet *newPageSet = [NSMutableIndexSet new];
NSMutableDictionary *unusedViews = [contentViews mutableCopy];
CGRect viewRect = CGRectZero; viewRect.size = theScrollView.bounds.size;
for (NSInteger number = minValue; number <= maxValue; number++)
{
NSNumber *key = [NSNumber numberWithInteger:number]; // # key
ReaderContentView *contentView = [contentViews objectForKey:key];
if (contentView == nil) // Create a brand new document content view
{
NSURL *fileURL = document.fileURL; NSString *phrase = document.password; // Document properties
contentView = [[ReaderContentView alloc] initWithFrame:viewRect fileURL:fileURL page:number password:phrase];
[theScrollView addSubview:contentView]; [contentViews setObject:contentView forKey:key];
contentView.message = self; [newPageSet addIndex:number];
}
else // Reposition the existing content view
{
contentView.frame = viewRect; [contentView zoomReset];
[unusedViews removeObjectForKey:key];
}
viewRect.origin.x += viewRect.size.width;
}
[unusedViews enumerateKeysAndObjectsUsingBlock: // Remove unused views
^(id key, id object, BOOL *stop)
{
[contentViews removeObjectForKey:key];
ReaderContentView *contentView = object;
[contentView removeFromSuperview];
}
];
unusedViews = nil; // Release unused views
CGFloat viewWidthX1 = viewRect.size.width;
CGFloat viewWidthX2 = (viewWidthX1 * 2.0f);
CGPoint contentOffset = CGPointZero;
if (maxPage >= PAGING_VIEWS)
{
if (page == maxPage)
contentOffset.x = viewWidthX2;
else
if (page != minPage)
contentOffset.x = viewWidthX1;
}
else
if (page == (PAGING_VIEWS - 1))
contentOffset.x = viewWidthX1;
if (CGPointEqualToPoint(theScrollView.contentOffset, contentOffset) == false)
{
theScrollView.contentOffset = contentOffset; // Update content offset
}
if ([document.pageNumber integerValue] != page) // Only if different
{
document.pageNumber = [NSNumber numberWithInteger:page]; // Update page number
}
NSURL *fileURL = document.fileURL; NSString *phrase = document.password; NSString *guid = document.guid;
if ([newPageSet containsIndex:page] == YES) // Preview visible page first
{
NSNumber *key = [NSNumber numberWithInteger:page]; // # key
ReaderContentView *targetView = [contentViews objectForKey:key];
[targetView showPageThumb:fileURL page:page password:phrase guid:guid];
[newPageSet removeIndex:page]; // Remove visible page from set
}
[newPageSet enumerateIndexesWithOptions:NSEnumerationReverse usingBlock: // Show previews
^(NSUInteger number, BOOL *stop)
{
NSNumber *key = [NSNumber numberWithInteger:number]; // # key
ReaderContentView *targetView = [contentViews objectForKey:key];
[targetView showPageThumb:fileURL page:number password:phrase guid:guid];
}
];
newPageSet = nil; // Release new page set
[mainPagebar updatePagebar]; // Update the pagebar display
[self updateToolbarBookmarkIcon]; // Update bookmark
currentPage = page; // Track current page number
}
}
- (void)showDocument:(id)object
{
[self updateScrollViewContentSize]; // Set content size
[self showDocumentPage:[document.pageNumber integerValue]];
document.lastOpen = [NSDate date]; // Update last opened date
isVisible = YES; // iOS present modal bodge
}
#pragma mark UIViewController methods
- (id)initWithReaderDocument:(ReaderDocument *)object
{
id reader = nil; // ReaderViewController object
if ((object != nil) && ([object isKindOfClass:[ReaderDocument class]]))
{
if ((self = [super initWithNibName:nil bundle:nil])) // Designated initializer
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(applicationWill:) name:UIApplicationWillTerminateNotification object:nil];
[notificationCenter addObserver:self selector:@selector(applicationWill:) name:UIApplicationWillResignActiveNotification object:nil];
[object updateProperties]; document = object; // Retain the supplied ReaderDocument object for our use
[ReaderThumbCache touchThumbCacheWithGUID:object.guid]; // Touch the document thumb cache directory
reader = self; // Return an initialized ReaderViewController object
}
}
return reader;
}
- (void)viewDidLoad
{
[super viewDidLoad];
assert(document != nil); // Must have a valid ReaderDocument
self.view.backgroundColor = [UIColor blackColor];
CGRect viewRect = self.view.bounds; // View controller's view bounds
theScrollView = [[UIScrollView alloc] initWithFrame:viewRect]; // All
theScrollView.scrollsToTop = NO;
theScrollView.pagingEnabled = YES;
theScrollView.delaysContentTouches = NO;
theScrollView.showsVerticalScrollIndicator = NO;
theScrollView.showsHorizontalScrollIndicator = NO;
theScrollView.contentMode = UIViewContentModeRedraw;
theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
theScrollView.backgroundColor = [UIColor blackColor];
theScrollView.userInteractionEnabled = YES;
theScrollView.autoresizesSubviews = NO;
theScrollView.delegate = self;
[self.view addSubview:theScrollView];
CGRect toolbarRect = viewRect;
toolbarRect.size.height = TOOLBAR_HEIGHT;
mainToolbar = [[ReaderMainToolbar alloc] initWithFrame:toolbarRect document:document]; // At top
mainToolbar.delegate = self;
[self.view addSubview:mainToolbar];
CGRect pagebarRect = viewRect;
pagebarRect.size.height = PAGEBAR_HEIGHT;
pagebarRect.origin.y = (viewRect.size.height - PAGEBAR_HEIGHT);
mainPagebar = [[ReaderMainPagebar alloc] initWithFrame:pagebarRect document:document]; // At bottom
mainPagebar.delegate = self;
[self.view addSubview:mainPagebar];
UITapGestureRecognizer *singleTapOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
singleTapOne.numberOfTouchesRequired = 1; singleTapOne.numberOfTapsRequired = 1; singleTapOne.delegate = self;
[self.view addGestureRecognizer:singleTapOne];
UITapGestureRecognizer *doubleTapOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
doubleTapOne.numberOfTouchesRequired = 1; doubleTapOne.numberOfTapsRequired = 2; doubleTapOne.delegate = self;
[self.view addGestureRecognizer:doubleTapOne];
UITapGestureRecognizer *doubleTapTwo = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
doubleTapTwo.numberOfTouchesRequired = 2; doubleTapTwo.numberOfTapsRequired = 2; doubleTapTwo.delegate = self;
[self.view addGestureRecognizer:doubleTapTwo];
[singleTapOne requireGestureRecognizerToFail:doubleTapOne]; // Single tap requires double tap to fail
contentViews = [NSMutableDictionary new]; lastHideTime = [NSDate date];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (CGSizeEqualToSize(lastAppearSize, CGSizeZero) == false)
{
if (CGSizeEqualToSize(lastAppearSize, self.view.bounds.size) == false)
{
[self updateScrollViewContentViews]; // Update content views
}
lastAppearSize = CGSizeZero; // Reset view size tracking
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (CGSizeEqualToSize(theScrollView.contentSize, CGSizeZero)) // First time
{
[self performSelector:@selector(showDocument:) withObject:nil afterDelay:0.02];
}
#if (READER_DISABLE_IDLE == TRUE) // Option
[UIApplication sharedApplication].idleTimerDisabled = YES;
#endif // end of READER_DISABLE_IDLE Option
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
lastAppearSize = self.view.bounds.size; // Track view size
#if (READER_DISABLE_IDLE == TRUE) // Option
[UIApplication sharedApplication].idleTimerDisabled = NO;
#endif // end of READER_DISABLE_IDLE Option
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)viewDidUnload
{
#ifdef DEBUG
NSLog(@"%s", __FUNCTION__);
#endif
mainToolbar = nil; mainPagebar = nil;
theScrollView = nil; contentViews = nil; lastHideTime = nil;
lastAppearSize = CGSizeZero; currentPage = 0;
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (isVisible == NO) return; // iOS present modal bodge
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
if (printInteraction != nil) [printInteraction dismissAnimated:NO];
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
if (isVisible == NO) return; // iOS present modal bodge
[self updateScrollViewContentViews]; // Update content views
lastAppearSize = CGSizeZero; // Reset view size tracking
}
/*
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//if (isVisible == NO) return; // iOS present modal bodge
//if (fromInterfaceOrientation == self.interfaceOrientation) return;
}
*/
- (void)didReceiveMemoryWarning
{
#ifdef DEBUG
NSLog(@"%s", __FUNCTION__);
#endif
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark UIScrollViewDelegate methods
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
__block NSInteger page = 0;
CGFloat contentOffsetX = scrollView.contentOffset.x;
[contentViews enumerateKeysAndObjectsUsingBlock: // Enumerate content views
^(id key, id object, BOOL *stop)
{
ReaderContentView *contentView = object;
if (contentView.frame.origin.x == contentOffsetX)
{
page = contentView.tag; *stop = YES;
}
}
];
if (page != 0) [self showDocumentPage:page]; // Show the page
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[self showDocumentPage:theScrollView.tag]; // Show page
theScrollView.tag = 0; // Clear page number tag
}
#pragma mark UIGestureRecognizerDelegate methods
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)recognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIScrollView class]]) return YES;
return NO;
}
#pragma mark UIGestureRecognizer action methods
- (void)decrementPageNumber
{
if (theScrollView.tag == 0) // Scroll view did end
{
NSInteger page = [document.pageNumber integerValue];
NSInteger maxPage = [document.pageCount integerValue];
NSInteger minPage = 1; // Minimum
if ((maxPage > minPage) && (page != minPage))
{
CGPoint contentOffset = theScrollView.contentOffset;
contentOffset.x -= theScrollView.bounds.size.width; // -= 1
[theScrollView setContentOffset:contentOffset animated:YES];
theScrollView.tag = (page - 1); // Decrement page number
}
}
}
- (void)incrementPageNumber
{
if (theScrollView.tag == 0) // Scroll view did end
{
NSInteger page = [document.pageNumber integerValue];
NSInteger maxPage = [document.pageCount integerValue];
NSInteger minPage = 1; // Minimum
if ((maxPage > minPage) && (page != maxPage))
{
CGPoint contentOffset = theScrollView.contentOffset;
contentOffset.x += theScrollView.bounds.size.width; // += 1
[theScrollView setContentOffset:contentOffset animated:YES];
theScrollView.tag = (page + 1); // Increment page number
}
}
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateRecognized)
{
CGRect viewRect = recognizer.view.bounds; // View bounds
CGPoint point = [recognizer locationInView:recognizer.view];
CGRect areaRect = CGRectInset(viewRect, TAP_AREA_SIZE, 0.0f); // Area
if (CGRectContainsPoint(areaRect, point)) // Single tap is inside the area
{
NSInteger page = [document.pageNumber integerValue]; // Current page #
NSNumber *key = [NSNumber numberWithInteger:page]; // Page number key
ReaderContentView *targetView = [contentViews objectForKey:key];
id target = [targetView processSingleTap:recognizer]; // Target
if (target != nil) // Handle the returned target object
{
if ([target isKindOfClass:[NSURL class]]) // Open a URL
{
NSURL *url = (NSURL *)target; // Cast to a NSURL object
if (url.scheme == nil) // Handle a missing URL scheme
{
NSString *www = url.absoluteString; // Get URL string
if ([www hasPrefix:@"www"] == YES) // Check for 'www' prefix
{
NSString *http = [NSString stringWithFormat:@"http://%@", www];
url = [NSURL URLWithString:http]; // Proper http-based URL
}
}
if ([[UIApplication sharedApplication] openURL:url] == NO)
{
#ifdef DEBUG
NSLog(@"%s '%@'", __FUNCTION__, url); // Bad or unknown URL
#endif
}
}
else // Not a URL, so check for other possible object type
{
if ([target isKindOfClass:[NSNumber class]]) // Goto page
{
NSInteger value = [target integerValue]; // Number
[self showDocumentPage:value]; // Show the page
}
}
}
else // Nothing active tapped in the target content view
{
if ([lastHideTime timeIntervalSinceNow] < -0.75) // Delay since hide
{
if ((mainToolbar.hidden == YES) || (mainPagebar.hidden == YES))
{
[mainToolbar showToolbar]; [mainPagebar showPagebar]; // Show
}
}
}
return;
}
CGRect nextPageRect = viewRect;
nextPageRect.size.width = TAP_AREA_SIZE;
nextPageRect.origin.x = (viewRect.size.width - TAP_AREA_SIZE);
if (CGRectContainsPoint(nextPageRect, point)) // page++ area
{
[self incrementPageNumber]; return;
}
CGRect prevPageRect = viewRect;
prevPageRect.size.width = TAP_AREA_SIZE;
if (CGRectContainsPoint(prevPageRect, point)) // page-- area
{
[self decrementPageNumber]; return;
}
}
}
- (void)handleDoubleTap:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateRecognized)
{
CGRect viewRect = recognizer.view.bounds; // View bounds
CGPoint point = [recognizer locationInView:recognizer.view];
CGRect zoomArea = CGRectInset(viewRect, TAP_AREA_SIZE, TAP_AREA_SIZE);
if (CGRectContainsPoint(zoomArea, point)) // Double tap is in the zoom area
{
NSInteger page = [document.pageNumber integerValue]; // Current page #
NSNumber *key = [NSNumber numberWithInteger:page]; // Page number key
ReaderContentView *targetView = [contentViews objectForKey:key];
switch (recognizer.numberOfTouchesRequired) // Touches count
{
case 1: // One finger double tap: zoom ++
{
[targetView zoomIncrement]; break;
}
case 2: // Two finger double tap: zoom --
{
[targetView zoomDecrement]; break;
}
}
return;
}
CGRect nextPageRect = viewRect;
nextPageRect.size.width = TAP_AREA_SIZE;
nextPageRect.origin.x = (viewRect.size.width - TAP_AREA_SIZE);
if (CGRectContainsPoint(nextPageRect, point)) // page++ area
{
[self incrementPageNumber]; return;
}
CGRect prevPageRect = viewRect;
prevPageRect.size.width = TAP_AREA_SIZE;
if (CGRectContainsPoint(prevPageRect, point)) // page-- area
{
[self decrementPageNumber]; return;
}
}
}
#pragma mark ReaderContentViewDelegate methods
- (void)contentView:(ReaderContentView *)contentView touchesBegan:(NSSet *)touches
{
if ((mainToolbar.hidden == NO) || (mainPagebar.hidden == NO))
{
if (touches.count == 1) // Single touches only
{
UITouch *touch = [touches anyObject]; // Touch info
CGPoint point = [touch locationInView:self.view]; // Touch location
CGRect areaRect = CGRectInset(self.view.bounds, TAP_AREA_SIZE, TAP_AREA_SIZE);
if (CGRectContainsPoint(areaRect, point) == false) return;
}
[mainToolbar hideToolbar]; [mainPagebar hidePagebar]; // Hide
lastHideTime = [NSDate date];
}
}
#pragma mark ReaderMainToolbarDelegate methods
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar doneButton:(UIButton *)button
{
#if (READER_STANDALONE == FALSE) // Option
[document saveReaderDocument]; // Save any ReaderDocument object changes
[[ReaderThumbQueue sharedInstance] cancelOperationsWithGUID:document.guid];
[[ReaderThumbCache sharedInstance] removeAllObjects]; // Empty the thumb cache
if (printInteraction != nil) [printInteraction dismissAnimated:NO]; // Dismiss
if ([delegate respondsToSelector:@selector(dismissReaderViewController:)] == YES)
{
[delegate dismissReaderViewController:self]; // Dismiss the ReaderViewController
}
else // We have a "Delegate must respond to -dismissReaderViewController: error"
{
NSAssert(NO, @"Delegate must respond to -dismissReaderViewController:");
}
#endif // end of READER_STANDALONE Option
}
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar thumbsButton:(UIButton *)button
{
if (printInteraction != nil) [printInteraction dismissAnimated:NO]; // Dismiss
ThumbsViewController *thumbsViewController = [[ThumbsViewController alloc] initWithReaderDocument:document];
thumbsViewController.delegate = self; thumbsViewController.title = self.title;
thumbsViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
thumbsViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:thumbsViewController animated:NO completion:nil];
}
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar printButton:(UIButton *)button
{
#if (READER_ENABLE_PRINT == TRUE) // Option
Class printInteractionController = NSClassFromString(@"UIPrintInteractionController");
if ((printInteractionController != nil) && [printInteractionController isPrintingAvailable])
{
NSURL *fileURL = document.fileURL; // Document file URL
printInteraction = [printInteractionController sharedPrintController];
if ([printInteractionController canPrintURL:fileURL] == YES) // Check first
{
UIPrintInfo *printInfo = [NSClassFromString(@"UIPrintInfo") printInfo];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = document.fileName;
printInteraction.printInfo = printInfo;
printInteraction.printingItem = fileURL;
printInteraction.showsPageRange = YES;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
[printInteraction presentFromRect:button.bounds inView:button animated:YES completionHandler:
^(UIPrintInteractionController *pic, BOOL completed, NSError *error)
{
#ifdef DEBUG
if ((completed == NO) && (error != nil)) NSLog(@"%s %@", __FUNCTION__, error);
#endif
}
];
}
else // Presume UIUserInterfaceIdiomPhone
{
[printInteraction presentAnimated:YES completionHandler:
^(UIPrintInteractionController *pic, BOOL completed, NSError *error)
{
#ifdef DEBUG
if ((completed == NO) && (error != nil)) NSLog(@"%s %@", __FUNCTION__, error);
#endif
}
];
}
}
}
#endif // end of READER_ENABLE_PRINT Option
}
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar emailButton:(UIButton *)button
{
#if (READER_ENABLE_MAIL == TRUE) // Option
if ([MFMailComposeViewController canSendMail] == NO) return;
if (printInteraction != nil) [printInteraction dismissAnimated:YES];
unsigned long long fileSize = [document.fileSize unsignedLongLongValue];
if (fileSize < (unsigned long long)15728640) // Check attachment size limit (15MB)
{
NSURL *fileURL = document.fileURL; NSString *fileName = document.fileName; // Document
NSData *attachment = [NSData dataWithContentsOfURL:fileURL options:(NSDataReadingMapped|NSDataReadingUncached) error:nil];
if (attachment != nil) // Ensure that we have valid document file attachment data
{
MFMailComposeViewController *mailComposer = [MFMailComposeViewController new];
[mailComposer addAttachmentData:attachment mimeType:@"application/pdf" fileName:fileName];
[mailComposer setSubject:fileName]; // Use the document file name for the subject
mailComposer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
mailComposer.modalPresentationStyle = UIModalPresentationFormSheet;
mailComposer.mailComposeDelegate = self; // Set the delegate
[self presentViewController:mailComposer animated:YES completion:nil];
}
}
#endif // end of READER_ENABLE_MAIL Option
}
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar markButton:(UIButton *)button
{
if (printInteraction != nil) [printInteraction dismissAnimated:YES];
NSInteger page = [document.pageNumber integerValue];
if ([document.bookmarks containsIndex:page]) // Remove bookmark
{
[mainToolbar setBookmarkState:NO]; [document.bookmarks removeIndex:page];
}
else // Add the bookmarked page index to the bookmarks set
{
[mainToolbar setBookmarkState:YES]; [document.bookmarks addIndex:page];
}
}
#pragma mark MFMailComposeViewControllerDelegate methods
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
#ifdef DEBUG
if ((result == MFMailComposeResultFailed) && (error != NULL)) NSLog(@"%@", error);
#endif
[self dismissViewControllerAnimated:YES completion:nil]; // Dismiss
}
#pragma mark ThumbsViewControllerDelegate methods
- (void)dismissThumbsViewController:(ThumbsViewController *)viewController
{
[self updateToolbarBookmarkIcon]; // Update bookmark icon
[self dismissViewControllerAnimated:NO completion:nil]; // Dismiss
}
- (void)thumbsViewController:(ThumbsViewController *)viewController gotoPage:(NSInteger)page
{
[self showDocumentPage:page]; // Show the page
}
#pragma mark ReaderMainPagebarDelegate methods
- (void)pagebar:(ReaderMainPagebar *)pagebar gotoPage:(NSInteger)page
{
[self showDocumentPage:page]; // Show the page
}
#pragma mark UIApplication notification methods
- (void)applicationWill:(NSNotification *)notification
{
[document saveReaderDocument]; // Save any ReaderDocument object changes
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
if (printInteraction != nil) [printInteraction dismissAnimated:NO];
}
}
@end

View File

@@ -0,0 +1,47 @@
//
// ThumbsMainToolbar.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "UIXToolbarView.h"
@class ThumbsMainToolbar;
@protocol ThumbsMainToolbarDelegate <NSObject>
@required // Delegate protocols
- (void)tappedInToolbar:(ThumbsMainToolbar *)toolbar doneButton:(UIButton *)button;
- (void)tappedInToolbar:(ThumbsMainToolbar *)toolbar showControl:(UISegmentedControl *)control;
@end
@interface ThumbsMainToolbar : UIXToolbarView
@property (nonatomic, unsafe_unretained, readwrite) id <ThumbsMainToolbarDelegate> delegate;
- (id)initWithFrame:(CGRect)frame title:(NSString *)title;
@end

View File

@@ -0,0 +1,149 @@
//
// ThumbsMainToolbar.m
// Reader v2.6.2
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
#import "ThumbsMainToolbar.h"
@implementation ThumbsMainToolbar
#pragma mark Constants
#define BUTTON_X 8.0f
#define BUTTON_Y 8.0f
#define BUTTON_SPACE 8.0f
#define BUTTON_HEIGHT 30.0f
#define DONE_BUTTON_WIDTH 56.0f
#define SHOW_CONTROL_WIDTH 78.0f
#define TITLE_HEIGHT 28.0f
#pragma mark Properties
@synthesize delegate;
#pragma mark ThumbsMainToolbar instance methods
- (id)initWithFrame:(CGRect)frame
{
return [self initWithFrame:frame title:nil];
}
- (id)initWithFrame:(CGRect)frame title:(NSString *)title
{
if ((self = [super initWithFrame:frame]))
{
CGFloat viewWidth = self.bounds.size.width;
UIImage *imageH = [UIImage imageNamed:@"Reader-Button-H"];
UIImage *imageN = [UIImage imageNamed:@"Reader-Button-N"];
UIImage *buttonH = [imageH stretchableImageWithLeftCapWidth:5 topCapHeight:0];
UIImage *buttonN = [imageN stretchableImageWithLeftCapWidth:5 topCapHeight:0];
CGFloat titleX = BUTTON_X; CGFloat titleWidth = (viewWidth - (titleX + titleX));
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(BUTTON_X, BUTTON_Y, DONE_BUTTON_WIDTH, BUTTON_HEIGHT);
[doneButton setTitle:NSLocalizedString(@"Done", @"button") forState:UIControlStateNormal];
[doneButton setTitleColor:[UIColor colorWithWhite:0.0f alpha:1.0f] forState:UIControlStateNormal];
[doneButton setTitleColor:[UIColor colorWithWhite:1.0f alpha:1.0f] forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(doneButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[doneButton setBackgroundImage:buttonH forState:UIControlStateHighlighted];
[doneButton setBackgroundImage:buttonN forState:UIControlStateNormal];
doneButton.titleLabel.font = [UIFont systemFontOfSize:14.0f];
doneButton.autoresizingMask = UIViewAutoresizingNone;
doneButton.exclusiveTouch = YES;
[self addSubview:doneButton];
titleX += (DONE_BUTTON_WIDTH + BUTTON_SPACE); titleWidth -= (DONE_BUTTON_WIDTH + BUTTON_SPACE);
#if (READER_BOOKMARKS == TRUE) // Option
CGFloat showControlX = (viewWidth - (SHOW_CONTROL_WIDTH + BUTTON_SPACE));
UIImage *thumbsImage = [UIImage imageNamed:@"Reader-Thumbs"];
UIImage *bookmarkImage = [UIImage imageNamed:@"Reader-Mark-Y"];
NSArray *buttonItems = [NSArray arrayWithObjects:thumbsImage, bookmarkImage, nil];
UISegmentedControl *showControl = [[UISegmentedControl alloc] initWithItems:buttonItems];
showControl.frame = CGRectMake(showControlX, BUTTON_Y, SHOW_CONTROL_WIDTH, BUTTON_HEIGHT);
showControl.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
// showControl.segmentedControlStyle = UISegmentedControlStyleBar;
showControl.tintColor = [UIColor blackColor];
showControl.selectedSegmentIndex = 0; // Default segment index
showControl.exclusiveTouch = YES;
[showControl addTarget:self action:@selector(showControlTapped:) forControlEvents:UIControlEventValueChanged];
[self addSubview:showControl];
titleWidth -= (SHOW_CONTROL_WIDTH + BUTTON_SPACE);
#endif // end of READER_BOOKMARKS Option
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
CGRect titleRect = CGRectMake(titleX, BUTTON_Y, titleWidth, TITLE_HEIGHT);
UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleRect];
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.font = [UIFont systemFontOfSize:19.0f];
titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
titleLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
titleLabel.textColor = [UIColor redColor];
titleLabel.shadowColor = [UIColor colorWithWhite:0.65f alpha:1.0f];
titleLabel.backgroundColor = [UIColor blackColor];
titleLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
titleLabel.adjustsFontSizeToFitWidth = YES;
titleLabel.MinimumScaleFactor = 14.0f;
titleLabel.text = title;
[self addSubview:titleLabel];
}
}
return self;
}
#pragma mark UISegmentedControl action methods
- (void)showControlTapped:(UISegmentedControl *)control
{
[delegate tappedInToolbar:self showControl:control];
}
#pragma mark UIButton action methods
- (void)doneButtonTapped:(UIButton *)button
{
[delegate tappedInToolbar:self doneButton:button];
}
@end

View File

@@ -0,0 +1,66 @@
//
// ThumbsViewController.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "ThumbsMainToolbar.h"
#import "ReaderThumbsView.h"
@class ReaderDocument;
@class ThumbsViewController;
@protocol ThumbsViewControllerDelegate <NSObject>
@required // Delegate protocols
- (void)thumbsViewController:(ThumbsViewController *)viewController gotoPage:(NSInteger)page;
- (void)dismissThumbsViewController:(ThumbsViewController *)viewController;
@end
@interface ThumbsViewController : UIViewController
@property (nonatomic, unsafe_unretained, readwrite) id <ThumbsViewControllerDelegate> delegate;
- (id)initWithReaderDocument:(ReaderDocument *)object;
@end
#pragma mark -
//
// ThumbsPageThumb class interface
//
@interface ThumbsPageThumb : ReaderThumbView
- (CGSize)maximumContentSize;
- (void)showText:(NSString *)text;
- (void)showBookmark:(BOOL)show;
@end

View File

@@ -0,0 +1,480 @@
//
// ThumbsViewController.m
// Reader v2.6.1
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "ReaderConstants.h"
#import "ThumbsViewController.h"
#import "ReaderThumbRequest.h"
#import "ReaderThumbCache.h"
#import "ReaderDocument.h"
#import <QuartzCore/QuartzCore.h>
@interface ThumbsViewController () <ThumbsMainToolbarDelegate, ReaderThumbsViewDelegate>
@end
@implementation ThumbsViewController
{
ReaderDocument *document;
ThumbsMainToolbar *mainToolbar;
ReaderThumbsView *theThumbsView;
NSMutableArray *bookmarked;
CGPoint thumbsOffset;
CGPoint markedOffset;
BOOL updateBookmarked;
BOOL showBookmarked;
}
#pragma mark Constants
#define TOOLBAR_HEIGHT 44.0f
#define PAGE_THUMB_SMALL 160
#define PAGE_THUMB_LARGE 256
#pragma mark Properties
@synthesize delegate;
#pragma mark UIViewController methods
- (id)initWithReaderDocument:(ReaderDocument *)object
{
id thumbs = nil; // ThumbsViewController object
if ((object != nil) && ([object isKindOfClass:[ReaderDocument class]]))
{
if ((self = [super initWithNibName:nil bundle:nil])) // Designated initializer
{
updateBookmarked = YES; bookmarked = [NSMutableArray new]; // Bookmarked pages
document = object; // Retain the ReaderDocument object for our use
thumbs = self; // Return an initialized ThumbsViewController object
}
}
return thumbs;
}
- (void)viewDidLoad
{
[super viewDidLoad];
assert(delegate != nil); assert(document != nil);
self.view.backgroundColor = [UIColor blackColor];
CGRect viewRect = self.view.bounds; // View controller's view bounds
NSString *toolbarTitle = [document.fileName stringByDeletingPathExtension];
CGRect toolbarRect = viewRect; toolbarRect.size.height = TOOLBAR_HEIGHT;
mainToolbar = [[ThumbsMainToolbar alloc] initWithFrame:toolbarRect title:toolbarTitle]; // At top
mainToolbar.delegate = self;
[self.view addSubview:mainToolbar];
CGRect thumbsRect = viewRect; UIEdgeInsets insets = UIEdgeInsetsZero;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
thumbsRect.origin.y += TOOLBAR_HEIGHT; thumbsRect.size.height -= TOOLBAR_HEIGHT;
}
else // Set UIScrollView insets for non-UIUserInterfaceIdiomPad case
{
insets.top = TOOLBAR_HEIGHT;
}
theThumbsView = [[ReaderThumbsView alloc] initWithFrame:thumbsRect]; // Rest
theThumbsView.contentInset = insets; theThumbsView.scrollIndicatorInsets = insets;
theThumbsView.delegate = self;
[self.view insertSubview:theThumbsView belowSubview:mainToolbar];
BOOL large = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
NSInteger thumbSize = (large ? PAGE_THUMB_LARGE : PAGE_THUMB_SMALL); // Thumb dimensions
[theThumbsView setThumbSize:CGSizeMake(thumbSize, thumbSize)]; // Thumb size based on device
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[theThumbsView reloadThumbsCenterOnIndex:([document.pageNumber integerValue] - 1)]; // Page
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)viewDidUnload
{
#ifdef DEBUG
NSLog(@"%s", __FUNCTION__);
#endif
mainToolbar = nil; theThumbsView = nil;
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
/*
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//if (fromInterfaceOrientation == self.interfaceOrientation) return;
}
*/
- (void)didReceiveMemoryWarning
{
#ifdef DEBUG
NSLog(@"%s", __FUNCTION__);
#endif
[super didReceiveMemoryWarning];
}
#pragma mark ThumbsMainToolbarDelegate methods
- (void)tappedInToolbar:(ThumbsMainToolbar *)toolbar showControl:(UISegmentedControl *)control
{
switch (control.selectedSegmentIndex)
{
case 0: // Show all page thumbs
{
showBookmarked = NO; // Show all thumbs
markedOffset = [theThumbsView insetContentOffset];
[theThumbsView reloadThumbsContentOffset:thumbsOffset];
break; // We're done
}
case 1: // Show bookmarked thumbs
{
showBookmarked = YES; // Only bookmarked
thumbsOffset = [theThumbsView insetContentOffset];
if (updateBookmarked == YES) // Update bookmarked list
{
[bookmarked removeAllObjects]; // Empty the list first
[document.bookmarks enumerateIndexesUsingBlock: // Enumerate
^(NSUInteger page, BOOL *stop)
{
[bookmarked addObject:[NSNumber numberWithInteger:page]];
}
];
markedOffset = CGPointZero; updateBookmarked = NO; // Reset
}
[theThumbsView reloadThumbsContentOffset:markedOffset];
break; // We're done
}
}
}
- (void)tappedInToolbar:(ThumbsMainToolbar *)toolbar doneButton:(UIButton *)button
{
[delegate dismissThumbsViewController:self]; // Dismiss thumbs display
}
#pragma mark UIThumbsViewDelegate methods
- (NSUInteger)numberOfThumbsInThumbsView:(ReaderThumbsView *)thumbsView
{
return (showBookmarked ? bookmarked.count : [document.pageCount integerValue]);
}
- (id)thumbsView:(ReaderThumbsView *)thumbsView thumbCellWithFrame:(CGRect)frame
{
return [[ThumbsPageThumb alloc] initWithFrame:frame];
}
- (void)thumbsView:(ReaderThumbsView *)thumbsView updateThumbCell:(ThumbsPageThumb *)thumbCell forIndex:(NSInteger)index
{
CGSize size = [thumbCell maximumContentSize]; // Get the cell's maximum content size
NSInteger page = (showBookmarked ? [[bookmarked objectAtIndex:index] integerValue] : (index + 1));
[thumbCell showText:[NSString stringWithFormat:@"%d", page]]; // Page number place holder
[thumbCell showBookmark:[document.bookmarks containsIndex:page]]; // Show bookmarked status
NSURL *fileURL = document.fileURL; NSString *guid = document.guid; NSString *phrase = document.password; // Document info
ReaderThumbRequest *thumbRequest = [ReaderThumbRequest newForView:thumbCell fileURL:fileURL password:phrase guid:guid page:page size:size];
UIImage *image = [[ReaderThumbCache sharedInstance] thumbRequest:thumbRequest priority:YES]; // Request the thumbnail
if ([image isKindOfClass:[UIImage class]]) [thumbCell showImage:image]; // Show image from cache
}
- (void)thumbsView:(ReaderThumbsView *)thumbsView refreshThumbCell:(ThumbsPageThumb *)thumbCell forIndex:(NSInteger)index
{
NSInteger page = (showBookmarked ? [[bookmarked objectAtIndex:index] integerValue] : (index + 1));
[thumbCell showBookmark:[document.bookmarks containsIndex:page]]; // Show bookmarked status
}
- (void)thumbsView:(ReaderThumbsView *)thumbsView didSelectThumbWithIndex:(NSInteger)index
{
NSInteger page = (showBookmarked ? [[bookmarked objectAtIndex:index] integerValue] : (index + 1));
[delegate thumbsViewController:self gotoPage:page]; // Show the selected page
[delegate dismissThumbsViewController:self]; // Dismiss thumbs display
}
- (void)thumbsView:(ReaderThumbsView *)thumbsView didPressThumbWithIndex:(NSInteger)index
{
NSInteger page = (showBookmarked ? [[bookmarked objectAtIndex:index] integerValue] : (index + 1));
if ([document.bookmarks containsIndex:page]) [document.bookmarks removeIndex:page]; else [document.bookmarks addIndex:page];
updateBookmarked = YES; [thumbsView refreshThumbWithIndex:index]; // Refresh page thumb
}
@end
#pragma mark -
//
// ThumbsPageThumb class implementation
//
@implementation ThumbsPageThumb
{
UIView *backView;
UIView *tintView;
UILabel *textLabel;
UIImageView *bookMark;
CGSize maximumSize;
CGRect defaultRect;
}
#pragma mark Constants
#define CONTENT_INSET 8.0f
#pragma mark ThumbsPageThumb instance methods
- (CGRect)markRectInImageView
{
CGRect iconRect = bookMark.frame; iconRect.origin.y = (-2.0f);
iconRect.origin.x = (imageView.bounds.size.width - bookMark.image.size.width - 8.0f);
return iconRect; // Frame position rect inside of image view
}
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
imageView.contentMode = UIViewContentModeCenter;
defaultRect = CGRectInset(self.bounds, CONTENT_INSET, CONTENT_INSET);
maximumSize = defaultRect.size; // Maximum thumb content size
CGFloat newWidth = ((defaultRect.size.width / 4.0f) * 3.0f);
CGFloat offsetX = ((defaultRect.size.width - newWidth) / 2.0f);
defaultRect.size.width = newWidth; defaultRect.origin.x += offsetX;
imageView.frame = defaultRect; // Update the image view frame
CGFloat fontSize = (([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ? 19.0f : 16.0f);
textLabel = [[UILabel alloc] initWithFrame:defaultRect];
textLabel.autoresizesSubviews = NO;
textLabel.userInteractionEnabled = NO;
textLabel.contentMode = UIViewContentModeRedraw;
textLabel.autoresizingMask = UIViewAutoresizingNone;
textLabel.textAlignment = NSTextAlignmentCenter;
textLabel.font = [UIFont systemFontOfSize:fontSize];
textLabel.textColor = [UIColor redColor];
textLabel.backgroundColor = [UIColor blackColor];
[self insertSubview:textLabel belowSubview:imageView];
backView = [[UIView alloc] initWithFrame:defaultRect];
backView.autoresizesSubviews = NO;
backView.userInteractionEnabled = NO;
backView.contentMode = UIViewContentModeRedraw;
backView.autoresizingMask = UIViewAutoresizingNone;
backView.backgroundColor = [UIColor blackColor];
#if (READER_SHOW_SHADOWS == TRUE) // Option
backView.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
backView.layer.shadowRadius = 3.0f; backView.layer.shadowOpacity = 1.0f;
backView.layer.shadowPath = [UIBezierPath bezierPathWithRect:backView.bounds].CGPath;
#endif // end of READER_SHOW_SHADOWS Option
[self insertSubview:backView belowSubview:textLabel];
/*
tintView = [[UIView alloc] initWithFrame:imageView.bounds];
tintView.hidden = YES;
tintView.autoresizesSubviews = NO;
tintView.userInteractionEnabled = NO;
tintView.contentMode = UIViewContentModeRedraw;
tintView.autoresizingMask = UIViewAutoresizingNone;
tintView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.25f];
[imageView addSubview:tintView];
*/
UIImage *image = [UIImage imageNamed:@"Reader-Mark-Y"];
bookMark = [[UIImageView alloc] initWithImage:image];
bookMark.hidden = YES;
bookMark.autoresizesSubviews = NO;
bookMark.userInteractionEnabled = NO;
bookMark.contentMode = UIViewContentModeCenter;
bookMark.autoresizingMask = UIViewAutoresizingNone;
bookMark.frame = [self markRectInImageView];
[imageView addSubview:bookMark];
}
return self;
}
- (CGSize)maximumContentSize
{
return maximumSize;
}
- (void)showImage:(UIImage *)image
{
NSInteger x = (self.bounds.size.width / 2.0f);
NSInteger y = (self.bounds.size.height / 2.0f);
CGPoint location = CGPointMake(x, y); // Center point
CGRect viewRect = CGRectZero; viewRect.size = image.size;
textLabel.bounds = viewRect; textLabel.center = location; // Position
imageView.bounds = viewRect; imageView.center = location; imageView.image = image;
bookMark.frame = [self markRectInImageView]; // Position bookmark image
tintView.frame = imageView.bounds; backView.bounds = viewRect; backView.center = location;
#if (READER_SHOW_SHADOWS == TRUE) // Option
backView.layer.shadowPath = [UIBezierPath bezierPathWithRect:backView.bounds].CGPath;
#endif // end of READER_SHOW_SHADOWS Option
}
- (void)reuse
{
[super reuse]; // Reuse thumb view
textLabel.text = nil; textLabel.frame = defaultRect;
imageView.image = nil; imageView.frame = defaultRect;
bookMark.hidden = YES; bookMark.frame = [self markRectInImageView];
tintView.hidden = YES; tintView.frame = imageView.bounds; backView.frame = defaultRect;
#if (READER_SHOW_SHADOWS == TRUE) // Option
backView.layer.shadowPath = [UIBezierPath bezierPathWithRect:backView.bounds].CGPath;
#endif // end of READER_SHOW_SHADOWS Option
}
- (void)showBookmark:(BOOL)show
{
bookMark.hidden = (show ? NO : YES);
}
- (void)showTouched:(BOOL)touched
{
tintView.hidden = (touched ? NO : YES);
}
- (void)showText:(NSString *)text
{
textLabel.text = text;
}
@end

View File

@@ -0,0 +1,40 @@
//
// UIXToolbarView.h
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface UIXToolbarView : UIView
@end
#pragma mark -
//
// UIXToolbarShadow class interface
//
@interface UIXToolbarShadow : UIView
@end

View File

@@ -0,0 +1,105 @@
//
// UIXToolbarView.m
// Reader v2.6.0
//
// Created by Julius Oklamcak on 2011-09-01.
// Copyright © 2011-2013 Julius Oklamcak. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to
// do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import "UIXToolbarView.h"
#import <QuartzCore/QuartzCore.h>
@implementation UIXToolbarView
#pragma mark Constants
#define SHADOW_HEIGHT 4.0f
#pragma mark UIXToolbarView class methods
+ (Class)layerClass
{
return [CAGradientLayer class];
}
#pragma mark UIXToolbarView instance methods
- (id)initWithFrame:(CGRect)frame
{
// UIColor *NightColor=[UIColor colorWithRed:70 green:0 blue:0 alpha:0.8];
UIColor *DarkNightColor=[UIColor blackColor];
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = YES;
self.userInteractionEnabled = YES;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = DarkNightColor;
}
return self;
}
@end
#pragma mark -
//
// UIXToolbarShadow class implementation
//
@implementation UIXToolbarShadow
#pragma mark UIXToolbarShadow class methods
+ (Class)layerClass
{
return [CAGradientLayer class];
}
#pragma mark UIXToolbarShadow instance methods
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.autoresizesSubviews = NO;
self.userInteractionEnabled = NO;
self.contentMode = UIViewContentModeRedraw;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = [UIColor blackColor];
/* CAGradientLayer *layer = (CAGradientLayer *)self.layer;
UIColor *blackColor = [UIColor colorWithWhite:0.24f alpha:1.0f];
UIColor *clearColor = [UIColor colorWithWhite:0.24f alpha:0.0f];
layer.colors = [NSArray arrayWithObjects:(id)blackColor.CGColor, (id)clearColor.CGColor, nil];
*/
}
return self;
}
@end

View File

@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@@ -0,0 +1,262 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1552</int>
<string key="IBDocument.SystemVersion">12E55</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.39</string>
<string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">2083</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBNSLayoutConstraint</string>
<string>IBProxyObject</string>
<string>IBUIButton</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="843779117">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="774585933">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIButton" id="44079163">
<reference key="NSNextResponder" ref="774585933"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{124, 252}, {73, 44}}</string>
<reference key="NSSuperview" ref="774585933"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">Button</string>
<object class="NSColor" key="IBUIHighlightedTitleColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 548}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC43NQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<object class="IBUIScreenMetrics" key="IBUISimulatedDestinationMetrics">
<string key="IBUISimulatedSizeMetricsClass">IBUIScreenMetrics</string>
<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
<bool key="EncodedWithXMLCoder">YES</bool>
<array key="dict.sortedKeys">
<integer value="1"/>
<integer value="3"/>
</array>
<array key="dict.values">
<string>{320, 568}</string>
<string>{568, 320}</string>
</array>
</object>
<string key="IBUITargetRuntime">IBCocoaTouchFramework</string>
<string key="IBUIDisplayName">Retina 4 Full Screen</string>
<int key="IBUIType">2</int>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="774585933"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">didclickPDF:</string>
<reference key="source" ref="44079163"/>
<reference key="destination" ref="843779117"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">11</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="843779117"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="774585933"/>
<array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="856257196">
<reference key="firstItem" ref="44079163"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="774585933"/>
<int key="secondAttribute">3</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">252</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="774585933"/>
<int key="scoringType">3</int>
<float key="scoringTypeFloat">9</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="339952439">
<reference key="firstItem" ref="44079163"/>
<int key="firstAttribute">9</int>
<int key="relation">0</int>
<reference key="secondItem" ref="774585933"/>
<int key="secondAttribute">9</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="774585933"/>
<int key="scoringType">5</int>
<float key="scoringTypeFloat">22</float>
<int key="contentType">2</int>
</object>
<reference ref="44079163"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="44079163"/>
<reference key="parent" ref="774585933"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="339952439"/>
<reference key="parent" ref="774585933"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="856257196"/>
<reference key="parent" ref="774585933"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">MTViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<array key="6.IBViewMetadataConstraints">
<reference ref="339952439"/>
<reference ref="856257196"/>
</array>
<string key="8.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<boolean value="NO" key="8.IBViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">11</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">MTViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">didclickPDF:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">didclickPDF:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">didclickPDF:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MTViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSLayoutConstraint</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<bool key="IBDocument.UseAutolayout">YES</bool>
<string key="IBCocoaTouchPluginVersion">2083</string>
</data>
</archive>

View File

@@ -0,0 +1,18 @@
//
// main.m
// Night Reader
//
// Created by Norbert Schmidt on 11-08-13.
// Copyright (c) 2013 Norbert Schmidt. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 KiB