Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/widget/cocoa/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 25 kB image not shown  

Quelle  nsPrintDialogX.mm  Sprache: unbekannt

 
Spracherkennung für: .mm vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/gfx/PrintTargetCG.h"
#include "mozilla/Preferences.h"
#include "mozilla/WidgetUtils.h"
#include "mozilla/dom/Promise.h"

#include "nsPrintDialogX.h"
#include "nsIPrintSettings.h"
#include "nsIPrintSettingsService.h"
#include "nsPrintSettingsX.h"
#include "nsCOMPtr.h"
#include "nsIGlobalObject.h"
#include "nsIWidget.h"
#include "nsPIDOMWindow.h"
#include "nsQueryObject.h"
#include "nsServiceManagerUtils.h"
#include "nsIStringBundle.h"
#include "nsCRT.h"
#include "nsThreadUtils.h"
#include "xpcpublic.h"

#import <Cocoa/Cocoa.h>
#include "nsObjCExceptions.h"

using namespace mozilla;
using namespace mozilla::dom;
using mozilla::gfx::PrintTarget;
using mozilla::widget::WidgetUtils;

// Adapts NSPrintPanel's and NSPageLayout's delegate-based sheet API into a
// block-based completion handler. The instance owns itself for the duration
// of the sheet: the caller alloc/inits it, hands it to the panel as the
// delegate, and the instance releases itself once didEnd: fires. This avoids
// requiring callers to track the adapter's lifetime across the async boundary.
@interface MozPrintPanelDidEndAdapter : NSObject {
  void (^mHandler)(NSInteger);
}
- (instancetype)initWithHandler:(void (^)(NSInteger))aHandler;
- (void)didEnd:(id)aPanel
     returnCode:(NSInteger)aReturnCode
    contextInfo:(void*)aContextInfo;
@end

@implementation MozPrintPanelDidEndAdapter
- (instancetype)initWithHandler:(void (^)(NSInteger))aHandler {
  if ((self = [super init])) {
    mHandler = [aHandler copy];
  }
  return self;
}
- (void)dealloc {
  [mHandler release];
  [super dealloc];
}
- (void)didEnd:(id)aPanel
     returnCode:(NSInteger)aReturnCode
    contextInfo:(void*)aContextInfo {
  if (mHandler) {
    mHandler(aReturnCode);
  }
  [self release];
}
@end

