// // KMPDFBookletWindowController.m // PDF Reader // // Created by 蒋志鹏 on 2018/5/22. // Copyright © 2018 Kdan Mobile. All rights reserved. // #import "PDF_Reader_Pro-Swift.h" #import "KMPDFBookletWindowController.h" #import "KMBookletParameterModel.h" #import "KMBookletManager.h" #import "KMBookletPDFView.h" //#import "KMFileAttribute.h" //#import "KMBookletMaskView.h" #import "NSMutableArray+KMOddEvenPartFetch.h" //#import "PasswordWindowController.h" //#import "KMSavePanelAccessoryController.h" //#import "NSWindowController_SKExtensions.h" //#import "KMPageSizeTool.h" #pragma mark KMBookletPDFPage @interface KMBookletPDFPage : PDFPage @property (nonatomic,retain) KMBookletParameterModel *properties; @property (nonatomic,retain) NSArray * pages; @end @implementation KMBookletPDFPage - (void)dealloc { } - (void)drawWithBox:(PDFDisplayBox)box { [super drawWithBox:box]; CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; if (context) { [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]]; } KMBookletManager *manager = [KMBookletManager sharedManager]; [manager drawPageWithContext:context parameterModel:self.properties printArray:self.pages]; } - (void)drawWithBox:(PDFDisplayBox)box toContext:(CGContextRef)context { [super drawWithBox:box toContext:context]; if (context) { [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]]; } KMBookletManager *manager = [KMBookletManager sharedManager]; [manager drawPageWithContext:context parameterModel:self.properties printArray:self.pages]; } @end //combobox tag 枚举 typedef NS_ENUM(NSUInteger, KBookletComboBoxTag) { KBookletComboBoxTag_Unit = 0, KBookletComboBoxTag_PageSize, KBookletComboBoxTag_Subset, KBookletComboBoxTag_Binding, KBookletComboBoxTag_PagenationFont, KBookletComboBoxTag_pageRange, KBookletComboBoxTag_Comments }; //页码范围选择枚举 typedef NS_ENUM(NSInteger,KBookletPageRangeSelectStyle){ KBookletPageRangeSelectStyle_AllPages = 0, KBookletPageRangeSelectStyle_OddPages,//奇数页 KBookletPageRangeSelectStyle_EvenPages,//偶数页 KBookletPageRangeSelectStyle_SelectPages }; //PDFView的最大宽高 static CGFloat KMPDFBookletGenerate_PDFViewMAXWidth = 290.0; static CGFloat KMPDFBookletGenerate_PDFViewMAXHeight = 404.0; //打印时PDFDocument的暂存路径 #define kPrintFolderPath [[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] #define kBookletPrintFolderPath [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:@"Booklet"] #define kBookletFileSavePath [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:@"SaveBooklet.pdf"] @interface KMPDFBookletWindowController () //尺寸标识Label @property (assign) IBOutlet NSTextField *bookletNewPageSizeLabel; //PDFView宽约束 @property (assign) IBOutlet NSLayoutConstraint *bookletPDFPreViewWidthConstant; //PDFView高约束 @property (assign) IBOutlet NSLayoutConstraint *bookletPDFPreViewHeightConstant; //单位label @property (assign) IBOutlet NSTextField *bookletUnitLabel; //尺寸label @property (assign) IBOutlet NSTextField *bookletPageSizeLabel; //子集Label @property (assign) IBOutlet NSTextField *bookletSubsetLable; //sheet开始Label @property (assign) IBOutlet NSTextField *bookletSheetFromLabel; //sheet结束Label @property (assign) IBOutlet NSTextField *bookletSheetPickToLabel; //装订线label @property (assign) IBOutlet NSTextField *bookletBindingLabel; //保留注释Label @property (assign) IBOutlet NSTextField *BookletCommentsFormsLabel; //页间距Label @property (assign) IBOutlet NSTextField *bookletPageGapLabel; //Gap单位 @property (assign) IBOutlet NSTextField *bookletGapUnitLabel; //页码选择Label @property (assign) IBOutlet NSTextField *bookletPageRangeLabel; //Gap 步进器 @property (assign) IBOutlet NSStepper *bookletPagesGapStepper; //取消按钮 @property (assign) IBOutlet NSButton *bookletCacelButton; //生成PDF按钮 @property (assign) IBOutlet NSButton *bookletDoneButton; //打印按钮 @property (assign) IBOutlet NSButton *bookletPrintButton; //Preview PDFView @property (assign) IBOutlet KMBookletPDFView *bookletPDFView; //单位ComboBox @property (assign) IBOutlet NSComboBox *bookletUnitComboBox; //尺寸ComboBox @property (assign) IBOutlet NSComboBox *bookletPageSizeComboBox; //子集ComboBox @property (assign) IBOutlet NSComboBox *bookletSubsetComboBox; //装订线ComboBox @property (assign) IBOutlet NSComboBox *bookletBindingComboBox; //保留注释Combobox @property (assign) IBOutlet NSComboBox *bookletCommentFormsComboBox; //页码选择ComboBox @property (assign) IBOutlet NSComboBox *bookletPageRangeComboBox; //页间距TextField @property (assign) IBOutlet NSTextField *bookletPageGapTextField; //自动旋转Button @property (assign) IBOutlet NSButton *bookletNeedAutoRotatePagesButton; //当前页码TextField @property (assign) IBOutlet NSTextField *previewPaginationTextField; //总页数Label @property (assign) IBOutlet NSTextField *bookletTotalPageLabel; //页面交换Button @property (assign) IBOutlet NSButton *bookletReversePagesButton; //sheet开始TextField @property (assign) IBOutlet NSTextField *bookletSheetStartTextField; //sheet结束TextField @property (assign) IBOutlet NSTextField *bookletSheetEndTextField; //单位数组 @property (nonatomic, retain) NSArray *unitArray; //打印样式尺寸数组 @property (nonatomic, retain) NSArray *bookletSubsetArray; //布局样式数组 @property (nonatomic, retain) NSArray *bookletBindingArray; //页面类型选择数组 @property (nonatomic, retain) NSArray *bookletPageRangeArray; //参数对象 @property (nonatomic, retain) KMBookletParameterModel *parameterModel; //选中页数组 @property (nonatomic, retain) NSMutableArray *selectdPagesArray; //是否保留注释数组 @property (nonatomic, retain) NSArray *bookletCommentsArray; //遮盖View @property (nonatomic, retain) KMBookletMaskView *bookletMaskView; //PDF文档 @property (nonatomic, retain) PDFDocument *pdfDocument; @property (nonatomic,retain) NSString *password; @property (assign) IBOutlet NSTextField *pageWidthTextField; @property (assign) IBOutlet NSTextField *pageHeightTextField; @property (assign) IBOutlet NSTextField *unitTLabel; @end @implementation KMPDFBookletWindowController - (void)dealloc { //移除缓存 NSFileManager *manager = [NSFileManager defaultManager]; if ([manager fileExistsAtPath:kBookletFileSavePath]) { [manager removeItemAtPath:kBookletFileSavePath error:nil]; } } #pragma mark - Lazy load - (NSArray *)unitArray { if (!_unitArray) { _unitArray = [[NSArray alloc] initWithArray:@[@"cm",@"mm",@"in"]]; } return _unitArray; } - (NSArray *)bookletSubsetArray { if (!_bookletSubsetArray ){ _bookletSubsetArray = [[NSArray alloc] initWithArray:@[ NSLocalizedString(@"Both sides", nil), NSLocalizedString(@"Front side only", nil), NSLocalizedString(@"Back side only", nil)]]; } return _bookletSubsetArray; } - (NSArray *)bookletBindingArray { if (!_bookletBindingArray) { _bookletBindingArray = [[NSArray alloc] initWithArray:@[ NSLocalizedString(@"Left", nil), NSLocalizedString(@"Right", nil), NSLocalizedString(@"Left (Tall)", nil),NSLocalizedString(@"Right (Tall)", nil)]]; } return _bookletBindingArray; } - (NSArray *)bookletPageRangeArray { if (!_bookletPageRangeArray) { _bookletPageRangeArray = [[NSArray alloc] initWithArray:@[NSLocalizedString(@"All Pages", nil), NSLocalizedString(@"Odd Pages Only", nil), NSLocalizedString(@"Even Pages Only", nil), NSLocalizedString(@"e.g. 1,3-5,10",nil)]]; } return _bookletPageRangeArray; } - (NSArray *)bookletCommentsArray { if (!_bookletCommentsArray) { _bookletCommentsArray = [[NSArray alloc] initWithArray:@[ NSLocalizedString(@"Document", nil), NSLocalizedString(@"Document and Markups", nil), NSLocalizedString(@"Document and Stamps",nil) ]]; } return _bookletCommentsArray; } - (KMBookletParameterModel *)parameterModel { if (!_parameterModel) { _parameterModel = [[KMBookletParameterModel alloc] init]; } return _parameterModel; } - (NSMutableArray *)selectdPagesArray { if (!_selectdPagesArray) { _selectdPagesArray = [NSMutableArray new]; } return _selectdPagesArray; } #pragma mark - life cycle - (void)windowDidLoad { [super windowDidLoad]; [self localizeLanguage]; [self configuViews]; if (!self.pdfDocument) { return; } if (![self.pdfDocument isLocked] && [self.pdfDocument unlockWithPassword:self.password]) { [self initData]; } else { // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // PasswordWindowController *com = [[PasswordWindowController alloc] initWithWindowNibName:@"PasswordWindowController"]; // com.fileURL = self.pdfDocument.documentURL; // [com beginSheetModalForWindow:self.window completionHandler:^(NSString *password) { // if (password) { // [self.pdfDocument unlockWithPassword:password]; // self.password = password; // [self initData]; // } else { // [self close]; // } // }]; // [com release]; // }); } } - (BOOL)windowShouldClose:(id)sender { [self close]; return YES; } #pragma mark - Private Method //多语言 - (void)localizeLanguage { self.bookletUnitLabel.stringValue = NSLocalizedString(@"Unit:", nil); self.bookletPageSizeLabel.stringValue = NSLocalizedString(@"Page size:", nil); self.bookletSubsetLable.stringValue = NSLocalizedString(@"Booklet Subset:", nil); self.bookletBindingLabel.stringValue = NSLocalizedString(@"Binding:", nil); self.bookletPageGapLabel.stringValue = [NSString stringWithFormat:@"%@:",NSLocalizedString(@"Margin", nil)]; self.bookletNeedAutoRotatePagesButton.title = NSLocalizedString(@"Auto-rotate pages within each sheet", nil); self.bookletReversePagesButton.title = NSLocalizedString(@"Reverse pages", nil); self.bookletPageRangeLabel.stringValue = NSLocalizedString(@"Page Range", nil); self.bookletSheetFromLabel.stringValue = NSLocalizedString(@"Sheet from:", nil); self.bookletSheetPickToLabel.stringValue = NSLocalizedString(@"to:", nil); self.bookletCacelButton.title = NSLocalizedString(@"Cancel", nil); self.bookletDoneButton.title = NSLocalizedString(@"Save as PDF", nil); self.window.title = NSLocalizedString(@"Booklet", nil); self.bookletPrintButton.title = NSLocalizedString(@"Print", nil); self.BookletCommentsFormsLabel.stringValue = NSLocalizedString(@"Comments & Forms:", nil); } //view设置 - (void) configuViews { [self.bookletUnitComboBox addItemsWithObjectValues:self.unitArray]; self.bookletUnitComboBox.editable = NO; self.bookletUnitComboBox.selectable = NO; self.bookletUnitComboBox.tag = KBookletComboBoxTag_Unit; [self.bookletUnitComboBox selectItemAtIndex:1]; self.bookletUnitComboBox.delegate = self; NSArray *paperArray = [KMPageSizeTool paperSize]; NSMutableArray *tPaperArray = [NSMutableArray arrayWithArray:paperArray]; [tPaperArray addObject:NSLocalizedString(@"Custom",nil)]; [self.bookletPageSizeComboBox addItemsWithObjectValues:tPaperArray]; self.bookletPageSizeComboBox.editable = NO; self.bookletPageSizeComboBox.selectable = NO; self.bookletPageSizeComboBox.tag = KBookletComboBoxTag_PageSize; [self.bookletPageSizeComboBox selectItemAtIndex:1]; self.bookletPageSizeComboBox.delegate = self; self.pageWidthTextField.enabled = NO; self.pageHeightTextField.enabled = NO; [self.bookletSubsetComboBox addItemsWithObjectValues:self.bookletSubsetArray]; self.bookletSubsetComboBox.editable = NO; self.bookletSubsetComboBox.selectable = NO; self.bookletSubsetComboBox.tag = KBookletComboBoxTag_Subset; [self.bookletSubsetComboBox selectItemAtIndex:0]; self.bookletSubsetComboBox.delegate = self; [self.bookletBindingComboBox addItemsWithObjectValues:self.bookletBindingArray]; self.bookletBindingComboBox.editable = NO; self.bookletBindingComboBox.selectable = NO; self.bookletBindingComboBox.tag = KBookletComboBoxTag_Binding; [self.bookletBindingComboBox selectItemAtIndex:2]; self.bookletBindingComboBox.delegate = self; [self.bookletCommentFormsComboBox addItemsWithObjectValues:self.bookletCommentsArray]; self.bookletCommentFormsComboBox.editable = NO; self.bookletCommentFormsComboBox.selectable = NO; self.bookletCommentFormsComboBox.tag = KBookletComboBoxTag_Comments; [self.bookletCommentFormsComboBox selectItemAtIndex:1]; self.bookletCommentFormsComboBox.delegate = self; [self.bookletPageRangeComboBox addItemsWithObjectValues:self.bookletPageRangeArray]; [self.bookletPageRangeComboBox.cell setPlaceholderString:NSLocalizedString(@"e.g. 1,3-5,10", nil)]; [self.bookletPageRangeComboBox selectItemAtIndex:0]; [self.bookletPageRangeComboBox setEditable:NO]; self.bookletPageRangeComboBox.tag = KBookletComboBoxTag_pageRange; self.bookletPDFView.autoScales = YES; self.bookletPDFView.displayMode = kPDFDisplaySinglePage; self.bookletPDFView.backgroundColor = [NSColor whiteColor]; self.bookletPDFView.wantsLayer = YES; self.bookletPDFView.layer.borderColor = [NSColor blackColor].CGColor; self.bookletPDFView.layer.borderWidth = 2; self.previewPaginationTextField.delegate = self; self.bookletPageGapTextField.delegate = self; self.bookletSheetStartTextField.delegate = self; self.bookletSheetEndTextField.delegate = self; self.bookletNewPageSizeLabel.stringValue = @"210 x 297 mm"; self.pageWidthTextField.stringValue = [KMPageSizeTool conversionWithUnit:self.bookletUnitComboBox.stringValue value:(210)]?:@""; self.pageHeightTextField.stringValue = [KMPageSizeTool conversionWithUnit:self.bookletUnitComboBox.stringValue value:297]?:@""; } //初始化数据 - (void) initData { //获取操作数组 NSArray *firstPagesArray = [self fetchTargetArray:KBookletPageRangeSelectStyle_AllPages]; KMBookletManager *manager = [KMBookletManager sharedManager]; NSArray *secondPagesArray = [manager regroupBothSidesPrintArrayWithPrimaryArray:firstPagesArray]; self.parameterModel.sheetEndindex = secondPagesArray.count/2; self.parameterModel.pageSize = CGSizeMake(595, 842); self.parameterModel.printStyle = kBLPrintStyle_BothSide; self.parameterModel.layoutStyle = kBLLayoutStyle_leftTall; self.parameterModel.commentForms = kBookletCommentForms_DocumentAndMarkups; self.parameterModel.sheetFromIndex = 0; self.bookletSheetEndTextField.stringValue = [NSString stringWithFormat:@"%ld",self.parameterModel.sheetEndindex]; self.bookletSheetStartTextField.stringValue = @"1"; self.bookletPageGapTextField.stringValue = self.bookletPagesGapStepper.stringValue = @"0"; self.previewPaginationTextField.stringValue = @"1"; self.parameterModel.gapUnit = kBookletPagesGapUnit_MM; [self refreshPreViewNeedRefreshCurrentPage:YES]; } // 产生新的pdf - (void)generateNewPDFAutoOpen:(BOOL)autoOpen { // 如果document不存在或者document的页面个数为0,提示,return if (!self.bookletPDFView.document ||self.pdfDocument.pageCount < 1) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert setMessageText:[NSString stringWithFormat:@"%@",NSLocalizedString(@"Failed to generate booklet document!", nil)]]; [alert runModal]; return; } [self showWaitting]; KMBookletManager *manager = [KMBookletManager sharedManager]; [manager generateNewPDFWithParameterModel:self.parameterModel completionHandler:^(BOOL success, NSString *urlString) { [self hideWaitting]; if (success) { if (autoOpen) { [self close]; [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:urlString] display:YES completionHandler:^(NSDocument * _Nullable document, BOOL documentWasAlreadyOpen, NSError * _Nullable error) { }]; } else { NSWorkspace *space = [NSWorkspace sharedWorkspace]; [space activateFileViewerSelectingURLs:@[[NSURL fileURLWithPath:urlString]]]; } } }]; } //计算当前选择page样式下有多少张page - (NSInteger)bookletCaculateMaxPageCountWithPDFDocument:(PDFDocument *)aDocument printStyle:(kBLPrintStyle)printStyle pageSelectStyle:(KBookletPageRangeSelectStyle) selectStyle { NSArray * arr = [self fetchTargetArray:selectStyle]; KMBookletManager *manager = [KMBookletManager sharedManager]; NSMutableArray *printArr = [manager regroupBothSidesPrintArrayWithPrimaryArray:arr]; if (self.parameterModel.printStyle == kBLPrintStyle_FrontOnly) { [printArr subArrayWithType:KMSubArrayTypeOdd]; } else if (self.parameterModel.printStyle == kBLPrintStyle_BackOnly){ [printArr subArrayWithType:KMSubArrayTypeEven]; } return printArr.count; } //根据选择样式得到数组。全部,奇数,偶数,手动选择界面 - (NSMutableArray *)fetchTargetArray:(KBookletPageRangeSelectStyle)selectStyle { NSMutableArray *arr = [NSMutableArray array]; if (selectStyle == KBookletPageRangeSelectStyle_AllPages) { for (NSUInteger i = 0; i < self.pdfDocument.pageCount; i++) { PDFPage *page = [[self.pdfDocument pageAtIndex:i] copy]; [arr addObject:page]; } } else if (selectStyle == KBookletPageRangeSelectStyle_OddPages) { for (NSUInteger i = 0; i < self.pdfDocument.pageCount; i = i + 2) { PDFPage *page = [[self.pdfDocument pageAtIndex:i] copy]; [arr addObject:page]; } } else if (selectStyle == KBookletPageRangeSelectStyle_EvenPages) { for (NSUInteger i = 1; i < self.pdfDocument.pageCount; i = i + 2) { PDFPage *page = [[self.pdfDocument pageAtIndex:i] copy]; [arr addObject:page]; } } else { //除了以上三种,那么就是手动选择页面 //如果数组个数为0 if (self.selectdPagesArray.count == 0) { return arr; } for (NSUInteger i = 0; i < self.selectdPagesArray.count; i++) { NSNumber *num = self.selectdPagesArray[i]; PDFPage *page = [[self.pdfDocument pageAtIndex:[num integerValue] - 1] copy]; [arr addObject:page]; } } return arr; } //单位转换 - (CGFloat)unitConversion { CGFloat unitScanl = 1.0; if (0 == [self.bookletUnitComboBox indexOfSelectedItem]) { unitScanl = 595.0/21.0; } else if (1 == [self.bookletUnitComboBox indexOfSelectedItem]) { unitScanl = 595.0/210.0; } else { unitScanl = (595.0/21.0) * 2.54; } return unitScanl; } - (NSString *)formatFloat:(float)f { if (fmodf(f, 1)==0) {//如果有一位小数点 return [NSString stringWithFormat:@"%.0f",f]; } else if (fmodf(f*10, 1)==0) {//如果有两位小数点 return [NSString stringWithFormat:@"%.1f",f]; } else { return [NSString stringWithFormat:@"%.2f",f]; } } - (void)showCriticalAlert:(NSString *)alertMsg { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; if (alertMsg) { [alert setInformativeText:alertMsg]; }else{ [alert setMessageText:[NSString stringWithFormat:@"%@ %@",self.pdfDocument.documentURL.path.lastPathComponent,NSLocalizedString(@"Invalid page range or the page number is out of range. Please try again.", nil)]]; } [alert runModal]; } - (void)refreshPreViewNeedRefreshCurrentPage:(BOOL)needRefreshPage { //page数组 NSMutableArray *arr = [self fetchTargetArray:self.bookletPageRangeComboBox.indexOfSelectedItem]; //如果得到的数组为空 if (arr.count == 0) { return; } //将数组信息赋值给模型对象 self.parameterModel.pageArray = arr; //获得将要用来PreView显示的数组 KMBookletManager *manager = [KMBookletManager sharedManager]; NSArray *printArr = [manager fetchDrawPageArraysWithModel:self.parameterModel]; //调整宽高 if (self.parameterModel.layoutStyle == kBLLayoutStyle_left || self.parameterModel.layoutStyle == kBLLayoutStyle_right) { if (self.parameterModel.pageSize.width < self.parameterModel.pageSize.height) { self.parameterModel.pageSize = CGSizeMake(self.parameterModel.pageSize.height, self.parameterModel.pageSize.width); } } else { if (self.parameterModel.pageSize.width > self.parameterModel.pageSize.height) { self.parameterModel.pageSize = CGSizeMake(self.parameterModel.pageSize.height,self.parameterModel.pageSize.width); } } //计算Preview的合适尺寸 [self setPDFViewSizeWithPageSize:self.parameterModel.pageSize]; //生成新的PDFDocument PDFDocument *newDocument = [[PDFDocument alloc] init]; for (NSUInteger i = 0; i < printArr.count; i++) { KMBookletPDFPage *page = [[KMBookletPDFPage alloc] init]; [page setBounds:CGRectMake(0, 0, self.parameterModel.pageSize.width, self.parameterModel.pageSize.height) forBox:kPDFDisplayBoxMediaBox]; page.pages = printArr[i]; page.properties = self.parameterModel; [newDocument insertPage:page atIndex:i]; } //给preView传参 self.bookletPDFView.document = newDocument; //需要刷新到第一页 if (needRefreshPage) { if ([self.bookletPDFView canGoToFirstPage] ) { [self.bookletPDFView goToFirstPage:nil]; self.previewPaginationTextField.stringValue = @"1"; } } //当前页数和总页数修改 self.previewPaginationTextField.stringValue = [NSString stringWithFormat:@"%ld",[newDocument indexForPage:[self.bookletPDFView currentPage]] + 1]; self.bookletTotalPageLabel.stringValue = [NSString stringWithFormat:@" / %ld",printArr.count]; } //计算Preview的合适尺寸 - (void)setPDFViewSizeWithPageSize:(CGSize)size { CGFloat wRatio = KMPDFBookletGenerate_PDFViewMAXWidth/size.width; CGFloat hRatio = KMPDFBookletGenerate_PDFViewMAXHeight/size.height; CGFloat activeRatio = MIN(wRatio, hRatio); self.bookletPDFPreViewWidthConstant.constant = size.width *activeRatio; self.bookletPDFPreViewHeightConstant.constant = size.height *activeRatio; } #pragma mark - Public Method - (id)initWithDocument:(PDFDocument *)pdfDocument { if (self = [super initWithWindowNibName:@"KMPDFBookletWindowController"]) { [self showWaitting]; dispatch_async(dispatch_get_global_queue(0, 0), ^{ if (![[NSFileManager defaultManager] fileExistsAtPath:kPrintFolderPath]) { if (![[NSFileManager defaultManager] createDirectoryAtPath:kPrintFolderPath withIntermediateDirectories:NO attributes:nil error:nil]) { return; } } [pdfDocument writeToURL:[NSURL fileURLWithPath:kBookletFileSavePath]]; self.pdfDocument = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:kBookletFileSavePath]]; dispatch_async(dispatch_get_main_queue(), ^{ if (self.pdfDocument) { [self hideWaitting]; [self initData]; }else{ [self hideWaitting]; [self close]; } }); }); } return self; } - (void) close { if (self.window.isSheet) { // [self dismissSheet:nil]; // [[NSApp mainWindow] endSheet:self.window]; [self.window.sheetParent endSheet:self.window]; } else { [super close]; } } - (id)initWithPDFFilePath:(NSString *)filePath password:(nullable NSString *)password{ if (self = [super initWithWindowNibName:@"KMPDFBookletWindowController"]) { PDFDocument * pdf = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:filePath]]; self.pdfDocument = pdf; self.password = password; } return self; } #pragma mark - button Action //gap步进器 - (IBAction)bookletStepperClicked_PagesGap:(id)sender { NSStepper *gapStepper = sender; CGFloat unitScanl = [self unitConversion]; self.bookletPageGapTextField.stringValue = [NSString stringWithFormat:@"%.2f",self.bookletPagesGapStepper.floatValue]; NSString * formatter = [self formatFloat:gapStepper.floatValue * unitScanl]; self.parameterModel.gap = formatter.floatValue; [self.bookletPDFView setNeedsDisplay:YES]; } //自动旋转 - (IBAction)bookletButtonClicked_AutoRotatePage:(id)sender { NSButton *button = (NSButton *)sender; self.parameterModel.autoRotatePage = button.state; [self refreshPreViewNeedRefreshCurrentPage:NO]; } //生成PDF - (IBAction)bookletButtonClicked_Done:(id)sender { [self.window makeFirstResponder:self]; if (self.bookletPageRangeComboBox.indexOfSelectedItem == 3 || self.bookletPageRangeComboBox.indexOfSelectedItem == -1) { KMFileAttribute *fileAttribute = [[KMFileAttribute alloc] init]; fileAttribute.filePath = [self.pdfDocument.documentURL path]; fileAttribute.bAllPage = NO; fileAttribute.pagesString = self.bookletPageRangeComboBox.stringValue; if (![fileAttribute fetchSelectPages]) { [self showCriticalAlert:nil]; return; } } KMSavePanelAccessoryController *panelAccessoryController = [[KMSavePanelAccessoryController alloc] init]; NSSavePanel* panel = [NSSavePanel savePanel]; NSString *fileName = [NSString stringWithFormat:@"%@_Booklet",self.pdfDocument.documentURL.lastPathComponent.stringByDeletingPathExtension]; [panel setNameFieldStringValue:fileName]; [panel setMessage:NSLocalizedString(@"Save as PDF", nil)]; [panel setAllowedFileTypes:@[@"pdf"]]; [panel setCanCreateDirectories:YES]; panel.accessoryView = panelAccessoryController.view; [panel beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse result) { if (result == NSFileHandlingPanelOKButton) { self.parameterModel.savePath = [[panel URL] path]; [self generateNewPDFAutoOpen:panelAccessoryController.openAutomaticButton.state == NSControlStateValueOn ? YES : NO]; } }]; } //取消 - (IBAction)bookletButtonClicked_Cancel:(id)sender { [self close]; } //前一张page - (IBAction)bookletPreviewButtonClicked_PreviousPage:(id)sender { if ([self.bookletPDFView canGoToPreviousPage]) { [self.bookletPDFView goToPreviousPage:nil]; NSInteger currentIndex = [self.bookletPDFView.document indexForPage:[self.bookletPDFView currentPage]]; self.previewPaginationTextField.stringValue = [NSString stringWithFormat:@"%ld",currentIndex + 1]; } } //下一张page - (IBAction)bookletPrevireButtonClicked_NextPage:(id)sender { if ([self.bookletPDFView canGoToNextPage]) { [self.bookletPDFView goToNextPage:nil]; NSInteger currentIndex = [self.bookletPDFView.document indexForPage:[self.bookletPDFView currentPage]]; self.previewPaginationTextField.stringValue = [NSString stringWithFormat:@"%ld",currentIndex + 1]; } } //反转顺序 - (IBAction)bookletButtonClicked_ReversePages:(id)sender { NSButton *button = sender; self.parameterModel.reversePages = button.state; [self refreshPreViewNeedRefreshCurrentPage:YES]; } //打印PDF - (IBAction)bookletButtonClicked_PrintPDF:(id)sender { [self.window makeFirstResponder:self]; if (self.bookletPageRangeComboBox.indexOfSelectedItem == 3 || self.bookletPageRangeComboBox.indexOfSelectedItem == -1) { KMFileAttribute *fileAttribute = [[KMFileAttribute alloc] init]; fileAttribute.filePath = [self.pdfDocument.documentURL path]; fileAttribute.bAllPage = NO; fileAttribute.pagesString = self.bookletPageRangeComboBox.stringValue; if (![fileAttribute fetchSelectPages]) { [self showCriticalAlert:nil]; [self.window makeFirstResponder:self.bookletPageRangeComboBox]; return; } } if (![[NSFileManager defaultManager] fileExistsAtPath:kBookletPrintFolderPath]) { if (![[NSFileManager defaultManager] createDirectoryAtPath:kBookletPrintFolderPath withIntermediateDirectories:NO attributes:nil error:nil]) { return; } } self.parameterModel.savePath = kBookletPrintFolderPath; if (!self.bookletPDFView.document ||self.pdfDocument.pageCount < 1) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert setMessageText:[NSString stringWithFormat:@"%@",NSLocalizedString(@"Failed to generate booklet document!", nil)]]; [alert runModal]; return; } [self showWaitting]; KMBookletManager *manager = [KMBookletManager sharedManager]; [manager generateNewPDFWithParameterModel:self.parameterModel completionHandler:^(BOOL success, NSString *urlString) { [self hideWaitting]; if (success) { [self bookletStartPrint:urlString]; } }]; } //打印操作 - (void)bookletStartPrint:(NSString *)filePath { PDFDocument * pdf = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:filePath]]; NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo]; NSPrintOperation *printOperation = nil; if ([pdf respondsToSelector:@selector(printOperationForPrintInfo:scalingMode:autoRotate:)]){ printOperation = [pdf printOperationForPrintInfo:printInfo scalingMode:kPDFPrintPageScaleNone autoRotate:YES]; } [printOperation runOperationModalForWindow:self.window delegate:self didRunSelector:nil contextInfo:NULL]; } //pageRange ComboBox点击 -(IBAction)comboBoxClick_PageRanage:(id)sender { NSLog(@"self.bookletPageRangeComboBox indexOfSelectedItem,%ld",[self.bookletPageRangeComboBox indexOfSelectedItem]); self.bookletSheetStartTextField.delegate = nil; self.bookletSheetEndTextField.delegate = nil; if (1 == [self.bookletPageRangeComboBox indexOfSelectedItem] || 2 == [self.bookletPageRangeComboBox indexOfSelectedItem] || 0 == [self.bookletPageRangeComboBox indexOfSelectedItem]) { self.bookletPageRangeComboBox.delegate = nil; [self.window makeFirstResponder:self]; [self.bookletPageRangeComboBox setEditable:NO]; NSInteger selectIndex = [self.bookletPageRangeComboBox indexOfSelectedItem]; NSInteger arrCount = [self bookletCaculateMaxPageCountWithPDFDocument:self.pdfDocument printStyle:self.parameterModel.printStyle pageSelectStyle:selectIndex]; if (self.parameterModel.printStyle == kBLPrintStyle_BothSide) { self.parameterModel.sheetEndindex = arrCount/2; } else { self.parameterModel.sheetEndindex = arrCount; } self.parameterModel.sheetFromIndex = 0; self.bookletSheetEndTextField.stringValue = [NSString stringWithFormat:@"%ld",self.parameterModel.sheetEndindex]; self.bookletSheetStartTextField.stringValue = @"1"; [self refreshPreViewNeedRefreshCurrentPage:YES]; } else if ([self.bookletPageRangeComboBox indexOfSelectedItem] == 3){ [self.bookletPageRangeComboBox setStringValue:@""]; [self.bookletPageRangeComboBox setEditable:YES]; self.bookletPageRangeComboBox.delegate = self; [self.window makeFirstResponder:self.bookletPageRangeComboBox]; } else if([self.bookletPageRangeComboBox indexOfSelectedItem] == -1){ // self.bookletPageRangeComboBox.delegate = nil; } self.bookletSheetStartTextField.delegate = self; self.bookletSheetEndTextField.delegate = self; } #pragma mark - comboBoxDelegate - (void)comboBoxSelectionDidChange:(NSNotification *)notification { NSComboBox *box = notification.object; NSInteger selectIndex = [box indexOfSelectedItem]; switch (box.tag) { case KBookletComboBoxTag_Unit: { NSInteger currentIndex = [self.bookletPageSizeComboBox indexOfSelectedItem]; //当界面初始化的时候设置combobox的选择界面,此时的indexofselectItem为-1;因为这个时候没有选中的按钮 if (currentIndex < 0) { return; } NSString * untiString = @"mm"; if (selectIndex == 1) { self.parameterModel.gapUnit = kBookletPagesGapUnit_MM; self.unitTLabel.stringValue = self.bookletGapUnitLabel.stringValue = NSLocalizedString(@"mm", nil); untiString = @"mm"; } else if (selectIndex == 0){ self.parameterModel.gapUnit = kBookletPagesGapUnit_CM; self.unitTLabel.stringValue = self.bookletGapUnitLabel.stringValue = NSLocalizedString(@"cm", nil); untiString = @"cm"; } else { self.parameterModel.gapUnit = kBookletPagesGapUnit_IN; self.unitTLabel.stringValue = self.bookletGapUnitLabel.stringValue = NSLocalizedString(@"in", nil); untiString = @"in"; } CGFloat unitScanl = [self unitConversion]; self.bookletPageGapTextField.stringValue = self.bookletPagesGapStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(self.parameterModel.gap / unitScanl)]]; self.pageWidthTextField.stringValue = [KMPageSizeTool conversionWithUnit:untiString value:(self.parameterModel.pageSize.width/595 * 210)]?:@""; self.pageHeightTextField.stringValue = [KMPageSizeTool conversionWithUnit:untiString value:(self.parameterModel.pageSize.height/842 * 297)]?:@""; self.bookletNewPageSizeLabel.stringValue = [NSString stringWithFormat:@"%@ x %@ %@",[KMPageSizeTool conversionWithUnit:untiString value:(self.parameterModel.pageSize.width/595 * 210)],[KMPageSizeTool conversionWithUnit:untiString value:(self.parameterModel.pageSize.height/842 * 297)],untiString] ?:@""; } break; case KBookletComboBoxTag_PageSize: { if (selectIndex < 0) { return; } NSString *string = [self.bookletPageSizeComboBox itemObjectValueAtIndex:selectIndex]; if (selectIndex == _bookletPageSizeComboBox.numberOfItems - 1) { self.parameterModel.pageSize = CGSizeMake(595, 842); self.pageWidthTextField.enabled = YES; self.pageHeightTextField.enabled = YES; } else { CGSize tSize = [KMPageSizeTool getPaperSizeWithPaperName:string]; self.parameterModel.pageSize = CGSizeMake(tSize.width * 595.0/210, tSize.height * 842.0/297.0); } CGSize tSize = [KMPageSizeTool getPaperSizeWithPaperName:string]; self.bookletNewPageSizeLabel.stringValue = [NSString stringWithFormat:@"%@ x %@ %@",[KMPageSizeTool conversionWithUnit:self.bookletUnitComboBox.stringValue value:tSize.width],[KMPageSizeTool conversionWithUnit:self.bookletUnitComboBox.stringValue value:tSize.height],self.bookletUnitComboBox.stringValue] ?:@""; self.pageWidthTextField.stringValue = [KMPageSizeTool conversionWithUnit:self.bookletUnitComboBox.stringValue value:(self.parameterModel.pageSize.width/595 * 210)]?:@""; self.pageHeightTextField.stringValue = [KMPageSizeTool conversionWithUnit:self.bookletUnitComboBox.stringValue value:(self.parameterModel.pageSize.height/842 * 297)]?:@""; [self refreshPreViewNeedRefreshCurrentPage:YES]; } break; case KBookletComboBoxTag_Subset: { if (selectIndex == 0) { self.parameterModel.printStyle = kBLPrintStyle_BothSide; } else if (selectIndex == 1){ self.parameterModel.printStyle = kBLPrintStyle_FrontOnly; } else { self.parameterModel.printStyle = kBLPrintStyle_BackOnly; } [self refreshPreViewNeedRefreshCurrentPage:NO]; } break; case KBookletComboBoxTag_Binding:{ if (selectIndex == 0) { self.parameterModel.layoutStyle = kBLLayoutStyle_left; } else if (selectIndex == 1){ self.parameterModel.layoutStyle = kBLLayoutStyle_right; } else if (selectIndex == 2){ self.parameterModel.layoutStyle = kBLLayoutStyle_leftTall; } else if (selectIndex == 3){ self.parameterModel.layoutStyle = kBLLayoutStyle_rightTall; } [self refreshPreViewNeedRefreshCurrentPage:NO]; } break; case KBookletComboBoxTag_Comments: self.parameterModel.commentForms = selectIndex; [self refreshPreViewNeedRefreshCurrentPage:NO]; default: break; } } #pragma mark - NSTextFieldDelegate - (void)controlTextDidChange:(NSNotification *)obj { id object = obj.object; if ([object isEqual:self.bookletSheetStartTextField]) { NSString *string = [self.bookletSheetStartTextField.formatter stringFromNumber:[NSNumber numberWithFloat:[self.bookletSheetStartTextField.stringValue integerValue]]]; self.bookletSheetStartTextField.stringValue = string; } else if ([object isEqual:self.bookletSheetEndTextField]) { NSString *string = [self.bookletSheetEndTextField.formatter stringFromNumber:[NSNumber numberWithFloat:[self.bookletSheetEndTextField.stringValue integerValue]]]; self.bookletSheetEndTextField.stringValue = string; } } - (void)controlTextDidEndEditing:(NSNotification *)obj { NSTextField * object = [obj object]; NSString *string = object.stringValue; if ([object isEqual:self.bookletPageGapTextField]) { //改变了页间距 CGFloat unitScanle = [self unitConversion]; if(string.floatValue <= 0){ self.bookletPageGapTextField.stringValue = @"0"; string = @"0"; } self.parameterModel.gap = [self formatFloat:[string floatValue] * unitScanle].floatValue; self.bookletPagesGapStepper.floatValue = [string floatValue]; [self.bookletPDFView setNeedsDisplay:YES]; } else if ([object isEqual:self.previewPaginationTextField]) { //改变页码 if ([string integerValue] > self.bookletPDFView.document.pageCount) { PDFPage *page = self.bookletPDFView.currentPage; self.previewPaginationTextField.stringValue = [NSString stringWithFormat:@"%ld",[self.bookletPDFView.document indexForPage:page] + 1]; return; } PDFPage *page = [self.bookletPDFView.document pageAtIndex:[string integerValue] - 1]; if (page) { [self.bookletPDFView goToPage:page]; } } else if([object isEqual:self.bookletSheetStartTextField]){ //改变sheet起点 //计算最大页数值,确定输入范围 NSInteger max = [self bookletCaculateMaxPageCountWithPDFDocument:self.pdfDocument printStyle:self.parameterModel.printStyle pageSelectStyle:[self.bookletPageRangeComboBox indexOfSelectedItem]]; //双页、单页区分 if (self.parameterModel.printStyle == kBLPrintStyle_BothSide) { if ([string integerValue] > max/2 || [string integerValue] <= 0) { object.stringValue = @"1"; } else { object.stringValue = [NSString stringWithFormat:@"%ld",[string integerValue]]; } } else { if ([string integerValue] > max || [string integerValue] <= 0) { object.stringValue = @"1"; } else { object.stringValue = [NSString stringWithFormat:@"%ld",[string integerValue]]; } } if ([string integerValue] > self.bookletSheetEndTextField.integerValue) { object.stringValue = @"1"; } self.parameterModel.sheetFromIndex = [object.stringValue integerValue] - 1; [self refreshPreViewNeedRefreshCurrentPage:YES]; } else if ([object isEqual:self.bookletSheetEndTextField]){ //改变sheet终点 //max 得到的是当前选择条件下得到的页数最大值,如果是双面打印那么要除以2才得到sheet的最大值,如果是单面打印,那么就不需要除以2 NSInteger max = [self bookletCaculateMaxPageCountWithPDFDocument:self.pdfDocument printStyle:self.parameterModel.printStyle pageSelectStyle:[self.bookletPageRangeComboBox indexOfSelectedItem]]; //区分 if (self.parameterModel.printStyle == kBLPrintStyle_BothSide) { //如果输入的值大于了所有页数的一半 或者小于等于0,设置为max/2 if ([string integerValue] > max/2 || [string integerValue] <= 0) { object.stringValue = [NSString stringWithFormat:@"%ld",max/2]; } if ([string integerValue] < self.bookletSheetStartTextField.integerValue) { object.stringValue = [NSString stringWithFormat:@"%ld",max/2]; } } else { if ([string integerValue] > max || [string integerValue] <= 0) { object.stringValue = [NSString stringWithFormat:@"%ld",max]; } if ([string integerValue] < self.bookletSheetStartTextField.integerValue) { object.stringValue = [NSString stringWithFormat:@"%ld",max]; } } self.parameterModel.sheetEndindex = [object.stringValue integerValue]; [self refreshPreViewNeedRefreshCurrentPage:YES]; } else if ([object isEqual:self.bookletPageRangeComboBox]){ //这种情况是用户从手动输入用户信息切换到选择全部或奇偶页 if ([self.bookletPageRangeComboBox.stringValue isEqualToString:NSLocalizedString(@"All Pages", nil)] || [self.bookletPageRangeComboBox.stringValue isEqualToString:NSLocalizedString(@"Odd Pages Only", nil)] || [self.bookletPageRangeComboBox.stringValue isEqualToString:NSLocalizedString(@"Even Pages Only", nil)]) { return; } //这种情况是反复点击了手动选择页面,自动保持第一响应者 if ([self.bookletPageRangeComboBox indexOfSelectedItem] == 3 && self.bookletPageRangeComboBox.stringValue.length == 0 ) { // [self showCriticalAlert:nil]; return; } KMFileAttribute *fileAttribute = [[KMFileAttribute alloc] init]; fileAttribute.filePath = [self.pdfDocument.documentURL path]; fileAttribute.bAllPage = NO; fileAttribute.pagesString = self.bookletPageRangeComboBox.stringValue; if (![fileAttribute fetchSelectPages]) { //如果存在条件不满足,那么就要弹框,并且将第一响应者给输入框 [self showCriticalAlert:nil]; [self.window makeFirstResponder:self.bookletPageRangeComboBox]; return; } self.selectdPagesArray = [fileAttribute fetchSelectPages]; NSInteger arrAcount = [self bookletCaculateMaxPageCountWithPDFDocument:self.pdfDocument printStyle:self.parameterModel.printStyle pageSelectStyle:KBookletPageRangeSelectStyle_SelectPages]; self.bookletSheetStartTextField.stringValue = @"1"; if (self.parameterModel.printStyle == kBLPrintStyle_BothSide) { self.bookletSheetEndTextField.stringValue = [NSString stringWithFormat:@"%ld",arrAcount/2]; } else { self.bookletSheetEndTextField.stringValue = [NSString stringWithFormat:@"%ld",arrAcount]; } self.parameterModel.sheetFromIndex = 0; self.parameterModel.sheetEndindex = [self.bookletSheetEndTextField.stringValue integerValue]; [self refreshPreViewNeedRefreshCurrentPage:YES]; [self.window makeFirstResponder:self]; } } #pragma mark - show / hide Waiting - (void)showWaitting { if (!_bookletMaskView) { _bookletMaskView = [[KMBookletMaskView alloc] initWithFrame:NSMakeRect(0, 0, self.window.frame.size.width, self.window.frame.size.height)]; } [self.window.contentView addSubview:self.bookletMaskView]; } - (void)hideWaitting { [self.bookletMaskView removeFromSuperview]; } @end