// // KMPDFMorePagePrintWindowController.m // PDF Reader Pro Edition // // Created by 丁林圭 on 2018/5/17. // #import "PDF_Reader_Pro-Swift.h" #import "KMPDFMultiplePrintWindowController.h" #import "KMPDFMultipleManager.h" //#import "KMBookletMaskView.h" //#import "KMSavePanelAccessoryController.h" //#import "NSWindowController_SKExtensions.h" //#import "KMPageSizeTool.h" #define KMPDFMultiplePrint_PrenViewWidth 315.0 #define KMPDFMultiplePrint_PrenViewHeight 446.0 #define KMPDFMultiplePrint_MaxEdge 80.0 #define KMPDFMultiplePrint_MaxSpace 50.0 #define kPrintFolderPath [[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] #define kKMPDFMultiplePrint_FolderPath [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:@"Multiple"] #define kMultipleFileSavePath [[[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier] stringByAppendingPathComponent:@"Multiple.pdf"] #pragma mark KMMultiplePDFPage @interface KMMultiplePDFPage : PDFPage @property (nonatomic,retain) KMEachPageProperties *properties; @property (nonatomic,retain) NSArray * pages; @end @implementation KMMultiplePDFPage - (void)dealloc { } - (void)drawWithBox:(PDFDisplayBox)box { [super drawWithBox:box]; CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; if (context) { [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]]; } [[KMPDFMultipleManager defaultManager] drawPageToContext:context eachPages:self.pages multipleOption:self.properties]; } - (void)drawWithBox:(PDFDisplayBox)box toContext:(CGContextRef)context { [super drawWithBox:box toContext:context]; if (context) { [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]]; } [[KMPDFMultipleManager defaultManager] drawPageToContext:context eachPages:self.pages multipleOption:self.properties]; } @end #pragma mark - KMMultiplePDFView @interface KMMultiplePDFView : PDFView @end @implementation KMMultiplePDFView @end #pragma mark - KMPDFMultiplePrintWindowController @interface KMPDFMultiplePrintWindowController () <NSComboBoxDelegate> @property (nonatomic,retain) PDFDocument *PDFDocument; @property (nonatomic,retain) NSString *password; @property (nonatomic,retain) PDFDocument *previewDocument; @property (nonatomic,assign) IBOutlet KMMultiplePDFView *PDFView; @property (assign) IBOutlet NSTextField *positionTextFiled; @property (assign) IBOutlet NSTextField *positionLabel; @property (assign,nonatomic) IBOutlet NSTextField *unitLabel; @property (nonatomic,assign) IBOutlet NSComboBox *unitComboBox; @property (nonatomic,assign) IBOutlet NSTextField *splitSizeLabel; @property (nonatomic,assign) IBOutlet NSComboBox *splitSizeComboBox; @property (nonatomic,assign) IBOutlet NSTextField *pagesPerLabel; @property (nonatomic,assign) IBOutlet NSComboBox *selectPerComboBox; @property (nonatomic,assign) IBOutlet NSTextField *byLabel; @property (assign,nonatomic) IBOutlet NSTextField *lineCountText; @property (assign,nonatomic) IBOutlet NSTextField *columnCountText; @property (nonatomic,assign) IBOutlet NSTextField *pagesOrderLabel; @property (nonatomic,assign) IBOutlet NSComboBox *pageOrderComboBox; @property (nonatomic,assign) IBOutlet NSTextField *commentsFormsLabel; @property (nonatomic,assign) IBOutlet NSComboBox *commentsFormsComboBox; @property (assign,nonatomic) IBOutlet NSButton *borderCheckButton; @property (assign,nonatomic) IBOutlet NSButton *autoRotaCheckButton; @property (assign,nonatomic) IBOutlet NSButton *reverseButton; @property (assign,nonatomic) IBOutlet NSTextField *pageEdgeLabel; @property (assign,nonatomic) IBOutlet NSTextField *topLabel; @property (assign,nonatomic) IBOutlet NSTextField *bottomLabel; @property (assign,nonatomic) IBOutlet NSTextField *leftLabel; @property (assign,nonatomic) IBOutlet NSTextField *rightLabel; @property (assign,nonatomic) IBOutlet NSTextField *topDistanceText; @property (assign,nonatomic) IBOutlet NSTextField *bottomDistanceText; @property (assign,nonatomic) IBOutlet NSTextField *leftDistanceText; @property (assign,nonatomic) IBOutlet NSTextField *rightDistanceText; @property (assign,nonatomic) IBOutlet NSStepper *topStepper; @property (assign,nonatomic) IBOutlet NSStepper *bottomStepper; @property (assign,nonatomic) IBOutlet NSStepper *leftStepper; @property (assign,nonatomic) IBOutlet NSStepper *rightStepper; @property (assign,nonatomic) IBOutlet NSTextField *pageSpaceLabel; @property (assign,nonatomic) IBOutlet NSTextField *lineLabel; @property (assign,nonatomic) IBOutlet NSTextField *columnLabel; @property (assign,nonatomic) IBOutlet NSTextField *lineSpaceText; @property (assign,nonatomic) IBOutlet NSTextField *columnSpaceText; @property (assign,nonatomic) IBOutlet NSStepper *lineStepper; @property (assign,nonatomic) IBOutlet NSStepper *columnStepper; @property (assign,nonatomic) IBOutlet NSTextField *orientationLabel; @property (assign,nonatomic) IBOutlet NSButton *portraitButton; @property (assign,nonatomic) IBOutlet NSButton *landscapeButton; @property (nonatomic,assign) IBOutlet NSTextField *pageRangeLabel; @property (nonatomic,assign) IBOutlet NSComboBox *pageRangeComboBox; @property (assign) IBOutlet NSButton *cancelButton; @property (assign) IBOutlet NSButton *saveButton; @property (assign) IBOutlet NSButton *printButton; @property (assign) IBOutlet NSLayoutConstraint *PDFHeight; @property (assign) IBOutlet NSLayoutConstraint *PDFWidth; @property (assign,nonatomic) IBOutlet NSTextField *spaceUnitLabel; @property (assign,nonatomic) IBOutlet NSTextField *edgeUnitLabel; @property (assign,nonatomic) IBOutlet NSTextField *allPageSizeLabel; @property (assign) IBOutlet NSTextField *pageWidthTextField; @property (assign) IBOutlet NSTextField *pageHeightTextField; @property (assign) IBOutlet NSTextField *unitTLabel; @property (nonatomic,retain) KMEachPageProperties *properties; @property (nonatomic,retain) NSArray *pages; @property (nonatomic, retain) KMBookletMaskView *multipleMaskView; @end @implementation KMPDFMultiplePrintWindowController - (void)dealloc { NSFileManager *manager = [NSFileManager defaultManager]; if ([manager fileExistsAtPath:kMultipleFileSavePath]) { [manager removeItemAtPath:kMultipleFileSavePath error:nil]; } } - (id)initWithPDFDocument:(PDFDocument *)pdfDocument { if (self = [super initWithWindowNibName:@"KMPDFMultiplePrintWindowController"]) { [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:kMultipleFileSavePath]]; self.PDFDocument = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:kMultipleFileSavePath]]; dispatch_async(dispatch_get_main_queue(), ^{ [self hideWaitting]; if (self.PDFDocument) { [self changePrenView]; [self reloadPDFView]; [self reloadPDFWithIndex]; } else { [self close]; } }); }); } return self; } - (id)initWithPDFFilePath:(NSString *)filePath password:(nullable NSString *)password{ if (self = [super initWithWindowNibName:@"KMPDFMultiplePrintWindowController"]) { PDFDocument * pdf = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:filePath]]; self.PDFDocument = pdf; self.password = password; } return self; } - (BOOL)windowShouldClose:(id)sender { [self close]; return YES; } - (void)close { if (self.window.isSheet) { // [self dismissSheet:nil]; [self.window.sheetParent endSheet:self.window]; } else { [super close]; } } #pragma mark - NSWindowController - (void)windowDidLoad { [super windowDidLoad]; self.PDFView.wantsLayer = YES; self.PDFView.layer.borderColor = [NSColor blackColor].CGColor; self.PDFView.layer.borderWidth = 2; self.PDFView.backgroundColor = [NSColor whiteColor]; self.PDFView.autoScales = YES; [self localizedString]; if (!self.PDFDocument) { return; } if (![self.PDFDocument isLocked] && [self.PDFDocument unlockWithPassword:self.password]) { [self changePrenView]; [self reloadPDFView]; [self reloadPDFWithIndex]; } 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 changePrenView]; // [self reloadPDFView]; // [self reloadPDFWithIndex]; // } else { // [self close]; // } // }]; // [com release]; }); } } #pragma mark - Private Methods - (void)localizedString { self.window.title = NSLocalizedString(@"Multiple", nil); self.pageRangeLabel.stringValue = NSLocalizedString(@"Page Range", nil); self.orientationLabel.stringValue = NSLocalizedString(@"Orientation:", nil); self.unitLabel.stringValue = NSLocalizedString(@"Unit:", nil); self.splitSizeLabel.stringValue = NSLocalizedString(@"Page size:", nil); self.pagesPerLabel.stringValue = NSLocalizedString(@"Pages per sheet:", nil); self.pagesOrderLabel.stringValue = NSLocalizedString(@"Page order:", nil); self.pageEdgeLabel.stringValue = NSLocalizedString(@"Margin", nil); self.topLabel.stringValue = NSLocalizedString(@"Top", nil); self.bottomLabel.stringValue = NSLocalizedString(@"Bottom", nil); self.leftLabel.stringValue = NSLocalizedString(@"Left", nil); self.rightLabel.stringValue = NSLocalizedString(@"Right", nil); self.pageSpaceLabel.stringValue = NSLocalizedString(@"Spacing", nil); self.lineLabel.stringValue = NSLocalizedString(@"Line spacing", nil); self.columnLabel.stringValue = NSLocalizedString(@"Column spacing", nil); self.byLabel.stringValue = @"X"; self.commentsFormsLabel.stringValue = NSLocalizedString(@"Comments & Forms:",nil); self.edgeUnitLabel.stringValue = self.spaceUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"mm", nil)]; self.unitTLabel.stringValue = NSLocalizedString(@"mm", nil); [self.pageRangeComboBox addItemsWithObjectValues:@[NSLocalizedString(@"All Pages", nil), NSLocalizedString(@"Odd Pages Only", nil), NSLocalizedString(@"Even Pages Only",nil), NSLocalizedString(@"e.g. 1,3-5,10",nil)]]; [self.pageRangeComboBox.cell setPlaceholderString:NSLocalizedString(@"e.g. 1,3-5,10", nil)]; [self.pageRangeComboBox selectItemAtIndex:0]; [self.pageRangeComboBox setEditable:NO]; [self.unitComboBox selectItemAtIndex:1]; NSArray *paperArray = [KMPageSizeTool paperSize]; NSMutableArray *tPaperArray = [NSMutableArray arrayWithArray:paperArray]; [tPaperArray addObject:NSLocalizedString(@"Custom",nil)]; [self.splitSizeComboBox addItemsWithObjectValues:tPaperArray]; [self.splitSizeComboBox selectItemAtIndex:1]; [self.splitSizeComboBox setEditable:NO]; self.pageWidthTextField.enabled = NO; self.pageHeightTextField.enabled = NO; CGFloat unitScanel = [self unitConversion]; self.topDistanceText.stringValue = self.bottomDistanceText.stringValue = self.leftDistanceText.stringValue = self.rightDistanceText.stringValue = self.bottomStepper.stringValue = self.topStepper.stringValue = self.leftStepper.stringValue = self.rightStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:self.properties.edgeInsets.top/unitScanel]]; self.lineStepper.stringValue = self.columnStepper.stringValue = self.lineSpaceText.stringValue = self.columnSpaceText.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:self.properties.rowSpace/unitScanel]]; self.lineStepper.maxValue = self.columnStepper.maxValue = KMPDFMultiplePrint_MaxSpace/unitScanel; self.bottomStepper.maxValue = self.topStepper.maxValue = self.leftStepper.maxValue = self.rightStepper.maxValue = KMPDFMultiplePrint_MaxSpace/unitScanel; self.lineStepper.minValue = self.columnStepper.minValue = 0; self.bottomStepper.minValue = self.topStepper.minValue = self.leftStepper.minValue = self.rightStepper.minValue = 0; [self.selectPerComboBox addItemsWithObjectValues:@[@"2", @"4", @"6", @"9", @"16", NSLocalizedString(@"Custom", nil)]]; [self.selectPerComboBox selectItemAtIndex:5]; [self.selectPerComboBox setEditable:NO]; [self.pageOrderComboBox addItemsWithObjectValues:@[NSLocalizedString(@"Horizontal", nil), NSLocalizedString(@"Horizontal Reversed", nil), NSLocalizedString(@"Vertical",nil), NSLocalizedString(@"Vertical Reversed",nil)]]; [self.pageOrderComboBox selectItemAtIndex:0]; [self.pageOrderComboBox setEditable:NO]; [self.commentsFormsComboBox addItemsWithObjectValues:@[NSLocalizedString(@"Document", nil), NSLocalizedString(@"Document and Markups", nil), NSLocalizedString(@"Document and Stamps",nil) ]]; [self.commentsFormsComboBox selectItemAtIndex:1]; [self.commentsFormsComboBox setEditable:NO]; self.columnCountText.stringValue = @"2"; self.lineCountText.stringValue = @"2"; [self.cancelButton setTitle:NSLocalizedString(@"Cancel", nil)]; [self.saveButton setTitle:NSLocalizedString(@"Save as PDF", nil)]; [self.printButton setTitle:NSLocalizedString(@"Print", nil)]; [self.portraitButton setTitle:NSLocalizedString(@"Portrait",nil)]; [self.landscapeButton setTitle:NSLocalizedString(@"Landscape",nil)]; [self.borderCheckButton setTitle:NSLocalizedString(@"Print page border",nil)]; [self.autoRotaCheckButton setTitle:NSLocalizedString(@"Auto-rotate pages within each sheet",nil)]; [self.reverseButton setTitle:NSLocalizedString(@"Reverse pages",nil)]; } - (KMEachPageProperties *)properties { if (!_properties) { _properties = [[KMEachPageProperties alloc] init]; _properties.rowCount = 2; _properties.columnCout = 2; _properties.pageSize = CGSizeMake(595, 842); _properties.isAutoRotate = NO; _properties.edgeInsets = NSEdgeInsetsMake(20, 20, 20, 20); _properties.rowSpace = 10; _properties.columnSpace = 10; _properties.isHasBorder = NO; _properties.order = kKMPDFMultiplePageOrder_Transverse; _properties.commentsForms = kKMPDFCommentsForms_DocumentMarkups; } return _properties; } - (void)reloadPDFView { CGFloat width =self.properties.pageSize.width; CGFloat height =self.properties.pageSize.height; self.pageWidthTextField.stringValue = [KMPageSizeTool conversionWithUnit:self.unitComboBox.stringValue value:(width/595 * 210)]?:@""; self.pageHeightTextField.stringValue = [KMPageSizeTool conversionWithUnit:self.unitComboBox.stringValue value:(height/842 * 297)]?:@""; if (kKMPDFMultiplePageDirection_Landscape == self.properties.direction) { width =self.properties.pageSize.height; height =self.properties.pageSize.width; } CGFloat previewScanle = MIN(KMPDFMultiplePrint_PrenViewWidth/width, KMPDFMultiplePrint_PrenViewHeight/height); self.PDFWidth.constant = width * previewScanle; self.PDFHeight.constant = height * previewScanle; CGFloat unitScanel = [self unitConversion]; if ([self.unitComboBox indexOfSelectedItem] == 0) { self.allPageSizeLabel.stringValue = [NSString stringWithFormat:@"%@ x %@ %@",[self formatFloat:width/unitScanel],[self formatFloat:height/unitScanel],NSLocalizedString(@"cm", nil)]; } else if ([self.unitComboBox indexOfSelectedItem] == 1) { self.allPageSizeLabel.stringValue = [NSString stringWithFormat:@"%@ x %@ %@",[self formatFloat:width/unitScanel],[self formatFloat:height/unitScanel],NSLocalizedString(@"mm", nil)]; } else { self.allPageSizeLabel.stringValue = [NSString stringWithFormat:@"%@ x %@ %@",[self formatFloat:width/unitScanel],[self formatFloat:height/unitScanel],NSLocalizedString(@"in", nil)]; } [self.PDFView setNeedsDisplay:YES]; } - (void)changePrenView { [self getDrawPages]; NSInteger pagesCount = self.properties.rowCount * self.properties.columnCout; NSInteger allPagesCount = 0; if (self.pages.count % pagesCount == 0) { allPagesCount = self.pages.count / pagesCount; } else { allPagesCount = self.pages.count / pagesCount +1; } if (!_previewDocument) { _previewDocument = [[PDFDocument alloc] init]; } else { _previewDocument = [[PDFDocument alloc] init]; } for (NSUInteger i= 0; i < allPagesCount; i++) { NSMutableArray *pages = [NSMutableArray array]; CGFloat width =self.properties.pageSize.width; CGFloat height =self.properties.pageSize.height; if (kKMPDFMultiplePageDirection_Landscape == _properties.direction) { width =self.properties.pageSize.height; height =self.properties.pageSize.width; } for (NSUInteger j = 0; j < pagesCount; j++) { NSUInteger index = j + i *pagesCount; if (index >= self.pages.count) { break; } [pages addObject:self.pages[index]]; } if (pages.count < 1) { break; } KMMultiplePDFPage * page = [[KMMultiplePDFPage alloc] init]; page.properties = self.properties; page.pages = pages; [page setBounds:CGRectMake(0, 0, width, height) forBox:kPDFDisplayBoxMediaBox]; if (self.properties.isReversePage) { [_previewDocument insertPage:page atIndex:0]; } else { [_previewDocument insertPage:page atIndex:_previewDocument.pageCount]; } } self.PDFView.document = _previewDocument; [self.PDFView setNeedsDisplay:YES]; [self.PDFView goToPage:[_previewDocument pageAtIndex:0]]; [self reloadPDFWithIndex]; } - (void)reloadPDFWithIndex { [self.PDFView.documentView.enclosingScrollView setHasVerticalScroller:NO]; [self.PDFView.documentView.enclosingScrollView setHasHorizontalScroller:NO]; NSInteger pageCount = self.previewDocument.pageCount; NSInteger currentPageIndex = [self.previewDocument indexForPage:self.PDFView.currentPage]; self.positionTextFiled.stringValue = [NSString stringWithFormat:@"%@",@(currentPageIndex+1)]; self.positionLabel.stringValue = [NSString stringWithFormat:NSLocalizedString(@" / %@", nil),@(pageCount)]; } - (void)viewFileAtFinder:(NSString *)fileName { NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSURL *url = [NSURL fileURLWithPath:fileName]; [workspace activateFileViewerSelectingURLs:[NSArray arrayWithObject:url]]; } - (void)getDrawPages { NSMutableArray * pages = [NSMutableArray array]; if (0 == self.pageRangeComboBox.indexOfSelectedItem) { for (NSUInteger i = 0; i<self.PDFDocument.pageCount; i++) { PDFPage * page = [[self.PDFDocument pageAtIndex:i] copy]; [pages addObject:page]; } } else if (1 == self.pageRangeComboBox.indexOfSelectedItem) { for (NSUInteger i = 0; i < self.PDFDocument.pageCount; i ++) { if (i % 2 == 0) { PDFPage * page = [[self.PDFDocument pageAtIndex:i] copy]; [pages addObject:page]; } } } else if (2 == self.pageRangeComboBox.indexOfSelectedItem) { for (NSUInteger i = 0; i < self.PDFDocument.pageCount; i ++) { if (i % 2 != 0) { PDFPage * page = [[self.PDFDocument pageAtIndex:i] copy]; [pages addObject:page]; } } } else { KMFileAttribute *fileAttribute = [[KMFileAttribute alloc] init]; fileAttribute.filePath = [self.PDFDocument.documentURL path]; fileAttribute.bAllPage = NO; fileAttribute.pagesString = _pageRangeComboBox.stringValue; if (![fileAttribute fetchSelectPages]) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert setMessageText:[NSString stringWithFormat:@"%@ %@",[fileAttribute.filePath lastPathComponent],NSLocalizedString(@"Invalid page range or the page number is out of range. Please try again.", nil)]]; [alert runModal]; return; } for (NSNumber * num in [fileAttribute fetchSelectPages]) { PDFPage * page = [[self.PDFDocument pageAtIndex:(num.integerValue - 1)] copy]; [pages addObject:page]; } } if (pages.count < 1 ) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [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]; } else { self.pages = pages; } } - (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]; } } - (CGFloat)unitConversion { CGFloat unitScanl = 1.0; if (0 == [self.unitComboBox indexOfSelectedItem]) { unitScanl = 595.0/21.0; } else if (1 == [self.unitComboBox indexOfSelectedItem]) { unitScanl = 595.0/210.0; } else { unitScanl = (595.0/21.0) * 2.54; } return unitScanl; } #pragma mark - Button Event Action - (IBAction)buttonItemClicked_Previous:(id)sender { [self.PDFView goToPreviousPage:nil]; [self reloadPDFWithIndex]; } - (IBAction)buttonItemClicked_Next:(id)sender { [self.PDFView goToNextPage:nil]; [self reloadPDFWithIndex]; } - (IBAction)buttonItemClick_Cancel:(id)sender { [self close]; } - (IBAction)buttonItemClick_Save:(id)sender { [self.window makeFirstResponder:self.PDFView]; if (self.pages.count < 1) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [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]; return; } NSString * fileName = [NSString stringWithFormat:@"%@_Multipe",self.PDFDocument.documentURL.lastPathComponent.stringByDeletingPathExtension]; KMSavePanelAccessoryController *panelAccessoryController = [[KMSavePanelAccessoryController alloc] init]; NSSavePanel *savePanel = [NSSavePanel savePanel]; savePanel.nameFieldStringValue = fileName; savePanel.allowedFileTypes = @[@"pdf"]; savePanel.accessoryView = panelAccessoryController.view; [savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { if (result) { [self showWaitting]; [[KMPDFMultipleManager defaultManager] savePDFDocumentPath:savePanel.URL.path drawPages:self.pages multipleOption:self.properties completionHandler:^(BOOL isSuccessfully) { [self hideWaitting]; if (panelAccessoryController.openAutomaticButton.state == NSControlStateValueOn) { [self close]; [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:savePanel.URL display:YES completionHandler:^(NSDocument * _Nullable document, BOOL documentWasAlreadyOpen, NSError * _Nullable error) { }]; } else { [self viewFileAtFinder:savePanel.URL.path]; } }]; } }]; } - (IBAction)buttonItemClick_Print:(id)sender { [self.window makeFirstResponder:self.PDFView]; if (self.pages.count < 1) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [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]; return; } NSString * fileName = nil; if (![[NSFileManager defaultManager] fileExistsAtPath:kKMPDFMultiplePrint_FolderPath]) { if (![[NSFileManager defaultManager] createDirectoryAtPath:kKMPDFMultiplePrint_FolderPath withIntermediateDirectories:NO attributes:nil error:nil]) { return; } } fileName = @"Multiple.pdf"; fileName = [kKMPDFMultiplePrint_FolderPath stringByAppendingPathComponent:fileName]; [self showWaitting]; [[KMPDFMultipleManager defaultManager] savePDFDocumentPath:fileName drawPages:self.pages multipleOption:self.properties completionHandler:^(BOOL isSuccessfully) { [self hideWaitting]; if (isSuccessfully) { PDFDocument * pdf = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:fileName]]; 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]; } }]; } - (IBAction)buttonItemClick_PageBorder:(id)sender { if (NSOnState == self.borderCheckButton.state) { self.properties.isHasBorder = YES; } else { self.properties.isHasBorder = NO; } [self reloadPDFView]; } - (IBAction)buttonItemClick_AutoRoate:(id)sender { if (NSOnState == self.autoRotaCheckButton.state) { self.properties.isAutoRotate = YES; } else { self.properties.isAutoRotate = NO; } [self changePrenView]; } - (IBAction)buttonItemClick_ReversePage:(id)sender { if (NSOnState == self.reverseButton.state) { self.properties.isReversePage = YES; } else { self.properties.isReversePage = NO; } [self changePrenView]; } - (IBAction)buttonItemClick_Orientation:(id)sender { if ( NSOnState == self.landscapeButton.state) { self.properties.direction = kKMPDFMultiplePageDirection_Landscape; } else if(NSOnState == self.portraitButton.state){ self.properties.direction = kKMPDFMultiplePageDirection_Portrait; } [self changePrenView]; [self reloadPDFView]; } - (IBAction)stepperItemClick_Distance:(id)sender { CGFloat unitScanl = [self unitConversion]; if ([sender isEqual:_topStepper]) { self.topDistanceText.stringValue = [NSString stringWithFormat:@"%.2f",self.topStepper.floatValue]; NSString * formatter = [self formatFloat:self.topStepper.floatValue * unitScanl]; self.properties.edgeInsets = NSEdgeInsetsMake(formatter.floatValue, _properties.edgeInsets.left, _properties.edgeInsets.bottom, _properties.edgeInsets.right); } else if ([sender isEqual:_bottomStepper]){ self.bottomDistanceText.stringValue = [NSString stringWithFormat:@"%.2f",self.bottomStepper.floatValue]; NSString * formatter = [self formatFloat:_bottomStepper.floatValue * unitScanl]; self.properties.edgeInsets = NSEdgeInsetsMake(_properties.edgeInsets.top, _properties.edgeInsets.left, formatter.floatValue, _properties.edgeInsets.right); } else if ([sender isEqual:_leftStepper]) { self.leftDistanceText.stringValue = [NSString stringWithFormat:@"%.2f",self.leftStepper.floatValue]; NSString * formatter = [self formatFloat:_leftStepper.floatValue * unitScanl]; self.properties.edgeInsets = NSEdgeInsetsMake(_properties.edgeInsets.top, formatter.floatValue, _properties.edgeInsets.bottom, _properties.edgeInsets.right); } else if ([sender isEqual:_rightStepper]) { self.rightDistanceText.stringValue = [NSString stringWithFormat:@"%.2f",self.rightStepper.floatValue]; NSString * formatter = [self formatFloat:_rightStepper.floatValue * unitScanl]; self.properties.edgeInsets = NSEdgeInsetsMake(_properties.edgeInsets.top, _properties.edgeInsets.left, _properties.edgeInsets.bottom, formatter.floatValue); } else if ([sender isEqual:_lineStepper]) { self.lineSpaceText.stringValue = [NSString stringWithFormat:@"%.2f",_lineStepper.floatValue]; NSString * formatter = [self formatFloat:_lineStepper.floatValue * unitScanl]; self.properties.rowSpace = formatter.floatValue; } else if ([sender isEqual:_columnStepper]) { self.columnSpaceText.stringValue = [NSString stringWithFormat:@"%.2f",_columnStepper.floatValue]; NSString * formatter = [self formatFloat:_columnStepper.floatValue * unitScanl]; self.properties.columnSpace = formatter.floatValue; } [self reloadPDFView]; } - (IBAction)comboBoxItemClick_PageRange:(id)sender { if (0 == [self.pageRangeComboBox indexOfSelectedItem] || 1 == [self.pageRangeComboBox indexOfSelectedItem] || 2 == [self.pageRangeComboBox indexOfSelectedItem]) { self.pageRangeComboBox.delegate = nil; [self.window makeFirstResponder:self]; [self.pageRangeComboBox setEditable:NO]; [self changePrenView]; } else if (3 == [self.pageRangeComboBox indexOfSelectedItem]) { self.pageRangeComboBox.delegate = self; [self.pageRangeComboBox setStringValue:@""]; [self.pageRangeComboBox setEditable:YES]; [self.window makeFirstResponder:self.pageRangeComboBox]; } } - (IBAction)comboBoxItemClick_PageOrder:(id)sender { if (0 == [self.pageOrderComboBox indexOfSelectedItem]) { self.properties.order = kKMPDFMultiplePageOrder_Transverse; } else if(1 == [self.pageOrderComboBox indexOfSelectedItem]){ self.properties.order = kKMPDFMultiplePageOrder_TransverseAntitone; } else if(2 == [self.pageOrderComboBox indexOfSelectedItem]){ self.properties.order = kKMPDFMultiplePageOrder_Longitudinal; } else if(3 == [self.pageOrderComboBox indexOfSelectedItem]){ self.properties.order = kKMPDFMultiplePageOrder_LongitudinalAntitone; } [self reloadPDFView]; } - (IBAction)comboBoxItemClick_PagesPer:(id)sender { if ( 5!= [self.selectPerComboBox indexOfSelectedItem]) { self.columnCountText.editable = NO; self.lineCountText.editable = NO; if (0 == [self.selectPerComboBox indexOfSelectedItem]) { self.properties.columnCout = 1; self.properties.rowCount = 2; } else if(1 == [self.selectPerComboBox indexOfSelectedItem]){ self.properties.columnCout = 2; self.properties.rowCount = 2; } else if(2 == [self.selectPerComboBox indexOfSelectedItem]){ self.properties.columnCout = 2; self.properties.rowCount = 3; } else if(3 == [self.selectPerComboBox indexOfSelectedItem]){ self.properties.columnCout = 3; self.properties.rowCount = 3; } else if(4 == [self.selectPerComboBox indexOfSelectedItem]){ self.properties.columnCout = 4; self.properties.rowCount = 4; } self.columnCountText.stringValue = [NSString stringWithFormat:@"%ld",self.properties.columnCout]; self.lineCountText.stringValue = [NSString stringWithFormat:@"%ld",self.properties.rowCount]; self.columnCountText.selectable = NO; self.lineCountText.selectable = NO; } else { self.properties.columnCout = 2; self.properties.rowCount = 2; self.columnCountText.stringValue = @"2"; self.lineCountText.stringValue = @"2"; self.columnCountText.editable = YES; self.lineCountText.editable = YES; self.columnCountText.selectable = YES; self.lineCountText.selectable = YES; } [self changePrenView]; } - (IBAction)comboBoxItemClick_SplitSize:(id)sender { self.pageWidthTextField.enabled = NO; self.pageHeightTextField.enabled = NO; if ([_splitSizeComboBox indexOfSelectedItem] == _splitSizeComboBox.numberOfItems - 1) { self.properties.pageSize = CGSizeMake(595, 842); self.pageWidthTextField.enabled = YES; self.pageHeightTextField.enabled = YES; } else { CGSize tSize = [KMPageSizeTool getPaperSizeWithPaperName:self.splitSizeComboBox.stringValue]; self.properties.pageSize = CGSizeMake(tSize.width * 595.0/210, tSize.height * 842.0/297.0); } CGFloat unitScanl = [self unitConversion]; self.topDistanceText.stringValue = self.bottomDistanceText.stringValue = self.leftDistanceText.stringValue = self.rightDistanceText.stringValue = self.bottomStepper.stringValue = self.topStepper.stringValue = self.leftStepper.stringValue = self.rightStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:20/unitScanl]]; self.lineStepper.stringValue = self.columnStepper.stringValue = self.lineSpaceText.stringValue = self.columnSpaceText.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:10/unitScanl]]; _properties.edgeInsets = NSEdgeInsetsMake(20, 20, 20, 20); _properties.rowSpace = _properties.columnSpace = 10; [self changePrenView]; [self reloadPDFView]; } - (IBAction)comboBoxItemClick_Unit:(id)sender { if ([self.unitComboBox indexOfSelectedItem] == 1) { self.spaceUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"mm", nil)]; self.edgeUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"mm", nil)]; self.unitTLabel.stringValue = NSLocalizedString(@"mm", nil); } else if([self.unitComboBox indexOfSelectedItem] == 0){ self.spaceUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"cm", nil)]; self.edgeUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"cm", nil)]; self.unitTLabel.stringValue = NSLocalizedString(@"cm", nil); } else { self.spaceUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"in", nil)]; self.edgeUnitLabel.stringValue = [NSString stringWithFormat:@"(%@)",NSLocalizedString(@"in", nil)]; self.unitTLabel.stringValue = NSLocalizedString(@"in", nil); } CGFloat unitScanle = [self unitConversion]; self.topDistanceText.stringValue = self.topStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(_properties.edgeInsets.top / unitScanle)]]; self.bottomDistanceText.stringValue = self.bottomStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(_properties.edgeInsets.bottom / unitScanle)]]; self.leftDistanceText.stringValue = self.leftStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(_properties.edgeInsets.left / unitScanle)]]; self.rightDistanceText.stringValue = self.rightStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(_properties.edgeInsets.right / unitScanle)]]; self.lineSpaceText.stringValue = self.lineStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(_properties.rowSpace / unitScanle)]]; self.columnSpaceText.stringValue = self.columnStepper.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:(_properties.columnSpace / unitScanle)]]; self.lineStepper.maxValue = self.columnStepper.maxValue = KMPDFMultiplePrint_MaxSpace/unitScanle; self.bottomStepper.maxValue = self.topStepper.maxValue = self.leftStepper.maxValue = self.rightStepper.maxValue = KMPDFMultiplePrint_MaxSpace/unitScanle; [self reloadPDFView]; } - (IBAction)comboBoxItemClick_CommentsForms:(id)sender { if (0 == [self.commentsFormsComboBox indexOfSelectedItem]) { self.properties.commentsForms = kKMPDFCommentsForms_Documents; } else if(1 == [self.commentsFormsComboBox indexOfSelectedItem]){ self.properties.commentsForms = kKMPDFCommentsForms_DocumentMarkups; } else if(2 == [self.commentsFormsComboBox indexOfSelectedItem]){ self.properties.commentsForms = kKMPDFCommentsForms_DocumentStamps; } [self reloadPDFView]; } #pragma mark - NSTextFieldDelegate Methods - (void)controlTextDidEndEditing:(NSNotification *)notification { NSTextField *textField = (NSTextField *)[notification object]; if (textField == self.positionTextFiled) { NSInteger index = [[self.positionTextFiled stringValue] integerValue]; NSInteger pageCount = self.previewDocument.pageCount; NSInteger currentPageIndex = [self.previewDocument indexForPage:self.PDFView.currentPage]; if (index > 0 && index <= pageCount) { [self.PDFView goToPage:[self.previewDocument pageAtIndex:index-1]]; [self reloadPDFView]; } else { self.positionTextFiled.stringValue = [NSString stringWithFormat:@"%@",@(currentPageIndex+1)]; } } else if (textField == self.columnCountText) { if ( 5!= [self.selectPerComboBox indexOfSelectedItem]) { return; } if (self.columnCountText.integerValue < 1) { self.columnCountText.stringValue = @"1"; } else if (self.columnCountText.integerValue > 99){ self.columnCountText.stringValue = @"99"; } self.properties.columnCout = self.columnCountText.integerValue; [self changePrenView]; } else if (textField == self.lineCountText) { if ( 5!= [self.selectPerComboBox indexOfSelectedItem]) { return; } if (self.lineCountText.integerValue < 1) { self.lineCountText.stringValue = @"1"; } else if (self.lineCountText.integerValue > 99){ self.lineCountText.stringValue = @"99"; } self.properties.rowCount = self.lineCountText.integerValue; [self changePrenView]; } else if (textField == self.pageRangeComboBox) { [self changePrenView]; } else if (_topDistanceText == textField) { CGFloat unitScanle = [self unitConversion]; NSString * unitMax = [self formatFloat:textField.floatValue * unitScanle]; if (unitMax.floatValue > KMPDFMultiplePrint_MaxEdge) { unitMax = [NSString stringWithFormat:@"%f",KMPDFMultiplePrint_MaxEdge]; textField.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:KMPDFMultiplePrint_MaxEdge/unitScanle]]; } else if(unitMax.floatValue <= 0) { unitMax = 0; textField.stringValue = @"0"; } _topStepper.stringValue = textField.stringValue; self.properties.edgeInsets = NSEdgeInsetsMake(unitMax.floatValue, _properties.edgeInsets.left, _properties.edgeInsets.bottom, _properties.edgeInsets.right); [self reloadPDFView]; } else if (_bottomDistanceText == textField) { CGFloat unitScanle = [self unitConversion]; NSString * unitMax = [self formatFloat:textField.floatValue * unitScanle]; if (unitMax.floatValue > KMPDFMultiplePrint_MaxEdge) { unitMax = [NSString stringWithFormat:@"%f",KMPDFMultiplePrint_MaxEdge]; textField.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:KMPDFMultiplePrint_MaxEdge/unitScanle]]; } else if(unitMax.floatValue <= 0) { unitMax = 0; textField.stringValue = @"0"; } _bottomStepper.stringValue = textField.stringValue; self.properties.edgeInsets = NSEdgeInsetsMake(_properties.edgeInsets.top, _properties.edgeInsets.left, unitMax.floatValue , _properties.edgeInsets.right); [self reloadPDFView]; } else if (_leftDistanceText == textField) { CGFloat unitScanle = [self unitConversion]; NSString * unitMax = [self formatFloat:textField.floatValue * unitScanle]; if (unitMax.floatValue > KMPDFMultiplePrint_MaxEdge) { unitMax = [NSString stringWithFormat:@"%f",KMPDFMultiplePrint_MaxEdge]; textField.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:KMPDFMultiplePrint_MaxEdge/unitScanle]]; } else if(unitMax.floatValue <= 0) { unitMax = 0; textField.stringValue = @"0"; } _leftStepper.stringValue = textField.stringValue; self.properties.edgeInsets = NSEdgeInsetsMake(_properties.edgeInsets.top,unitMax.floatValue , _properties.edgeInsets.bottom, _properties.edgeInsets.right); [self reloadPDFView]; } else if (_rightDistanceText == textField) { CGFloat unitScanle = [self unitConversion]; NSString * unitMax = [self formatFloat:textField.floatValue * unitScanle]; if (unitMax.floatValue > KMPDFMultiplePrint_MaxEdge) { unitMax = [NSString stringWithFormat:@"%f",KMPDFMultiplePrint_MaxEdge]; textField.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:KMPDFMultiplePrint_MaxEdge/unitScanle]]; } else if(unitMax.floatValue <= 0) { unitMax = 0; textField.stringValue = @"0"; } _rightStepper.stringValue = textField.stringValue; self.properties.edgeInsets = NSEdgeInsetsMake(_properties.edgeInsets.top, _properties.edgeInsets.left, _properties.edgeInsets.bottom, unitMax.floatValue); [self reloadPDFView]; } else if (_lineSpaceText == textField) { CGFloat unitScanle = [self unitConversion]; NSString * unitMax = [self formatFloat:textField.floatValue * unitScanle]; if (unitMax.floatValue > KMPDFMultiplePrint_MaxSpace) { unitMax = [NSString stringWithFormat:@"%f",KMPDFMultiplePrint_MaxSpace]; textField.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:KMPDFMultiplePrint_MaxSpace/unitScanle]]; } else if(unitMax.floatValue <= 0) { unitMax = 0; textField.stringValue = @"0"; } _lineStepper.stringValue = textField.stringValue; self.properties.rowSpace = unitMax.floatValue; [self reloadPDFView]; } else if (_columnSpaceText == textField) { CGFloat unitScanle = [self unitConversion]; NSString * unitMax = [self formatFloat:textField.floatValue * unitScanle]; if (unitMax.floatValue > KMPDFMultiplePrint_MaxSpace) { unitMax = [NSString stringWithFormat:@"%f",KMPDFMultiplePrint_MaxSpace]; textField.stringValue = [NSString stringWithFormat:@"%@",[self formatFloat:KMPDFMultiplePrint_MaxSpace/unitScanle]]; } else if(unitMax.floatValue <= 0) { unitMax = 0; textField.stringValue = @"0"; } _columnStepper.stringValue = textField.stringValue; self.properties.columnSpace = unitMax.floatValue; [self reloadPDFView]; } else if (textField == self.pageWidthTextField) { CGFloat over = [[textField stringValue] floatValue]; if ([self.unitComboBox indexOfSelectedItem] == 0) { over *= 595.0/21; } else if([self.unitComboBox indexOfSelectedItem] == 3){ over *= 595.0/210 * 25.4; } else { over *= 595.0/210; } CGSize size = CGSizeZero; size = self.properties.pageSize; size.width = over; self.properties.pageSize = size; [self reloadPDFView]; } else if (textField == self.pageHeightTextField) { CGFloat over = [[textField stringValue] floatValue]; if ([self.unitComboBox indexOfSelectedItem] == 0) { over *= 842.0/29.7; } else if([self.unitComboBox indexOfSelectedItem] == 3){ over *= 842.0/297 * 25.4; } else { over *= 842.0/297; } CGSize size = CGSizeZero; size = self.properties.pageSize; size.height = over; self.properties.pageSize = size; [self reloadPDFView]; } } - (void)controlTextDidChange:(NSNotification *)notification { NSTextField *textField = (NSTextField *)[notification object]; if (textField == self.positionTextFiled || textField == self.columnCountText || textField == self.lineCountText) { NSString *string = [textField.formatter stringFromNumber:[NSNumber numberWithFloat:[textField.stringValue integerValue]]]; textField.stringValue = string; } } #pragma mark - show / hide Waiting - (void)showWaitting { if (!_multipleMaskView) { _multipleMaskView = [[KMBookletMaskView alloc] initWithFrame:NSMakeRect(0, 0, self.window.frame.size.width, self.window.frame.size.height)]; } [self.window.contentView addSubview:self.multipleMaskView]; } - (void)hideWaitting { [self.multipleMaskView removeFromSuperview]; } @end