static NSWindow* GetParentWindow(mozIDOMWindowProxy* aParent) {
  if (!aParent) {
    return nil;
  }
  nsCOMPtr<nsIWidget> widget =
      WidgetUtils::DOMWindowToWidget(nsPIDOMWindowOuter::From(aParent));
  if (!widget) {
    return nil;
  }
  return (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
}

NS_IMPL_ISUPPORTS(nsPrintDialogServiceX, nsIPrintDialogService)

// Splits our single pages-per-sheet count for native NSPrintInfo:
static void setPagesPerSheet(NSPrintInfo* aPrintInfo, int32_t aPPS) {
  int32_t across, down;
  // Assumes portrait - we'll swap if landscape.
  switch (aPPS) {
    case 2:
      across = 1;
      down = 2;
      break;
    case 4:
      across = 2;
      down = 2;
      break;
    case 6:
      across = 2;
      down = 3;
      break;
    case 9:
      across = 3;
      down = 3;
      break;
    case 16:
      across = 4;
      down = 4;
      break;
    default:
      across = 1;
      down = 1;
      break;
  }
  if ([aPrintInfo orientation] == NSPaperOrientationLandscape) {
    std::swap(across, down);
  }

  NSMutableDictionary* dict = [aPrintInfo dictionary];

  [dict setObject:[NSNumber numberWithInt:across] forKey:@"NSPagesAcross"];
  [dict setObject:[NSNumber numberWithInt:down] forKey:@"NSPagesDown"];
}

nsPrintDialogServiceX::nsPrintDialogServiceX() {}

nsPrintDialogServiceX::~nsPrintDialogServiceX() {}

NS_IMETHODIMP
nsPrintDialogServiceX::Init() { return NS_OK; }

NS_IMETHODIMP
nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent,
                                       bool aHaveSelection,
                                       nsIPrintSettings* aSettings,
                                       JSContext* aCx, Promise** aPromise) {
  NS_OBJC_BEGIN_TRY_BLOCK_RETURN;

  MOZ_ASSERT(NS_IsMainThread());
  NS_ENSURE_ARG(aParent);
  NS_ENSURE_ARG(aSettings);
  NS_ENSURE_ARG(aCx);
  NS_ENSURE_ARG(aPromise);

  ErrorResult rvErr;
  nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
  RefPtr<Promise> promise = Promise::Create(global, rvErr);
  if (NS_WARN_IF(rvErr.Failed())) {
    return rvErr.StealNSResult();
  }

  NSWindow* parentWindow = GetParentWindow(aParent);
  if (!parentWindow) {
    return NS_ERROR_FAILURE;
  }

  RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aSettings));
  if (!settingsX) {
    return NS_ERROR_FAILURE;
  }

  NSPrintInfo* printInfo =
      settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
  if (NS_WARN_IF(!printInfo)) {
    return NS_ERROR_FAILURE;
  }
  [printInfo autorelease];

  // Set the print job title
  nsAutoString docName;
  nsresult rv = aSettings->GetTitle(docName);
  if (NS_SUCCEEDED(rv)) {
    nsAutoString adjustedTitle;
    PrintTarget::AdjustPrintJobNameForIPP(docName, adjustedTitle);
    CFStringRef cfTitleString = CFStringCreateWithCharacters(
        nullptr, reinterpret_cast<const UniChar*>(adjustedTitle.BeginReading()),
        adjustedTitle.Length());
    if (cfTitleString) {
      auto pmPrintSettings =
          static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
      ::PMPrintSettingsSetJobName(pmPrintSettings, cfTitleString);
      [printInfo updateFromPMPrintSettings];
      CFRelease(cfTitleString);
    }
  }

  // Temporarily set the pages-per-sheet count set in our print preview to
  // pre-populate the system dialog with the same value:
  int32_t pagesPerSheet;
  aSettings->GetNumPagesPerSheet(&pagesPerSheet);
  setPagesPerSheet(printInfo, pagesPerSheet);

  // Put the print info into the current print operation, since that's where
  // the panel will look for it. We create the view because otherwise we'll
  // get unrelated warnings printed to the console.
  NSView* tmpView = [[NSView alloc] init];
  NSPrintOperation* printOperation =
      [NSPrintOperation printOperationWithView:tmpView printInfo:printInfo];
  [NSPrintOperation setCurrentOperation:printOperation];

  NSPrintPanel* panel = [NSPrintPanel printPanel];
  [panel setOptions:NSPrintPanelShowsCopies | NSPrintPanelShowsPageRange |
                    NSPrintPanelShowsPaperSize | NSPrintPanelShowsOrientation |
                    NSPrintPanelShowsScaling];
  PrintPanelAccessoryController* viewController =
      [[PrintPanelAccessoryController alloc] initWithSettings:aSettings
                                                haveSelection:aHaveSelection];
  [panel addAccessoryController:viewController];
  [viewController release];

  RefPtr<nsIPrintSettings> settings = aSettings;
  RefPtr<nsPrintSettingsX> settingsXRef = settingsX;
  RefPtr<Promise> promiseForBlock = promise;

  MozPrintPanelDidEndAdapter* adapter =
      [[MozPrintPanelDidEndAdapter alloc] initWithHandler:^(NSInteger button) {
        NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
        // The sheet writes the user's choices (including the print
        // destination) back into the printInfo we passed to
        // beginSheetWithPrintInfo:, so read the updated settings from
        // printInfo.
        NSPrintInfo* result = printInfo;
        [NSPrintOperation setCurrentOperation:nil];
        [tmpView release];

        if (button != NSModalResponseOK || !result) {
          promiseForBlock->MaybeReject(NS_ERROR_ABORT);
          return;
        }

        // We handle pages-per-sheet internally and we want to prevent the
        // macOS printing code from also applying the pages-per-sheet count.
        // So we need to move the count off the NSPrintInfo and over to the
        // nsIPrintSettings.
        NSMutableDictionary* dict = [result dictionary];
        auto pagesAcross = [[dict objectForKey:@"NSPagesAcross"] intValue];
        auto pagesDown = [[dict objectForKey:@"NSPagesDown"] intValue];
        [dict setObject:[NSNumber numberWithUnsignedInt:1]
                 forKey:@"NSPagesAcross"];
        [dict setObject:[NSNumber numberWithUnsignedInt:1]
                 forKey:@"NSPagesDown"];
        settings->SetNumPagesPerSheet(pagesAcross * pagesDown);

        [viewController exportSettings];

        // Update our settings object based on the user's choices in the
        // dialog. We tell settingsX to adopt this printInfo so that it will
        // be used to run the print job, so that any printer-specific custom
        // settings from print dialog extension panels will be carried
        // through.
        settingsXRef->SetFromPrintInfo(result, /* aAdoptPrintInfo = */ true);

        promiseForBlock->MaybeResolveWithUndefined();
        NS_OBJC_END_TRY_IGNORE_BLOCK;
      }];

  [panel beginSheetWithPrintInfo:printInfo
                  modalForWindow:parentWindow
                        delegate:adapter
                  didEndSelector:@selector(didEnd:returnCode:contextInfo:)
                     contextInfo:nullptr];

  promise.forget(aPromise);
  return NS_OK;

  NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}

