// // KMPDFInsertWindowController.swift // PDF Master // // Created by tangchao on 2023/12/7. // import Cocoa //enum KMPDFEditInsertType: Int { // case management = 1 // case pageEdit //} class KMPDFInsertWindowController: NSWindowController { /* @interface KMPDFInsertPageWindow :NSWindowController - (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(PDFDocument *pdfDocument,NSString* password ,NSMutableArray* pages,NSInteger indexPage))handler; */ @IBOutlet weak var progress: NSProgressIndicator! @IBOutlet weak var pageCountLabel: NSTextField! @IBOutlet weak var insertTypeLabel: NSTextField! @IBOutlet weak var locationLabel: NSTextField! @IBOutlet weak var pageRangeLabel: NSTextField! @IBOutlet weak var pageLabel: NSTextField! @IBOutlet weak var pagesText: NSTextField! @IBOutlet weak var outputFolderText: NSTextField! @IBOutlet weak var blankButton: NSButton! @IBOutlet weak var outputFolderButton: NSButton! @IBOutlet weak var locationFirstButton: NSButton! @IBOutlet weak var locationLastButton: NSButton! @IBOutlet weak var rangeButton: NSButton! @IBOutlet weak var insertButton: NSButton! @IBOutlet weak var cancelButton: NSButton! @IBOutlet weak var selectedPathButton: NSButton! @IBOutlet weak var pageRangeBox: NSComboBox! @IBOutlet weak var byPageStepper: NSStepper! @IBOutlet weak var fromBackView: NSView! @IBOutlet weak var insertBox: NSBox! @IBOutlet weak var whereInsertBox: NSBox! @IBOutlet weak var insertLabel: NSTextField! @IBOutlet weak var whereInsertLabel: NSTextField! @IBOutlet weak var locationRangePopUpButton: NSPopUpButton! var insertLocation: Int = 0 var currentPage: Int = 0 private var _pdfDocument: CPDFDocument? private var _type: KMPDFEditInsertType = .management private var _insertPages: [CPDFPage] = [] private var _fromFilePath: URL? private var _password: String? private var _fromFilePassword: String? private var _insertPageIndex = 0 var callback: KMCommonClickBlock? convenience init(document: CPDFDocument) { self.init(windowNibName: "KMPDFInsertWindowController") self._type = .pageEdit self._pdfDocument = document } convenience init(fileURL documentPath: URL) { self.init(windowNibName: "KMPDFInsertWindowController") self._type = .management self.currentPage = 1 self._pdfDocument = CPDFDocument(url: documentPath) } override func windowDidLoad() { super.windowDidLoad() self._insertPages = [] self.fromBackView.wantsLayer = true self.fromBackView.layer?.borderWidth = 0.8 self.fromBackView.layer?.cornerRadius = 2.0 var viewColor = NSColor.white var viewborderColor = NSColor(red: 195.0/255.0, green: 195.0/255.0, blue: 195.0/255.0, alpha: 1) var textColor = NSColor(red: 51.0/255.0, green: 51.0/255.0, blue: 51.0/255.0, alpha: 1) if KMAppearance.isDarkMode() { viewColor = NSColor(red: 101.0/255.0, green: 101.0/255.0, blue: 101.0/255.0, alpha: 1) viewborderColor = .clear textColor = .white } self.fromBackView.layer?.backgroundColor = viewColor.cgColor self.fromBackView.layer?.borderColor = viewborderColor.cgColor self.outputFolderText.textColor = textColor self.selectedPathButton.title = KMLocalizedString("Choose...", nil) self.insertLabel.stringValue = KMLocalizedString("Insert",nil) self.whereInsertLabel.stringValue = KMLocalizedString("Where to insert?",nil) self.pageRangeLabel.stringValue = KMLocalizedString("Page Range:", nil) self.pageLabel.stringValue = KMLocalizedString("Page", nil) self.selectedPathButton.isEnabled = false self.progress.isHidden = true self.pageRangeBox.isEditable = false self.outputFolderText.isEditable = false self.pagesText.isEditable = false self.byPageStepper.isEnabled = false self.pageRangeLabel.isHidden = true self.pageRangeBox.isHidden = true self.blankButton.title = KMLocalizedString("Blank Page", nil) self.locationFirstButton.title = KMLocalizedString("First", nil) self.locationLastButton.title = KMLocalizedString("Last", nil) self.outputFolderButton.title = KMLocalizedString("From PDF", nil) self.cancelButton.title = KMLocalizedString("Cancel", nil) self.insertButton.title = KMLocalizedString("Insert", nil) self.pagesText.formatter = TextFieldFormatter() self.pagesText.delegate = self self.pageRangeBox.addItem(withObjectValue: KMLocalizedString("All Pages", nil)) self.pageRangeBox.addItem(withObjectValue: KMLocalizedString("Odd Pages Only", nil)) self.pageRangeBox.addItem(withObjectValue: KMLocalizedString("Even Pages Only", nil)) self.pageRangeBox.addItem(withObjectValue: KMLocalizedString("e.g. 1,3-5,10", nil)) (self.pageRangeBox.cell as? NSComboBoxCell)?.placeholderString = KMLocalizedString("e.g. 1,3-5,10", nil) self.pageRangeBox.selectItem(at: 0) let menu = NSMenu() _ = menu.addItem(title: KMLocalizedString("After", nil), action: #selector(after_Action), target: self) _ = menu.addItem(title: KMLocalizedString("Before", nil), action: #selector(before_Action), target: self) self.locationRangePopUpButton.menu = menu self.outputFolderText.placeholderString = KMLocalizedString("Select a File", nil) self.pageRangeBox.isEnabled = false self.locationRangePopUpButton.isEnabled = false if let data = self._pdfDocument?.isLocked, data { // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // PasswordWindowController *passwordVC = [[PasswordWindowController alloc] initWithWindowNibName:@"PasswordWindowController"]; // passwordVC.fileURL = [self.pdfDocument documentURL]; // [passwordVC beginSheetModalForWindow:self.window completionHandler:^(NSString *password) { // if (password) { // [_pdfDocument unlockWithPassword:password]; // self.password = password; // // _pageCountLabel.stringValue = [NSString stringWithFormat:@"/%ld",_pdfDocument.pageCount]; // _byPageStepper.minValue = 1.0; // _byPageStepper.maxValue = _pdfDocument.pageCount; // // } // }]; // [passwordVC release]; // }); } else { self.byPageStepper.minValue = 1.0 self.byPageStepper.maxValue = Double(self._pdfDocument?.pageCount ?? 0) self.pageCountLabel.stringValue = String(format: "/%ld", self._pdfDocument?.pageCount ?? 0) } if (self.insertLocation == 2) { self.locationLastButton.state = .on } else if (self.insertLocation == 3) { self.rangeButton.state = .on self.locationRangePopUpButton.isEnabled = true self.pagesText.isEditable = true self.byPageStepper.isEnabled = true } else { self.locationFirstButton.state = .on } self.pagesText.stringValue = String(format: "%ld", self.currentPage) self.byPageStepper.integerValue = Int(self.pagesText.stringValue) ?? 0 } /* #pragma mark Private methor - (void)viewFileAtFinder:(NSString *)filePath { NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSURL *url = [NSURL fileURLWithPath:filePath]; [workspace activateFileViewerSelectingURLs:[NSArray arrayWithObject:url]]; } #pragma mark Show Methods - (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { if (contextInfo != NULL) { void (^handler)(PDFDocument *pdfDocument ,NSString* password,NSMutableArray* pages,NSInteger indexPage) = (void(^)(PDFDocument *pdfDocument,NSString* password,NSMutableArray* pages,NSInteger indexPage))contextInfo; handler(self.pdfDocument,self.password,self.insertPages,self.insertPageIndex); Block_release(handler); } } - (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(PDFDocument *pdfDocument,NSString* password ,NSMutableArray* pages,NSInteger indexPage))handler; { [self retain]; // make sure we stay around long enough [NSApp beginSheet:[self window] modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) contextInfo:handler ? Block_copy(handler) : NULL]; } - (IBAction)buttonItemClicked_Insert:(id)sender { if ([self.pdfDocument isLocked]) { [self.pdfDocument unlockWithPassword:_password]; } PDFDocument *fromDocument = [[PDFDocument alloc] initWithURL:_fromFilePath]; if ([fromDocument isLocked]) { [fromDocument unlockWithPassword:_fromFilePassword]; } [_progress setHidden:NO]; [_cancelButton setEnabled:NO]; [_insertButton setEnabled:NO]; [_progress startAnimation:nil]; NSMutableArray *pages = [NSMutableArray array]; if (_blankButton.state == 1) { PDFPage *page = [[PDFPage alloc] init]; [page setBounds:NSMakeRect(0, 0, 588, 832) forBox:kPDFDisplayBoxCropBox]; [pages addObject:page]; [page release]; } else { if ([_outputFolderText.stringValue isEqualToString:@""] || _outputFolderText.stringValue.length < 1) { NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert setMessageText:[NSString stringWithFormat:NSLocalizedString(@"Select a File", nil)]]; [alert runModal]; [alert release]; [_progress setHidden:YES]; [_cancelButton setEnabled:YES]; [_insertButton setEnabled:YES]; [_progress stopAnimation:nil]; return; } KMFileAttribute *fileAttribute = [[KMFileAttribute alloc] init]; fileAttribute.filePath = _outputFolderText.stringValue; if ((0 == [_pageRangeBox indexOfSelectedItem])) { fileAttribute.bAllPage = YES; } else if(1 == [_pageRangeBox indexOfSelectedItem]){ fileAttribute.bAllPage = NO; PDFDocument *tDocument = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:fileAttribute.filePath]]; NSString *tPagesString = @""; for (NSUInteger i = 0; i < tDocument.pageCount; i++) { if (i%2 == 0) { if (tPagesString.length == 0) { tPagesString = [tPagesString stringByAppendingString:[NSString stringWithFormat:@"%ld",i +1]]; }else{ tPagesString = [tPagesString stringByAppendingString:[NSString stringWithFormat:@",%ld",i +1]]; } } } fileAttribute.pagesString = tPagesString; [tDocument release]; } else if (2 == [_pageRangeBox indexOfSelectedItem]){ fileAttribute.bAllPage = NO; PDFDocument *tDocument = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:fileAttribute.filePath]]; NSString *tPagesString = @""; for (NSUInteger i = 0; i < tDocument.pageCount; i++) { if (i%2) { if (tPagesString.length == 0) { tPagesString = [tPagesString stringByAppendingString:[NSString stringWithFormat:@"%ld",i +1]]; }else{ tPagesString = [tPagesString stringByAppendingString:[NSString stringWithFormat:@",%ld",i +1]]; } } } fileAttribute.pagesString = tPagesString; [tDocument release]; } else { fileAttribute.bAllPage = NO; fileAttribute.pagesString = _pageRangeBox.stringValue; } if (!fileAttribute.selectPages) { 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]; [alert release]; [_progress setHidden:YES]; [_cancelButton setEnabled:YES]; [_insertButton setEnabled:YES]; [_progress stopAnimation:nil]; [fileAttribute release]; return; } else { PDFDocument *insertPDF = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:_outputFolderText.stringValue]]; for(NSNumber *number in fileAttribute.selectPages){ PDFPage * page = [[insertPDF pageAtIndex:([number intValue] -1)] copy]; [pages addObject:page]; } [fileAttribute release]; [insertPDF release]; } } NSInteger index = 0; if (_locationFirstButton.state == 1) { index = 0; } else if (_locationLastButton.state == 1) { index = _pdfDocument.pageCount; } else { index = _pagesText.stringValue.integerValue; if ((1 == [_locationRangePopUpButton indexOfSelectedItem])) { index = index - 1; } } [self.insertPages addObjectsFromArray:pages]; self.insertPageIndex = index; [_progress setHidden:YES]; [_cancelButton setEnabled:YES]; [_insertButton setEnabled:YES]; [_progress stopAnimation:nil]; [NSApp endSheet:[self window] returnCode:[sender tag]]; [[self window] orderOut:self]; [self release]; } */ @IBAction func byPageStepperAction(_ sender: AnyObject?) { self.pagesText.stringValue = "\(self.byPageStepper.integerValue)" } @IBAction func buttonItemClicked_InsertType(_ sender: AnyObject?) { if self.blankButton.isEqual(to: sender) { self.selectedPathButton.isEnabled = false self.pageRangeBox.isEnabled = false self.pageRangeLabel.isHidden = true self.pageRangeBox.isHidden = true } else { self.pageRangeBox.isEnabled = true self.selectedPathButton.isEnabled = true self.pageRangeLabel.isHidden = false self.pageRangeBox.isHidden = false } } @IBAction func buttonItemClicked_Location(_ sender: AnyObject?) { if self.rangeButton.isEqual(to: sender) { self.pagesText.isEditable = true self.locationRangePopUpButton.isEnabled = true self.byPageStepper.isEnabled = true } else { self.pagesText.isEditable = false self.locationRangePopUpButton.isEnabled = false self.byPageStepper.isEnabled = false } } @IBAction func buttonItemClicked_Cancel(_ sender: AnyObject?) { self._pdfDocument = nil guard let block = self.callback else { return } block(0) } @IBAction func buttonItemClicked_OutputFolder(_ sender: AnyObject?) { let openPanel = NSOpenPanel() openPanel.allowedFileTypes = ["pdf"] openPanel.beginSheetModal(for: self.window!) { result in if (result == .OK) { for fileURL in openPanel.urls { guard let pdfDoc = CPDFDocument(url: fileURL) else { continue } if (pdfDoc.isLocked) { // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // PasswordWindowController *com = [[PasswordWindowController alloc] initWithWindowNibName:@"PasswordWindowController"]; // com.fileURL = fileURL; // // [com beginSheetModalForWindow:self.window completionHandler:^(NSString *password) { // if (password) { // self.password = password; // self.fromFilePath = fileURL; // _outputFolderText.stringValue = [_fromFilePath path]; // // [_pageRangeBox selectItemAtIndex:0]; // [self.window makeFirstResponder:self]; // [_pageRangeBox setEditable:NO]; // _pagesText.stringValue = [NSString stringWithFormat:@"%d",1]; // [_insertButton setEnabled:YES]; // // } // }]; // [com release]; // }); } else { self._fromFilePath = fileURL self.outputFolderText.stringValue = self._fromFilePath?.path ?? "" self.pageRangeBox.selectItem(at: 0) self.window?.makeFirstResponder(self) self.pageRangeBox.isEditable = false self.pagesText.stringValue = "1" self.insertButton.isEnabled = true } } } } } @IBAction func after_Action(_ sender: AnyObject?) { } @IBAction func before_Action(_ sender: AnyObject?) { } @IBAction func comboxClicked_PageRange(_ sender: AnyObject?) { if (0 == self.pageRangeBox.indexOfSelectedItem || 1 == self.pageRangeBox.indexOfSelectedItem || 2 == self.pageRangeBox.indexOfSelectedItem) { self.window?.makeFirstResponder(self) self.pageRangeBox.isEditable = false }else{ self.pageRangeBox.stringValue = self.pageRangeBox.stringValue self.pageRangeBox.isEditable = true self.window?.makeFirstResponder(self.pageRangeBox) } } } extension KMPDFInsertWindowController: NSTextFieldDelegate { func controlTextDidChange(_ obj: Notification) { if self.pagesText.isEqual(to: obj.object) { let pageNum = Int(self.pagesText.stringValue) ?? 0 if (pageNum <= 0) { self.pagesText.stringValue = "1" self.byPageStepper.integerValue = 1 } else if (pageNum > Int(self.byPageStepper.maxValue)) { self.pagesText.stringValue = "\(self.byPageStepper.maxValue)" self.byPageStepper.integerValue = Int(self.byPageStepper.maxValue) } else { self.byPageStepper.integerValue = pageNum } } } }