/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * This file is part of the LibreOffice project. * * 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/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */#include <printdlg.hxx>#include <svdata.hxx>#include <strings.hrc>#include <bitmaps.hlst>#include <vcl/print.hxx>#include <vcl/dialog.hxx>#include <vcl/button.hxx>#include <vcl/wall.hxx>#include <vcl/status.hxx>#include <vcl/decoview.hxx>#include <vcl/configsettings.hxx>#include <vcl/help.hxx>#include <vcl/layout.hxx>#include <vcl/svapp.hxx>#include <vcl/unohelp.hxx>#include <vcl/settings.hxx>#include <vcl/builderfactory.hxx>#include <vcl/lstbox.hxx>#include <jobset.h>#include <unotools/localedatawrapper.hxx>#include <rtl/strbuf.hxx>#include <sal/log.hxx>#include <com/sun/star/lang/XMultiServiceFactory.hpp>#include <com/sun/star/container/XNameAccess.hpp>#include <com/sun/star/beans/PropertyValue.hpp>#include <com/sun/star/awt/Size.hpp>usingnamespacevcl;usingnamespacecom::sun::star;usingnamespacecom::sun::star::uno;usingnamespacecom::sun::star::lang;usingnamespacecom::sun::star::container;usingnamespacecom::sun::star::beans;extern"C"SAL_DLLPUBLIC_EXPORTvoidmakePrintPreviewWindow(VclPtr<vcl::Window>&rRet,VclPtr<vcl::Window>&pParent,VclBuilder::stringmap&)<--- The function 'makePrintPreviewWindow' is never used.{rRet=VclPtr<PrintDialog::PrintPreviewWindow>::Create(pParent);}extern"C"SAL_DLLPUBLIC_EXPORTvoidmakeShowNupOrderWindow(VclPtr<vcl::Window>&rRet,VclPtr<vcl::Window>&pParent,VclBuilder::stringmap&)<--- The function 'makeShowNupOrderWindow' is never used.{rRet=VclPtr<PrintDialog::ShowNupOrderWindow>::Create(pParent);}PrintDialog::PrintPreviewWindow::PrintPreviewWindow(vcl::Window*i_pParent):Window(i_pParent,0),maMtf(),maOrigSize(10,10),maPreviewSize(),mnDPIX(Application::GetDefaultDevice()->GetDPIX()),mnDPIY(Application::GetDefaultDevice()->GetDPIY()),maPreviewBitmap(),maReplacementString(),maToolTipString(VclResId(SV_PRINT_PRINTPREVIEW_TXT)),mbGreyscale(false),maHorzDim(VclPtr<FixedLine>::Create(this,WB_HORZ|WB_CENTER)),maVertDim(VclPtr<FixedLine>::Create(this,WB_VERT|WB_VCENTER)){SetPaintTransparent(true);SetBackground();maHorzDim->Show();maVertDim->Show();maHorzDim->SetText("2.0in");maVertDim->SetText("2.0in");}PrintDialog::PrintPreviewWindow::~PrintPreviewWindow(){disposeOnce();}voidPrintDialog::PrintPreviewWindow::dispose(){maHorzDim.disposeAndClear();maVertDim.disposeAndClear();Window::dispose();}voidPrintDialog::PrintPreviewWindow::Resize(){SizeaNewSize(GetSizePixel());longnTextHeight=maHorzDim->GetTextHeight();// leave small space for decorationaNewSize.AdjustWidth(-(nTextHeight+2));aNewSize.AdjustHeight(-(nTextHeight+2));SizeaScaledSize;doublefScale=1.0;// #i106435# catch corner case of Size(0,0)SizeaOrigSize(maOrigSize);if(aOrigSize.Width()<1)aOrigSize.setWidth(aNewSize.Width());if(aOrigSize.Height()<1)aOrigSize.setHeight(aNewSize.Height());if(aOrigSize.Width()>aOrigSize.Height()){aScaledSize=Size(aNewSize.Width(),aNewSize.Width()*aOrigSize.Height()/aOrigSize.Width());if(aScaledSize.Height()>aNewSize.Height())fScale=double(aNewSize.Height())/double(aScaledSize.Height());}else{aScaledSize=Size(aNewSize.Height()*aOrigSize.Width()/aOrigSize.Height(),aNewSize.Height());if(aScaledSize.Width()>aNewSize.Width())fScale=double(aNewSize.Width())/double(aScaledSize.Width());}aScaledSize.setWidth(long(aScaledSize.Width()*fScale));aScaledSize.setHeight(long(aScaledSize.Height()*fScale));maPreviewSize=aScaledSize;// position dimension linesPointaRef(nTextHeight+(aNewSize.Width()-maPreviewSize.Width())/2,nTextHeight+(aNewSize.Height()-maPreviewSize.Height())/2);maHorzDim->SetPosSizePixel(Point(aRef.X(),aRef.Y()-nTextHeight),Size(maPreviewSize.Width(),nTextHeight));maVertDim->SetPosSizePixel(Point(aRef.X()-nTextHeight,aRef.Y()),Size(nTextHeight,maPreviewSize.Height()));// check and evtl. recreate preview bitmappreparePreviewBitmap();}voidPrintDialog::PrintPreviewWindow::Paint(vcl::RenderContext&rRenderContext,consttools::Rectangle&){longnTextHeight=maHorzDim->GetTextHeight();SizeaSize(GetSizePixel());PointaOffset((aSize.Width()-maPreviewSize.Width()+nTextHeight)/2,(aSize.Height()-maPreviewSize.Height()+nTextHeight)/2);if(!maReplacementString.isEmpty()){// replacement is activerRenderContext.Push();FontaFont(rRenderContext.GetSettings().GetStyleSettings().GetLabelFont());SetZoomedPointFont(rRenderContext,aFont);tools::RectangleaTextRect(aOffset+Point(2,2),Size(maPreviewSize.Width()-4,maPreviewSize.Height()-4));rRenderContext.DrawText(aTextRect,maReplacementString,DrawTextFlags::Center|DrawTextFlags::VCenter|DrawTextFlags::WordBreak|DrawTextFlags::MultiLine);rRenderContext.Pop();}else{BitmapExaPreviewBitmap(maPreviewBitmap);// This explicit force-to-scale allows us to get the// mentioned best quality here. Unfortunately this is// currently not sure when using just ::DrawBitmap with// a defined size or ::DrawOutDevaPreviewBitmap.Scale(maPreviewSize,BmpScaleFlag::BestQuality);rRenderContext.DrawBitmapEx(aOffset,aPreviewBitmap);}tools::RectangleaFrameRect(aOffset+Point(-1,-1),Size(maPreviewSize.Width()+2,maPreviewSize.Height()+2));DecorationViewaDecorationView(&rRenderContext);aDecorationView.DrawFrame(aFrameRect,DrawFrameStyle::Group);}voidPrintDialog::PrintPreviewWindow::Command(constCommandEvent&rEvt){if(rEvt.GetCommand()==CommandEventId::Wheel){constCommandWheelData*pWheelData=rEvt.GetWheelData();PrintDialog*pDlg=dynamic_cast<PrintDialog*>(GetParentDialog());if(pDlg){if(pWheelData->GetDelta()>0)pDlg->previewForward();elseif(pWheelData->GetDelta()<0)pDlg->previewBackward();}}}voidPrintDialog::PrintPreviewWindow::setPreview(constGDIMetaFile&i_rNewPreview,constSize&i_rOrigSize,constOUString&i_rPaperName,constOUString&i_rReplacement,sal_Int32i_nDPIX,sal_Int32i_nDPIY,booli_bGreyscale){OUStringBufferaBuf(256);aBuf.append(maToolTipString);SetQuickHelpText(aBuf.makeStringAndClear());maMtf=i_rNewPreview;mnDPIX=i_nDPIX;mnDPIY=i_nDPIY;maOrigSize=i_rOrigSize;maReplacementString=i_rReplacement;mbGreyscale=i_bGreyscale;// use correct measurementsconstLocaleDataWrapper&rLocWrap(GetSettings().GetLocaleDataWrapper());MapUniteUnit=MapUnit::MapMM;intnDigits=0;if(rLocWrap.getMeasurementSystemEnum()==MeasurementSystem::US){eUnit=MapUnit::Map100thInch;nDigits=2;}SizeaLogicPaperSize(LogicToLogic(i_rOrigSize,MapMode(MapUnit::Map100thMM),MapMode(eUnit)));OUStringaNumText(rLocWrap.getNum(aLogicPaperSize.Width(),nDigits));aBuf.append(aNumText).append(u' ');aBuf.appendAscii(eUnit==MapUnit::MapMM?"mm":"in");if(!i_rPaperName.isEmpty()){aBuf.append(" (");aBuf.append(i_rPaperName);aBuf.append(')');}maHorzDim->SetText(aBuf.makeStringAndClear());aNumText=rLocWrap.getNum(aLogicPaperSize.Height(),nDigits);aBuf.append(aNumText).append(u' ');aBuf.appendAscii(eUnit==MapUnit::MapMM?"mm":"in");maVertDim->SetText(aBuf.makeStringAndClear());// We have a new Metafile and evtl. a new page, so we need to reset// the PreviewBitmap to force new creationmaPreviewBitmap=Bitmap();// sets/calculates e.g. maPreviewSize// also triggers preparePreviewBitmap()Resize();Invalidate();}voidPrintDialog::PrintPreviewWindow::preparePreviewBitmap(){if(maPreviewSize.getWidth()<0||maPreviewSize.getHeight()<0){// not yet fully initialized, no need to prepare anythingreturn;}// define an allowed number of pixels, also see// defaults for primitive renderers and similar. This// might be centralized and made dependent of 32/64bitconstsal_uInt32nMaxSquarePixels(500000);// check how big (squarePixels) the preview is currently (with// max value of MaxSquarePixels)constsal_uInt32nCurrentSquarePixels(std::min(nMaxSquarePixels,static_cast<sal_uInt32>(maPreviewBitmap.GetSizePixel().getWidth())*static_cast<sal_uInt32>(maPreviewBitmap.GetSizePixel().getHeight())));// check how big (squarePixels) the preview needs to be (with// max value of MaxSquarePixels)constsal_uInt32nRequiredSquarePixels(std::min(nMaxSquarePixels,static_cast<sal_uInt32>(maPreviewSize.getWidth())*static_cast<sal_uInt32>(maPreviewSize.getHeight())));// check if preview is big enough. Use a scaling value in// the comparison to not get bigger at the last possible moment// what may look awkward and pixelated (again). This means// to use a percentage value - if we have at least// that value of required pixels, we are good.staticdoublefPreventAwkwardFactor(1.35);// 35%if(nCurrentSquarePixels>=static_cast<sal_uInt32>(nRequiredSquarePixels*fPreventAwkwardFactor)){// at this place we also could add a mechanism to let the preview// bitmap 'shrink' again if it is currently 'too big' -> bigger// than required. I think this is not necessary for now.// already sufficient, done.return;}// check if we have enough square pixels e.g for 8x8 pixelsif(nRequiredSquarePixels<64){// too small preview - let it emptyreturn;}// Calculate nPlannedSquarePixels which is the required size// expanded by a percentage (with max value of MaxSquarePixels)staticdoublefExtraSpaceFactor(1.65);// 65%constsal_uInt32nPlannedSquarePixels(std::min(nMaxSquarePixels,static_cast<sal_uInt32>(maPreviewSize.getWidth()*fExtraSpaceFactor)*static_cast<sal_uInt32>(maPreviewSize.getHeight()*fExtraSpaceFactor)));// calculate back new width and height - it might have been// truncated by MaxSquarePixels.// We know that w*h == nPlannedSquarePixels and w/h == ratioconstdoublefRatio(static_cast<double>(maPreviewSize.getWidth())/static_cast<double>(maPreviewSize.getHeight()));constdoublefNewWidth(sqrt(static_cast<double>(nPlannedSquarePixels)*fRatio));constdoublefNewHeight(sqrt(static_cast<double>(nPlannedSquarePixels)/fRatio));constSizeaScaledSize(basegfx::fround(fNewWidth),basegfx::fround(fNewHeight));// check if this eventual maximum is already reached// due to having hit the MaxSquarePixels. Due to using// an integer AspectRatio, we cannot make a numeric exact// comparison - we need to compare if we are closeconstdoublefScaledSizeSquare(static_cast<double>(aScaledSize.getWidth()*aScaledSize.getHeight()));constdoublefPreviewSizeSquare(static_cast<double>(maPreviewBitmap.GetSizePixel().getWidth()*maPreviewBitmap.GetSizePixel().getHeight()));// test as equal up to 0.1% (0.001)if(fPreviewSizeSquare!=0.0&&fabs((fScaledSizeSquare/fPreviewSizeSquare)-1.0)<0.001){// maximum is reached, avoid bigger scalingreturn;}// create temporary VDev and render to itScopedVclPtrInstance<VirtualDevice>pPrerenderVDev(*Application::GetDefaultDevice());pPrerenderVDev->SetOutputSizePixel(aScaledSize,false);pPrerenderVDev->SetReferenceDevice(mnDPIX,mnDPIY);pPrerenderVDev->EnableOutput();pPrerenderVDev->SetBackground(Wallpaper(COL_WHITE));GDIMetaFileaMtf(maMtf);SizeaVDevSize(pPrerenderVDev->GetOutputSizePixel());constSizeaLogicSize(pPrerenderVDev->PixelToLogic(aVDevSize,MapMode(MapUnit::Map100thMM)));SizeaOrigSize(maOrigSize);if(aOrigSize.Width()<1)aOrigSize.setWidth(aLogicSize.Width());if(aOrigSize.Height()<1)aOrigSize.setHeight(aLogicSize.Height());doublefScale=double(aLogicSize.Width())/double(aOrigSize.Width());pPrerenderVDev->Erase();pPrerenderVDev->Push();pPrerenderVDev->SetMapMode(MapMode(MapUnit::Map100thMM));DrawModeFlagsnOldDrawMode=pPrerenderVDev->GetDrawMode();if(mbGreyscale)pPrerenderVDev->SetDrawMode(pPrerenderVDev->GetDrawMode()|(DrawModeFlags::GrayLine|DrawModeFlags::GrayFill|DrawModeFlags::GrayText|DrawModeFlags::GrayBitmap|DrawModeFlags::GrayGradient));aMtf.WindStart();aMtf.Scale(fScale,fScale);aMtf.WindStart();constAntialiasingFlagsnOriginalAA(pPrerenderVDev->GetAntialiasing());pPrerenderVDev->SetAntialiasing(nOriginalAA|AntialiasingFlags::EnableB2dDraw);aMtf.Play(pPrerenderVDev.get(),Point(0,0),aLogicSize);pPrerenderVDev->SetAntialiasing(nOriginalAA);pPrerenderVDev->Pop();SetMapMode(MapMode(MapUnit::MapPixel));pPrerenderVDev->SetMapMode(MapMode(MapUnit::MapPixel));maPreviewBitmap=pPrerenderVDev->GetBitmapEx(Point(0,0),aVDevSize);pPrerenderVDev->SetDrawMode(nOldDrawMode);}PrintDialog::ShowNupOrderWindow::ShowNupOrderWindow(vcl::Window*i_pParent):Window(i_pParent,WB_NOBORDER),mnOrderMode(NupOrderType::LRTB),mnRows(1),mnColumns(1){SetBackground(Wallpaper(GetSettings().GetStyleSettings().GetFieldColor()));}SizePrintDialog::ShowNupOrderWindow::GetOptimalSize()const{returnSize(70,70);}voidPrintDialog::ShowNupOrderWindow::Paint(vcl::RenderContext&rRenderContext,consttools::Rectangle&i_rRect){Window::Paint(rRenderContext,i_rRect);rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));rRenderContext.SetTextColor(rRenderContext.GetSettings().GetStyleSettings().GetFieldTextColor());intnPages=mnRows*mnColumns;FontaFont(rRenderContext.GetSettings().GetStyleSettings().GetFieldFont());aFont.SetFontSize(Size(0,24));rRenderContext.SetFont(aFont);SizeaSampleTextSize(rRenderContext.GetTextWidth(OUString::number(nPages+1)),rRenderContext.GetTextHeight());SizeaOutSize(GetOutputSizePixel());SizeaSubSize(aOutSize.Width()/mnColumns,aOutSize.Height()/mnRows);// calculate font size: shrink the sample text so it fitsdoublefX=double(aSubSize.Width())/double(aSampleTextSize.Width());doublefY=double(aSubSize.Height())/double(aSampleTextSize.Height());doublefScale=(fX<fY)?fX:fY;longnFontHeight=long(24.0*fScale)-3;if(nFontHeight<5)nFontHeight=5;aFont.SetFontSize(Size(0,nFontHeight));rRenderContext.SetFont(aFont);longnTextHeight=rRenderContext.GetTextHeight();for(inti=0;i<nPages;i++){OUStringaPageText(OUString::number(i+1));intnX=0,nY=0;switch(mnOrderMode){caseNupOrderType::LRTB:nX=(i%mnColumns);nY=(i/mnColumns);break;caseNupOrderType::TBLR:nX=(i/mnRows);nY=(i%mnRows);break;caseNupOrderType::RLTB:nX=mnColumns-1-(i%mnColumns);nY=(i/mnColumns);break;caseNupOrderType::TBRL:nX=mnColumns-1-(i/mnRows);nY=(i%mnRows);break;}SizeaTextSize(rRenderContext.GetTextWidth(aPageText),nTextHeight);intnDeltaX=(aSubSize.Width()-aTextSize.Width())/2;intnDeltaY=(aSubSize.Height()-aTextSize.Height())/2;rRenderContext.DrawText(Point(nX*aSubSize.Width()+nDeltaX,nY*aSubSize.Height()+nDeltaY),aPageText);}DecorationViewaDecorationView(&rRenderContext);aDecorationView.DrawFrame(tools::Rectangle(Point(0,0),aOutSize),DrawFrameStyle::Group);}PrintDialog::NUpTabPage::NUpTabPage(VclBuilder*pUIBuilder){pUIBuilder->get(mpPagesBtn,"pagespersheetbtn");pUIBuilder->get(mpBrochureBtn,"brochure");pUIBuilder->get(mpPagesBoxTitleTxt,"pagespersheettxt");pUIBuilder->get(mpNupPagesBox,"paperspersheetlb");pUIBuilder->get(mpNupNumPagesTxt,"pagestxt");pUIBuilder->get(mpNupColEdt,"pagecols");pUIBuilder->get(mpNupTimesTxt,"by");pUIBuilder->get(mpNupRowsEdt,"pagerows");pUIBuilder->get(mpPageMarginTxt1,"pagemargintxt1");pUIBuilder->get(mpPageMarginEdt,"pagemarginsb");pUIBuilder->get(mpPageMarginTxt2,"pagemargintxt2");pUIBuilder->get(mpSheetMarginTxt1,"sheetmargintxt1");pUIBuilder->get(mpSheetMarginEdt,"sheetmarginsb");pUIBuilder->get(mpSheetMarginTxt2,"sheetmargintxt2");pUIBuilder->get(mpNupOrientationTxt,"orientationtxt");pUIBuilder->get(mpNupOrientationBox,"orientationlb");pUIBuilder->get(mpNupOrderTxt,"ordertxt");pUIBuilder->get(mpNupOrderBox,"orderlb");pUIBuilder->get(mpNupOrderWin,"orderpreview");pUIBuilder->get(mpBorderCB,"bordercb");}voidPrintDialog::NUpTabPage::enableNupControls(boolbEnable){mpNupPagesBox->Enable(bEnable);mpNupNumPagesTxt->Enable(bEnable);mpNupColEdt->Enable(bEnable);mpNupTimesTxt->Enable(bEnable);mpNupRowsEdt->Enable(bEnable);mpPageMarginTxt1->Enable(bEnable);mpPageMarginEdt->Enable(bEnable);mpPageMarginTxt2->Enable(bEnable);mpSheetMarginTxt1->Enable(bEnable);mpSheetMarginEdt->Enable(bEnable);mpSheetMarginTxt2->Enable(bEnable);mpNupOrientationTxt->Enable(bEnable);mpNupOrientationBox->Enable(bEnable);mpNupOrderTxt->Enable(bEnable);mpNupOrderBox->Enable(bEnable);mpNupOrderWin->Enable(bEnable);mpBorderCB->Enable(bEnable);}voidPrintDialog::NUpTabPage::showAdvancedControls(booli_bShow){mpNupNumPagesTxt->Show(i_bShow);mpNupColEdt->Show(i_bShow);mpNupTimesTxt->Show(i_bShow);mpNupRowsEdt->Show(i_bShow);mpPageMarginTxt1->Show(i_bShow);mpPageMarginEdt->Show(i_bShow);mpPageMarginTxt2->Show(i_bShow);mpSheetMarginTxt1->Show(i_bShow);mpSheetMarginEdt->Show(i_bShow);mpSheetMarginTxt2->Show(i_bShow);mpNupOrientationTxt->Show(i_bShow);mpNupOrientationBox->Show(i_bShow);}voidPrintDialog::NUpTabPage::initFromMultiPageSetup(constvcl::PrinterController::MultiPageSetup&i_rMPS){mpNupOrderWin->Show();mpPagesBtn->Check();mpBrochureBtn->Show(false);// setup field units for metric fieldsconstLocaleDataWrapper&rLocWrap(mpPageMarginEdt->GetLocaleDataWrapper());FieldUniteUnit=FieldUnit::MM;sal_uInt16nDigits=0;if(rLocWrap.getMeasurementSystemEnum()==MeasurementSystem::US){eUnit=FieldUnit::INCH;nDigits=2;}// set unitsmpPageMarginEdt->SetUnit(eUnit);mpSheetMarginEdt->SetUnit(eUnit);// set precisionmpPageMarginEdt->SetDecimalDigits(nDigits);mpSheetMarginEdt->SetDecimalDigits(nDigits);mpSheetMarginEdt->SetValue(mpSheetMarginEdt->Normalize(i_rMPS.nLeftMargin),FieldUnit::MM_100TH);mpPageMarginEdt->SetValue(mpPageMarginEdt->Normalize(i_rMPS.nHorizontalSpacing),FieldUnit::MM_100TH);mpBorderCB->Check(i_rMPS.bDrawBorder);mpNupRowsEdt->SetValue(i_rMPS.nRows);mpNupColEdt->SetValue(i_rMPS.nColumns);mpNupOrderBox->SelectEntryPos(static_cast<sal_Int32>(i_rMPS.nOrder));if(i_rMPS.nRows!=1||i_rMPS.nColumns!=1){mpNupPagesBox->SelectEntryPos(mpNupPagesBox->GetEntryCount()-1);showAdvancedControls(true);mpNupOrderWin->setValues(i_rMPS.nOrder,i_rMPS.nColumns,i_rMPS.nRows);}}PrintDialog::JobTabPage::JobTabPage(VclBuilder*pUIBuilder):maCollateBmp(SV_PRINT_COLLATE_BMP),maNoCollateBmp(SV_PRINT_NOCOLLATE_BMP),mbCollateAlwaysOff(false){pUIBuilder->get(mpPrinters,"printers");pUIBuilder->get(mpStatusTxt,"status");pUIBuilder->get(mpLocationTxt,"location");pUIBuilder->get(mpCommentTxt,"comment");pUIBuilder->get(mpSetupButton,"setup");pUIBuilder->get(mpCopyCountField,"copycount");pUIBuilder->get(mpCollateBox,"collate");pUIBuilder->get(mpCollateImage,"collateimage");pUIBuilder->get(mpReverseOrderBox,"reverseorder");// HACK: this is not a dropdown box, but the dropdown line count// sets the results of GetOptimalSize in a normal ListBoxmpPrinters->SetDropDownLineCount(4);}voidPrintDialog::JobTabPage::readFromSettings(){SettingsConfigItem*pItem=SettingsConfigItem::get();OUStringaValue;aValue=pItem->getValue("PrintDialog","CollateBox");if(aValue.equalsIgnoreAsciiCase("alwaysoff")){mbCollateAlwaysOff=true;mpCollateBox->Check(false);mpCollateBox->Enable(false);}else{mbCollateAlwaysOff=false;aValue=pItem->getValue("PrintDialog","Collate");mpCollateBox->Check(aValue.equalsIgnoreAsciiCase("true"));}}voidPrintDialog::JobTabPage::storeToSettings(){SettingsConfigItem*pItem=SettingsConfigItem::get();pItem->setValue("PrintDialog","CopyCount",mpCopyCountField->GetText());pItem->setValue("PrintDialog","Collate",mpCollateBox->IsChecked()?OUString("true"):OUString("false"));}PrintDialog::OutputOptPage::OutputOptPage(VclBuilder*pUIBuilder){pUIBuilder->get(mpCollateSingleJobsBox,"singleprintjob");pUIBuilder->get(mpPapersizeFromSetup,"papersizefromsetup");}voidPrintDialog::OutputOptPage::readFromSettings(){SettingsConfigItem*pItem=SettingsConfigItem::get();OUStringaValue;aValue=pItem->getValue("PrintDialog","CollateSingleJobs");if(aValue.equalsIgnoreAsciiCase("true")){mpCollateSingleJobsBox->Check();}else{mpCollateSingleJobsBox->Check(false);}}voidPrintDialog::OutputOptPage::storeToSettings(){SettingsConfigItem*pItem=SettingsConfigItem::get();pItem->setValue("PrintDialog","CollateSingleJobs",mpCollateSingleJobsBox->IsChecked()?OUString("true"):OUString("false"));}namespace{boollcl_ListBoxCompare(constOUString&rStr1,constOUString&rStr2){returnListBox::NaturalSortCompare(rStr1,rStr2)<0;}}PrintDialog::PrintDialog(vcl::Window*i_pParent,conststd::shared_ptr<PrinterController>&i_rController):ModalDialog(i_pParent,"PrintDialog","vcl/ui/printdialog.ui"),maPController(i_rController),maNUpPage(m_pUIBuilder.get()),maJobPage(m_pUIBuilder.get()),maOptionsPage(m_pUIBuilder.get()),maNoPageStr(VclResId(SV_PRINT_NOPAGES)),mnCurPage(0),mnCachedPages(0),maPrintToFileText(VclResId(SV_PRINT_TOFILE_TXT)),maDefPrtText(VclResId(SV_PRINT_DEFPRT_TXT)),mbShowLayoutPage(true){get(mpOKButton,"ok");get(mpCancelButton,"cancel");get(mpHelpButton,"help");get(mpForwardBtn,"forward");get(mpBackwardBtn,"backward");get(mpNumPagesText,"totalnumpages");get(mpPageEdit,"pageedit-nospin");get(mpTabCtrl,"tabcontrol");get(mpPreviewWindow,"preview");// save printbutton text, gets exchanged occasionally with print to filemaPrintText=mpOKButton->GetText();// setup preview controlsmpForwardBtn->SetStyle(mpForwardBtn->GetStyle()|WB_BEVELBUTTON);mpBackwardBtn->SetStyle(mpBackwardBtn->GetStyle()|WB_BEVELBUTTON);maPageStr=mpNumPagesText->GetText();// init reverse printmaJobPage.mpReverseOrderBox->Check(maPController->getReversePrint());Printer::updatePrinters();maJobPage.mpPrinters->InsertEntry(maPrintToFileText);// fill printer listboxstd::vector<OUString>rQueues(Printer::GetPrinterQueues());std::sort(rQueues.begin(),rQueues.end(),lcl_ListBoxCompare);for(constauto&rQueue:rQueues){maJobPage.mpPrinters->InsertEntry(rQueue);}// select current printerif(maJobPage.mpPrinters->GetEntryPos(maPController->getPrinter()->GetName())!=LISTBOX_ENTRY_NOTFOUND){maJobPage.mpPrinters->SelectEntry(maPController->getPrinter()->GetName());}else{// fall back to last printerSettingsConfigItem*pItem=SettingsConfigItem::get();OUStringaValue(pItem->getValue("PrintDialog","LastPrinter"));if(maJobPage.mpPrinters->GetEntryPos(aValue)!=LISTBOX_ENTRY_NOTFOUND){maJobPage.mpPrinters->SelectEntry(aValue);maPController->setPrinter(VclPtrInstance<Printer>(aValue));}else{// fall back to default printermaJobPage.mpPrinters->SelectEntry(Printer::GetDefaultPrinterName());maPController->setPrinter(VclPtrInstance<Printer>(Printer::GetDefaultPrinterName()));}}// not printing to filemaPController->resetPrinterOptions(false);// get the first pagepreparePreview(true,true);// update the text fields for the printerupdatePrinterText();// set a select handlermaJobPage.mpPrinters->SetSelectHdl(LINK(this,PrintDialog,SelectHdl));mpTabCtrl->SetActivatePageHdl(LINK(this,PrintDialog,ActivatePageHdl));// setup sizes for N-UpSizeaNupSize(maPController->getPrinter()->PixelToLogic(maPController->getPrinter()->GetPaperSizePixel(),MapMode(MapUnit::Map100thMM)));if(maPController->getPrinter()->GetOrientation()==Orientation::Landscape){maNupLandscapeSize=aNupSize;maNupPortraitSize=Size(aNupSize.Height(),aNupSize.Width());}else{maNupPortraitSize=aNupSize;maNupLandscapeSize=Size(aNupSize.Height(),aNupSize.Width());}maNUpPage.initFromMultiPageSetup(maPController->getMultipage());// setup click handler on the various buttonsmpOKButton->SetClickHdl(LINK(this,PrintDialog,ClickHdl));#ifOSL_DEBUG_LEVEL>1mpCancelButton->SetClickHdl(LINK(this,PrintDialog,ClickHdl));#endifmpHelpButton->SetClickHdl(LINK(this,PrintDialog,ClickHdl));mpForwardBtn->SetClickHdl(LINK(this,PrintDialog,ClickHdl));mpBackwardBtn->SetClickHdl(LINK(this,PrintDialog,ClickHdl));maJobPage.mpCollateBox->SetToggleHdl(LINK(this,PrintDialog,ToggleHdl));maJobPage.mpSetupButton->SetClickHdl(LINK(this,PrintDialog,ClickHdl));maNUpPage.mpBorderCB->SetClickHdl(LINK(this,PrintDialog,ClickHdl));maOptionsPage.mpPapersizeFromSetup->SetToggleHdl(LINK(this,PrintDialog,ToggleHdl));maOptionsPage.mpPapersizeFromSetup->Check(maPController->getPapersizeFromSetup());maJobPage.mpReverseOrderBox->SetToggleHdl(LINK(this,PrintDialog,ToggleHdl));maOptionsPage.mpCollateSingleJobsBox->SetToggleHdl(LINK(this,PrintDialog,ToggleHdl));maNUpPage.mpPagesBtn->SetToggleHdl(LINK(this,PrintDialog,ToggleRadioHdl));// setup modify hdlmpPageEdit->SetModifyHdl(LINK(this,PrintDialog,ModifyHdl));maJobPage.mpCopyCountField->SetModifyHdl(LINK(this,PrintDialog,ModifyHdl));maNUpPage.mpNupRowsEdt->SetModifyHdl(LINK(this,PrintDialog,ModifyHdl));maNUpPage.mpNupColEdt->SetModifyHdl(LINK(this,PrintDialog,ModifyHdl));maNUpPage.mpPageMarginEdt->SetModifyHdl(LINK(this,PrintDialog,ModifyHdl));maNUpPage.mpSheetMarginEdt->SetModifyHdl(LINK(this,PrintDialog,ModifyHdl));// setup select hdlmaNUpPage.mpNupPagesBox->SetSelectHdl(LINK(this,PrintDialog,SelectHdl));maNUpPage.mpNupOrientationBox->SetSelectHdl(LINK(this,PrintDialog,SelectHdl));maNUpPage.mpNupOrderBox->SetSelectHdl(LINK(this,PrintDialog,SelectHdl));// setup optional UI options set by applicationsetupOptionalUI();// remove layout page if unwantedif(!mbShowLayoutPage)mpTabCtrl->RemovePage(mpTabCtrl->GetPageId(2));// restore settings from last runreadFromSettings();// setup dependenciescheckControlDependencies();if(maPController->getBoolProperty("HideHelpButton",false))mpHelpButton->Hide();// set initial focus to "Number of copies"maJobPage.mpCopyCountField->GrabFocus();maJobPage.mpCopyCountField->SetSelection(Selection(0,0xFFFF));updateNupFromPages();}PrintDialog::~PrintDialog(){disposeOnce();}voidPrintDialog::dispose(){mpCustomOptionsUIBuilder.reset();mpTabCtrl.clear();mpPreviewWindow.clear();mpPageEdit.clear();mpNumPagesText.clear();mpBackwardBtn.clear();mpForwardBtn.clear();mpOKButton.clear();mpCancelButton.clear();mpHelpButton.clear();maPController.reset();maControlToPropertyMap.clear();maControlToNumValMap.clear();ModalDialog::dispose();}voidPrintDialog::readFromSettings(){maJobPage.readFromSettings();maOptionsPage.readFromSettings();// read last selected tab page; if it exists, activate itSettingsConfigItem*pItem=SettingsConfigItem::get();OUStringaValue=pItem->getValue("PrintDialog","LastPage");sal_uInt16nCount=mpTabCtrl->GetPageCount();for(sal_uInt16i=0;i<nCount;i++){sal_uInt16nPageId=mpTabCtrl->GetPageId(i);if(aValue==mpTabCtrl->GetPageText(nPageId)){mpTabCtrl->SelectTabPage(nPageId);break;}}// persistent window stateOUStringaWinState(pItem->getValue("PrintDialog","WindowState"));if(!aWinState.isEmpty())SetWindowState(OUStringToOString(aWinState,RTL_TEXTENCODING_UTF8));}voidPrintDialog::storeToSettings(){maJobPage.storeToSettings();maOptionsPage.storeToSettings();// store last selected printerSettingsConfigItem*pItem=SettingsConfigItem::get();pItem->setValue("PrintDialog","ToFile",isPrintToFile()?OUString("true"):OUString("false"));pItem->setValue("PrintDialog","LastPrinter",isPrintToFile()?Printer::GetDefaultPrinterName():maJobPage.mpPrinters->GetSelectedEntry());pItem->setValue("PrintDialog","LastPage",mpTabCtrl->GetPageText(mpTabCtrl->GetCurPageId()));pItem->setValue("PrintDialog","WindowState",OStringToOUString(GetWindowState(),RTL_TEXTENCODING_UTF8));pItem->Commit();}boolPrintDialog::isPrintToFile(){return(maJobPage.mpPrinters->GetSelectedEntryPos()==0);}boolPrintDialog::isCollate(){returnmaJobPage.mpCopyCountField->GetValue()>1&&maJobPage.mpCollateBox->IsChecked();}boolPrintDialog::isSingleJobs(){returnmaOptionsPage.mpCollateSingleJobsBox->IsChecked();}staticvoidsetHelpId(vcl::Window*i_pWindow,constSequence<OUString>&i_rHelpIds,sal_Int32i_nIndex){if(i_nIndex>=0&&i_nIndex<i_rHelpIds.getLength())i_pWindow->SetHelpId(OUStringToOString(i_rHelpIds.getConstArray()[i_nIndex],RTL_TEXTENCODING_UTF8));}staticvoidsetHelpText(vcl::Window*i_pWindow,constSequence<OUString>&i_rHelpTexts,sal_Int32i_nIndex){// without a help text set and the correct smartID,// help texts will be retrieved from the online help systemif(i_nIndex>=0&&i_nIndex<i_rHelpTexts.getLength())i_pWindow->SetHelpText(i_rHelpTexts.getConstArray()[i_nIndex]);}voidPrintDialog::setupOptionalUI(){constSequence<PropertyValue>&rOptions(maPController->getUIOptions());for(inti=0;i<rOptions.getLength();i++){if(rOptions[i].Name=="OptionsUIFile"){OUStringsOptionsUIFile;rOptions[i].Value>>=sOptionsUIFile;vcl::Window*pCustom=get<vcl::Window>("customcontents");mpCustomOptionsUIBuilder.reset(newVclBuilder(pCustom,getUIRootDir(),sOptionsUIFile));vcl::Window*pWindow=mpCustomOptionsUIBuilder->get_widget_root();pWindow->Show();continue;}Sequence<beans::PropertyValue>aOptProp;rOptions[i].Value>>=aOptProp;// extract ui elementOUStringaCtrlType;OStringaID;OUStringaText;OUStringaPropertyName;Sequence<OUString>aChoices;Sequence<sal_Bool>aChoicesDisabled;Sequence<OUString>aHelpTexts;Sequence<OUString>aIDs;Sequence<OUString>aHelpIds;sal_Int64nMinValue=0,nMaxValue=0;OUStringaGroupingHint;OUStringaDependsOnName;sal_Int32nDependsOnValue=0;boolbUseDependencyRow=false;for(intn=0;n<aOptProp.getLength();n++){constbeans::PropertyValue&rEntry(aOptProp[n]);if(rEntry.Name=="ID"){rEntry.Value>>=aIDs;aID=OUStringToOString(aIDs[0],RTL_TEXTENCODING_UTF8);}if(rEntry.Name=="Text"){rEntry.Value>>=aText;}elseif(rEntry.Name=="ControlType"){rEntry.Value>>=aCtrlType;}elseif(rEntry.Name=="Choices"){rEntry.Value>>=aChoices;}elseif(rEntry.Name=="ChoicesDisabled"){rEntry.Value>>=aChoicesDisabled;}elseif(rEntry.Name=="Property"){PropertyValueaVal;rEntry.Value>>=aVal;aPropertyName=aVal.Name;}elseif(rEntry.Name=="Enabled"){boolbValue=true;rEntry.Value>>=bValue;}elseif(rEntry.Name=="GroupingHint"){rEntry.Value>>=aGroupingHint;}elseif(rEntry.Name=="DependsOnName"){rEntry.Value>>=aDependsOnName;}elseif(rEntry.Name=="DependsOnEntry"){rEntry.Value>>=nDependsOnValue;}elseif(rEntry.Name=="AttachToDependency"){rEntry.Value>>=bUseDependencyRow;}elseif(rEntry.Name=="MinValue"){rEntry.Value>>=nMinValue;}elseif(rEntry.Name=="MaxValue"){rEntry.Value>>=nMaxValue;}elseif(rEntry.Name=="HelpText"){if(!(rEntry.Value>>=aHelpTexts)){OUStringaHelpText;if(rEntry.Value>>=aHelpText){aHelpTexts.realloc(1);*aHelpTexts.getArray()=aHelpText;}}}elseif(rEntry.Name=="HelpId"){if(!(rEntry.Value>>=aHelpIds)){OUStringaHelpId;if(rEntry.Value>>=aHelpId){aHelpIds.realloc(1);*aHelpIds.getArray()=aHelpId;}}}elseif(rEntry.Name=="HintNoLayoutPage"){boolbNoLayoutPage=false;<--- Condition '!bNoLayoutPage' is always truerEntry.Value>>=bNoLayoutPage;mbShowLayoutPage=!bNoLayoutPage;}}if(aCtrlType=="Group"&&!aID.isEmpty()){TabPage*pPage=get<TabPage>(aID);if(!pPage&&mpCustomOptionsUIBuilder)pPage=mpCustomOptionsUIBuilder->get<TabPage>(aID);if(!pPage)continue;sal_uInt16nPageId=mpTabCtrl->GetPageId(*pPage);mpTabCtrl->SetPageText(nPageId,aText);// set help idif(aHelpIds.getLength()>0)mpTabCtrl->SetHelpId(nPageId,OUStringToOString(aHelpIds.getConstArray()[0],RTL_TEXTENCODING_UTF8));// set help textif(aHelpTexts.getLength()>0)mpTabCtrl->SetHelpText(nPageId,aHelpTexts.getConstArray()[0]);pPage->Show();}elseif(aCtrlType=="Subgroup"&&!aID.isEmpty()){vcl::Window*pFrame=get<vcl::Window>(aID);if(!pFrame&&mpCustomOptionsUIBuilder)pFrame=mpCustomOptionsUIBuilder->get<vcl::Window>(aID);if(!pFrame)continue;pFrame->SetText(aText);// set help idsetHelpId(pFrame,aHelpIds,0);// set help textsetHelpText(pFrame,aHelpTexts,0);pFrame->Show();}// EVILelseif(aCtrlType=="Bool"&&aGroupingHint=="LayoutPage"&&aPropertyName=="PrintProspect"){maNUpPage.mpBrochureBtn->SetText(aText);maNUpPage.mpBrochureBtn->Show();boolbVal=false;PropertyValue*pVal=maPController->getValue(aPropertyName);if(pVal)pVal->Value>>=bVal;maNUpPage.mpBrochureBtn->Check(bVal);maNUpPage.mpBrochureBtn->Enable(maPController->isUIOptionEnabled(aPropertyName)&&pVal!=nullptr);maNUpPage.mpBrochureBtn->SetToggleHdl(LINK(this,PrintDialog,ToggleRadioHdl));maPropertyToWindowMap[aPropertyName].emplace_back(maNUpPage.mpBrochureBtn);maControlToPropertyMap[maNUpPage.mpBrochureBtn]=aPropertyName;// set help idsetHelpId(maNUpPage.mpBrochureBtn,aHelpIds,0);// set help textsetHelpText(maNUpPage.mpBrochureBtn,aHelpTexts,0);}elseif(aCtrlType=="Bool"){// add a check boxCheckBox*pNewBox=get<CheckBox>(aID);if(!pNewBox&&mpCustomOptionsUIBuilder)pNewBox=mpCustomOptionsUIBuilder->get<CheckBox>(aID);if(!pNewBox)continue;pNewBox->SetText(aText);pNewBox->Show();boolbVal=false;PropertyValue*pVal=maPController->getValue(aPropertyName);if(pVal)pVal->Value>>=bVal;pNewBox->Check(bVal);pNewBox->SetToggleHdl(LINK(this,PrintDialog,UIOption_CheckHdl));maPropertyToWindowMap[aPropertyName].emplace_back(pNewBox);maControlToPropertyMap[pNewBox]=aPropertyName;// set help idsetHelpId(pNewBox,aHelpIds,0);// set help textsetHelpText(pNewBox,aHelpTexts,0);}elseif(aCtrlType=="Radio"){sal_Int32nCurHelpText=0;// iterate optionssal_Int32nSelectVal=0;PropertyValue*pVal=maPController->getValue(aPropertyName);if(pVal&&pVal->Value.hasValue())pVal->Value>>=nSelectVal;for(sal_Int32m=0;m<aChoices.getLength();m++){aID=OUStringToOString(aIDs[m],RTL_TEXTENCODING_UTF8);RadioButton*pBtn=get<RadioButton>(aID);if(!pBtn&&mpCustomOptionsUIBuilder)pBtn=mpCustomOptionsUIBuilder->get<RadioButton>(aID);if(!pBtn)continue;pBtn->SetText(aChoices[m]);pBtn->Check(m==nSelectVal);pBtn->SetToggleHdl(LINK(this,PrintDialog,UIOption_RadioHdl));if(aChoicesDisabled.getLength()>m&&aChoicesDisabled[m])pBtn->Enable(false);pBtn->Show();maPropertyToWindowMap[aPropertyName].emplace_back(pBtn);maControlToPropertyMap[pBtn]=aPropertyName;maControlToNumValMap[pBtn]=m;// set help idsetHelpId(pBtn,aHelpIds,nCurHelpText);// set help textsetHelpText(pBtn,aHelpTexts,nCurHelpText);nCurHelpText++;}}elseif(aCtrlType=="List"){ListBox*pList=get<ListBox>(aID);if(!pList&&mpCustomOptionsUIBuilder)pList=mpCustomOptionsUIBuilder->get<ListBox>(aID);if(!pList)continue;// iterate optionsfor(sal_Int32m=0;m<aChoices.getLength();m++){pList->InsertEntry(aChoices[m]);}sal_Int32nSelectVal=0;PropertyValue*pVal=maPController->getValue(aPropertyName);if(pVal&&pVal->Value.hasValue())pVal->Value>>=nSelectVal;pList->SelectEntryPos(static_cast<sal_uInt16>(nSelectVal));pList->SetSelectHdl(LINK(this,PrintDialog,UIOption_SelectHdl));pList->SetDropDownLineCount(static_cast<sal_uInt16>(aChoices.getLength()));pList->Show();// set help idsetHelpId(pList,aHelpIds,0);// set help textsetHelpText(pList,aHelpTexts,0);maPropertyToWindowMap[aPropertyName].emplace_back(pList);maControlToPropertyMap[pList]=aPropertyName;}elseif(aCtrlType=="Range"){NumericField*pField=get<NumericField>(aID);if(!pField&&mpCustomOptionsUIBuilder)pField=mpCustomOptionsUIBuilder->get<NumericField>(aID);if(!pField)continue;// set min/max and current valueif(nMinValue!=nMaxValue){pField->SetMin(nMinValue);pField->SetMax(nMaxValue);}sal_Int64nCurVal=0;PropertyValue*pVal=maPController->getValue(aPropertyName);if(pVal&&pVal->Value.hasValue())pVal->Value>>=nCurVal;pField->SetValue(nCurVal);pField->SetModifyHdl(LINK(this,PrintDialog,UIOption_ModifyHdl));pField->Show();// set help idsetHelpId(pField,aHelpIds,0);// set help textsetHelpText(pField,aHelpTexts,0);maPropertyToWindowMap[aPropertyName].emplace_back(pField);maControlToPropertyMap[pField]=aPropertyName;}elseif(aCtrlType=="Edit"){Edit*pField=get<Edit>(aID);if(!pField&&mpCustomOptionsUIBuilder)pField=mpCustomOptionsUIBuilder->get<Edit>(aID);if(!pField)continue;OUStringaCurVal;PropertyValue*pVal=maPController->getValue(aPropertyName);if(pVal&&pVal->Value.hasValue())pVal->Value>>=aCurVal;pField->SetText(aCurVal);pField->SetModifyHdl(LINK(this,PrintDialog,UIOption_ModifyHdl));pField->Show();// set help idsetHelpId(pField,aHelpIds,0);// set help textsetHelpText(pField,aHelpTexts,0);maPropertyToWindowMap[aPropertyName].emplace_back(pField);maControlToPropertyMap[pField]=aPropertyName;}else{SAL_WARN("vcl","Unsupported UI option: \""<<aCtrlType<<'"');}}// #i106506# if no brochure button, then the singular Pages radio button// makes no sense, so replace it by a FixedText labelif(!maNUpPage.mpBrochureBtn->IsVisible()&&maNUpPage.mpPagesBtn->IsVisible()){maNUpPage.mpPagesBoxTitleTxt->SetText(maNUpPage.mpPagesBtn->GetText());maNUpPage.mpPagesBoxTitleTxt->Show();maNUpPage.mpPagesBtn->Show(false);maNUpPage.mpPagesBoxTitleTxt->SetAccessibleRelationLabelFor(maNUpPage.mpNupPagesBox);maNUpPage.mpNupPagesBox->SetAccessibleRelationLabeledBy(maNUpPage.mpPagesBoxTitleTxt);maNUpPage.mpPagesBtn->SetAccessibleRelationLabelFor(nullptr);}// update enable statescheckOptionalControlDependencies();vcl::Window*pPageRange=get<vcl::Window>("pagerange");// print range not shown (currently math only) -> hide spacer line and reverse orderif(!pPageRange||!pPageRange->IsVisible()){maJobPage.mpReverseOrderBox->Show(false);}if(!mpCustomOptionsUIBuilder)mpTabCtrl->RemovePage(mpTabCtrl->GetPageId(1));}voidPrintDialog::DataChanged(constDataChangedEvent&i_rDCEvt){// react on settings changedif(i_rDCEvt.GetType()==DataChangedEventType::SETTINGS)checkControlDependencies();ModalDialog::DataChanged(i_rDCEvt);}voidPrintDialog::checkControlDependencies(){if(maJobPage.mpCopyCountField->GetValue()>1)maJobPage.mpCollateBox->Enable(!maJobPage.mbCollateAlwaysOff);elsemaJobPage.mpCollateBox->Enable(false);ImageaImg(maJobPage.mpCollateBox->IsChecked()?maJobPage.maCollateBmp:maJobPage.maNoCollateBmp);SizeaImgSize(aImg.GetSizePixel());// adjust size of imagemaJobPage.mpCollateImage->SetSizePixel(aImgSize);maJobPage.mpCollateImage->SetImage(aImg);// enable setup button only for printers that can be setupboolbHaveSetup=maPController->getPrinter()->HasSupport(PrinterSupport::SetupDialog);maJobPage.mpSetupButton->Enable(bHaveSetup);}voidPrintDialog::checkOptionalControlDependencies(){for(constauto&rEntry:maControlToPropertyMap){boolbShouldbeEnabled=maPController->isUIOptionEnabled(rEntry.second);if(bShouldbeEnabled&&dynamic_cast<RadioButton*>(rEntry.first.get())){autor_it=maControlToNumValMap.find(rEntry.first);if(r_it!=maControlToNumValMap.end()){bShouldbeEnabled=maPController->isUIChoiceEnabled(rEntry.second,r_it->second);}}boolbIsEnabled=rEntry.first->IsEnabled();// Enable does not do a change check first, so can be less cheap than expectedif(bShouldbeEnabled!=bIsEnabled)rEntry.first->Enable(bShouldbeEnabled);}}staticOUStringsearchAndReplace(constOUString&i_rOrig,constchar*i_pRepl,sal_Int32i_nReplLen,constOUString&i_rRepl){sal_Int32nPos=i_rOrig.indexOfAsciiL(i_pRepl,i_nReplLen);if(nPos!=-1){OUStringBufferaBuf(i_rOrig.getLength());aBuf.appendCopy(i_rOrig,0,nPos);aBuf.append(i_rRepl);if(nPos+i_nReplLen<i_rOrig.getLength())aBuf.appendCopy(i_rOrig,nPos+i_nReplLen);returnaBuf.makeStringAndClear();}returni_rOrig;}voidPrintDialog::updatePrinterText(){constOUStringaDefPrt(Printer::GetDefaultPrinterName());constQueueInfo*pInfo=Printer::GetQueueInfo(maJobPage.mpPrinters->GetSelectedEntry(),true);if(pInfo){maJobPage.mpLocationTxt->SetText(pInfo->GetLocation());maJobPage.mpCommentTxt->SetText(pInfo->GetComment());// FIXME: status textOUStringaStatus;if(aDefPrt==pInfo->GetPrinterName())aStatus=maDefPrtText;maJobPage.mpStatusTxt->SetText(aStatus);}else{maJobPage.mpLocationTxt->SetText(OUString());maJobPage.mpCommentTxt->SetText(OUString());maJobPage.mpStatusTxt->SetText(OUString());}}voidPrintDialog::setPreviewText(){OUStringaNewText(searchAndReplace(maPageStr,"%n",2,OUString::number(mnCachedPages)));mpNumPagesText->SetText(aNewText);}voidPrintDialog::preparePreview(booli_bNewPage,booli_bMayUseCache){// page range may have changed depending on optionssal_Int32nPages=maPController->getFilteredPageCount();mnCachedPages=nPages;if(mnCurPage>=nPages)mnCurPage=nPages-1;if(mnCurPage<0)mnCurPage=0;setPreviewText();mpPageEdit->SetMin(1);mpPageEdit->SetMax(nPages);if(i_bNewPage){constMapModeaMapMode(MapUnit::Map100thMM);GDIMetaFileaMtf;VclPtr<Printer>aPrt(maPController->getPrinter());if(nPages>0){PrinterController::PageSizeaPageSize=maPController->getFilteredPageFile(mnCurPage,aMtf,i_bMayUseCache);if(!aPageSize.bFullPaper){PointaOff(aPrt->PixelToLogic(aPrt->GetPageOffsetPixel(),aMapMode));aMtf.Move(aOff.X(),aOff.Y());}}SizeaCurPageSize=aPrt->PixelToLogic(aPrt->GetPaperSizePixel(),MapMode(MapUnit::Map100thMM));mpPreviewWindow->setPreview(aMtf,aCurPageSize,aPrt->GetPaperName(),nPages>0?OUString():maNoPageStr,aPrt->GetDPIX(),aPrt->GetDPIY(),aPrt->GetPrinterOptions().IsConvertToGreyscales());mpForwardBtn->Enable(mnCurPage<nPages-1);mpBackwardBtn->Enable(mnCurPage!=0);mpPageEdit->Enable(nPages>1);}}Sizeconst&PrintDialog::getJobPageSize(){if(maFirstPageSize.Width()==0&&maFirstPageSize.Height()==0){maFirstPageSize=maNupPortraitSize;GDIMetaFileaMtf;if(maPController->getPageCountProtected()>0){PrinterController::PageSizeaPageSize=maPController->getPageFile(0,aMtf,true);maFirstPageSize=aPageSize.aSize;}}returnmaFirstPageSize;}voidPrintDialog::updateNupFromPages(){sal_IntPtrnPages=sal_IntPtr(maNUpPage.mpNupPagesBox->GetSelectedEntryData());intnRows=int(maNUpPage.mpNupRowsEdt->GetValue());intnCols=int(maNUpPage.mpNupColEdt->GetValue());longnPageMargin=maNUpPage.mpPageMarginEdt->Denormalize(maNUpPage.mpPageMarginEdt->GetValue(FieldUnit::MM_100TH));longnSheetMargin=maNUpPage.mpSheetMarginEdt->Denormalize(maNUpPage.mpSheetMarginEdt->GetValue(FieldUnit::MM_100TH));boolbCustom=false;if(nPages==1){nRows=nCols=1;nSheetMargin=0;nPageMargin=0;}elseif(nPages==2||nPages==4||nPages==6||nPages==9||nPages==16){SizeaJobPageSize(getJobPageSize());boolbPortrait=aJobPageSize.Width()<aJobPageSize.Height();if(nPages==2){if(bPortrait){nRows=1;nCols=2;}else{nRows=2;nCols=1;}}elseif(nPages==4)nRows=nCols=2;elseif(nPages==6){if(bPortrait){nRows=2;nCols=3;}else{nRows=3;nCols=2;}}elseif(nPages==9)nRows=nCols=3;elseif(nPages==16)nRows=nCols=4;nPageMargin=0;nSheetMargin=0;}elsebCustom=true;if(nPages>1){// set upper limits for margins based on job page size and rows/columnsSizeaSize(getJobPageSize());// maximum sheet distance: 1/2 sheetlongnHorzMax=aSize.Width()/2;longnVertMax=aSize.Height()/2;if(nSheetMargin>nHorzMax)nSheetMargin=nHorzMax;if(nSheetMargin>nVertMax)nSheetMargin=nVertMax;maNUpPage.mpSheetMarginEdt->SetMax(maNUpPage.mpSheetMarginEdt->Normalize(std::min(nHorzMax,nVertMax)),FieldUnit::MM_100TH);// maximum page distancenHorzMax=(aSize.Width()-2*nSheetMargin);if(nCols>1)nHorzMax/=(nCols-1);nVertMax=(aSize.Height()-2*nSheetMargin);if(nRows>1)nHorzMax/=(nRows-1);if(nPageMargin>nHorzMax)nPageMargin=nHorzMax;if(nPageMargin>nVertMax)nPageMargin=nVertMax;maNUpPage.mpPageMarginEdt->SetMax(maNUpPage.mpSheetMarginEdt->Normalize(std::min(nHorzMax,nVertMax)),FieldUnit::MM_100TH);}maNUpPage.mpNupRowsEdt->SetValue(nRows);maNUpPage.mpNupColEdt->SetValue(nCols);maNUpPage.mpPageMarginEdt->SetValue(maNUpPage.mpPageMarginEdt->Normalize(nPageMargin),FieldUnit::MM_100TH);maNUpPage.mpSheetMarginEdt->SetValue(maNUpPage.mpSheetMarginEdt->Normalize(nSheetMargin),FieldUnit::MM_100TH);maNUpPage.showAdvancedControls(bCustom);updateNup();}#define SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT 1#define SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE 2voidPrintDialog::updateNup(){intnRows=int(maNUpPage.mpNupRowsEdt->GetValue());intnCols=int(maNUpPage.mpNupColEdt->GetValue());longnPageMargin=maNUpPage.mpPageMarginEdt->Denormalize(maNUpPage.mpPageMarginEdt->GetValue(FieldUnit::MM_100TH));longnSheetMargin=maNUpPage.mpSheetMarginEdt->Denormalize(maNUpPage.mpSheetMarginEdt->GetValue(FieldUnit::MM_100TH));PrinterController::MultiPageSetupaMPS;aMPS.nRows=nRows;aMPS.nColumns=nCols;aMPS.nLeftMargin=aMPS.nTopMargin=aMPS.nRightMargin=aMPS.nBottomMargin=nSheetMargin;aMPS.nHorizontalSpacing=aMPS.nVerticalSpacing=nPageMargin;aMPS.bDrawBorder=maNUpPage.mpBorderCB->IsChecked();aMPS.nOrder=static_cast<NupOrderType>(maNUpPage.mpNupOrderBox->GetSelectedEntryPos());intnOrientationMode=maNUpPage.mpNupOrientationBox->GetSelectedEntryPos();if(nOrientationMode==SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE)aMPS.aPaperSize=maNupLandscapeSize;elseif(nOrientationMode==SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT)aMPS.aPaperSize=maNupPortraitSize;else// automatic mode{// get size of first real page to see if it is portrait or landscape// we assume same page sizes for all the pages for thisSizeaPageSize=getJobPageSize();SizeaMultiSize(aPageSize.Width()*nCols,aPageSize.Height()*nRows);if(aMultiSize.Width()>aMultiSize.Height())// fits better on landscapeaMPS.aPaperSize=maNupLandscapeSize;elseaMPS.aPaperSize=maNupPortraitSize;}maPController->setMultipage(aMPS);maNUpPage.mpNupOrderWin->setValues(aMPS.nOrder,nCols,nRows);preparePreview(true,true);}IMPL_LINK(PrintDialog,SelectHdl,ListBox&,rBox,void){if(&rBox==maJobPage.mpPrinters){if(rBox.GetSelectedEntryPos()!=0){OUStringaNewPrinter(rBox.GetSelectedEntry());// set new printermaPController->setPrinter(VclPtrInstance<Printer>(aNewPrinter));maPController->resetPrinterOptions(false);// update text fieldsmpOKButton->SetText(maPrintText);updatePrinterText();preparePreview();}else// print to file{// use the default printer or FIXME: the last used one?maPController->setPrinter(VclPtrInstance<Printer>(Printer::GetDefaultPrinterName()));mpOKButton->SetText(maPrintToFileText);maPController->resetPrinterOptions(true);preparePreview(true,true);}}elseif(&rBox==maNUpPage.mpNupOrientationBox||&rBox==maNUpPage.mpNupOrderBox){updateNup();}elseif(&rBox==maNUpPage.mpNupPagesBox){if(!maNUpPage.mpPagesBtn->IsChecked())maNUpPage.mpPagesBtn->Check();updateNupFromPages();}}IMPL_LINK(PrintDialog,ToggleRadioHdl,RadioButton&,rButton,void){ClickHdl(static_cast<Button*>(&rButton));}IMPL_LINK(PrintDialog,ToggleHdl,CheckBox&,rButton,void){ClickHdl(&rButton);}IMPL_LINK(PrintDialog,ClickHdl,Button*,pButton,void){if(pButton==mpOKButton||pButton==mpCancelButton){storeToSettings();EndDialog(pButton==mpOKButton?RET_OK:RET_CANCEL);}elseif(pButton==mpHelpButton){// start help systemHelp*pHelp=Application::GetHelp();if(pHelp){pHelp->Start("vcl/ui/printdialog",mpOKButton);}}elseif(pButton==mpForwardBtn){previewForward();}elseif(pButton==mpBackwardBtn){previewBackward();}elseif(pButton==maOptionsPage.mpPapersizeFromSetup){boolbChecked=maOptionsPage.mpPapersizeFromSetup->IsChecked();maPController->setPapersizeFromSetup(bChecked);maPController->setValue("PapersizeFromSetup",makeAny(bChecked));preparePreview(true,true);}elseif(pButton==maNUpPage.mpBrochureBtn){PropertyValue*pVal=getValueForWindow(pButton);if(pVal){boolbVal=maNUpPage.mpBrochureBtn->IsChecked();pVal->Value<<=bVal;checkOptionalControlDependencies();// update preview and page settingspreparePreview();}if(maNUpPage.mpBrochureBtn->IsChecked()){maNUpPage.mpNupPagesBox->SelectEntryPos(0);updateNupFromPages();maNUpPage.showAdvancedControls(false);maNUpPage.enableNupControls(false);}}elseif(pButton==maNUpPage.mpPagesBtn){maNUpPage.enableNupControls(true);updateNupFromPages();}elseif(pButton==maJobPage.mpCollateBox){maPController->setValue("Collate",makeAny(isCollate()));checkControlDependencies();}elseif(pButton==maJobPage.mpReverseOrderBox){boolbChecked=maJobPage.mpReverseOrderBox->IsChecked();maPController->setReversePrint(bChecked);maPController->setValue("PrintReverse",makeAny(bChecked));preparePreview(true,true);}elseif(pButton==maNUpPage.mpBorderCB){updateNup();}else{if(pButton==maJobPage.mpSetupButton){maPController->setupPrinter(GetFrameWeld());// tdf#63905 don't use cache: page size may changepreparePreview();}checkControlDependencies();}}IMPL_LINK(PrintDialog,ModifyHdl,Edit&,rEdit,void){checkControlDependencies();if(&rEdit==maNUpPage.mpNupRowsEdt||&rEdit==maNUpPage.mpNupColEdt||&rEdit==maNUpPage.mpSheetMarginEdt||&rEdit==maNUpPage.mpPageMarginEdt){updateNupFromPages();}elseif(&rEdit==mpPageEdit){mnCurPage=sal_Int32(mpPageEdit->GetValue()-1);preparePreview(true,true);}elseif(&rEdit==maJobPage.mpCopyCountField){maPController->setValue("CopyCount",makeAny(sal_Int32(maJobPage.mpCopyCountField->GetValue())));maPController->setValue("Collate",makeAny(isCollate()));}}IMPL_LINK(PrintDialog,ActivatePageHdl,TabControl*,pTabCtrl,void){constsal_uInt16id=pTabCtrl->GetCurPageId();if(pTabCtrl->GetPageName(id)=="optionstab"){maOptionsPage.mpPapersizeFromSetup->Check(maPController->getPapersizeFromSetup());}}PropertyValue*PrintDialog::getValueForWindow(vcl::Window*i_pWindow)const{PropertyValue*pVal=nullptr;autoit=maControlToPropertyMap.find(i_pWindow);if(it!=maControlToPropertyMap.end()){pVal=maPController->getValue(it->second);SAL_WARN_IF(!pVal,"vcl","property value not found");}else{OSL_FAIL("changed control not in property map");}returnpVal;}voidPrintDialog::updateWindowFromProperty(constOUString&i_rProperty){beans::PropertyValue*pValue=maPController->getValue(i_rProperty);autoit=maPropertyToWindowMap.find(i_rProperty);if(pValue&&it!=maPropertyToWindowMap.end()){conststd::vector<VclPtr<vcl::Window>>&rWindows(it->second);if(!rWindows.empty()){boolbVal=false;sal_Int32nVal=-1;if(pValue->Value>>=bVal){// we should have a CheckBox for this oneCheckBox*pBox=dynamic_cast<CheckBox*>(rWindows.front().get());if(pBox){pBox->Check(bVal);}elseif(i_rProperty=="PrintProspect"){// EVIL special caseif(bVal)maNUpPage.mpBrochureBtn->Check();elsemaNUpPage.mpPagesBtn->Check();}else{SAL_WARN("vcl","missing a checkbox");}}elseif(pValue->Value>>=nVal){// this could be a ListBox or a RadioButtonGroupListBox*pList=dynamic_cast<ListBox*>(rWindows.front().get());if(pList){pList->SelectEntryPos(static_cast<sal_uInt16>(nVal));}elseif(nVal>=0&&nVal<sal_Int32(rWindows.size())){RadioButton*pBtn=dynamic_cast<RadioButton*>(rWindows[nVal].get());SAL_WARN_IF(!pBtn,"vcl","unexpected control for property");if(pBtn)pBtn->Check();}}}}}voidPrintDialog::makeEnabled(vcl::Window*i_pWindow){autoit=maControlToPropertyMap.find(i_pWindow);if(it!=maControlToPropertyMap.end()){OUStringaDependency(maPController->makeEnabled(it->second));if(!aDependency.isEmpty())updateWindowFromProperty(aDependency);}}IMPL_LINK(PrintDialog,UIOption_CheckHdl,CheckBox&,i_rBox,void){PropertyValue*pVal=getValueForWindow(&i_rBox);if(pVal){makeEnabled(&i_rBox);boolbVal=i_rBox.IsChecked();pVal->Value<<=bVal;checkOptionalControlDependencies();// update preview and page settingspreparePreview();}}IMPL_LINK(PrintDialog,UIOption_RadioHdl,RadioButton&,i_rBtn,void){// this handler gets called for all radiobuttons that get unchecked, too// however we only want one notification for the new value (that is for// the button that gets checked)if(i_rBtn.IsChecked()){PropertyValue*pVal=getValueForWindow(&i_rBtn);autoit=maControlToNumValMap.find(&i_rBtn);if(pVal&&it!=maControlToNumValMap.end()){makeEnabled(&i_rBtn);sal_Int32nVal=it->second;pVal->Value<<=nVal;// tdf#63905 use paper size set in printer propertiesif(pVal->Name=="PageOptions")maPController->resetPaperToLastConfigured();checkOptionalControlDependencies();// update preview and page settingspreparePreview();}}}IMPL_LINK(PrintDialog,UIOption_SelectHdl,ListBox&,i_rBox,void){PropertyValue*pVal=getValueForWindow(&i_rBox);if(pVal){makeEnabled(&i_rBox);sal_Int32nVal(i_rBox.GetSelectedEntryPos());pVal->Value<<=nVal;//If we are in impress we start in print slides mode and get a//maFirstPageSize for slides which are usually landscape mode, if we//change to notes which are usually in portrait mode, and then visit//n-up print, we will assume notes are in landscape unless we throw//away maFirstPageSize when we change page content typeif(pVal->Name=="PageContentType")maFirstPageSize=Size();checkOptionalControlDependencies();// update preview and page settingspreparePreview();}}IMPL_LINK(PrintDialog,UIOption_ModifyHdl,Edit&,i_rBox,void){PropertyValue*pVal=getValueForWindow(&i_rBox);if(pVal){makeEnabled(&i_rBox);NumericField*pNum=dynamic_cast<NumericField*>(&i_rBox);MetricField*pMetric=dynamic_cast<MetricField*>(&i_rBox);if(pNum){sal_Int64nVal=pNum->GetValue();pVal->Value<<=nVal;}elseif(pMetric){sal_Int64nVal=pMetric->GetValue();pVal->Value<<=nVal;}else{OUStringaVal(i_rBox.GetText());pVal->Value<<=aVal;}checkOptionalControlDependencies();// update preview and page settingspreparePreview();}}voidPrintDialog::Command(constCommandEvent&rEvt){if(rEvt.GetCommand()==CommandEventId::Wheel){constCommandWheelData*pWheelData=rEvt.GetWheelData();if(pWheelData->GetDelta()>0)previewForward();elseif(pWheelData->GetDelta()<0)previewBackward();}}voidPrintDialog::Resize(){// maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) );// and do the preview; however the metafile does not need to be gotten anewpreparePreview(false);Dialog::Resize();}voidPrintDialog::previewForward(){mpPageEdit->Up();}voidPrintDialog::previewBackward(){mpPageEdit->Down();}// PrintProgressDialogPrintProgressDialog::PrintProgressDialog(vcl::Window*i_pParent,inti_nMax):ModelessDialog(i_pParent,"PrintProgressDialog","vcl/ui/printprogressdialog.ui"),mbCanceled(false),mnCur(0),mnMax(i_nMax){get(mpButton,"cancel");get(mpProgress,"progressbar");get(mpText,"label");if(mnMax<1)mnMax=1;maStr=mpText->GetText();//just multiply largest value by 10 and take the width of that string as//the max size we will wantOUStringaNewText(searchAndReplace(maStr,"%p",2,OUString::number(mnMax*10)));aNewText=searchAndReplace(aNewText,"%n",2,OUString::number(mnMax*10));mpText->SetText(aNewText);mpText->set_width_request(mpText->get_preferred_size().Width());//Pick a useful max widthmpProgress->set_width_request(mpProgress->LogicToPixel(Size(100,0),MapMode(MapUnit::MapAppFont)).Width());mpButton->SetClickHdl(LINK(this,PrintProgressDialog,ClickHdl));}PrintProgressDialog::~PrintProgressDialog(){disposeOnce();}voidPrintProgressDialog::dispose(){mpText.clear();mpProgress.clear();mpButton.clear();ModelessDialog::dispose();}IMPL_LINK(PrintProgressDialog,ClickHdl,Button*,pButton,void){if(pButton==mpButton)mbCanceled=true;}voidPrintProgressDialog::setProgress(inti_nCurrent){mnCur=i_nCurrent;if(mnMax<1)mnMax=1;mpProgress->SetValue(mnCur*100/mnMax);OUStringaNewText(searchAndReplace(maStr,"%p",2,OUString::number(mnCur)));aNewText=searchAndReplace(aNewText,"%n",2,OUString::number(mnMax));mpText->SetText(aNewText);}voidPrintProgressDialog::tick(){if(mnCur<mnMax)setProgress(++mnCur);}voidPrintProgressDialog::reset(){mbCanceled=false;setProgress(0);}/* vim:set shiftwidth=4 softtabstop=4 expandtab: */