CPDFListView.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. //
  2. // CPDFListView.m
  3. // compdfkit-tools
  4. //
  5. // Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. #import "CPDFListView.h"
  13. #import "CPDFListView+Annotation.h"
  14. #import "CPDFListView+Private.h"
  15. #import "CPDFColorUtils.h"
  16. #import "CPDFSlider.h"
  17. #import "CPDFPageIndicatorView.h"
  18. NSNotificationName const CPDFListViewToolModeChangeNotification = @"CPDFListViewToolModeChangeNotification";
  19. NSNotificationName const CPDFListViewAnnotationModeChangeNotification = @"CPDFListViewAnnotationModeChangeNotification";
  20. NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification = @"CPDFListViewActiveAnnotationsChangeNotification";
  21. @interface CPDFListView()
  22. @property (nonatomic, strong) CPDFPageIndicatorView * pageIndicatorView;
  23. @end
  24. @implementation CPDFListView
  25. #pragma mark - Initializers
  26. - (instancetype)initWithFrame:(CGRect)frame {
  27. if (self = [super initWithFrame:frame]) {
  28. self.backgroundColor = [UIColor lightGrayColor];
  29. [self commomInit];
  30. [self addNotification];
  31. }
  32. return self;
  33. }
  34. - (id)initWithCoder:(NSCoder *)decoder {
  35. self = [super initWithCoder:decoder];
  36. if (self) {
  37. self.backgroundColor = [UIColor lightGrayColor];
  38. [self commomInit];
  39. [self addNotification];
  40. }
  41. return self;
  42. }
  43. #pragma mark - Accessors
  44. - (void)setAnnotationMode:(CPDFViewAnnotationMode)annotationMode {
  45. _annotationMode = annotationMode;
  46. if (CPDFViewAnnotationModeHighlight == annotationMode ||
  47. CPDFViewAnnotationModeUnderline == annotationMode ||
  48. CPDFViewAnnotationModeStrikeout == annotationMode ||
  49. CPDFViewAnnotationModeSquiggly == annotationMode) {
  50. self.textSelectionMode = YES;
  51. } else {
  52. self.textSelectionMode = NO;
  53. }
  54. if (CPDFViewAnnotationModeLink == annotationMode) {
  55. self.scrollEnabled = NO;
  56. [self endDrawing];
  57. } else if (CPDFViewAnnotationModeInk == annotationMode) {
  58. self.scrollEnabled = NO;
  59. [self beginDrawing];
  60. } else {
  61. if (self.activeAnnotation) {
  62. self.scrollEnabled = NO;
  63. } else {
  64. self.scrollEnabled = YES;
  65. }
  66. [self endDrawing];
  67. [self becomeFirstResponder];
  68. }
  69. if (CPDFViewAnnotationModeNone != annotationMode) {
  70. CPDFPage *page = self.activeAnnotation.page;
  71. [self updateActiveAnnotations:@[]];
  72. [self setNeedsDisplayForPage:page];
  73. }
  74. dispatch_async(dispatch_get_main_queue(), ^{
  75. [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self];
  76. if([self.performDelegate respondsToSelector:@selector(PDFListViewChangedAnnotationType:forAnnotationMode:)]) {
  77. [self.performDelegate PDFListViewChangedAnnotationType:self forAnnotationMode:self.annotationMode];
  78. }
  79. });
  80. }
  81. -(void)setToolModel:(CToolModel)toolModel {
  82. _toolModel = toolModel;
  83. dispatch_async(dispatch_get_main_queue(), ^{
  84. [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewToolModeChangeNotification object:self];
  85. if([self.performDelegate respondsToSelector:@selector(PDFListViewChangedToolMode:forToolMode:)]) {
  86. [self.performDelegate PDFListViewChangedToolMode:self forToolMode:self.toolModel];
  87. }
  88. });
  89. }
  90. - (NSMutableArray *)activeAnnotations {
  91. if(!_activeAnnotations) {
  92. _activeAnnotations = [[NSMutableArray alloc] init];
  93. }
  94. return _activeAnnotations;
  95. }
  96. - (CPDFAnnotation *)activeAnnotation {
  97. return self.activeAnnotations.firstObject;
  98. }
  99. #pragma mark - Touch
  100. - (void)touchBeganAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  101. if (CToolModelAnnotation == self.toolModel) {
  102. [self annotationTouchBeganAtPoint:point forPage:page];
  103. } else if (CToolModelForm == self.toolModel) {
  104. } else if (CToolModelEdit == self.toolModel) {
  105. } else {
  106. }
  107. }
  108. - (void)touchMovedAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  109. if (CToolModelAnnotation == self.toolModel) {
  110. [self annotationTouchMovedAtPoint:point forPage:page];
  111. } else if (CToolModelForm == self.toolModel) {
  112. } else if (CToolModelEdit == self.toolModel) {
  113. } else {
  114. }
  115. }
  116. - (void)touchEndedAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  117. if (CToolModelAnnotation == self.toolModel) {
  118. [self annotationTouchEndedAtPoint:point forPage:page];
  119. } else if (CToolModelForm == self.toolModel) {
  120. } else if (CToolModelEdit == self.toolModel) {
  121. } else {
  122. }
  123. }
  124. - (void)touchCancelledAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  125. if (CToolModelAnnotation == self.toolModel) {
  126. [self annotationTouchCancelledAtPoint:point forPage:page];
  127. } else if (CToolModelForm == self.toolModel) {
  128. } else if (CToolModelEdit == self.toolModel) {
  129. } else {
  130. }
  131. }
  132. - (NSArray<UIMenuItem *> *)menuItemsAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
  133. if([self.performDelegate respondsToSelector:@selector(PDFListView:customizeMenuForPage:forPagePoint:)])
  134. return [self.performDelegate PDFListView:self customizeMenuForPage:page forPagePoint:point];
  135. return [super menuItemsAtPoint:point forPage:page];
  136. }
  137. #pragma mark - Private method
  138. - (void)commomInit {
  139. _pageSliderView = [[CPDFSlider alloc] initWithPDFView:self];
  140. _pageSliderView.frame = CGRectMake(self.bounds.size.width-22, 0, 22, self.bounds.size.height);
  141. _pageSliderView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin;
  142. [self addSubview:self.pageSliderView];
  143. _pageIndicatorView = [[CPDFPageIndicatorView alloc] init];
  144. __weak typeof(self) weakSelf = self;
  145. _pageIndicatorView.touchCallBack = ^{
  146. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:NSLocalizedString(@"Enter a page number", nil) preferredStyle:UIAlertControllerStyleAlert];
  147. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  148. }]];
  149. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  150. UITextField *pageTextField = alertController.textFields.firstObject;
  151. NSInteger pageIndex = [pageTextField.text integerValue] - 1;
  152. if (pageIndex > weakSelf.document.pageCount){
  153. pageIndex = weakSelf.document.pageCount;
  154. } else if(pageIndex<0){
  155. pageIndex = 0;
  156. } else if(pageTextField.text.length == 0){
  157. pageIndex = (int)weakSelf.currentPageIndex;
  158. }
  159. [weakSelf goToPageIndex:pageIndex animated:YES];
  160. }]];
  161. [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  162. NSString *str = [NSString stringWithFormat:@"Page(1/%lu)", weakSelf.document.pageCount];
  163. textField.placeholder = NSLocalizedString(str, nil);
  164. textField.keyboardType = UIKeyboardTypeNumberPad;
  165. }];
  166. UIViewController *tRootViewControl = [UIApplication sharedApplication].keyWindow.rootViewController;
  167. if ([tRootViewControl presentedViewController]) {
  168. tRootViewControl = [tRootViewControl presentedViewController];
  169. }
  170. [tRootViewControl presentViewController:alertController animated:true completion:nil];
  171. };
  172. }
  173. - (void)addNotification {
  174. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentChangedNotification:) name:CPDFViewDocumentChangedNotification object:nil];
  175. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageChangedNotification:) name:CPDFViewPageChangedNotification object:nil];
  176. }
  177. - (void)showPageNumIndicator {
  178. __weak typeof(self) weakSelf = self;
  179. if(![self.pageIndicatorView superview])
  180. [self.pageIndicatorView showInView:weakSelf position:CPDFPageIndicatorViewPositionLeftBottom];
  181. [self.pageIndicatorView updatePageCount:weakSelf.document.pageCount currentPageIndex:self.currentPageIndex + 1];
  182. }
  183. - (NSString *)annotationUserName {
  184. NSString *annotationUserName = CPDFKitShareConfig.annotationAuthor;
  185. if (!annotationUserName || [annotationUserName length] <= 0) {
  186. annotationUserName = [[UIDevice currentDevice] name];
  187. }
  188. return annotationUserName ? : @"";
  189. }
  190. - (void)updateActiveAnnotations:(NSArray <CPDFAnnotation *> *)activeAnnotations {
  191. if(activeAnnotations) {
  192. self.activeAnnotations = [NSMutableArray arrayWithArray:activeAnnotations];
  193. dispatch_async(dispatch_get_main_queue(), ^{
  194. [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self];
  195. if([self.performDelegate respondsToSelector:@selector(PDFListViewChangeatioActiveAnnotations:forActiveAnnotations:)]) {
  196. [self.performDelegate PDFListViewChangeatioActiveAnnotations:self forActiveAnnotations:self.activeAnnotations];
  197. }
  198. });
  199. } else if (!activeAnnotations && self.activeAnnotations.count > 0) {
  200. [self.activeAnnotations removeAllObjects];
  201. dispatch_async(dispatch_get_main_queue(), ^{
  202. [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self];
  203. if([self.performDelegate respondsToSelector:@selector(PDFListViewChangeatioActiveAnnotations:forActiveAnnotations:)]) {
  204. [self.performDelegate PDFListViewChangeatioActiveAnnotations:self forActiveAnnotations:self.activeAnnotations];
  205. }
  206. });
  207. }
  208. }
  209. #pragma mark - NotificationCenter
  210. - (void)documentChangedNotification:(NSNotification *)notification {
  211. CPDFView *pdfview = notification.object;
  212. if (pdfview.document == self.document) {
  213. [self showPageNumIndicator];
  214. [self.pageSliderView reloadData];
  215. }
  216. }
  217. - (void)pageChangedNotification:(NSNotification *)notification {
  218. CPDFView *pdfview = notification.object;
  219. if (pdfview.document == self.document) {
  220. [self showPageNumIndicator];
  221. [self.pageSliderView reloadData];
  222. }
  223. }
  224. #pragma mark - Rendering
  225. - (void)drawPage:(CPDFPage *)page toContext:(CGContextRef)context {
  226. if (CToolModelAnnotation == self.toolModel) {
  227. [self annotationDrawPage:page toContext:context];
  228. } else if (CToolModelForm == self.toolModel) {
  229. } else if (CToolModelEdit == self.toolModel) {
  230. } else {
  231. }
  232. }
  233. @end