NS_IMETHODIMP
nsPrintDialogServiceX::ShowPageSetupDialog(mozIDOMWindowProxy* aParent,
                                           nsIPrintSettings* aNSSettings,
                                           JSContext* aCx, Promise** aPromise) {
  NS_OBJC_BEGIN_TRY_BLOCK_RETURN;

  MOZ_ASSERT(NS_IsMainThread());
  NS_ENSURE_ARG(aParent);
  NS_ENSURE_ARG(aNSSettings);
  NS_ENSURE_ARG(aCx);
  NS_ENSURE_ARG(aPromise);

  ErrorResult rvErr;
  nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
  RefPtr<Promise> promise = Promise::Create(global, rvErr);
  if (NS_WARN_IF(rvErr.Failed())) {
    return rvErr.StealNSResult();
  }

  NSWindow* parentWindow = GetParentWindow(aParent);
  if (!parentWindow) {
    return NS_ERROR_FAILURE;
  }

  RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aNSSettings));
  if (!settingsX) {
    return NS_ERROR_FAILURE;
  }

  NSPrintInfo* printInfo =
      settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
  if (NS_WARN_IF(!printInfo)) {
    return NS_ERROR_FAILURE;
  }
  [printInfo autorelease];

  NSPageLayout* pageLayout = [NSPageLayout pageLayout];

  nsCOMPtr<nsIPrintSettings> settings = aNSSettings;
  RefPtr<nsPrintSettingsX> settingsXRef = settingsX;
  RefPtr<Promise> promiseForBlock = promise;

  MozPrintPanelDidEndAdapter* adapter =
      [[MozPrintPanelDidEndAdapter alloc] initWithHandler:^(NSInteger button) {
        NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
        if (button != NSModalResponseOK) {
          promiseForBlock->MaybeReject(NS_ERROR_ABORT);
          return;
        }
        // The Page Setup dialog does not include non-standard settings that
        // need to be preserved, separate from what the base printSettings
        // object handles, so we do not need it to adopt the printInfo object
        // here.
        settingsXRef->SetFromPrintInfo(printInfo,
                                       /* aAdoptPrintInfo = */ false);
        nsCOMPtr<nsIPrintSettingsService> printSettingsService =
            do_GetService("@mozilla.org/gfx/printsettings-service;1");
        if (printSettingsService &&
            Preferences::GetBool("print.save_print_settings", false)) {
          uint32_t flags = nsIPrintSettings::kInitSavePaperSize |
                           nsIPrintSettings::kInitSaveOrientation |
                           nsIPrintSettings::kInitSaveScaling;
          printSettingsService->MaybeSavePrintSettingsToPrefs(settings, flags);
        }
        promiseForBlock->MaybeResolveWithUndefined();
        NS_OBJC_END_TRY_IGNORE_BLOCK;
      }];

  [pageLayout beginSheetWithPrintInfo:printInfo
                       modalForWindow:parentWindow
                             delegate:adapter
                       didEndSelector:@selector(didEnd:returnCode:contextInfo:)
                          contextInfo:nullptr];

  promise.forget(aPromise);
  return NS_OK;

  NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}

// Accessory view

@interface PrintPanelAccessoryView (Private)

- (NSString*)localizedString:(const char*)aKey;

- (const char*)headerFooterStringForList:(NSPopUpButton*)aList;

- (void)exportHeaderFooterSettings;

- (void)initBundle;

- (NSTextField*)label:(const char*)aLabel
            withFrame:(NSRect)aRect
            alignment:(NSTextAlignment)aAlignment;

- (void)addLabel:(const char*)aLabel
       withFrame:(NSRect)aRect
       alignment:(NSTextAlignment)aAlignment;

- (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect;

- (void)addCenteredLabel:(const char*)aLabel withFrame:(NSRect)aRect;

- (NSButton*)checkboxWithLabel:(const char*)aLabel andFrame:(NSRect)aRect;

- (NSPopUpButton*)headerFooterItemListWithFrame:(NSRect)aRect
                                   selectedItem:
                                       (const nsAString&)aCurrentString;

- (void)addOptionsSection:(bool)aHaveSelection;

- (void)addAppearanceSection;

- (void)addHeaderFooterSection;

- (NSString*)summaryValueForCheckbox:(NSButton*)aCheckbox;

- (NSString*)headerSummaryValue;

- (NSString*)footerSummaryValue;

@end

static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};

@implementation PrintPanelAccessoryView

// Public methods

- (id)initWithSettings:(nsIPrintSettings*)aSettings
         haveSelection:(bool)aHaveSelection {
  [super initWithFrame:NSMakeRect(0, 0, 540, 185)];

  mSettings = aSettings;
  [self initBundle];
  [self addOptionsSection:aHaveSelection];
  [self addAppearanceSection];
  [self addHeaderFooterSection];

  return self;
}

- (void)exportSettings {
  mSettings->SetPrintSelectionOnly([mPrintSelectionOnlyCheckbox state] ==
                                   NSControlStateValueOn);
  mSettings->SetShrinkToFit([mShrinkToFitCheckbox state] ==
                            NSControlStateValueOn);
  mSettings->SetPrintBGColors([mPrintBGColorsCheckbox state] ==
                              NSControlStateValueOn);
  mSettings->SetPrintBGImages([mPrintBGImagesCheckbox state] ==
                              NSControlStateValueOn);

  [self exportHeaderFooterSettings];
}

- (void)dealloc {
  NS_IF_RELEASE(mPrintBundle);
  [super dealloc];
}

// Localization

- (void)initBundle {
  nsCOMPtr<nsIStringBundleService> bundleSvc =
      do_GetService(NS_STRINGBUNDLE_CONTRACTID);
  bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties",
                          &mPrintBundle);
}

- (NSString*)localizedString:(const char*)aKey {
  if (!mPrintBundle) return @"";

  nsAutoString intlString;
  mPrintBundle->GetStringFromName(aKey, intlString);
  NSMutableString* s = [NSMutableString
      stringWithUTF8String:NS_ConvertUTF16toUTF8(intlString).get()];

  // Remove all underscores (they're used in the GTK dialog for accesskeys).
  [s replaceOccurrencesOfString:@"_"
                     withString:@""
                        options:0
                          range:NSMakeRange(0, [s length])];
  return s;
}

// Widget helpers

