Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / cocoa / nsPrintDialogX.mm
blob5cad69d547cfbca4412f3a0043e7a634a9bab5fb
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/ArrayUtils.h"
7 #include "mozilla/gfx/PrintTargetCG.h"
8 #include "mozilla/Preferences.h"
10 #include "nsPrintDialogX.h"
11 #include "nsIPrintSettings.h"
12 #include "nsIPrintSettingsService.h"
13 #include "nsPrintSettingsX.h"
14 #include "nsCOMPtr.h"
15 #include "nsQueryObject.h"
16 #include "nsServiceManagerUtils.h"
17 #include "nsIStringBundle.h"
18 #include "nsCRT.h"
20 #import <Cocoa/Cocoa.h>
21 #include "nsObjCExceptions.h"
23 using namespace mozilla;
24 using mozilla::gfx::PrintTarget;
26 NS_IMPL_ISUPPORTS(nsPrintDialogServiceX, nsIPrintDialogService)
28 // Splits our single pages-per-sheet count for native NSPrintInfo:
29 static void setPagesPerSheet(NSPrintInfo* aPrintInfo, int32_t aPPS) {
30   int32_t across, down;
31   // Assumes portrait - we'll swap if landscape.
32   switch (aPPS) {
33     case 2:
34       across = 1;
35       down = 2;
36       break;
37     case 4:
38       across = 2;
39       down = 2;
40       break;
41     case 6:
42       across = 2;
43       down = 3;
44       break;
45     case 9:
46       across = 3;
47       down = 3;
48       break;
49     case 16:
50       across = 4;
51       down = 4;
52       break;
53     default:
54       across = 1;
55       down = 1;
56       break;
57   }
58   if ([aPrintInfo orientation] == NSPaperOrientationLandscape) {
59     std::swap(across, down);
60   }
62   NSMutableDictionary* dict = [aPrintInfo dictionary];
64   [dict setObject:[NSNumber numberWithInt:across] forKey:@"NSPagesAcross"];
65   [dict setObject:[NSNumber numberWithInt:down] forKey:@"NSPagesDown"];
68 nsPrintDialogServiceX::nsPrintDialogServiceX() {}
70 nsPrintDialogServiceX::~nsPrintDialogServiceX() {}
72 NS_IMETHODIMP
73 nsPrintDialogServiceX::Init() { return NS_OK; }
75 NS_IMETHODIMP
76 nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent,
77                                        bool aHaveSelection,
78                                        nsIPrintSettings* aSettings) {
79   NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
81   MOZ_ASSERT(aSettings, "aSettings must not be null");
83   RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aSettings));
84   if (!settingsX) {
85     return NS_ERROR_FAILURE;
86   }
88   NSPrintInfo* printInfo =
89       settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
90   if (NS_WARN_IF(!printInfo)) {
91     return NS_ERROR_FAILURE;
92   }
93   [printInfo autorelease];
95   // Set the print job title
96   nsAutoString docName;
97   nsresult rv = aSettings->GetTitle(docName);
98   if (NS_SUCCEEDED(rv)) {
99     nsAutoString adjustedTitle;
100     PrintTarget::AdjustPrintJobNameForIPP(docName, adjustedTitle);
101     CFStringRef cfTitleString = CFStringCreateWithCharacters(
102         NULL, reinterpret_cast<const UniChar*>(adjustedTitle.BeginReading()),
103         adjustedTitle.Length());
104     if (cfTitleString) {
105       auto pmPrintSettings =
106           static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
107       ::PMPrintSettingsSetJobName(pmPrintSettings, cfTitleString);
108       [printInfo updateFromPMPrintSettings];
109       CFRelease(cfTitleString);
110     }
111   }
113   // Temporarily set the pages-per-sheet count set in our print preview to
114   // pre-populate the system dialog with the same value:
115   int32_t pagesPerSheet;
116   aSettings->GetNumPagesPerSheet(&pagesPerSheet);
117   setPagesPerSheet(printInfo, pagesPerSheet);
119   // Put the print info into the current print operation, since that's where
120   // [panel runModal] will look for it. We create the view because otherwise
121   // we'll get unrelated warnings printed to the console.
122   NSView* tmpView = [[NSView alloc] init];
123   NSPrintOperation* printOperation =
124       [NSPrintOperation printOperationWithView:tmpView printInfo:printInfo];
125   [NSPrintOperation setCurrentOperation:printOperation];
127   NSPrintPanel* panel = [NSPrintPanel printPanel];
128   [panel setOptions:NSPrintPanelShowsCopies | NSPrintPanelShowsPageRange |
129                     NSPrintPanelShowsPaperSize | NSPrintPanelShowsOrientation |
130                     NSPrintPanelShowsScaling];
131   PrintPanelAccessoryController* viewController =
132       [[PrintPanelAccessoryController alloc] initWithSettings:aSettings
133                                                 haveSelection:aHaveSelection];
134   [panel addAccessoryController:viewController];
135   [viewController release];
137   // Show the dialog.
138   nsCocoaUtils::PrepareForNativeAppModalDialog();
139   int button = [panel runModal];
140   nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
142   // Retrieve a printInfo with the updated settings. (The NSPrintOperation
143   // operates on a copy, so the object we passed in will not have been
144   // modified.)
145   NSPrintInfo* result = [[NSPrintOperation currentOperation] printInfo];
146   if (!result) {
147     return NS_ERROR_FAILURE;
148   }
150   [NSPrintOperation setCurrentOperation:nil];
151   [tmpView release];
153   if (button != NSModalResponseOK) {
154     return NS_ERROR_ABORT;
155   }
157   // We handle pages-per-sheet internally and we want to prevent the macOS
158   // printing code from also applying the pages-per-sheet count. So we need
159   // to move the count off the NSPrintInfo and over to the nsIPrintSettings.
160   NSMutableDictionary* dict = [result dictionary];
161   auto pagesAcross = [[dict objectForKey:@"NSPagesAcross"] intValue];
162   auto pagesDown = [[dict objectForKey:@"NSPagesDown"] intValue];
163   [dict setObject:[NSNumber numberWithUnsignedInt:1] forKey:@"NSPagesAcross"];
164   [dict setObject:[NSNumber numberWithUnsignedInt:1] forKey:@"NSPagesDown"];
165   aSettings->SetNumPagesPerSheet(pagesAcross * pagesDown);
167   // Export settings.
168   [viewController exportSettings];
170   // Update our settings object based on the user's choices in the dialog.
171   // We tell settingsX to adopt this printInfo so that it will be used to run
172   // print job, so that any printer-specific custom settings from print dialog
173   // extension panels will be carried through.
174   settingsX->SetFromPrintInfo(result, /* aAdoptPrintInfo = */ true);
176   return NS_OK;
178   NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
181 NS_IMETHODIMP
182 nsPrintDialogServiceX::ShowPageSetupDialog(mozIDOMWindowProxy* aParent,
183                                            nsIPrintSettings* aNSSettings) {
184   NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
186   MOZ_ASSERT(aParent, "aParent must not be null");
187   MOZ_ASSERT(aNSSettings, "aSettings must not be null");
188   NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
190   RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aNSSettings));
191   if (!settingsX) {
192     return NS_ERROR_FAILURE;
193   }
195   NSPrintInfo* printInfo =
196       settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
197   if (NS_WARN_IF(!printInfo)) {
198     return NS_ERROR_FAILURE;
199   }
200   [printInfo autorelease];
202   NSPageLayout* pageLayout = [NSPageLayout pageLayout];
203   nsCocoaUtils::PrepareForNativeAppModalDialog();
204   int button = [pageLayout runModalWithPrintInfo:printInfo];
205   nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
207   if (button == NSModalResponseOK) {
208     // The Page Setup dialog does not include non-standard settings that need to
209     // be preserved, separate from what the base printSettings object handles,
210     // so we do not need it to adopt the printInfo object here.
211     settingsX->SetFromPrintInfo(printInfo, /* aAdoptPrintInfo = */ false);
212     nsCOMPtr<nsIPrintSettingsService> printSettingsService =
213         do_GetService("@mozilla.org/gfx/printsettings-service;1");
214     if (printSettingsService &&
215         Preferences::GetBool("print.save_print_settings", false)) {
216       uint32_t flags = nsIPrintSettings::kInitSavePaperSize |
217                        nsIPrintSettings::kInitSaveOrientation |
218                        nsIPrintSettings::kInitSaveScaling;
219       printSettingsService->MaybeSavePrintSettingsToPrefs(aNSSettings, flags);
220     }
221     return NS_OK;
222   }
223   return NS_ERROR_ABORT;
225   NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
228 // Accessory view
230 @interface PrintPanelAccessoryView (Private)
232 - (NSString*)localizedString:(const char*)aKey;
234 - (const char*)headerFooterStringForList:(NSPopUpButton*)aList;
236 - (void)exportHeaderFooterSettings;
238 - (void)initBundle;
240 - (NSTextField*)label:(const char*)aLabel
241             withFrame:(NSRect)aRect
242             alignment:(NSTextAlignment)aAlignment;
244 - (void)addLabel:(const char*)aLabel
245        withFrame:(NSRect)aRect
246        alignment:(NSTextAlignment)aAlignment;
248 - (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect;
250 - (void)addCenteredLabel:(const char*)aLabel withFrame:(NSRect)aRect;
252 - (NSButton*)checkboxWithLabel:(const char*)aLabel andFrame:(NSRect)aRect;
254 - (NSPopUpButton*)headerFooterItemListWithFrame:(NSRect)aRect
255                                    selectedItem:
256                                        (const nsAString&)aCurrentString;
258 - (void)addOptionsSection:(bool)aHaveSelection;
260 - (void)addAppearanceSection;
262 - (void)addHeaderFooterSection;
264 - (NSString*)summaryValueForCheckbox:(NSButton*)aCheckbox;
266 - (NSString*)headerSummaryValue;
268 - (NSString*)footerSummaryValue;
270 @end
272 static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
274 @implementation PrintPanelAccessoryView
276 // Public methods
278 - (id)initWithSettings:(nsIPrintSettings*)aSettings
279          haveSelection:(bool)aHaveSelection {
280   [super initWithFrame:NSMakeRect(0, 0, 540, 185)];
282   mSettings = aSettings;
283   [self initBundle];
284   [self addOptionsSection:aHaveSelection];
285   [self addAppearanceSection];
286   [self addHeaderFooterSection];
288   return self;
291 - (void)exportSettings {
292   mSettings->SetPrintSelectionOnly([mPrintSelectionOnlyCheckbox state] ==
293                                    NSControlStateValueOn);
294   mSettings->SetShrinkToFit([mShrinkToFitCheckbox state] ==
295                             NSControlStateValueOn);
296   mSettings->SetPrintBGColors([mPrintBGColorsCheckbox state] ==
297                               NSControlStateValueOn);
298   mSettings->SetPrintBGImages([mPrintBGImagesCheckbox state] ==
299                               NSControlStateValueOn);
301   [self exportHeaderFooterSettings];
304 - (void)dealloc {
305   NS_IF_RELEASE(mPrintBundle);
306   [super dealloc];
309 // Localization
311 - (void)initBundle {
312   nsCOMPtr<nsIStringBundleService> bundleSvc =
313       do_GetService(NS_STRINGBUNDLE_CONTRACTID);
314   bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties",
315                           &mPrintBundle);
318 - (NSString*)localizedString:(const char*)aKey {
319   if (!mPrintBundle) return @"";
321   nsAutoString intlString;
322   mPrintBundle->GetStringFromName(aKey, intlString);
323   NSMutableString* s = [NSMutableString
324       stringWithUTF8String:NS_ConvertUTF16toUTF8(intlString).get()];
326   // Remove all underscores (they're used in the GTK dialog for accesskeys).
327   [s replaceOccurrencesOfString:@"_"
328                      withString:@""
329                         options:0
330                           range:NSMakeRange(0, [s length])];
331   return s;
334 // Widget helpers
336 - (NSTextField*)label:(const char*)aLabel
337             withFrame:(NSRect)aRect
338             alignment:(NSTextAlignment)aAlignment {
339   NSTextField* label = [[[NSTextField alloc] initWithFrame:aRect] autorelease];
340   [label setStringValue:[self localizedString:aLabel]];
341   [label setEditable:NO];
342   [label setSelectable:NO];
343   [label setBezeled:NO];
344   [label setBordered:NO];
345   [label setDrawsBackground:NO];
346   [label setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
347   [label setAlignment:aAlignment];
348   return label;
351 - (void)addLabel:(const char*)aLabel
352        withFrame:(NSRect)aRect
353        alignment:(NSTextAlignment)aAlignment {
354   NSTextField* label = [self label:aLabel withFrame:aRect alignment:aAlignment];
355   [self addSubview:label];
358 - (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect {
359   [self addLabel:aLabel withFrame:aRect alignment:NSTextAlignmentRight];
362 - (void)addCenteredLabel:(const char*)aLabel withFrame:(NSRect)aRect {
363   [self addLabel:aLabel withFrame:aRect alignment:NSTextAlignmentCenter];
366 - (NSButton*)checkboxWithLabel:(const char*)aLabel andFrame:(NSRect)aRect {
367   aRect.origin.y += 4.0f;
368   NSButton* checkbox = [[[NSButton alloc] initWithFrame:aRect] autorelease];
369   [checkbox setButtonType:NSButtonTypeSwitch];
370   [checkbox setTitle:[self localizedString:aLabel]];
371   [checkbox setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
372   [checkbox sizeToFit];
373   return checkbox;
376 - (NSPopUpButton*)headerFooterItemListWithFrame:(NSRect)aRect
377                                    selectedItem:
378                                        (const nsAString&)aCurrentString {
379   NSPopUpButton* list = [[[NSPopUpButton alloc] initWithFrame:aRect
380                                                     pullsDown:NO] autorelease];
381   [list setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
382   [[list cell] setControlSize:NSControlSizeSmall];
383   NSArray* items = [NSArray
384       arrayWithObjects:[self localizedString:"headerFooterBlank"],
385                        [self localizedString:"headerFooterTitle"],
386                        [self localizedString:"headerFooterURL"],
387                        [self localizedString:"headerFooterDate"],
388                        [self localizedString:"headerFooterPage"],
389                        [self localizedString:"headerFooterPageTotal"], nil];
390   [list addItemsWithTitles:items];
392   NS_ConvertUTF16toUTF8 currentStringUTF8(aCurrentString);
393   for (unsigned int i = 0; i < ArrayLength(sHeaderFooterTags); i++) {
394     if (!strcmp(currentStringUTF8.get(), sHeaderFooterTags[i])) {
395       [list selectItemAtIndex:i];
396       break;
397     }
398   }
400   return list;
403 // Build sections
405 - (void)addOptionsSection:(bool)aHaveSelection {
406   // Title
407   [self addLabel:"optionsTitleMac" withFrame:NSMakeRect(0, 155, 151, 22)];
409   // "Print Selection Only"
410   mPrintSelectionOnlyCheckbox =
411       [self checkboxWithLabel:"selectionOnly"
412                      andFrame:NSMakeRect(156, 155, 0, 0)];
413   [mPrintSelectionOnlyCheckbox setEnabled:aHaveSelection];
415   if (mSettings->GetPrintSelectionOnly()) {
416     [mPrintSelectionOnlyCheckbox setState:NSControlStateValueOn];
417   }
419   [self addSubview:mPrintSelectionOnlyCheckbox];
421   // "Shrink To Fit"
422   mShrinkToFitCheckbox = [self checkboxWithLabel:"shrinkToFit"
423                                         andFrame:NSMakeRect(156, 133, 0, 0)];
425   bool shrinkToFit;
426   mSettings->GetShrinkToFit(&shrinkToFit);
427   [mShrinkToFitCheckbox
428       setState:(shrinkToFit ? NSControlStateValueOn : NSControlStateValueOff)];
430   [self addSubview:mShrinkToFitCheckbox];
433 - (void)addAppearanceSection {
434   // Title
435   [self addLabel:"appearanceTitleMac" withFrame:NSMakeRect(0, 103, 151, 22)];
437   // "Print Background Colors"
438   mPrintBGColorsCheckbox = [self checkboxWithLabel:"printBGColors"
439                                           andFrame:NSMakeRect(156, 103, 0, 0)];
441   bool geckoBool = mSettings->GetPrintBGColors();
442   [mPrintBGColorsCheckbox
443       setState:(geckoBool ? NSControlStateValueOn : NSControlStateValueOff)];
445   [self addSubview:mPrintBGColorsCheckbox];
447   // "Print Background Images"
448   mPrintBGImagesCheckbox = [self checkboxWithLabel:"printBGImages"
449                                           andFrame:NSMakeRect(156, 81, 0, 0)];
451   geckoBool = mSettings->GetPrintBGImages();
452   [mPrintBGImagesCheckbox
453       setState:(geckoBool ? NSControlStateValueOn : NSControlStateValueOff)];
455   [self addSubview:mPrintBGImagesCheckbox];
458 - (void)addHeaderFooterSection {
459   // Labels
460   [self addLabel:"pageHeadersTitleMac" withFrame:NSMakeRect(0, 44, 151, 22)];
461   [self addLabel:"pageFootersTitleMac" withFrame:NSMakeRect(0, 0, 151, 22)];
462   [self addCenteredLabel:"left" withFrame:NSMakeRect(156, 22, 100, 22)];
463   [self addCenteredLabel:"center" withFrame:NSMakeRect(256, 22, 100, 22)];
464   [self addCenteredLabel:"right" withFrame:NSMakeRect(356, 22, 100, 22)];
466   // Lists
467   nsString sel;
469   mSettings->GetHeaderStrLeft(sel);
470   mHeaderLeftList =
471       [self headerFooterItemListWithFrame:NSMakeRect(156, 44, 100, 22)
472                              selectedItem:sel];
473   [self addSubview:mHeaderLeftList];
475   mSettings->GetHeaderStrCenter(sel);
476   mHeaderCenterList =
477       [self headerFooterItemListWithFrame:NSMakeRect(256, 44, 100, 22)
478                              selectedItem:sel];
479   [self addSubview:mHeaderCenterList];
481   mSettings->GetHeaderStrRight(sel);
482   mHeaderRightList =
483       [self headerFooterItemListWithFrame:NSMakeRect(356, 44, 100, 22)
484                              selectedItem:sel];
485   [self addSubview:mHeaderRightList];
487   mSettings->GetFooterStrLeft(sel);
488   mFooterLeftList =
489       [self headerFooterItemListWithFrame:NSMakeRect(156, 0, 100, 22)
490                              selectedItem:sel];
491   [self addSubview:mFooterLeftList];
493   mSettings->GetFooterStrCenter(sel);
494   mFooterCenterList =
495       [self headerFooterItemListWithFrame:NSMakeRect(256, 0, 100, 22)
496                              selectedItem:sel];
497   [self addSubview:mFooterCenterList];
499   mSettings->GetFooterStrRight(sel);
500   mFooterRightList =
501       [self headerFooterItemListWithFrame:NSMakeRect(356, 0, 100, 22)
502                              selectedItem:sel];
503   [self addSubview:mFooterRightList];
506 // Export settings
508 - (const char*)headerFooterStringForList:(NSPopUpButton*)aList {
509   NSInteger index = [aList indexOfSelectedItem];
510   NS_ASSERTION(index < NSInteger(ArrayLength(sHeaderFooterTags)),
511                "Index of dropdown is higher than expected!");
512   return sHeaderFooterTags[index];
515 - (void)exportHeaderFooterSettings {
516   const char* headerFooterStr;
517   headerFooterStr = [self headerFooterStringForList:mHeaderLeftList];
518   mSettings->SetHeaderStrLeft(NS_ConvertUTF8toUTF16(headerFooterStr));
520   headerFooterStr = [self headerFooterStringForList:mHeaderCenterList];
521   mSettings->SetHeaderStrCenter(NS_ConvertUTF8toUTF16(headerFooterStr));
523   headerFooterStr = [self headerFooterStringForList:mHeaderRightList];
524   mSettings->SetHeaderStrRight(NS_ConvertUTF8toUTF16(headerFooterStr));
526   headerFooterStr = [self headerFooterStringForList:mFooterLeftList];
527   mSettings->SetFooterStrLeft(NS_ConvertUTF8toUTF16(headerFooterStr));
529   headerFooterStr = [self headerFooterStringForList:mFooterCenterList];
530   mSettings->SetFooterStrCenter(NS_ConvertUTF8toUTF16(headerFooterStr));
532   headerFooterStr = [self headerFooterStringForList:mFooterRightList];
533   mSettings->SetFooterStrRight(NS_ConvertUTF8toUTF16(headerFooterStr));
536 // Summary
538 - (NSString*)summaryValueForCheckbox:(NSButton*)aCheckbox {
539   if (![aCheckbox isEnabled]) return [self localizedString:"summaryNAValue"];
541   return [aCheckbox state] == NSControlStateValueOn
542              ? [self localizedString:"summaryOnValue"]
543              : [self localizedString:"summaryOffValue"];
546 - (NSString*)headerSummaryValue {
547   return [[mHeaderLeftList titleOfSelectedItem]
548       stringByAppendingString:
549           [@", "
550               stringByAppendingString:
551                   [[mHeaderCenterList titleOfSelectedItem]
552                       stringByAppendingString:
553                           [@", " stringByAppendingString:
554                                      [mHeaderRightList titleOfSelectedItem]]]]];
557 - (NSString*)footerSummaryValue {
558   return [[mFooterLeftList titleOfSelectedItem]
559       stringByAppendingString:
560           [@", "
561               stringByAppendingString:
562                   [[mFooterCenterList titleOfSelectedItem]
563                       stringByAppendingString:
564                           [@", " stringByAppendingString:
565                                      [mFooterRightList titleOfSelectedItem]]]]];
568 - (NSArray*)localizedSummaryItems {
569   return [NSArray
570       arrayWithObjects:
571           [NSDictionary
572               dictionaryWithObjectsAndKeys:
573                   [self localizedString:"summarySelectionOnlyTitle"],
574                   NSPrintPanelAccessorySummaryItemNameKey,
575                   [self summaryValueForCheckbox:mPrintSelectionOnlyCheckbox],
576                   NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
577           [NSDictionary dictionaryWithObjectsAndKeys:
578                             [self localizedString:"summaryShrinkToFitTitle"],
579                             NSPrintPanelAccessorySummaryItemNameKey,
580                             [self summaryValueForCheckbox:mShrinkToFitCheckbox],
581                             NSPrintPanelAccessorySummaryItemDescriptionKey,
582                             nil],
583           [NSDictionary
584               dictionaryWithObjectsAndKeys:
585                   [self localizedString:"summaryPrintBGColorsTitle"],
586                   NSPrintPanelAccessorySummaryItemNameKey,
587                   [self summaryValueForCheckbox:mPrintBGColorsCheckbox],
588                   NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
589           [NSDictionary
590               dictionaryWithObjectsAndKeys:
591                   [self localizedString:"summaryPrintBGImagesTitle"],
592                   NSPrintPanelAccessorySummaryItemNameKey,
593                   [self summaryValueForCheckbox:mPrintBGImagesCheckbox],
594                   NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
595           [NSDictionary dictionaryWithObjectsAndKeys:
596                             [self localizedString:"summaryHeaderTitle"],
597                             NSPrintPanelAccessorySummaryItemNameKey,
598                             [self headerSummaryValue],
599                             NSPrintPanelAccessorySummaryItemDescriptionKey,
600                             nil],
601           [NSDictionary dictionaryWithObjectsAndKeys:
602                             [self localizedString:"summaryFooterTitle"],
603                             NSPrintPanelAccessorySummaryItemNameKey,
604                             [self footerSummaryValue],
605                             NSPrintPanelAccessorySummaryItemDescriptionKey,
606                             nil],
607           nil];
610 @end
612 // Accessory controller
614 @implementation PrintPanelAccessoryController
616 - (id)initWithSettings:(nsIPrintSettings*)aSettings
617          haveSelection:(bool)aHaveSelection {
618   [super initWithNibName:nil bundle:nil];
620   NSView* accView =
621       [[PrintPanelAccessoryView alloc] initWithSettings:aSettings
622                                           haveSelection:aHaveSelection];
623   [self setView:accView];
624   [accView release];
625   return self;
628 - (void)exportSettings {
629   return [(PrintPanelAccessoryView*)[self view] exportSettings];
632 - (NSArray*)localizedSummaryItems {
633   return [(PrintPanelAccessoryView*)[self view] localizedSummaryItems];
636 @end