build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / printdlg.cxx
blob02317ac90e0041975e12ec74fe00ad90c4fc2481
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "printdlg.hxx"
21 #include "svdata.hxx"
22 #include "svids.hrc"
24 #include <vcl/print.hxx>
25 #include <vcl/dialog.hxx>
26 #include <vcl/button.hxx>
27 #include <vcl/wall.hxx>
28 #include <vcl/status.hxx>
29 #include <vcl/decoview.hxx>
30 #include <vcl/configsettings.hxx>
31 #include <vcl/help.hxx>
32 #include <vcl/layout.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/unohelp.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/builderfactory.hxx>
37 #include "jobset.h"
39 #include "unotools/localedatawrapper.hxx"
41 #include "rtl/strbuf.hxx"
43 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
44 #include "com/sun/star/container/XNameAccess.hpp"
45 #include "com/sun/star/beans/PropertyValue.hpp"
46 #include "com/sun/star/awt/Size.hpp"
48 using namespace vcl;
49 using namespace com::sun::star;
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::container;
53 using namespace com::sun::star::beans;
55 VCL_BUILDER_DECL_FACTORY(PrintPreviewWindow)
57 (void)rMap;
58 rRet = VclPtr<PrintDialog::PrintPreviewWindow>::Create(pParent);
61 VCL_BUILDER_DECL_FACTORY(ShowNupOrderWindow)
63 (void)rMap;
64 rRet = VclPtr<PrintDialog::ShowNupOrderWindow>::Create(pParent);
67 PrintDialog::PrintPreviewWindow::PrintPreviewWindow( vcl::Window* i_pParent )
68 : Window( i_pParent, 0 )
69 , maOrigSize( 10, 10 )
70 , maPageVDev( VclPtr<VirtualDevice>::Create(*this) )
71 , maToolTipString(VclResId( SV_PRINT_PRINTPREVIEW_TXT).toString())
72 , mbGreyscale( false )
73 , maHorzDim(VclPtr<FixedLine>::Create(this, WB_HORZ | WB_CENTER))
74 , maVertDim(VclPtr<FixedLine>::Create(this, WB_VERT | WB_VCENTER))
76 SetPaintTransparent( true );
77 SetBackground();
78 maPageVDev->SetBackground( Color( COL_WHITE ) );
79 maHorzDim->Show();
80 maVertDim->Show();
82 maHorzDim->SetText( "2.0in" );
83 maVertDim->SetText( "2.0in" );
86 PrintDialog::PrintPreviewWindow::~PrintPreviewWindow()
88 disposeOnce();
91 void PrintDialog::PrintPreviewWindow::dispose()
93 maHorzDim.disposeAndClear();
94 maVertDim.disposeAndClear();
95 maPageVDev.disposeAndClear();
96 Window::dispose();
99 const sal_Int32 PrintDialog::PrintPreviewWindow::PREVIEW_BITMAP_WIDTH = 1600;
101 void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt )
103 // react on settings changed
104 if( i_rDCEvt.GetType() == DataChangedEventType::SETTINGS )
106 maPageVDev->SetBackground( Color( COL_WHITE ) );
108 Window::DataChanged( i_rDCEvt );
111 void PrintDialog::PrintPreviewWindow::Resize()
113 Size aNewSize( GetSizePixel() );
114 long nTextHeight = maHorzDim->GetTextHeight();
115 // leave small space for decoration
116 aNewSize.Width() -= nTextHeight + 2;
117 aNewSize.Height() -= nTextHeight + 2;
118 Size aScaledSize;
119 double fScale = 1.0;
121 // #i106435# catch corner case of Size(0,0)
122 Size aOrigSize( maOrigSize );
123 if( aOrigSize.Width() < 1 )
124 aOrigSize.Width() = aNewSize.Width();
125 if( aOrigSize.Height() < 1 )
126 aOrigSize.Height() = aNewSize.Height();
127 if( aOrigSize.Width() > aOrigSize.Height() )
129 aScaledSize = Size( aNewSize.Width(), aNewSize.Width() * aOrigSize.Height() / aOrigSize.Width() );
130 if( aScaledSize.Height() > aNewSize.Height() )
131 fScale = double(aNewSize.Height())/double(aScaledSize.Height());
133 else
135 aScaledSize = Size( aNewSize.Height() * aOrigSize.Width() / aOrigSize.Height(), aNewSize.Height() );
136 if( aScaledSize.Width() > aNewSize.Width() )
137 fScale = double(aNewSize.Width())/double(aScaledSize.Width());
139 aScaledSize.Width() = long(aScaledSize.Width()*fScale);
140 aScaledSize.Height() = long(aScaledSize.Height()*fScale);
142 maPreviewSize = aScaledSize;
144 // #i104784# if we render the page too small then rounding issues result in
145 // layout artifacts looking really bad. So scale the page unto a device that is not
146 // full page size but not too small either. This also results in much better visual
147 // quality of the preview, e.g. when its height approaches the number of text lines
148 // find a good scaling factor
150 double aAspectRatio = aScaledSize.Height() / (double) aScaledSize.Width();
152 aScaledSize.Width() = PREVIEW_BITMAP_WIDTH;
153 aScaledSize.Height() = PREVIEW_BITMAP_WIDTH * aAspectRatio;
155 maPageVDev->SetOutputSizePixel( aScaledSize, false );
157 // position dimension lines
158 Point aRef( nTextHeight + (aNewSize.Width() - maPreviewSize.Width())/2,
159 nTextHeight + (aNewSize.Height() - maPreviewSize.Height())/2 );
160 maHorzDim->SetPosSizePixel( Point( aRef.X(), aRef.Y() - nTextHeight ),
161 Size( maPreviewSize.Width(), nTextHeight ) );
162 maVertDim->SetPosSizePixel( Point( aRef.X() - nTextHeight, aRef.Y() ),
163 Size( nTextHeight, maPreviewSize.Height() ) );
167 void PrintDialog::PrintPreviewWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
169 long nTextHeight = maHorzDim->GetTextHeight();
170 Size aSize(GetSizePixel());
171 Point aOffset((aSize.Width() - maPreviewSize.Width() + nTextHeight) / 2,
172 (aSize.Height() - maPreviewSize.Height() + nTextHeight) / 2);
174 if (!maReplacementString.isEmpty())
176 // replacement is active
177 rRenderContext.Push();
178 Font aFont(rRenderContext.GetSettings().GetStyleSettings().GetLabelFont());
179 SetZoomedPointFont(rRenderContext, aFont);
180 Rectangle aTextRect(aOffset + Point(2, 2), Size(maPreviewSize.Width() - 4, maPreviewSize.Height() - 4));
181 rRenderContext.DrawText(aTextRect, maReplacementString,
182 DrawTextFlags::Center | DrawTextFlags::VCenter |
183 DrawTextFlags::WordBreak | DrawTextFlags::MultiLine);
184 rRenderContext.Pop();
186 else
188 Bitmap aPreviewBitmap(maPreviewBitmap);
189 aPreviewBitmap.Scale(maPreviewSize, BmpScaleFlag::BestQuality);
190 rRenderContext.DrawBitmap(aOffset, aPreviewBitmap);
193 Rectangle aFrameRect(aOffset + Point(-1, -1), Size(maPreviewSize.Width() + 2, maPreviewSize.Height() + 2));
194 DecorationView aDecorationView(&rRenderContext);
195 aDecorationView.DrawFrame(aFrameRect, DrawFrameStyle::Group);
198 void PrintDialog::PrintPreviewWindow::Command( const CommandEvent& rEvt )
200 if( rEvt.GetCommand() == CommandEventId::Wheel )
202 const CommandWheelData* pWheelData = rEvt.GetWheelData();
203 PrintDialog* pDlg = dynamic_cast<PrintDialog*>(GetParentDialog());
204 if( pDlg )
206 if( pWheelData->GetDelta() > 0 )
207 pDlg->previewForward();
208 else if( pWheelData->GetDelta() < 0 )
209 pDlg->previewBackward();
214 void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview,
215 const Size& i_rOrigSize,
216 const OUString& i_rPaperName,
217 const OUString& i_rReplacement,
218 sal_Int32 i_nDPIX,
219 sal_Int32 i_nDPIY,
220 bool i_bGreyscale
223 OUStringBuffer aBuf( 256 );
224 aBuf.append( maToolTipString );
225 SetQuickHelpText( aBuf.makeStringAndClear() );
226 maMtf = i_rNewPreview;
228 maOrigSize = i_rOrigSize;
229 maReplacementString = i_rReplacement;
230 mbGreyscale = i_bGreyscale;
231 maPageVDev->SetReferenceDevice( i_nDPIX, i_nDPIY );
232 maPageVDev->EnableOutput();
234 // use correct measurements
235 const LocaleDataWrapper& rLocWrap( GetSettings().GetLocaleDataWrapper() );
236 MapUnit eUnit = MapUnit::MapMM;
237 int nDigits = 0;
238 if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US )
240 eUnit = MapUnit::Map100thInch;
241 nDigits = 2;
243 Size aLogicPaperSize( LogicToLogic( i_rOrigSize, MapMode( MapUnit::Map100thMM ), MapMode( eUnit ) ) );
244 OUString aNumText( rLocWrap.getNum( aLogicPaperSize.Width(), nDigits ) );
245 aBuf.append( aNumText )
246 .append( sal_Unicode( ' ' ) );
247 aBuf.appendAscii( eUnit == MapUnit::MapMM ? "mm" : "in" );
248 if( !i_rPaperName.isEmpty() )
250 aBuf.append( " (" );
251 aBuf.append( i_rPaperName );
252 aBuf.append( ')' );
254 maHorzDim->SetText( aBuf.makeStringAndClear() );
256 aNumText = rLocWrap.getNum( aLogicPaperSize.Height(), nDigits );
257 aBuf.append( aNumText )
258 .append( sal_Unicode( ' ' ) );
259 aBuf.appendAscii( eUnit == MapUnit::MapMM ? "mm" : "in" );
260 maVertDim->SetText( aBuf.makeStringAndClear() );
262 Resize();
263 preparePreviewBitmap();
264 Invalidate();
267 void PrintDialog::PrintPreviewWindow::preparePreviewBitmap()
269 GDIMetaFile aMtf( maMtf );
271 Size aVDevSize( maPageVDev->GetOutputSizePixel() );
272 const Size aLogicSize( maPageVDev->PixelToLogic( aVDevSize, MapMode( MapUnit::Map100thMM ) ) );
273 Size aOrigSize( maOrigSize );
274 if( aOrigSize.Width() < 1 )
275 aOrigSize.Width() = aLogicSize.Width();
276 if( aOrigSize.Height() < 1 )
277 aOrigSize.Height() = aLogicSize.Height();
278 double fScale = double(aLogicSize.Width())/double(aOrigSize.Width());
280 maPageVDev->Erase();
281 maPageVDev->Push();
282 maPageVDev->SetMapMode( MapUnit::Map100thMM );
283 DrawModeFlags nOldDrawMode = maPageVDev->GetDrawMode();
284 if( mbGreyscale )
285 maPageVDev->SetDrawMode( maPageVDev->GetDrawMode() |
286 ( DrawModeFlags::GrayLine | DrawModeFlags::GrayFill | DrawModeFlags::GrayText |
287 DrawModeFlags::GrayBitmap | DrawModeFlags::GrayGradient ) );
288 aMtf.WindStart();
289 aMtf.Scale( fScale, fScale );
290 aMtf.WindStart();
292 const AntialiasingFlags nOriginalAA(maPageVDev->GetAntialiasing());
293 maPageVDev->SetAntialiasing(nOriginalAA | AntialiasingFlags::EnableB2dDraw);
294 aMtf.Play( maPageVDev.get(), Point( 0, 0 ), aLogicSize );
295 maPageVDev->SetAntialiasing(nOriginalAA);
297 maPageVDev->Pop();
299 SetMapMode( MapUnit::MapPixel );
300 maPageVDev->SetMapMode( MapUnit::MapPixel );
302 maPreviewBitmap = Bitmap(maPageVDev->GetBitmap(Point(0, 0), aVDevSize));
304 maPageVDev->SetDrawMode( nOldDrawMode );
307 PrintDialog::ShowNupOrderWindow::ShowNupOrderWindow( vcl::Window* i_pParent )
308 : Window( i_pParent, WB_NOBORDER )
309 , mnOrderMode( NupOrderType::LRTB )
310 , mnRows( 1 )
311 , mnColumns( 1 )
313 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
316 Size PrintDialog::ShowNupOrderWindow::GetOptimalSize() const
318 return Size(70, 70);
321 void PrintDialog::ShowNupOrderWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle& i_rRect)
323 Window::Paint(rRenderContext, i_rRect);
325 rRenderContext.SetMapMode(MapUnit::MapPixel);
326 rRenderContext.SetTextColor(rRenderContext.GetSettings().GetStyleSettings().GetFieldTextColor());
328 int nPages = mnRows * mnColumns;
329 Font aFont(rRenderContext.GetSettings().GetStyleSettings().GetFieldFont());
330 aFont.SetFontSize(Size(0, 24));
331 rRenderContext.SetFont(aFont);
332 Size aSampleTextSize(rRenderContext.GetTextWidth(OUString::number(nPages + 1)), rRenderContext.GetTextHeight());
333 Size aOutSize(GetOutputSizePixel());
334 Size aSubSize(aOutSize.Width() / mnColumns, aOutSize.Height() / mnRows);
335 // calculate font size: shrink the sample text so it fits
336 double fX = double(aSubSize.Width()) / double(aSampleTextSize.Width());
337 double fY = double(aSubSize.Height()) / double(aSampleTextSize.Height());
338 double fScale = (fX < fY) ? fX : fY;
339 long nFontHeight = long(24.0 * fScale) - 3;
340 if (nFontHeight < 5)
341 nFontHeight = 5;
342 aFont.SetFontSize(Size( 0, nFontHeight));
343 rRenderContext.SetFont(aFont);
344 long nTextHeight = rRenderContext.GetTextHeight();
345 for (int i = 0; i < nPages; i++)
347 OUString aPageText(OUString::number(i + 1));
348 int nX = 0, nY = 0;
349 switch (mnOrderMode)
351 case NupOrderType::LRTB:
352 nX = (i % mnColumns);
353 nY = (i / mnColumns);
354 break;
355 case NupOrderType::TBLR:
356 nX = (i / mnRows);
357 nY = (i % mnRows);
358 break;
359 case NupOrderType::RLTB:
360 nX = mnColumns - 1 - (i % mnColumns);
361 nY = (i / mnColumns);
362 break;
363 case NupOrderType::TBRL:
364 nX = mnColumns - 1 - (i / mnRows);
365 nY = (i % mnRows);
366 break;
368 Size aTextSize(rRenderContext.GetTextWidth(aPageText), nTextHeight);
369 int nDeltaX = (aSubSize.Width() - aTextSize.Width()) / 2;
370 int nDeltaY = (aSubSize.Height() - aTextSize.Height()) / 2;
371 rRenderContext.DrawText(Point(nX * aSubSize.Width() + nDeltaX,
372 nY * aSubSize.Height() + nDeltaY), aPageText);
374 DecorationView aDecorationView(&rRenderContext);
375 aDecorationView.DrawFrame(Rectangle(Point(0, 0), aOutSize), DrawFrameStyle::Group);
378 PrintDialog::NUpTabPage::NUpTabPage( VclBuilder *pUIBuilder )
380 pUIBuilder->get(mpPagesBtn, "pagespersheetbtn");
381 pUIBuilder->get(mpBrochureBtn, "brochure");
382 pUIBuilder->get(mpPagesBoxTitleTxt, "pagespersheettxt");
383 pUIBuilder->get(mpNupPagesBox, "paperspersheetlb");
384 pUIBuilder->get(mpNupNumPagesTxt, "pagestxt");
385 pUIBuilder->get(mpNupColEdt, "pagecols");
386 pUIBuilder->get(mpNupTimesTxt, "by");
387 pUIBuilder->get(mpNupRowsEdt, "pagerows");
388 pUIBuilder->get(mpPageMarginTxt1, "pagemargintxt1");
389 pUIBuilder->get(mpPageMarginEdt, "pagemarginsb");
390 pUIBuilder->get(mpPageMarginTxt2, "pagemargintxt2");
391 pUIBuilder->get(mpSheetMarginTxt1, "sheetmargintxt1");
392 pUIBuilder->get(mpSheetMarginEdt, "sheetmarginsb");
393 pUIBuilder->get(mpSheetMarginTxt2, "sheetmargintxt2");
394 pUIBuilder->get(mpNupOrientationTxt, "orientationtxt");
395 pUIBuilder->get(mpNupOrientationBox, "orientationlb");
396 pUIBuilder->get(mpNupOrderTxt, "ordertxt");
397 pUIBuilder->get(mpNupOrderBox, "orderlb");
398 pUIBuilder->get(mpNupOrderWin, "orderpreview");
399 pUIBuilder->get(mpBorderCB, "bordercb");
402 void PrintDialog::NUpTabPage::enableNupControls( bool bEnable )
404 mpNupPagesBox->Enable( bEnable );
405 mpNupNumPagesTxt->Enable( bEnable );
406 mpNupColEdt->Enable( bEnable );
407 mpNupTimesTxt->Enable( bEnable );
408 mpNupRowsEdt->Enable( bEnable );
409 mpPageMarginTxt1->Enable( bEnable );
410 mpPageMarginEdt->Enable( bEnable );
411 mpPageMarginTxt2->Enable( bEnable );
412 mpSheetMarginTxt1->Enable( bEnable );
413 mpSheetMarginEdt->Enable( bEnable );
414 mpSheetMarginTxt2->Enable( bEnable );
415 mpNupOrientationTxt->Enable( bEnable );
416 mpNupOrientationBox->Enable( bEnable );
417 mpNupOrderTxt->Enable( bEnable );
418 mpNupOrderBox->Enable( bEnable );
419 mpNupOrderWin->Enable( bEnable );
420 mpBorderCB->Enable( bEnable );
423 void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow )
425 mpNupNumPagesTxt->Show( i_bShow );
426 mpNupColEdt->Show( i_bShow );
427 mpNupTimesTxt->Show( i_bShow );
428 mpNupRowsEdt->Show( i_bShow );
429 mpPageMarginTxt1->Show( i_bShow );
430 mpPageMarginEdt->Show( i_bShow );
431 mpPageMarginTxt2->Show( i_bShow );
432 mpSheetMarginTxt1->Show( i_bShow );
433 mpSheetMarginEdt->Show( i_bShow );
434 mpSheetMarginTxt2->Show( i_bShow );
435 mpNupOrientationTxt->Show( i_bShow );
436 mpNupOrientationBox->Show( i_bShow );
439 void PrintDialog::NUpTabPage::initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& i_rMPS )
441 mpNupOrderWin->Show();
442 mpPagesBtn->Check();
443 mpBrochureBtn->Show( false );
445 // setup field units for metric fields
446 const LocaleDataWrapper& rLocWrap( mpPageMarginEdt->GetLocaleDataWrapper() );
447 FieldUnit eUnit = FUNIT_MM;
448 sal_uInt16 nDigits = 0;
449 if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US )
451 eUnit = FUNIT_INCH;
452 nDigits = 2;
454 // set units
455 mpPageMarginEdt->SetUnit( eUnit );
456 mpSheetMarginEdt->SetUnit( eUnit );
458 // set precision
459 mpPageMarginEdt->SetDecimalDigits( nDigits );
460 mpSheetMarginEdt->SetDecimalDigits( nDigits );
462 mpSheetMarginEdt->SetValue( mpSheetMarginEdt->Normalize( i_rMPS.nLeftMargin ), FUNIT_100TH_MM );
463 mpPageMarginEdt->SetValue( mpPageMarginEdt->Normalize( i_rMPS.nHorizontalSpacing ), FUNIT_100TH_MM );
464 mpBorderCB->Check( i_rMPS.bDrawBorder );
465 mpNupRowsEdt->SetValue( i_rMPS.nRows );
466 mpNupColEdt->SetValue( i_rMPS.nColumns );
467 mpNupOrderBox->SelectEntryPos( (sal_Int32)i_rMPS.nOrder );
468 if( i_rMPS.nRows != 1 || i_rMPS.nColumns != 1 )
470 mpNupPagesBox->SelectEntryPos( mpNupPagesBox->GetEntryCount()-1 );
471 showAdvancedControls( true );
472 mpNupOrderWin->setValues( i_rMPS.nOrder, i_rMPS.nColumns, i_rMPS.nRows );
476 PrintDialog::JobTabPage::JobTabPage( VclBuilder* pUIBuilder )
477 : maCollateImg( VclResId( SV_PRINT_COLLATE_IMG ) )
478 , maNoCollateImg( VclResId( SV_PRINT_NOCOLLATE_IMG ) )
479 , mnCollateUIMode( 0 )
481 pUIBuilder->get(mpPrinters, "printers");
482 pUIBuilder->get(mpStatusTxt, "status");
483 pUIBuilder->get(mpLocationTxt, "location");
484 pUIBuilder->get(mpCommentTxt, "comment");
485 pUIBuilder->get(mpSetupButton, "setup");
486 pUIBuilder->get(mpCopyCountField, "copycount");
487 pUIBuilder->get(mpCollateBox, "collate");
488 pUIBuilder->get(mpCollateImage, "collateimage");
489 pUIBuilder->get(mpReverseOrderBox, "reverseorder");
490 // HACK: this is not a dropdown box, but the dropdown line count
491 // sets the results of GetOptimalSize in a normal ListBox
492 mpPrinters->SetDropDownLineCount( 4 );
495 void PrintDialog::JobTabPage::readFromSettings()
497 SettingsConfigItem* pItem = SettingsConfigItem::get();
498 OUString aValue;
500 aValue = pItem->getValue( "PrintDialog",
501 "CollateBox" );
502 if( aValue.equalsIgnoreAsciiCase("alwaysoff") )
504 mnCollateUIMode = 1;
505 mpCollateBox->Check( false );
506 mpCollateBox->Enable( false );
508 else
510 mnCollateUIMode = 0;
511 aValue = pItem->getValue( "PrintDialog",
512 "Collate" );
513 mpCollateBox->Check( aValue.equalsIgnoreAsciiCase("true") );
517 void PrintDialog::JobTabPage::storeToSettings()
519 SettingsConfigItem* pItem = SettingsConfigItem::get();
520 pItem->setValue( "PrintDialog",
521 "CopyCount",
522 mpCopyCountField->GetText() );
523 pItem->setValue( "PrintDialog",
524 "Collate",
525 mpCollateBox->IsChecked() ? OUString("true") :
526 OUString("false") );
529 PrintDialog::OutputOptPage::OutputOptPage( VclBuilder *pUIBuilder )
531 pUIBuilder->get(mpCollateSingleJobsBox, "singleprintjob");
532 pUIBuilder->get(mpPapersizeFromSetup, "papersizefromsetup");
535 void PrintDialog::OutputOptPage::readFromSettings()
537 SettingsConfigItem* pItem = SettingsConfigItem::get();
538 OUString aValue;
539 aValue = pItem->getValue( "PrintDialog",
540 "CollateSingleJobs" );
541 if ( aValue.equalsIgnoreAsciiCase("true") )
543 mpCollateSingleJobsBox->Check();
545 else
547 mpCollateSingleJobsBox->Check( false );
551 void PrintDialog::OutputOptPage::storeToSettings()
553 SettingsConfigItem* pItem = SettingsConfigItem::get();
554 pItem->setValue( "PrintDialog",
555 "CollateSingleJobs",
556 mpCollateSingleJobsBox->IsChecked() ? OUString("true") :
557 OUString("false") );
560 namespace {
561 bool lcl_ListBoxCompare( const OUString& rStr1, const OUString& rStr2 )
563 return ListBox::NaturalSortCompare( rStr1, rStr2 ) < 0;
567 PrintDialog::PrintDialog( vcl::Window* i_pParent, const std::shared_ptr<PrinterController>& i_rController )
568 : ModalDialog(i_pParent, "PrintDialog", "vcl/ui/printdialog.ui")
569 , mpCustomOptionsUIBuilder(nullptr)
570 , maPController( i_rController )
571 , maNUpPage(m_pUIBuilder.get())
572 , maJobPage(m_pUIBuilder.get())
573 , maOptionsPage(m_pUIBuilder.get())
574 , maNoPageStr( VclResId( SV_PRINT_NOPAGES ).toString() )
575 , mnCurPage( 0 )
576 , mnCachedPages( 0 )
577 , maPrintToFileText( VclResId( SV_PRINT_TOFILE_TXT ).toString() )
578 , maDefPrtText( VclResId( SV_PRINT_DEFPRT_TXT ).toString() )
579 , mbShowLayoutPage( true )
581 get(mpOKButton, "ok");
582 get(mpCancelButton, "cancel");
583 get(mpHelpButton, "help");
584 get(mpForwardBtn, "forward");
585 get(mpBackwardBtn, "backward");
586 get(mpNumPagesText, "totalnumpages");
587 get(mpPageEdit, "pageedit-nospin");
588 get(mpTabCtrl, "tabcontrol");
589 get(mpPreviewWindow, "preview");
591 // save printbutton text, gets exchanged occasionally with print to file
592 maPrintText = mpOKButton->GetText();
594 // setup preview controls
595 mpForwardBtn->SetStyle( mpForwardBtn->GetStyle() | WB_BEVELBUTTON );
596 mpBackwardBtn->SetStyle( mpBackwardBtn->GetStyle() | WB_BEVELBUTTON );
598 maPageStr = mpNumPagesText->GetText();
600 // init reverse print
601 maJobPage.mpReverseOrderBox->Check( maPController->getReversePrint() );
603 Printer::updatePrinters();
605 maJobPage.mpPrinters->InsertEntry( maPrintToFileText );
606 // fill printer listbox
607 std::vector< OUString > rQueues( Printer::GetPrinterQueues() );
608 std::sort( rQueues.begin(), rQueues.end(), lcl_ListBoxCompare );
609 for( std::vector< OUString >::const_iterator it = rQueues.begin();
610 it != rQueues.end(); ++it )
612 maJobPage.mpPrinters->InsertEntry( *it );
614 // select current printer
615 if( maJobPage.mpPrinters->GetEntryPos( maPController->getPrinter()->GetName() ) != LISTBOX_ENTRY_NOTFOUND )
617 maJobPage.mpPrinters->SelectEntry( maPController->getPrinter()->GetName() );
619 else
621 // fall back to last printer
622 SettingsConfigItem* pItem = SettingsConfigItem::get();
623 OUString aValue( pItem->getValue( "PrintDialog",
624 "LastPrinter" ) );
625 if( maJobPage.mpPrinters->GetEntryPos( aValue ) != LISTBOX_ENTRY_NOTFOUND )
627 maJobPage.mpPrinters->SelectEntry( aValue );
628 maPController->setPrinter( VclPtrInstance<Printer>( aValue ) );
630 else
632 // fall back to default printer
633 maJobPage.mpPrinters->SelectEntry( Printer::GetDefaultPrinterName() );
634 maPController->setPrinter( VclPtrInstance<Printer>( Printer::GetDefaultPrinterName() ) );
637 // not printing to file
638 maPController->resetPrinterOptions( false );
640 // get the first page
641 preparePreview( true, true );
643 // update the text fields for the printer
644 updatePrinterText();
646 // set a select handler
647 maJobPage.mpPrinters->SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
649 // setup sizes for N-Up
650 Size aNupSize( maPController->getPrinter()->PixelToLogic(
651 maPController->getPrinter()->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) ) );
652 if( maPController->getPrinter()->GetOrientation() == Orientation::Landscape )
654 maNupLandscapeSize = aNupSize;
655 maNupPortraitSize = Size( aNupSize.Height(), aNupSize.Width() );
657 else
659 maNupPortraitSize = aNupSize;
660 maNupLandscapeSize = Size( aNupSize.Height(), aNupSize.Width() );
662 maNUpPage.initFromMultiPageSetup( maPController->getMultipage() );
664 // setup click handler on the various buttons
665 mpOKButton->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
666 #if OSL_DEBUG_LEVEL > 1
667 mpCancelButton->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
668 #endif
669 mpHelpButton->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
670 mpForwardBtn->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
671 mpBackwardBtn->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
673 maJobPage.mpCollateBox->SetToggleHdl( LINK( this, PrintDialog, ToggleHdl ) );
674 maJobPage.mpSetupButton->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
675 maNUpPage.mpBorderCB->SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
676 maOptionsPage.mpPapersizeFromSetup->SetToggleHdl( LINK( this, PrintDialog, ToggleHdl ) );
677 maJobPage.mpReverseOrderBox->SetToggleHdl( LINK( this, PrintDialog, ToggleHdl ) );
678 maOptionsPage.mpCollateSingleJobsBox->SetToggleHdl( LINK( this, PrintDialog, ToggleHdl ) );
679 maNUpPage.mpPagesBtn->SetToggleHdl( LINK( this, PrintDialog, ToggleRadioHdl ) );
680 // setup modify hdl
681 mpPageEdit->SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
682 maJobPage.mpCopyCountField->SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
683 maNUpPage.mpNupRowsEdt->SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
684 maNUpPage.mpNupColEdt->SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
685 maNUpPage.mpPageMarginEdt->SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
686 maNUpPage.mpSheetMarginEdt->SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
688 // setup select hdl
689 maNUpPage.mpNupPagesBox->SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
690 maNUpPage.mpNupOrientationBox->SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
691 maNUpPage.mpNupOrderBox->SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
693 // setup optional UI options set by application
694 setupOptionalUI();
696 // remove layout page if unwanted
697 if (!mbShowLayoutPage)
698 mpTabCtrl->RemovePage(mpTabCtrl->GetPageId(2));
700 // restore settings from last run
701 readFromSettings();
703 // setup dependencies
704 checkControlDependencies();
706 if ( maPController->getBoolProperty( "HideHelpButton", false ) )
707 mpHelpButton->Hide();
708 // set initial focus to "Number of copies"
709 maJobPage.mpCopyCountField->GrabFocus();
710 maJobPage.mpCopyCountField->SetSelection( Selection(0, 0xFFFF) );
712 updateNupFromPages();
715 PrintDialog::~PrintDialog()
717 disposeOnce();
720 void PrintDialog::dispose()
722 delete mpCustomOptionsUIBuilder;
723 mpTabCtrl.clear();
724 mpPreviewWindow.clear();
725 mpPageEdit.clear();
726 mpNumPagesText.clear();
727 mpBackwardBtn.clear();
728 mpForwardBtn.clear();
729 mpOKButton.clear();
730 mpCancelButton.clear();
731 mpHelpButton.clear();
732 maPController.reset();
733 maControlToPropertyMap.clear();
734 maControlToNumValMap.clear();
735 ModalDialog::dispose();
738 void PrintDialog::readFromSettings()
740 maJobPage.readFromSettings();
741 maOptionsPage.readFromSettings();
743 // read last selected tab page; if it exists, activate it
744 SettingsConfigItem* pItem = SettingsConfigItem::get();
745 OUString aValue = pItem->getValue( "PrintDialog",
746 "LastPage" );
747 sal_uInt16 nCount = mpTabCtrl->GetPageCount();
748 for( sal_uInt16 i = 0; i < nCount; i++ )
750 sal_uInt16 nPageId = mpTabCtrl->GetPageId( i );
751 if( aValue.equals( mpTabCtrl->GetPageText( nPageId ) ) )
753 mpTabCtrl->SelectTabPage( nPageId );
754 break;
758 // persistent window state
759 OUString aWinState( pItem->getValue( "PrintDialog",
760 "WindowState" ) );
761 if( !aWinState.isEmpty() )
762 SetWindowState( OUStringToOString( aWinState, RTL_TEXTENCODING_UTF8 ) );
765 void PrintDialog::storeToSettings()
767 maJobPage.storeToSettings();
768 maOptionsPage.storeToSettings();
770 // store last selected printer
771 SettingsConfigItem* pItem = SettingsConfigItem::get();
772 pItem->setValue( "PrintDialog",
773 "ToFile",
774 isPrintToFile() ? OUString("true")
775 : OUString("false") );
776 pItem->setValue( "PrintDialog",
777 "LastPrinter",
778 isPrintToFile() ? Printer::GetDefaultPrinterName()
779 : maJobPage.mpPrinters->GetSelectEntry() );
781 pItem->setValue( "PrintDialog",
782 "LastPage",
783 mpTabCtrl->GetPageText( mpTabCtrl->GetCurPageId() ) );
784 pItem->setValue( "PrintDialog",
785 "WindowState",
786 OStringToOUString( GetWindowState(), RTL_TEXTENCODING_UTF8 )
788 pItem->Commit();
791 bool PrintDialog::isPrintToFile()
793 return ( maJobPage.mpPrinters->GetSelectEntryPos() == 0 );
796 bool PrintDialog::isCollate()
798 return maJobPage.mpCopyCountField->GetValue() > 1 && maJobPage.mpCollateBox->IsChecked();
801 bool PrintDialog::isSingleJobs()
803 return maOptionsPage.mpCollateSingleJobsBox->IsChecked();
806 void setHelpId( vcl::Window* i_pWindow, const Sequence< OUString >& i_rHelpIds, sal_Int32 i_nIndex )
808 if( i_nIndex >= 0 && i_nIndex < i_rHelpIds.getLength() )
809 i_pWindow->SetHelpId( OUStringToOString( i_rHelpIds.getConstArray()[i_nIndex], RTL_TEXTENCODING_UTF8 ) );
812 static void setHelpText( vcl::Window* i_pWindow, const Sequence< OUString >& i_rHelpTexts, sal_Int32 i_nIndex )
814 // without a help text set and the correct smartID,
815 // help texts will be retrieved from the online help system
816 if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() )
817 i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] );
820 void PrintDialog::setupOptionalUI()
822 const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() );
823 for( int i = 0; i < rOptions.getLength(); i++ )
825 if (rOptions[i].Name == "OptionsUIFile")
827 OUString sOptionsUIFile;
828 rOptions[i].Value >>= sOptionsUIFile;
830 vcl::Window *pCustom = get<vcl::Window>("customcontents");
832 delete mpCustomOptionsUIBuilder;
833 mpCustomOptionsUIBuilder = new VclBuilder(pCustom, getUIRootDir(), sOptionsUIFile);
834 vcl::Window *pWindow = mpCustomOptionsUIBuilder->get_widget_root();
835 pWindow->Show();
836 continue;
839 Sequence< beans::PropertyValue > aOptProp;
840 rOptions[i].Value >>= aOptProp;
842 // extract ui element
843 OUString aCtrlType;
844 OString aID;
845 OUString aText;
846 OUString aPropertyName;
847 Sequence< OUString > aChoices;
848 Sequence< sal_Bool > aChoicesDisabled;
849 Sequence< OUString > aHelpTexts;
850 Sequence< OUString > aIDs;
851 Sequence< OUString > aHelpIds;
852 sal_Int64 nMinValue = 0, nMaxValue = 0;
853 OUString aGroupingHint;
854 OUString aDependsOnName;
855 sal_Int32 nDependsOnValue = 0;
856 bool bUseDependencyRow = false;
858 for( int n = 0; n < aOptProp.getLength(); n++ )
860 const beans::PropertyValue& rEntry( aOptProp[ n ] );
861 if ( rEntry.Name == "ID" )
863 rEntry.Value >>= aIDs;
864 aID = OUStringToOString(aIDs[0], RTL_TEXTENCODING_UTF8);
866 if ( rEntry.Name == "Text" )
868 rEntry.Value >>= aText;
870 else if ( rEntry.Name == "ControlType" )
872 rEntry.Value >>= aCtrlType;
874 else if ( rEntry.Name == "Choices" )
876 rEntry.Value >>= aChoices;
878 else if ( rEntry.Name == "ChoicesDisabled" )
880 rEntry.Value >>= aChoicesDisabled;
882 else if ( rEntry.Name == "Property" )
884 PropertyValue aVal;
885 rEntry.Value >>= aVal;
886 aPropertyName = aVal.Name;
888 else if ( rEntry.Name == "Enabled" )
890 bool bValue = true;
891 rEntry.Value >>= bValue;
893 else if ( rEntry.Name == "GroupingHint" )
895 rEntry.Value >>= aGroupingHint;
897 else if ( rEntry.Name == "DependsOnName" )
899 rEntry.Value >>= aDependsOnName;
901 else if ( rEntry.Name == "DependsOnEntry" )
903 rEntry.Value >>= nDependsOnValue;
905 else if ( rEntry.Name == "AttachToDependency" )
907 rEntry.Value >>= bUseDependencyRow;
909 else if ( rEntry.Name == "MinValue" )
911 rEntry.Value >>= nMinValue;
913 else if ( rEntry.Name == "MaxValue" )
915 rEntry.Value >>= nMaxValue;
917 else if ( rEntry.Name == "HelpText" )
919 if( ! (rEntry.Value >>= aHelpTexts) )
921 OUString aHelpText;
922 if( (rEntry.Value >>= aHelpText) )
924 aHelpTexts.realloc( 1 );
925 *aHelpTexts.getArray() = aHelpText;
929 else if ( rEntry.Name == "HelpId" )
931 if( ! (rEntry.Value >>= aHelpIds ) )
933 OUString aHelpId;
934 if( (rEntry.Value >>= aHelpId) )
936 aHelpIds.realloc( 1 );
937 *aHelpIds.getArray() = aHelpId;
941 else if ( rEntry.Name == "HintNoLayoutPage" )
943 bool bNoLayoutPage = false;
944 rEntry.Value >>= bNoLayoutPage;
945 mbShowLayoutPage = ! bNoLayoutPage;
949 if (aCtrlType == "Group" && !aID.isEmpty())
951 TabPage *pPage = get<TabPage>(aID);
952 if (!pPage && mpCustomOptionsUIBuilder)
953 pPage = mpCustomOptionsUIBuilder->get<TabPage>(aID);
955 if (!pPage)
956 continue;
958 sal_uInt16 nPageId = mpTabCtrl->GetPageId(*pPage);
960 mpTabCtrl->SetPageText(nPageId, aText);
962 // set help id
963 if (aHelpIds.getLength() > 0)
964 mpTabCtrl->SetHelpId(nPageId, OUStringToOString(aHelpIds.getConstArray()[0], RTL_TEXTENCODING_UTF8));
966 // set help text
967 if (aHelpTexts.getLength() > 0)
968 mpTabCtrl->SetHelpText(nPageId, aHelpTexts.getConstArray()[0]);
970 pPage->Show();
972 else if (aCtrlType == "Subgroup" && !aID.isEmpty())
974 vcl::Window *pFrame = get<vcl::Window>(aID);
975 if (!pFrame && mpCustomOptionsUIBuilder)
976 pFrame = mpCustomOptionsUIBuilder->get<vcl::Window>(aID);
978 if (!pFrame)
979 continue;
981 pFrame->SetText(aText);
983 // set help id
984 setHelpId(pFrame, aHelpIds, 0);
985 // set help text
986 setHelpText(pFrame, aHelpTexts, 0);
988 pFrame->Show();
990 // EVIL
991 else if( aCtrlType == "Bool" && aGroupingHint == "LayoutPage" && aPropertyName == "PrintProspect" )
993 maNUpPage.mpBrochureBtn->SetText( aText );
994 maNUpPage.mpBrochureBtn->Show();
996 bool bVal = false;
997 PropertyValue* pVal = maPController->getValue( aPropertyName );
998 if( pVal )
999 pVal->Value >>= bVal;
1000 maNUpPage.mpBrochureBtn->Check( bVal );
1001 maNUpPage.mpBrochureBtn->Enable( maPController->isUIOptionEnabled( aPropertyName ) && pVal != nullptr );
1002 maNUpPage.mpBrochureBtn->SetToggleHdl( LINK( this, PrintDialog, ToggleRadioHdl ) );
1004 maPropertyToWindowMap[ aPropertyName ].push_back( maNUpPage.mpBrochureBtn );
1005 maControlToPropertyMap[maNUpPage.mpBrochureBtn] = aPropertyName;
1007 // set help id
1008 setHelpId( maNUpPage.mpBrochureBtn, aHelpIds, 0 );
1009 // set help text
1010 setHelpText( maNUpPage.mpBrochureBtn, aHelpTexts, 0 );
1012 else if (aCtrlType == "Bool")
1014 // add a check box
1015 CheckBox* pNewBox = get<CheckBox>(aID);
1016 if (!pNewBox && mpCustomOptionsUIBuilder)
1017 pNewBox = mpCustomOptionsUIBuilder->get<CheckBox>(aID);
1019 if (!pNewBox)
1020 continue;
1022 pNewBox->SetText( aText );
1023 pNewBox->Show();
1025 bool bVal = false;
1026 PropertyValue* pVal = maPController->getValue( aPropertyName );
1027 if( pVal )
1028 pVal->Value >>= bVal;
1029 pNewBox->Check( bVal );
1030 pNewBox->SetToggleHdl( LINK( this, PrintDialog, UIOption_CheckHdl ) );
1032 maPropertyToWindowMap[ aPropertyName ].push_back( pNewBox );
1033 maControlToPropertyMap[pNewBox] = aPropertyName;
1035 // set help id
1036 setHelpId( pNewBox, aHelpIds, 0 );
1037 // set help text
1038 setHelpText( pNewBox, aHelpTexts, 0 );
1040 else if (aCtrlType == "Radio")
1042 sal_Int32 nCurHelpText = 0;
1044 // iterate options
1045 sal_Int32 nSelectVal = 0;
1046 PropertyValue* pVal = maPController->getValue( aPropertyName );
1047 if( pVal && pVal->Value.hasValue() )
1048 pVal->Value >>= nSelectVal;
1049 for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
1051 aID = OUStringToOString(aIDs[m], RTL_TEXTENCODING_UTF8);
1052 RadioButton* pBtn = get<RadioButton>(aID);
1053 if (!pBtn && mpCustomOptionsUIBuilder)
1054 pBtn = mpCustomOptionsUIBuilder->get<RadioButton>(aID);
1056 if (!pBtn)
1057 continue;
1059 pBtn->SetText( aChoices[m] );
1060 pBtn->Check( m == nSelectVal );
1061 pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) );
1062 if( aChoicesDisabled.getLength() > m && aChoicesDisabled[m] )
1063 pBtn->Enable( false );
1064 pBtn->Show();
1065 maPropertyToWindowMap[ aPropertyName ].push_back( pBtn );
1066 maControlToPropertyMap[pBtn] = aPropertyName;
1067 maControlToNumValMap[pBtn] = m;
1069 // set help id
1070 setHelpId( pBtn, aHelpIds, nCurHelpText );
1071 // set help text
1072 setHelpText( pBtn, aHelpTexts, nCurHelpText );
1073 nCurHelpText++;
1076 else if ( aCtrlType == "List" )
1078 ListBox* pList = get<ListBox>(aID);
1079 if (!pList && mpCustomOptionsUIBuilder)
1080 pList = mpCustomOptionsUIBuilder->get<ListBox>(aID);
1082 if (!pList)
1083 continue;
1085 // iterate options
1086 for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
1088 pList->InsertEntry( aChoices[m] );
1090 sal_Int32 nSelectVal = 0;
1091 PropertyValue* pVal = maPController->getValue( aPropertyName );
1092 if( pVal && pVal->Value.hasValue() )
1093 pVal->Value >>= nSelectVal;
1094 pList->SelectEntryPos( static_cast<sal_uInt16>(nSelectVal) );
1095 pList->SetSelectHdl( LINK( this, PrintDialog, UIOption_SelectHdl ) );
1096 pList->SetDropDownLineCount( static_cast<sal_uInt16>(aChoices.getLength()) );
1097 pList->Show();
1099 // set help id
1100 setHelpId( pList, aHelpIds, 0 );
1101 // set help text
1102 setHelpText( pList, aHelpTexts, 0 );
1104 maPropertyToWindowMap[ aPropertyName ].push_back( pList );
1105 maControlToPropertyMap[pList] = aPropertyName;
1107 else if ( aCtrlType == "Range" )
1109 NumericField* pField = get<NumericField>(aID);
1110 if (!pField && mpCustomOptionsUIBuilder)
1111 pField = mpCustomOptionsUIBuilder->get<NumericField>(aID);
1113 if (!pField)
1114 continue;
1116 // set min/max and current value
1117 if( nMinValue != nMaxValue )
1119 pField->SetMin( nMinValue );
1120 pField->SetMax( nMaxValue );
1122 sal_Int64 nCurVal = 0;
1123 PropertyValue* pVal = maPController->getValue( aPropertyName );
1124 if( pVal && pVal->Value.hasValue() )
1125 pVal->Value >>= nCurVal;
1126 pField->SetValue( nCurVal );
1127 pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) );
1128 pField->Show();
1130 // set help id
1131 setHelpId( pField, aHelpIds, 0 );
1132 // set help text
1133 setHelpText( pField, aHelpTexts, 0 );
1135 maPropertyToWindowMap[ aPropertyName ].push_back( pField );
1136 maControlToPropertyMap[pField] = aPropertyName;
1138 else if (aCtrlType == "Edit")
1140 Edit *pField = get<Edit>(aID);
1141 if (!pField && mpCustomOptionsUIBuilder)
1142 pField = mpCustomOptionsUIBuilder->get<Edit>(aID);
1144 if (!pField)
1145 continue;
1147 OUString aCurVal;
1148 PropertyValue* pVal = maPController->getValue( aPropertyName );
1149 if( pVal && pVal->Value.hasValue() )
1150 pVal->Value >>= aCurVal;
1151 pField->SetText( aCurVal );
1152 pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) );
1153 pField->Show();
1155 // set help id
1156 setHelpId( pField, aHelpIds, 0 );
1157 // set help text
1158 setHelpText( pField, aHelpTexts, 0 );
1160 maPropertyToWindowMap[ aPropertyName ].push_back( pField );
1161 maControlToPropertyMap[pField] = aPropertyName;
1163 else
1165 OStringBuffer sMessage;
1166 sMessage.append("Unsupported UI option: \"");
1167 sMessage.append(OUStringToOString(aCtrlType, RTL_TEXTENCODING_UTF8));
1168 sMessage.append('"');
1169 OSL_FAIL( sMessage.getStr() );
1173 // #i106506# if no brochure button, then the singular Pages radio button
1174 // makes no sense, so replace it by a FixedText label
1175 if (!maNUpPage.mpBrochureBtn->IsVisible() && maNUpPage.mpPagesBtn->IsVisible())
1177 maNUpPage.mpPagesBoxTitleTxt->SetText( maNUpPage.mpPagesBtn->GetText() );
1178 maNUpPage.mpPagesBoxTitleTxt->Show();
1179 maNUpPage.mpPagesBtn->Show( false );
1182 // update enable states
1183 checkOptionalControlDependencies();
1185 vcl::Window *pPageRange = get<vcl::Window>("pagerange");
1187 // print range not shown (currently math only) -> hide spacer line and reverse order
1188 if (!pPageRange || !pPageRange->IsVisible())
1190 maJobPage.mpReverseOrderBox->Show( false );
1193 if (!mpCustomOptionsUIBuilder)
1194 mpTabCtrl->RemovePage(mpTabCtrl->GetPageId(1));
1197 void PrintDialog::DataChanged( const DataChangedEvent& i_rDCEvt )
1199 // react on settings changed
1200 if( i_rDCEvt.GetType() == DataChangedEventType::SETTINGS )
1201 checkControlDependencies();
1202 ModalDialog::DataChanged( i_rDCEvt );
1205 void PrintDialog::checkControlDependencies()
1207 if( maJobPage.mpCopyCountField->GetValue() > 1 )
1208 maJobPage.mpCollateBox->Enable( maJobPage.mnCollateUIMode == 0 );
1209 else
1210 maJobPage.mpCollateBox->Enable( false );
1212 Image aImg( maJobPage.mpCollateBox->IsChecked() ? maJobPage.maCollateImg : maJobPage.maNoCollateImg );
1214 Size aImgSize( aImg.GetSizePixel() );
1216 // adjust size of image
1217 maJobPage.mpCollateImage->SetSizePixel( aImgSize );
1218 maJobPage.mpCollateImage->SetImage( aImg );
1220 // enable setup button only for printers that can be setup
1221 bool bHaveSetup = maPController->getPrinter()->HasSupport( PrinterSupport::SetupDialog );
1222 maJobPage.mpSetupButton->Enable(bHaveSetup);
1225 void PrintDialog::checkOptionalControlDependencies()
1227 for( auto it = maControlToPropertyMap.begin();
1228 it != maControlToPropertyMap.end(); ++it )
1230 bool bShouldbeEnabled = maPController->isUIOptionEnabled( it->second );
1231 if( ! bShouldbeEnabled )
1233 // enable controls that are directly attached to a dependency anyway
1234 // if the normally disabled controls get modified, change the dependency
1235 // so the control would be enabled
1236 // example: in print range "Print All" is selected, "Page Range" is then of course
1237 // not selected and the Edit for the Page Range would be disabled
1238 // as a convenience we should enable the Edit anyway and automatically select
1239 // "Page Range" instead of "Print All" if the Edit gets modified
1240 if( maReverseDependencySet.find( it->second ) != maReverseDependencySet.end() )
1242 OUString aDep( maPController->getDependency( it->second ) );
1243 // if the dependency is at least enabled, then enable this control anyway
1244 if( !aDep.isEmpty() && maPController->isUIOptionEnabled( aDep ) )
1245 bShouldbeEnabled = true;
1249 if( bShouldbeEnabled && dynamic_cast<RadioButton*>(it->first.get()) )
1251 auto r_it = maControlToNumValMap.find( it->first );
1252 if( r_it != maControlToNumValMap.end() )
1254 bShouldbeEnabled = maPController->isUIChoiceEnabled( it->second, r_it->second );
1258 bool bIsEnabled = it->first->IsEnabled();
1259 // Enable does not do a change check first, so can be less cheap than expected
1260 if( bShouldbeEnabled != bIsEnabled )
1261 it->first->Enable( bShouldbeEnabled );
1265 static OUString searchAndReplace( const OUString& i_rOrig, const char* i_pRepl, sal_Int32 i_nReplLen, const OUString& i_rRepl )
1267 sal_Int32 nPos = i_rOrig.indexOfAsciiL( i_pRepl, i_nReplLen );
1268 if( nPos != -1 )
1270 OUStringBuffer aBuf( i_rOrig.getLength() );
1271 aBuf.append( i_rOrig.getStr(), nPos );
1272 aBuf.append( i_rRepl );
1273 if( nPos + i_nReplLen < i_rOrig.getLength() )
1274 aBuf.append( i_rOrig.getStr() + nPos + i_nReplLen );
1275 return aBuf.makeStringAndClear();
1277 return i_rOrig;
1280 void PrintDialog::updatePrinterText()
1282 const OUString aDefPrt( Printer::GetDefaultPrinterName() );
1283 const QueueInfo* pInfo = Printer::GetQueueInfo( maJobPage.mpPrinters->GetSelectEntry(), true );
1284 if( pInfo )
1286 maJobPage.mpLocationTxt->SetText( pInfo->GetLocation() );
1287 maJobPage.mpCommentTxt->SetText( pInfo->GetComment() );
1288 // FIXME: status text
1289 OUString aStatus;
1290 if( aDefPrt == pInfo->GetPrinterName() )
1291 aStatus = maDefPrtText;
1292 maJobPage.mpStatusTxt->SetText( aStatus );
1294 else
1296 maJobPage.mpLocationTxt->SetText( OUString() );
1297 maJobPage.mpCommentTxt->SetText( OUString() );
1298 maJobPage.mpStatusTxt->SetText( OUString() );
1302 void PrintDialog::setPreviewText( sal_Int32 )
1304 OUString aNewText( searchAndReplace( maPageStr, "%n", 2, OUString::number( mnCachedPages ) ) );
1305 mpNumPagesText->SetText( aNewText );
1308 void PrintDialog::preparePreview( bool i_bNewPage, bool i_bMayUseCache )
1310 // page range may have changed depending on options
1311 sal_Int32 nPages = maPController->getFilteredPageCount();
1312 mnCachedPages = nPages;
1314 if( mnCurPage >= nPages )
1315 mnCurPage = nPages-1;
1316 if( mnCurPage < 0 )
1317 mnCurPage = 0;
1319 setPreviewText( mnCurPage );
1321 mpPageEdit->SetMin( 1 );
1322 mpPageEdit->SetMax( nPages );
1324 if( i_bNewPage )
1326 const MapMode aMapMode( MapUnit::Map100thMM );
1327 GDIMetaFile aMtf;
1328 VclPtr<Printer> aPrt( maPController->getPrinter() );
1329 if( nPages > 0 )
1331 PrinterController::PageSize aPageSize =
1332 maPController->getFilteredPageFile( mnCurPage, aMtf, i_bMayUseCache );
1333 if( ! aPageSize.bFullPaper )
1335 Point aOff( aPrt->PixelToLogic( aPrt->GetPageOffsetPixel(), aMapMode ) );
1336 aMtf.Move( aOff.X(), aOff.Y() );
1340 Size aCurPageSize = aPrt->PixelToLogic( aPrt->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
1341 mpPreviewWindow->setPreview( aMtf, aCurPageSize,
1342 aPrt->GetPaperName(),
1343 nPages > 0 ? OUString() : maNoPageStr,
1344 aPrt->GetDPIX(), aPrt->GetDPIY(),
1345 aPrt->GetPrinterOptions().IsConvertToGreyscales()
1348 mpForwardBtn->Enable( mnCurPage < nPages-1 );
1349 mpBackwardBtn->Enable( mnCurPage != 0 );
1350 mpPageEdit->Enable( nPages > 1 );
1354 Size const & PrintDialog::getJobPageSize()
1356 if( maFirstPageSize.Width() == 0 && maFirstPageSize.Height() == 0)
1358 maFirstPageSize = maNupPortraitSize;
1359 GDIMetaFile aMtf;
1360 if( maPController->getPageCountProtected() > 0 )
1362 PrinterController::PageSize aPageSize = maPController->getPageFile( 0, aMtf, true );
1363 maFirstPageSize = aPageSize.aSize;
1366 return maFirstPageSize;
1369 void PrintDialog::updateNupFromPages()
1371 sal_IntPtr nPages = sal_IntPtr(maNUpPage.mpNupPagesBox->GetSelectEntryData());
1372 int nRows = int(maNUpPage.mpNupRowsEdt->GetValue());
1373 int nCols = int(maNUpPage.mpNupColEdt->GetValue());
1374 long nPageMargin = long(maNUpPage.mpPageMarginEdt->Denormalize(maNUpPage.mpPageMarginEdt->GetValue( FUNIT_100TH_MM )));
1375 long nSheetMargin = long(maNUpPage.mpSheetMarginEdt->Denormalize(maNUpPage.mpSheetMarginEdt->GetValue( FUNIT_100TH_MM )));
1376 bool bCustom = false;
1378 if( nPages == 1 )
1380 nRows = nCols = 1;
1381 nSheetMargin = 0;
1382 nPageMargin = 0;
1384 else if( nPages == 2 || nPages == 4 || nPages == 6 || nPages == 9 || nPages == 16 )
1386 Size aJobPageSize( getJobPageSize() );
1387 bool bPortrait = aJobPageSize.Width() < aJobPageSize.Height();
1388 if( nPages == 2 )
1390 if( bPortrait )
1392 nRows = 1;
1393 nCols = 2;
1395 else
1397 nRows = 2;
1398 nCols = 1;
1401 else if( nPages == 4 )
1402 nRows = nCols = 2;
1403 else if( nPages == 6 )
1405 if( bPortrait )
1407 nRows = 2;
1408 nCols = 3;
1410 else
1412 nRows = 3;
1413 nCols = 2;
1416 else if( nPages == 9 )
1417 nRows = nCols = 3;
1418 else if( nPages == 16 )
1419 nRows = nCols = 4;
1420 nPageMargin = 0;
1421 nSheetMargin = 0;
1423 else
1424 bCustom = true;
1426 if( nPages > 1 )
1428 // set upper limits for margins based on job page size and rows/columns
1429 Size aSize( getJobPageSize() );
1431 // maximum sheet distance: 1/2 sheet
1432 long nHorzMax = aSize.Width()/2;
1433 long nVertMax = aSize.Height()/2;
1434 if( nSheetMargin > nHorzMax )
1435 nSheetMargin = nHorzMax;
1436 if( nSheetMargin > nVertMax )
1437 nSheetMargin = nVertMax;
1439 maNUpPage.mpSheetMarginEdt->SetMax(
1440 maNUpPage.mpSheetMarginEdt->Normalize(
1441 nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM );
1443 // maximum page distance
1444 nHorzMax = (aSize.Width() - 2*nSheetMargin);
1445 if( nCols > 1 )
1446 nHorzMax /= (nCols-1);
1447 nVertMax = (aSize.Height() - 2*nSheetMargin);
1448 if( nRows > 1 )
1449 nHorzMax /= (nRows-1);
1451 if( nPageMargin > nHorzMax )
1452 nPageMargin = nHorzMax;
1453 if( nPageMargin > nVertMax )
1454 nPageMargin = nVertMax;
1456 maNUpPage.mpPageMarginEdt->SetMax(
1457 maNUpPage.mpSheetMarginEdt->Normalize(
1458 nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM );
1461 maNUpPage.mpNupRowsEdt->SetValue( nRows );
1462 maNUpPage.mpNupColEdt->SetValue( nCols );
1463 maNUpPage.mpPageMarginEdt->SetValue( maNUpPage.mpPageMarginEdt->Normalize( nPageMargin ), FUNIT_100TH_MM );
1464 maNUpPage.mpSheetMarginEdt->SetValue( maNUpPage.mpSheetMarginEdt->Normalize( nSheetMargin ), FUNIT_100TH_MM );
1466 maNUpPage.showAdvancedControls( bCustom );
1468 updateNup();
1471 void PrintDialog::updateNup()
1473 int nRows = int(maNUpPage.mpNupRowsEdt->GetValue());
1474 int nCols = int(maNUpPage.mpNupColEdt->GetValue());
1475 long nPageMargin = long(maNUpPage.mpPageMarginEdt->Denormalize(maNUpPage.mpPageMarginEdt->GetValue( FUNIT_100TH_MM )));
1476 long nSheetMargin = long(maNUpPage.mpSheetMarginEdt->Denormalize(maNUpPage.mpSheetMarginEdt->GetValue( FUNIT_100TH_MM )));
1478 PrinterController::MultiPageSetup aMPS;
1479 aMPS.nRows = nRows;
1480 aMPS.nColumns = nCols;
1481 aMPS.nLeftMargin =
1482 aMPS.nTopMargin =
1483 aMPS.nRightMargin =
1484 aMPS.nBottomMargin = nSheetMargin;
1486 aMPS.nHorizontalSpacing =
1487 aMPS.nVerticalSpacing = nPageMargin;
1489 aMPS.bDrawBorder = maNUpPage.mpBorderCB->IsChecked();
1491 aMPS.nOrder = (NupOrderType)maNUpPage.mpNupOrderBox->GetSelectEntryPos();
1493 int nOrientationMode = maNUpPage.mpNupOrientationBox->GetSelectEntryPos();
1494 if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE )
1495 aMPS.aPaperSize = maNupLandscapeSize;
1496 else if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT )
1497 aMPS.aPaperSize = maNupPortraitSize;
1498 else // automatic mode
1500 // get size of first real page to see if it is portrait or landscape
1501 // we assume same page sizes for all the pages for this
1502 Size aPageSize = getJobPageSize();
1504 Size aMultiSize( aPageSize.Width() * nCols, aPageSize.Height() * nRows );
1505 if( aMultiSize.Width() > aMultiSize.Height() ) // fits better on landscape
1506 aMPS.aPaperSize = maNupLandscapeSize;
1507 else
1508 aMPS.aPaperSize = maNupPortraitSize;
1511 maPController->setMultipage( aMPS );
1513 maNUpPage.mpNupOrderWin->setValues( aMPS.nOrder, nCols, nRows );
1515 preparePreview( true, true );
1518 IMPL_LINK( PrintDialog, SelectHdl, ListBox&, rBox, void )
1520 if( &rBox == maJobPage.mpPrinters )
1523 if ( rBox.GetSelectEntryPos() != 0)
1525 OUString aNewPrinter( rBox.GetSelectEntry() );
1526 // set new printer
1527 maPController->setPrinter( VclPtrInstance<Printer>( aNewPrinter ) );
1528 maPController->resetPrinterOptions( false );
1529 // update text fields
1530 mpOKButton->SetText( maPrintText );
1531 updatePrinterText();
1532 preparePreview();
1534 else // print to file
1536 // use the default printer or FIXME: the last used one?
1537 maPController->setPrinter( VclPtrInstance<Printer>( Printer::GetDefaultPrinterName() ) );
1538 mpOKButton->SetText( maPrintToFileText );
1539 maPController->resetPrinterOptions( true );
1540 preparePreview( true, true );
1543 else if( &rBox == maNUpPage.mpNupOrientationBox || &rBox == maNUpPage.mpNupOrderBox )
1545 updateNup();
1547 else if( &rBox == maNUpPage.mpNupPagesBox )
1549 if( !maNUpPage.mpPagesBtn->IsChecked() )
1550 maNUpPage.mpPagesBtn->Check();
1551 updateNupFromPages();
1555 IMPL_LINK( PrintDialog, ToggleRadioHdl, RadioButton&, rButton, void )
1557 ClickHdl(static_cast<Button*>(&rButton));
1560 IMPL_LINK( PrintDialog, ToggleHdl, CheckBox&, rButton, void )
1562 ClickHdl(&rButton);
1565 IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton, void )
1567 if( pButton == mpOKButton || pButton == mpCancelButton )
1569 storeToSettings();
1570 EndDialog( pButton == mpOKButton ? RET_OK : RET_CANCEL );
1572 else if( pButton == mpHelpButton )
1574 // start help system
1575 Help* pHelp = Application::GetHelp();
1576 if( pHelp )
1578 pHelp->Start( "vcl/ui/printdialog", mpOKButton );
1581 else if( pButton == mpForwardBtn )
1583 previewForward();
1585 else if( pButton == mpBackwardBtn )
1587 previewBackward();
1589 else if( pButton == maOptionsPage.mpPapersizeFromSetup )
1591 bool bChecked = maOptionsPage.mpPapersizeFromSetup->IsChecked();
1592 maPController->setPapersizeFromSetup( bChecked );
1593 maPController->setValue( "PapersizeFromSetup",
1594 makeAny( bChecked ) );
1595 preparePreview( true, true );
1597 else if( pButton == maNUpPage.mpBrochureBtn )
1599 PropertyValue* pVal = getValueForWindow( pButton );
1600 if( pVal )
1602 bool bVal = maNUpPage.mpBrochureBtn->IsChecked();
1603 pVal->Value <<= bVal;
1605 checkOptionalControlDependencies();
1607 // update preview and page settings
1608 preparePreview();
1610 if( maNUpPage.mpBrochureBtn->IsChecked() )
1612 maNUpPage.mpNupPagesBox->SelectEntryPos( 0 );
1613 updateNupFromPages();
1614 maNUpPage.showAdvancedControls( false );
1615 maNUpPage.enableNupControls( false );
1618 else if( pButton == maNUpPage.mpPagesBtn )
1620 maNUpPage.enableNupControls( true );
1621 updateNupFromPages();
1623 else if( pButton == maJobPage.mpCollateBox )
1625 maPController->setValue( "Collate",
1626 makeAny( isCollate() ) );
1627 checkControlDependencies();
1629 else if( pButton == maJobPage.mpReverseOrderBox )
1631 bool bChecked = maJobPage.mpReverseOrderBox->IsChecked();
1632 maPController->setReversePrint( bChecked );
1633 maPController->setValue( "PrintReverse",
1634 makeAny( bChecked ) );
1635 preparePreview( true, true );
1637 else if( pButton == maNUpPage.mpBorderCB )
1639 updateNup();
1641 else
1643 if( pButton == maJobPage.mpSetupButton )
1645 maPController->setupPrinter( this );
1647 // tdf#63905 don't use cache: page size may change
1648 preparePreview();
1650 checkControlDependencies();
1654 IMPL_LINK( PrintDialog, ModifyHdl, Edit&, rEdit, void )
1656 checkControlDependencies();
1657 if( &rEdit == maNUpPage.mpNupRowsEdt || &rEdit == maNUpPage.mpNupColEdt ||
1658 &rEdit == maNUpPage.mpSheetMarginEdt || &rEdit == maNUpPage.mpPageMarginEdt
1661 updateNupFromPages();
1663 else if( &rEdit == mpPageEdit )
1665 mnCurPage = sal_Int32( mpPageEdit->GetValue() - 1 );
1666 preparePreview( true, true );
1668 else if( &rEdit == maJobPage.mpCopyCountField )
1670 maPController->setValue( "CopyCount",
1671 makeAny( sal_Int32(maJobPage.mpCopyCountField->GetValue()) ) );
1672 maPController->setValue( "Collate",
1673 makeAny( isCollate() ) );
1677 PropertyValue* PrintDialog::getValueForWindow( vcl::Window* i_pWindow ) const
1679 PropertyValue* pVal = nullptr;
1680 auto it = maControlToPropertyMap.find( i_pWindow );
1681 if( it != maControlToPropertyMap.end() )
1683 pVal = maPController->getValue( it->second );
1684 SAL_WARN_IF( !pVal, "vcl", "property value not found" );
1686 else
1688 OSL_FAIL( "changed control not in property map" );
1690 return pVal;
1693 void PrintDialog::updateWindowFromProperty( const OUString& i_rProperty )
1695 beans::PropertyValue* pValue = maPController->getValue( i_rProperty );
1696 auto it = maPropertyToWindowMap.find( i_rProperty );
1697 if( pValue && it != maPropertyToWindowMap.end() )
1699 const std::vector< VclPtr<vcl::Window> >& rWindows( it->second );
1700 if( ! rWindows.empty() )
1702 bool bVal = false;
1703 sal_Int32 nVal = -1;
1704 if( pValue->Value >>= bVal )
1706 // we should have a CheckBox for this one
1707 CheckBox* pBox = dynamic_cast< CheckBox* >( rWindows.front().get() );
1708 if( pBox )
1710 pBox->Check( bVal );
1712 else if ( i_rProperty == "PrintProspect" )
1714 // EVIL special case
1715 if( bVal )
1716 maNUpPage.mpBrochureBtn->Check();
1717 else
1718 maNUpPage.mpPagesBtn->Check();
1720 else
1722 SAL_WARN( "vcl", "missing a checkbox" );
1725 else if( pValue->Value >>= nVal )
1727 // this could be a ListBox or a RadioButtonGroup
1728 ListBox* pList = dynamic_cast< ListBox* >( rWindows.front().get() );
1729 if( pList )
1731 pList->SelectEntryPos( static_cast< sal_uInt16 >(nVal) );
1733 else if( nVal >= 0 && nVal < sal_Int32(rWindows.size() ) )
1735 RadioButton* pBtn = dynamic_cast< RadioButton* >( rWindows[nVal].get() );
1736 SAL_WARN_IF( !pBtn, "vcl", "unexpected control for property" );
1737 if( pBtn )
1738 pBtn->Check();
1745 void PrintDialog::makeEnabled( vcl::Window* i_pWindow )
1747 auto it = maControlToPropertyMap.find( i_pWindow );
1748 if( it != maControlToPropertyMap.end() )
1750 OUString aDependency( maPController->makeEnabled( it->second ) );
1751 if( !aDependency.isEmpty() )
1752 updateWindowFromProperty( aDependency );
1756 IMPL_LINK( PrintDialog, UIOption_CheckHdl, CheckBox&, i_rBox, void )
1758 PropertyValue* pVal = getValueForWindow( &i_rBox );
1759 if( pVal )
1761 makeEnabled( &i_rBox );
1763 bool bVal = i_rBox.IsChecked();
1764 pVal->Value <<= bVal;
1766 checkOptionalControlDependencies();
1768 // update preview and page settings
1769 preparePreview();
1773 IMPL_LINK( PrintDialog, UIOption_RadioHdl, RadioButton&, i_rBtn, void )
1775 // this handler gets called for all radiobuttons that get unchecked, too
1776 // however we only want one notificaction for the new value (that is for
1777 // the button that gets checked)
1778 if( i_rBtn.IsChecked() )
1780 PropertyValue* pVal = getValueForWindow( &i_rBtn );
1781 auto it = maControlToNumValMap.find( &i_rBtn );
1782 if( pVal && it != maControlToNumValMap.end() )
1784 makeEnabled( &i_rBtn );
1786 sal_Int32 nVal = it->second;
1787 pVal->Value <<= nVal;
1789 // tdf#63905 use paper size set in printer properties
1790 if (pVal->Name == "PageOptions")
1791 maPController->resetPaperToLastConfigured();
1793 checkOptionalControlDependencies();
1795 // update preview and page settings
1796 preparePreview();
1801 IMPL_LINK( PrintDialog, UIOption_SelectHdl, ListBox&, i_rBox, void )
1803 PropertyValue* pVal = getValueForWindow( &i_rBox );
1804 if( pVal )
1806 makeEnabled( &i_rBox );
1808 sal_Int32 nVal( i_rBox.GetSelectEntryPos() );
1809 pVal->Value <<= nVal;
1811 //If we are in impress we start in print slides mode and get a
1812 //maFirstPageSize for slides which are usually landscape mode, if we
1813 //change to notes which are usually in portrait mode, and then visit
1814 //n-up print, we will assume notes are in landscape unless we throw
1815 //away maFirstPageSize when we change page content type
1816 if (pVal->Name == "PageContentType")
1817 maFirstPageSize = Size();
1819 checkOptionalControlDependencies();
1821 // update preview and page settings
1822 preparePreview();
1826 IMPL_LINK( PrintDialog, UIOption_ModifyHdl, Edit&, i_rBox, void )
1828 PropertyValue* pVal = getValueForWindow( &i_rBox );
1829 if( pVal )
1831 makeEnabled( &i_rBox );
1833 NumericField* pNum = dynamic_cast<NumericField*>(&i_rBox);
1834 MetricField* pMetric = dynamic_cast<MetricField*>(&i_rBox);
1835 if( pNum )
1837 sal_Int64 nVal = pNum->GetValue();
1838 pVal->Value <<= nVal;
1840 else if( pMetric )
1842 sal_Int64 nVal = pMetric->GetValue();
1843 pVal->Value <<= nVal;
1845 else
1847 OUString aVal( i_rBox.GetText() );
1848 pVal->Value <<= aVal;
1851 checkOptionalControlDependencies();
1853 // update preview and page settings
1854 preparePreview();
1858 void PrintDialog::Command( const CommandEvent& rEvt )
1860 if( rEvt.GetCommand() == CommandEventId::Wheel )
1862 const CommandWheelData* pWheelData = rEvt.GetWheelData();
1863 if( pWheelData->GetDelta() > 0 )
1864 previewForward();
1865 else if( pWheelData->GetDelta() < 0 )
1866 previewBackward();
1870 void PrintDialog::Resize()
1872 // maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
1873 // and do the preview; however the metafile does not need to be gotten anew
1874 preparePreview( false );
1876 Dialog::Resize();
1879 void PrintDialog::previewForward()
1881 mpPageEdit->Up();
1884 void PrintDialog::previewBackward()
1886 mpPageEdit->Down();
1889 // PrintProgressDialog
1891 PrintProgressDialog::PrintProgressDialog(vcl::Window* i_pParent, int i_nMax)
1892 : ModelessDialog(i_pParent, "PrintProgressDialog", "vcl/ui/printprogressdialog.ui")
1893 , mbCanceled(false)
1894 , mnCur(0)
1895 , mnMax(i_nMax)
1897 get(mpButton, "cancel");
1898 get(mpProgress, "progressbar");
1899 get(mpText, "label");
1901 if( mnMax < 1 )
1902 mnMax = 1;
1904 maStr = mpText->GetText();
1906 //just multiply largest value by 10 and take the width of that string as
1907 //the max size we will want
1908 OUString aNewText( searchAndReplace( maStr, "%p", 2, OUString::number( mnMax * 10 ) ) );
1909 aNewText = searchAndReplace( aNewText, "%n", 2, OUString::number( mnMax * 10 ) );
1910 mpText->SetText( aNewText );
1911 mpText->set_width_request(mpText->get_preferred_size().Width());
1913 //Pick a useful max width
1914 mpProgress->set_width_request(mpProgress->LogicToPixel(Size(100, 0), MapMode(MapUnit::MapAppFont)).Width());
1916 mpButton->SetClickHdl( LINK( this, PrintProgressDialog, ClickHdl ) );
1920 PrintProgressDialog::~PrintProgressDialog()
1922 disposeOnce();
1925 void PrintProgressDialog::dispose()
1927 mpText.clear();
1928 mpProgress.clear();
1929 mpButton.clear();
1930 ModelessDialog::dispose();
1933 IMPL_LINK( PrintProgressDialog, ClickHdl, Button*, pButton, void )
1935 if( pButton == mpButton )
1936 mbCanceled = true;
1939 void PrintProgressDialog::setProgress( int i_nCurrent )
1941 mnCur = i_nCurrent;
1943 if( mnMax < 1 )
1944 mnMax = 1;
1946 mpProgress->SetValue(mnCur*100/mnMax);
1948 OUString aNewText( searchAndReplace( maStr, "%p", 2, OUString::number( mnCur ) ) );
1949 aNewText = searchAndReplace( aNewText, "%n", 2, OUString::number( mnMax ) );
1950 mpText->SetText( aNewText );
1953 void PrintProgressDialog::tick()
1955 if( mnCur < mnMax )
1956 setProgress( ++mnCur );
1959 void PrintProgressDialog::reset()
1961 mbCanceled = false;
1962 setProgress( 0 );
1965 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */