/* NSPrintPanel.m Creates a Print panel for the user to select various print options. Copyright (C) 2001 Free Software Foundation, Inc. Author: Adam Fedor Date: 2001 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GSPANELNAME @"GSPrintPanel" @implementation NSPrintPanel // // Class methods // + (void)initialize { if (self == [NSPrintPanel class]) { // Initial version [self setVersion:1]; } } // // Creating an NSPrintPanel // /* It seems like this should be a singleton, but the docs say this returns a newly created panel object */ + (NSPrintPanel *)printPanel { int style = NSTitledWindowMask | NSClosableWindowMask; NSRect frame = NSMakeRect(300, 300, 420, 350); return [[NSPrintPanel alloc] initWithContentRect: frame styleMask: style backing: NSBackingStoreBuffered defer: YES]; } // // Instance methods // /* Designated initializer */ - (id) initWithContentRect: (NSRect)contentRect styleMask: (unsigned int)aStyle backing: (NSBackingStoreType)bufferingType defer: (BOOL)flag screen: (NSScreen*)aScreen { int i; NSArray *subviews; NSString *panel; NSDictionary *table; self = [super initWithContentRect: contentRect styleMask: aStyle backing: bufferingType defer: flag screen: aScreen]; if (self == nil) return nil; panel = [NSBundle pathForGNUstepResource: GSPANELNAME ofType: @"gorm" inDirectory: nil]; if (panel == nil) { NSRunAlertPanel(@"Error", @"Could not find print panel resource", @"OK", NULL, NULL); return nil; } table = [NSDictionary dictionaryWithObject: self forKey: @"NSOwner"]; if ([NSBundle loadNibFile: panel externalNameTable: table withZone: [self zone]] == NO) { NSRunAlertPanel(@"Error", @"Could not load print panel resource", @"OK", NULL, NULL); return nil; } /* Transfer the objects to us. FIXME: There must be a way to instantiate the panel directly */ subviews = [[_panelWindow contentView] subviews]; for (i = 0; i < [subviews count]; i++) { [_contentView addSubview: [subviews objectAtIndex: i]]; } DESTROY(_panelWindow); /* FIXME: Can't do this in Gorm yet: */ [_printForm setBezeled: NO]; [_printForm setBordered: NO]; [[_printForm cellAtIndex: 0] setEditable: NO]; [[_printForm cellAtIndex: 1] setEditable: NO]; [[_printForm cellAtIndex: 2] setEditable: NO]; [[_printForm cellAtIndex: 0] setSelectable: NO]; [[_printForm cellAtIndex: 1] setSelectable: NO]; [[_printForm cellAtIndex: 2] setSelectable: NO]; return self; } // // Customizing the Panel // - (void)setAccessoryView:(NSView *)aView { ASSIGN(_accessoryView, aView); } - (NSView *)accessoryView { return _accessoryView; } // // Running the Panel // - (int)runModal { _picked = NSCancelButton; [NSApp runModalForWindow: self]; [self orderOut: self]; return (_picked == NSCancelButton) ? NSCancelButton : NSOKButton; } - (void) beginSheetWithPrintInfo: (NSPrintInfo *)printInfo modalForWindow: (NSWindow *)docWindow delegate: (id)delegate didEndSelector: (SEL)didEndSelector contextInfo: (void *)contextInfo { _picked = NSCancelButton; // FIXME: We should probably arrange to call endSheet instead of stopModal [NSApp beginSheet: self modalForWindow: docWindow modalDelegate: delegate didEndSelector: didEndSelector contextInfo: contextInfo]; [self orderOut: self]; } - (BOOL) _getSavePath { int result; NSSavePanel *sp; sp = [NSSavePanel savePanel]; [sp setRequiredFileType: @"ps"]; result = [sp runModal]; if (result == NSOKButton) { NSFileManager *mgr = [NSFileManager defaultManager]; NSString *path = [sp filename]; if ([path isEqual: _savePath] == NO && [mgr fileExistsAtPath: path] == YES) { if (NSRunAlertPanel(NULL, @"A document with that name exists", @"Replace", @"Cancel", NULL) != NSAlertDefaultReturn) { return NO; } } _savePath = RETAIN(path); } return (result == NSOKButton); } /* Private communication with our panel objects */ - (void) _pickedButton: (id)sender { if (sender == _saveButton) { _picked = NSPPSaveButton; if ([self _getSavePath] == NO) { /* User pressed save, then changed his mind, so go back to the print panel (don't stop the modal session) */ return; } } else if (sender == _previewButton) { _picked = NSPPPreviewButton; } else if (sender == _faxButton) { _picked = NSFaxButton; NSRunAlertPanel(@"Warning", @"Fax of print file not implemented", @"OK", NULL, NULL); /* Don't stop the modal session */ return; } else if (sender == _cancelButton) { _picked = NSCancelButton; } else if (sender == _printButton) { _picked = NSOKButton; } else { NSLog(@"Print panel buttonAction: from unknown sender - x%x\n", (unsigned)sender); } [NSApp stopModalWithCode: _picked]; } - (void) _pickedPage: (id)sender { if ([_pageMatrix selectedColumn] == 0) { [[_fromRangeForm cellAtIndex: 0] setStringValue: @"" ]; [[_toRangeForm cellAtIndex: 0] setStringValue: @"" ]; } else { NSString *str; str = [NSString stringWithFormat: @"%d", _pages.location]; [[_fromRangeForm cellAtIndex: 0] setStringValue: str]; str = [NSString stringWithFormat: @"%d", NSMaxRange(_pages)]; [[_toRangeForm cellAtIndex: 0] setStringValue: str]; } } - (void) _pickedPrintOp: (id)sender { NSLog(@"pick print op from sender %@, title %@", sender, [sender title]); } /* Depreciated communication methods */ - (void)pickedButton:(id)sender { NSLog(@"[NSPrintPanel -pickedButton:] method depreciated"); [self pickedButton: sender]; } - (void)pickedAllPages:(id)sender { NSLog(@"[NSPrintPanel -pickedAllPages:] method depreciated"); [self _pickedPage: sender]; } - (void)pickedLayoutList:(id)sender { NSLog(@"[NSPrintPanel -pickedLayoutList:] method depreciated"); } // // Communicating with the NSPrintInfo Object // - (void)updateFromPrintInfo { NSString *str; NSPrinter *printer; NSDictionary *dict; NSPrintInfo* info = [[NSPrintOperation currentOperation] printInfo]; printer = [info printer]; [[_printForm cellAtIndex: 0] setStringValue: [printer name] ]; [[_printForm cellAtIndex: 1] setStringValue: [printer note] ]; [[_printForm cellAtIndex: 2] setStringValue: @"" ]; [_copiesField setIntValue: 1]; [[_fromRangeForm cellAtIndex: 0] setStringValue: @"" ]; [[_toRangeForm cellAtIndex: 0] setStringValue: @"" ]; [_pageMatrix selectCellAtRow: 0 column: 0]; dict = [info dictionary]; NSDebugLLog(@"NSPrintPanel", @"Update PrintInfo dictionary\n %@ \n --------------", dict); _pages = NSMakeRange([[dict objectForKey: NSPrintFirstPage] intValue], [[dict objectForKey: NSPrintLastPage] intValue]); if (NSMaxRange(_pages) == 0) _pages = NSMakeRange(1, 0); /* Setup the resolution popup */ [_resButton removeAllItems]; str = [printer stringForKey:@"DefaultResolution" inTable: @"PPD"]; if (str) { NSArray *resList; resList = [printer stringListForKey:@"Resolution" inTable: @"PPD"]; if ([resList count]) { int i; NSString *displayRes, *listRes; for (i = 0; i < [resList count]; i++) { NSString *res = [resList objectAtIndex: i]; listRes = [@"Resolution/" stringByAppendingString: res]; displayRes = [printer stringForKey: listRes inTable: @"PPDOptionTranslation"]; if (displayRes == nil) displayRes = res; [_resButton addItemWithTitle: displayRes]; } listRes = [@"Resolution/" stringByAppendingString: str]; displayRes = [printer stringForKey: listRes inTable: @"PPDOptionTranslation"]; if (displayRes == nil) displayRes = str; [_resButton selectItemWithTitle: displayRes]; } else { [_resButton addItemWithTitle: str]; } } else [_resButton addItemWithTitle: @"Unknown"]; /* Setup the paper feed popup */ [_paperButton removeAllItems]; str = [printer stringForKey:@"DefaultInputSlot" inTable: @"PPD"]; if (str) { NSString *manual; NSArray *inputList; manual = [printer stringForKey:@"DefaultManualFeed" inTable: @"PPD"]; if (manual) [_paperButton addItemWithTitle: @"Manual"]; inputList = [printer stringListForKey:@"InputSlot" inTable: @"PPD"]; if ([inputList count]) { int i; NSString *displayPaper, *listPaper; for (i = 0; i < [inputList count]; i++) { NSString *paper = [inputList objectAtIndex: i]; listPaper = [@"InputSlot/" stringByAppendingString: paper]; displayPaper = [printer stringForKey: listPaper inTable: @"PPDOptionTranslation"]; if (displayPaper == nil) displayPaper = paper; [_paperButton addItemWithTitle: displayPaper]; } /* FIXME: What if manual is default ? */ listPaper = [@"InputSlot/" stringByAppendingString: str]; displayPaper = [printer stringForKey: listPaper inTable: @"PPDOptionTranslation"]; if (displayPaper == nil) displayPaper = str; [_paperButton selectItemWithTitle: displayPaper]; } else { [_paperButton addItemWithTitle: str]; } } else [_paperButton addItemWithTitle: @"Unknown"]; } #define NSNUMBER(a) [NSNumber numberWithInt: (a)] - (void)finalWritePrintInfo { NSString *sel; NSArray *list; NSPrinter *printer; NSMutableDictionary *dict; NSMutableDictionary *features; NSPrintInfo* info = [[NSPrintOperation currentOperation] printInfo]; dict = [info dictionary]; printer = [info printer]; features = [dict objectForKey: NSPrintJobFeatures]; /* Copies */ if ([_copiesField intValue] > 1) { [dict setObject: NSNUMBER([_copiesField intValue]) forKey: NSPrintCopies]; } /* Pages */ if ([_pageMatrix selectedColumn] != 0) { [dict setObject: NSNUMBER([[_fromRangeForm cellAtIndex: 0] intValue]) forKey: NSPrintFirstPage]; [dict setObject: NSNUMBER([[_toRangeForm cellAtIndex: 0] intValue]) forKey: NSPrintLastPage]; [dict setObject: NSNUMBER(NO) forKey: NSPrintAllPages]; } else [dict setObject: NSNUMBER(YES) forKey: NSPrintAllPages]; /* Resolution */ /* Here we take advantage of the fact the names in the popup list are in the same order as the PPD file, so we don't actually compare the values */ list = [printer stringListForKey: @"Resolution" inTable: @"PPD"]; if (list) { NSString *def; sel = [list objectAtIndex: [_resButton indexOfSelectedItem]]; def = [printer stringForKey:@"DefaultResolution" inTable: @"PPD"]; if ([sel isEqual: def] == NO) { if (features == nil) { features = [NSMutableDictionary dictionary]; [dict setObject: features forKey: NSPrintJobFeatures]; } sel = [@"Resolution/" stringByAppendingString: sel]; [features setObject: sel forKey: @"Resolution"]; } } /* Input Slot */ list = [printer stringListForKey:@"InputSlot" inTable: @"PPD"]; if (list) { int selected; NSString *def, *manual; sel = nil; selected = [_paperButton indexOfSelectedItem]; manual = [printer stringForKey:@"DefaultManualFeed" inTable: @"PPD"]; if (manual) { if (selected == 0) sel = @"Manual"; else selected--; } if (sel == nil) sel = [list objectAtIndex: selected]; def = [printer stringForKey:@"DefaultInputSlot" inTable: @"PPD"]; if ([sel isEqual: @"Manual"] == YES) { [dict setObject: NSPrintManualFeed forKey: NSPrintPaperFeed]; /* FIXME: This needs to be more robust. I'm just assuming that all Manual Feed keys can be True or False (which is the case for all the ppd files that I know of). */ [dict setObject: @"ManualFeed/True" forKey: NSPrintManualFeed]; [features setObject: @"ManualFeed/True" forKey: NSPrintPaperFeed]; } else if ([sel isEqual: def] == NO) { if (features == nil) { features = [NSMutableDictionary dictionary]; [dict setObject: features forKey: NSPrintJobFeatures]; } sel = [@"InputSlot/" stringByAppendingString: sel]; [features setObject: sel forKey: @"InputSlot"]; [dict setObject: sel forKey: NSPrintPaperFeed]; } } /* Job Resolution */ switch (_picked) { case NSPPSaveButton: sel = NSPrintSaveJob; [dict setObject: _savePath forKey: NSPrintSavePath]; break; case NSPPPreviewButton: sel = NSPrintPreviewJob; break; case NSFaxButton: sel = NSPrintFaxJob; break; case NSOKButton: sel = NSPrintSpoolJob; break; case NSCancelButton: default: sel = NSPrintCancelJob; } [info setJobDisposition: sel]; NSDebugLLog(@"NSPrintPanel", @"Final info dictionary ----\n %@ \n --------------", dict); } @end