// // PDFStampViewController.m // PDFReader // // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved. // // The PDF Reader Sample applications are licensed with a modified BSD license. // Please see License for details. This notice may not be removed from this file. // #import "PDFStampViewController.h" #import "StampCollectionViewCell.h" #import "StampPreview.h" #import "StampFileManager.h" #import "StampImageViewController.h" #import "StampTextViewController.h" #import #define kStamp_Cell_Height 60 extern PDFAnnotationStampKey PDFAnnotationStampKeyType = @"PDFAnnotationStampKeyType"; extern PDFAnnotationStampKey PDFAnnotationStampKeyImagePath = @"PDFAnnotationStampKeyImagePath"; extern PDFAnnotationStampKey PDFAnnotationStampKeyText = @"PDFAnnotationStampKeyText"; extern PDFAnnotationStampKey PDFAnnotationStampKeyShowDate = @"PDFAnnotationStampKeyShowDate"; extern PDFAnnotationStampKey PDFAnnotationStampKeyShowTime = @"PDFAnnotationStampKeyShowTime"; extern PDFAnnotationStampKey PDFAnnotationStampKeyStyle = @"PDFAnnotationStampKeyStyle"; extern PDFAnnotationStampKey PDFAnnotationStampKeyShape = @"PDFAnnotationStampKeyShape"; @interface PDFStampViewController () @property (nonatomic,retain) UICollectionView *collectView; @property (nonatomic,retain) UISegmentedControl *segmentedControl; @property (nonatomic,retain) NSArray *standardArray; @property (nonatomic,retain) NSArray *customTextArray; @property (nonatomic,retain) NSArray *customImageArray; @property (nonatomic,retain) NSMutableDictionary *imgDicCache; @property (nonatomic,retain) StampFileManager *stampFileManager; @end @implementation PDFStampViewController #pragma mark - Init Methods - (void)dealloc { Block_release(_callback); [_stampFileManager release]; [_imgDicCache release]; [_standardArray release]; [_customTextArray release]; [_customImageArray release]; _collectView.dataSource = nil; _collectView.delegate = nil; [_collectView release]; [_segmentedControl release]; [super dealloc]; } #pragma mark - UIViewController Methods - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0]; [self.navigationController.navigationBar setTranslucent:NO]; if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) { self.preferredContentSize = CGSizeMake(300, 400); } else { self.preferredContentSize = CGSizeMake(360, 480); } NSMutableArray *array = [NSMutableArray array]; for (int i=1; i<13; i++) { NSString *tPicName = nil; if (i<10) { tPicName = [NSString stringWithFormat:@"stamp-0%d.png",i]; } else { tPicName = [NSString stringWithFormat:@"stamp-%d.png",i]; } [array addObject:tPicName]; } [array addObjectsFromArray:@[@"stamp-13.png", @"stamp-14.png", @"stamp-15.png", @"stamp-16.png", @"stamp-20.png", @"stamp-18.png", @"stamp_chick.png", @"stamp_cross.png", @"stamp_circle_01.png"]]; self.standardArray = array; self.imgDicCache = [NSMutableDictionary dictionary]; self.stampFileManager = [[[StampFileManager alloc] init] autorelease]; [self.stampFileManager readStampDataFromFile]; self.customTextArray = [self.stampFileManager getTextStampData]; self.customImageArray = [self.stampFileManager getImageStampData]; [self.view addSubview:self.collectView]; self.navigationItem.titleView = self.segmentedControl; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (self.editing) { self.navigationItem.titleView.hidden = YES; } else { self.navigationItem.titleView.hidden = NO; } [self.collectView reloadData]; } - (void)setEditing:(BOOL)editing animated:(BOOL)animated { [super setEditing:editing animated:animated]; if (editing) { UIBarButtonItem *tLeftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:self.editButtonItem.action]; [self.navigationItem setRightBarButtonItem:tLeftItem]; [tLeftItem release]; UIBarButtonItem *tRightItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(buttonItemClicked_Delete:)]; if (self.customTextArray.count + self.customImageArray.count > 0){ [self.navigationItem setLeftBarButtonItem:tRightItem]; } else { self.navigationItem.leftBarButtonItem = nil; } [tRightItem release]; self.navigationItem.titleView.hidden = YES; self.collectView.allowsMultipleSelection = YES; } else { if (self.segmentedControl.selectedSegmentIndex == 1) { UIBarButtonItem *tLeftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:self.editButtonItem.action]; [self.navigationItem setRightBarButtonItem:tLeftItem]; [tLeftItem release]; [self.navigationItem setLeftBarButtonItem:nil]; } else { [self.navigationItem setRightBarButtonItem:nil]; [self.navigationItem setLeftBarButtonItem:nil]; } [self.navigationItem setLeftBarButtonItem:nil]; self.navigationItem.titleView.hidden = NO; self.collectView.allowsMultipleSelection = NO; } for (StampCollectionViewCell *cell in [self.collectView visibleCells]) { cell.editing = self.editing; } } #pragma mark - getter && setter Methods - (UICollectionView *)collectView { if (!_collectView) { UICollectionViewFlowLayout *layout = [[[UICollectionViewFlowLayout alloc] init] autorelease]; layout.scrollDirection = UICollectionViewScrollDirectionVertical; layout.minimumInteritemSpacing = 10; layout.minimumLineSpacing = 10; layout.itemSize = CGSizeMake((self.preferredContentSize.width - 60)/2,80); layout.sectionInset = UIEdgeInsetsMake(5, 20, 5, 20); _collectView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; _collectView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; _collectView.delegate = self; _collectView.dataSource = self; _collectView.backgroundColor = [UIColor clearColor]; [_collectView registerClass:[StampCollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"]; [_collectView registerClass:[StampCollectionHeaderView1 class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header1"]; [_collectView registerClass:[StampCollectionViewCell class] forCellWithReuseIdentifier:@"TStampViewCell"]; if (@available(iOS 11.0, *)) { _collectView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways; } } return _collectView; } - (UISegmentedControl *)segmentedControl { if (!_segmentedControl) { _segmentedControl = [[UISegmentedControl alloc] initWithItems:@[NSLocalizedString(@"Standard", nil), NSLocalizedString(@"Custom",nil)]]; _segmentedControl.selectedSegmentIndex = 0; [_segmentedControl addTarget:self action:@selector(segmentedControlValueChanged_Mode:) forControlEvents:UIControlEventValueChanged]; } return _segmentedControl; } #pragma mark - Button Event Action - (void)segmentedControlValueChanged_Mode:(id)sender { if (self.segmentedControl.selectedSegmentIndex == 1 && ![[CPDFKit sharedInstance] allowsFeature:CPDFKitFeatureAnnotationCustomizedStamp]) { UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleCancel handler:nil]; UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:NSLocalizedString(@"Your license does not support this feature, please upgrade your license privilege.", nil) preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:cancelAction]; [self presentViewController:alert animated:YES completion:nil]; [self.segmentedControl setSelectedSegmentIndex:0]; return; } self.editing = NO; [self.collectView reloadData]; } - (void)buttonItemClicked_Delete:(id)sender { NSArray *selectedArray = [self.collectView indexPathsForSelectedItems]; if (selectedArray.count < 1) return; NSMutableArray *selectArrayTxt = [NSMutableArray array]; NSMutableArray *selectArrayImage = [NSMutableArray array]; for (NSIndexPath *indexPath in selectedArray) { if (indexPath.section == 0) { [selectArrayTxt addObject:@(indexPath.row)]; } else { [selectArrayImage addObject:@(indexPath.row)]; } } NSArray *tempArray1 = [[[selectArrayTxt sortedArrayUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects]; NSArray *tempArray2 = [[[selectArrayImage sortedArrayUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects]; for (NSNumber *tNum in tempArray1) { int tIndex = [tNum intValue]; [self.stampFileManager removeStampItem:tIndex type:PDFStampCustomType_Text]; } for (NSNumber *tNum in tempArray2) { int tIndex = [tNum intValue]; [self.stampFileManager removeStampItem:tIndex type:PDFStampCustomType_Image]; } [self.collectView reloadData]; if (self.customImageArray.count + self.customTextArray.count == 0) { self.navigationItem.leftBarButtonItem = nil; } } #pragma mark - Private Methods - (UIImage *)compressImage:(UIImage *)image { CGFloat maxWH = kStamp_Cell_Height; if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) maxWH *=[UIScreen mainScreen].scale; CGFloat imageScale = 1.0; if (image.size.width > maxWH || image.size.height>maxWH) imageScale = MIN(maxWH / image.size.width, maxWH / image.size.height); CGSize newSize = CGSizeMake(image.size.width * imageScale, image.size.height * imageScale); UIGraphicsBeginImageContext(newSize); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } #pragma mark - Public Methods - (void)showViewController:(UIViewController *)viewController inRect:(CGRect)rect { UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:self] autorelease]; navigationController.modalPresentationStyle = UIModalPresentationPopover; UIPopoverPresentationController *popVC = navigationController.popoverPresentationController; popVC.delegate = self; popVC.sourceRect = rect; popVC.sourceView = viewController.view; [viewController presentViewController:navigationController animated:YES completion:nil]; } #pragma mark - UIPopoverPresentationControllerDelegate - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection { return UIModalPresentationNone; } - (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController { if (self.callback) { self.callback(-1, nil); self.callback = nil; } } #pragma mark - UICollectionViewDataSource & UICollectionViewDelegate - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { if (self.segmentedControl.selectedSegmentIndex == 0) { return 1; } else { return 2; } } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { if (self.segmentedControl.selectedSegmentIndex == 0) { return self.standardArray.count; } else { switch (section) { case 0: return self.customTextArray.count; case 1: return self.customImageArray.count; default: return 0; } } } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { StampCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TStampViewCell" forIndexPath:indexPath]; cell.backgroundColor = [UIColor whiteColor]; if (self.segmentedControl.selectedSegmentIndex == 0) { cell.editing = NO; cell.stampImage.image =[UIImage imageNamed:self.standardArray[indexPath.item]]; } else { cell.editing = self.editing; NSUInteger txtLength = indexPath.item; NSUInteger imgLength = indexPath.item; NSUInteger location = indexPath.item; NSUInteger length; NSRange range; length = indexPath.section ? imgLength : txtLength; range = NSMakeRange(location, length); if (0 == indexPath.section) { NSDictionary *tDic = _customTextArray[indexPath.item]; NSString *tText = [tDic objectForKey:@"text"]; NSInteger tStyle = [[tDic objectForKey:@"style"] integerValue]; BOOL tHaveDate = [[tDic objectForKey:@"haveDate"] boolValue]; BOOL tHaveTime = [[tDic objectForKey:@"haveTime"] boolValue]; StampPreview *tPreview = [[StampPreview alloc] initWithFrame:CGRectMake(0, 0, 320, kStamp_Cell_Height)]; [tPreview setTextStampText:tText]; [tPreview setTextStampStyle:tStyle]; [tPreview setTextStampHaveDate:tHaveDate]; [tPreview setTextStampHaveTime:tHaveTime]; tPreview.leftMargin = 0; UIImage *tImg = [tPreview renderImage]; cell.stampImage.image = tImg; [tPreview release]; } else { NSDictionary *tDic = self.customImageArray[indexPath.item]; UIImage *img = [self.imgDicCache objectForKey:tDic]; if (!img) { NSString *tPath = [tDic objectForKey:@"path"]; NSString *tFileName = [[NSFileManager defaultManager] displayNameAtPath:tPath]; NSString *tRealPath = [NSString stringWithFormat:@"%@/%@",kPDFStampDataFolder,tFileName]; UIImage *tImg = [UIImage imageWithContentsOfFile:tRealPath]; img = [self compressImage:tImg]; [self.imgDicCache setObject:img forKey:tDic]; } cell.stampImage.image = img; } } return cell; } - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { if (self.segmentedControl.selectedSegmentIndex == 1) { if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { if (indexPath.section == 0) { StampCollectionHeaderView1 *headerView = [_collectView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"header1" forIndexPath:indexPath]; headerView.delegate = self; if ([self.customTextArray count] > 0) { headerView.textLabel.hidden = NO; headerView.textLabel.text = NSLocalizedString(@"New Text Stamp", nil); } else { headerView.textLabel.hidden = YES; } return headerView; } else { StampCollectionHeaderView *headerView = [_collectView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"header" forIndexPath:indexPath]; if (self.customImageArray.count > 0) { headerView.textLabel.hidden = NO; headerView.textLabel.text = NSLocalizedString(@"New Image Stamp", nil); } else { headerView.textLabel.hidden = YES; } return headerView; } } } return nil; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { if (self.segmentedControl.selectedSegmentIndex == 1) { if (section == 0) { if ([self.customTextArray count] > 0) { return CGSizeMake(self.preferredContentSize.width, 100); } else { return CGSizeMake(self.preferredContentSize.width, 80); } } else { if ([self.customImageArray count] > 0) { return CGSizeMake(self.preferredContentSize.width, 20); } } } return CGSizeZero; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { if (!self.editing) { if (self.segmentedControl.selectedSegmentIndex == 0) { [self dismissViewControllerAnimated:YES completion:^{ if (self.callback) { self.callback(indexPath.row, nil); self.callback = nil; } }]; } else { if (indexPath.section == 0) { NSDictionary *tDict = self.customTextArray[indexPath.row]; NSString *tText = [tDict objectForKey:@"text"]; BOOL tHaveDate = [[tDict objectForKey:@"haveDate"] boolValue]; BOOL tHaveTime = [[tDict objectForKey:@"haveTime"] boolValue]; NSInteger tStyle = [[tDict objectForKey:@"style"] integerValue]; NSInteger stampStype = 0; NSInteger stampShape = 0; switch (tStyle) { case TextStampColorType_Black: { stampStype = 0; stampShape = 0; } break; case TextStampColorType_Red: case TextStampColorType_RedLeft: case TextStampColorType_RedRight: { stampStype = 1; if (TextStampColorType_RedRight== tStyle) { stampShape = 2; } else if (TextStampColorType_RedLeft == tStyle) { stampShape = 1; } else { stampShape = 0; } } break; case TextStampColorType_Green: case TextStampColorType_GreenLeft: case TextStampColorType_GreenRight: { stampStype = 2; if (TextStampColorType_GreenRight== tStyle) { stampShape = 2; } else if (TextStampColorType_GreenLeft == tStyle) { stampShape = 1; } else { stampShape = 0; } } break; case TextStampColorType_Blue: case TextStampColorType_BlueLeft: case TextStampColorType_BlueRight: { stampStype = 3; if (TextStampColorType_BlueRight== tStyle) { stampShape = 2; } else if (TextStampColorType_BlueLeft == tStyle) { stampShape = 1; } else { stampShape = 0; } } break; } [self dismissViewControllerAnimated:YES completion:^{ if (self.callback) { self.callback(indexPath.row, @{PDFAnnotationStampKeyText : tText, PDFAnnotationStampKeyShowDate : @(tHaveDate), PDFAnnotationStampKeyShowTime : @(tHaveTime), PDFAnnotationStampKeyStyle : @(stampStype), PDFAnnotationStampKeyShape : @(stampShape)}); self.callback = nil; } }]; } else { NSDictionary *tDict = self.customImageArray[indexPath.row]; NSString *tPath = [tDict objectForKey:@"path"]; NSString *tFileName = [[NSFileManager defaultManager] displayNameAtPath:tPath]; NSString *tRealPath = [NSString stringWithFormat:@"%@/%@",kPDFStampDataFolder,tFileName]; [self dismissViewControllerAnimated:YES completion:^{ if (self.callback) { self.callback(indexPath.row, @{PDFAnnotationStampKeyImagePath : tRealPath}); self.callback = nil; } }]; } } } } #pragma mark - TStampHeaderViewDelegate - (void)addImageWithHeaderView:(StampCollectionHeaderView1 *)headerView { self.editing = NO; StampImageViewController *vc = [[StampImageViewController alloc] init]; vc.callback = ^(UIImage *image) { NSString *tPath = [self.stampFileManager saveStampWithImage:image]; if (tPath) { NSMutableDictionary *tStampItem = [[NSMutableDictionary alloc] init]; [tStampItem setObject:tPath forKey:@"path"]; [self.stampFileManager insertStampItem:tStampItem type:PDFStampCustomType_Image]; [tStampItem release]; } }; [self.navigationController pushViewController:vc animated:YES]; [vc release]; } - (void)addTextWithHeaderView:(StampCollectionHeaderView1 *)headerView { self.editing = NO; StampTextViewController *vc = [[StampTextViewController alloc] init]; vc.callback = ^(NSDictionary *dictionary) { [self.stampFileManager insertStampItem:dictionary type:PDFStampCustomType_Text]; }; [self.navigationController pushViewController:vc animated:YES]; [vc release]; } @end