- (NSTextField*)label:(const char*)aLabel
            withFrame:(NSRect)aRect
            alignment:(NSTextAlignment)aAlignment {
  NSTextField* label = [[[NSTextField alloc] initWithFrame:aRect] autorelease];
  [label setStringValue:[self localizedString:aLabel]];
  [label setEditable:NO];
  [label setSelectable:NO];
  [label setBezeled:NO];
  [label setBordered:NO];
  [label setDrawsBackground:NO];
  [label setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
  [label setAlignment:aAlignment];
  return label;
}

- (void)addLabel:(const char*)aLabel
       withFrame:(NSRect)aRect
       alignment:(NSTextAlignment)aAlignment {
  NSTextField* label = [self label:aLabel withFrame:aRect alignment:aAlignment];
  [self addSubview:label];
}

- (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect {
  [self addLabel:aLabel withFrame:aRect alignment:NSTextAlignmentRight];
}

- (void)addCenteredLabel:(const char*)aLabel withFrame:(NSRect)aRect {
  [self addLabel:aLabel withFrame:aRect alignment:NSTextAlignmentCenter];
}

- (NSButton*)checkboxWithLabel:(const char*)aLabel andFrame:(NSRect)aRect {
  aRect.origin.y += 4.0f;
  NSButton* checkbox = [[[NSButton alloc] initWithFrame:aRect] autorelease];
  [checkbox setButtonType:NSButtonTypeSwitch];
  [checkbox setTitle:[self localizedString:aLabel]];
  [checkbox setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
  [checkbox sizeToFit];
  return checkbox;
}

- (NSPopUpButton*)headerFooterItemListWithFrame:(NSRect)aRect
                                   selectedItem:
                                       (const nsAString&)aCurrentString {
  NSPopUpButton* list = [[[NSPopUpButton alloc] initWithFrame:aRect
                                                    pullsDown:NO] autorelease];
  [list setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
  [[list cell] setControlSize:NSControlSizeSmall];
  NSArray* items = [NSArray
      arrayWithObjects:[self localizedString:"headerFooterBlank"],
                       [self localizedString:"headerFooterTitle"],
                       [self localizedString:"headerFooterURL"],
                       [self localizedString:"headerFooterDate"],
                       [self localizedString:"headerFooterPage"],
                       [self localizedString:"headerFooterPageTotal"], nil];
  [list addItemsWithTitles:items];

  NS_ConvertUTF16toUTF8 currentStringUTF8(aCurrentString);
  for (unsigned int i = 0; i < std::size(sHeaderFooterTags); i++) {
    if (!strcmp(currentStringUTF8.get(), sHeaderFooterTags[i])) {
      [list selectItemAtIndex:i];
      break;
    }
  }

  return list;
}

// Build sections

- (void)addOptionsSection:(bool)aHaveSelection {
  // Title
  [self addLabel:"optionsTitleMac" withFrame:NSMakeRect(0, 155, 151, 22)];

  // "Print Selection Only"
  mPrintSelectionOnlyCheckbox =
      [self checkboxWithLabel:"selectionOnly"
                     andFrame:NSMakeRect(156, 155, 0, 0)];
  [mPrintSelectionOnlyCheckbox setEnabled:aHaveSelection];

  if (mSettings->GetPrintSelectionOnly()) {
    [mPrintSelectionOnlyCheckbox setState:NSControlStateValueOn];
  }

  [self addSubview:mPrintSelectionOnlyCheckbox];

  // "Shrink To Fit"
  mShrinkToFitCheckbox = [self checkboxWithLabel:"shrinkToFit"
                                        andFrame:NSMakeRect(156, 133, 0, 0)];

  bool shrinkToFit;
  mSettings->GetShrinkToFit(&shrinkToFit);
  [mShrinkToFitCheckbox
      setState:(shrinkToFit ? NSControlStateValueOn : NSControlStateValueOff)];

  [self addSubview:mShrinkToFitCheckbox];
}

- (void)addAppearanceSection {
  // Title
  [self addLabel:"appearanceTitleMac" withFrame:NSMakeRect(0, 103, 151, 22)];

  // "Print Background Colors"
  mPrintBGColorsCheckbox = [self checkboxWithLabel:"printBGColors"
                                          andFrame:NSMakeRect(156, 103, 0, 0)];

  bool geckoBool = mSettings->GetPrintBGColors();
  [mPrintBGColorsCheckbox
      setState:(geckoBool ? NSControlStateValueOn : NSControlStateValueOff)];

  [self addSubview:mPrintBGColorsCheckbox];

  // "Print Background Images"
  mPrintBGImagesCheckbox = [self checkboxWithLabel:"printBGImages"
                                          andFrame:NSMakeRect(156, 81, 0, 0)];

  geckoBool = mSettings->GetPrintBGImages();
  [mPrintBGImagesCheckbox
      setState:(geckoBool ? NSControlStateValueOn : NSControlStateValueOff)];

  [self addSubview:mPrintBGImagesCheckbox];
}

- (void)addHeaderFooterSection {
  // Labels
  [self addLabel:"pageHeadersTitleMac" withFrame:NSMakeRect(0, 44, 151, 22)];
  [self addLabel:"pageFootersTitleMac" withFrame:NSMakeRect(0, 0, 151, 22)];
  [self addCenteredLabel:"left" withFrame:NSMakeRect(156, 22, 100, 22)];
  [self addCenteredLabel:"center" withFrame:NSMakeRect(262, 22, 100, 22)];
  [self addCenteredLabel:"right" withFrame:NSMakeRect(368, 22, 100, 22)];

  // Lists
  nsString sel;

  mSettings->GetHeaderStrLeft(sel);
  mHeaderLeftList =
      [self headerFooterItemListWithFrame:NSMakeRect(156, 44, 100, 22)
                             selectedItem:sel];
  [self addSubview:mHeaderLeftList];

  mSettings->GetHeaderStrCenter(sel);
  mHeaderCenterList =
      [self headerFooterItemListWithFrame:NSMakeRect(262, 44, 100, 22)
                             selectedItem:sel];
  [self addSubview:mHeaderCenterList];

  mSettings->GetHeaderStrRight(sel);
  mHeaderRightList =
      [self headerFooterItemListWithFrame:NSMakeRect(368, 44, 100, 22)
                             selectedItem:sel];
  [self addSubview:mHeaderRightList];

  mSettings->GetFooterStrLeft(sel);
  mFooterLeftList =
      [self headerFooterItemListWithFrame:NSMakeRect(156, 0, 100, 22)
                             selectedItem:sel];
  [self addSubview:mFooterLeftList];

  mSettings->GetFooterStrCenter(sel);
  mFooterCenterList =
      [self headerFooterItemListWithFrame:NSMakeRect(262, 0, 100, 22)
                             selectedItem:sel];
  [self addSubview:mFooterCenterList];

  mSettings->GetFooterStrRight(sel);
  mFooterRightList =
      [self headerFooterItemListWithFrame:NSMakeRect(368, 0, 100, 22)
                             selectedItem:sel];
  [self addSubview:mFooterRightList];
}

// Export settings

- (const char*)headerFooterStringForList:(NSPopUpButton*)aList {
  NSInteger index = [aList indexOfSelectedItem];
  NS_ASSERTION(index < NSInteger(std::size(sHeaderFooterTags)),
               "Index of dropdown is higher than expected!");
  return sHeaderFooterTags[index];
}

- (void)exportHeaderFooterSettings {
  const char* headerFooterStr;
  headerFooterStr = [self headerFooterStringForList:mHeaderLeftList];
  mSettings->SetHeaderStrLeft(NS_ConvertUTF8toUTF16(headerFooterStr));

  headerFooterStr = [self headerFooterStringForList:mHeaderCenterList];
  mSettings->SetHeaderStrCenter(NS_ConvertUTF8toUTF16(headerFooterStr));

  headerFooterStr = [self headerFooterStringForList:mHeaderRightList];
  mSettings->SetHeaderStrRight(NS_ConvertUTF8toUTF16(headerFooterStr));

  headerFooterStr = [self headerFooterStringForList:mFooterLeftList];
  mSettings->SetFooterStrLeft(NS_ConvertUTF8toUTF16(headerFooterStr));

  headerFooterStr = [self headerFooterStringForList:mFooterCenterList];
  mSettings->SetFooterStrCenter(NS_ConvertUTF8toUTF16(headerFooterStr));

  headerFooterStr = [self headerFooterStringForList:mFooterRightList];
  mSettings->SetFooterStrRight(NS_ConvertUTF8toUTF16(headerFooterStr));
}

// Summary

- (NSString*)summaryValueForCheckbox:(NSButton*)aCheckbox {
  if (![aCheckbox isEnabled]) return [self localizedString:"summaryNAValue"];

  return [aCheckbox state] == NSControlStateValueOn
             ? [self localizedString:"summaryOnValue"]
             : [self localizedString:"summaryOffValue"];
}

- (NSString*)headerSummaryValue {
  return [[mHeaderLeftList titleOfSelectedItem]
      stringByAppendingString:
          [@", "
              stringByAppendingString:
                  [[mHeaderCenterList titleOfSelectedItem]
                      stringByAppendingString:
                          [@", " stringByAppendingString:
                                     [mHeaderRightList titleOfSelectedItem]]]]];
}

- (NSString*)footerSummaryValue {
  return [[mFooterLeftList titleOfSelectedItem]
      stringByAppendingString:
          [@", "
              stringByAppendingString:
                  [[mFooterCenterList titleOfSelectedItem]
                      stringByAppendingString:
                          [@", " stringByAppendingString:
                                     [mFooterRightList titleOfSelectedItem]]]]];
}

- (NSArray*)localizedSummaryItems {
  return [NSArray
      arrayWithObjects:
          [NSDictionary
              dictionaryWithObjectsAndKeys:
                  [self localizedString:"summarySelectionOnlyTitle"],
                  NSPrintPanelAccessorySummaryItemNameKey,
                  [self summaryValueForCheckbox:mPrintSelectionOnlyCheckbox],
                  NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
          [NSDictionary dictionaryWithObjectsAndKeys:
                            [self localizedString:"summaryShrinkToFitTitle"],
                            NSPrintPanelAccessorySummaryItemNameKey,
                            [self summaryValueForCheckbox:mShrinkToFitCheckbox],
                            NSPrintPanelAccessorySummaryItemDescriptionKey,
                            nil],
          [NSDictionary
              dictionaryWithObjectsAndKeys:
                  [self localizedString:"summaryPrintBGColorsTitle"],
                  NSPrintPanelAccessorySummaryItemNameKey,
                  [self summaryValueForCheckbox:mPrintBGColorsCheckbox],
                  NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
          [NSDictionary
              dictionaryWithObjectsAndKeys:
                  [self localizedString:"summaryPrintBGImagesTitle"],
                  NSPrintPanelAccessorySummaryItemNameKey,
                  [self summaryValueForCheckbox:mPrintBGImagesCheckbox],
                  NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
          [NSDictionary dictionaryWithObjectsAndKeys:
                            [self localizedString:"summaryHeaderTitle"],
                            NSPrintPanelAccessorySummaryItemNameKey,
                            [self headerSummaryValue],
                            NSPrintPanelAccessorySummaryItemDescriptionKey,
                            nil],
          [NSDictionary dictionaryWithObjectsAndKeys:
                            [self localizedString:"summaryFooterTitle"],
                            NSPrintPanelAccessorySummaryItemNameKey,
                            [self footerSummaryValue],
                            NSPrintPanelAccessorySummaryItemDescriptionKey,
                            nil],
          nil];
}

@end

// Accessory controller

@implementation PrintPanelAccessoryController

- (id)initWithSettings:(nsIPrintSettings*)aSettings
         haveSelection:(bool)aHaveSelection {
  [super initWithNibName:nil bundle:nil];

  NSView* accView =
      [[PrintPanelAccessoryView alloc] initWithSettings:aSettings
                                          haveSelection:aHaveSelection];
  [self setView:accView];
  [accView release];
  return self;
}

- (void)exportSettings {
  return [(PrintPanelAccessoryView*)[self view] exportSettings];
}

- (NSArray*)localizedSummaryItems {
  return [(PrintPanelAccessoryView*)[self view] localizedSummaryItems];
}

@end

[Dauer der Verarbeitung: 0.18 Sekunden, vorverarbeitet 2026-09-29]