1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "precompiled_vcl.hxx" 25 26 #include "printdlg.hxx" 27 #include "svdata.hxx" 28 #include "svids.hrc" 29 #include "jobset.h" 30 31 #include "vcl/print.hxx" 32 #include "vcl/dialog.hxx" 33 #include "vcl/button.hxx" 34 #include "vcl/wall.hxx" 35 #include "vcl/status.hxx" 36 #include "vcl/decoview.hxx" 37 #include "vcl/arrange.hxx" 38 #include "vcl/configsettings.hxx" 39 #include "vcl/help.hxx" 40 #include "vcl/decoview.hxx" 41 #include "vcl/svapp.hxx" 42 #include "vcl/unohelp.hxx" 43 44 #include "unotools/localedatawrapper.hxx" 45 46 #include "rtl/strbuf.hxx" 47 48 #include "com/sun/star/lang/XMultiServiceFactory.hpp" 49 #include "com/sun/star/container/XNameAccess.hpp" 50 #include "com/sun/star/beans/PropertyValue.hpp" 51 #include "com/sun/star/awt/Size.hpp" 52 53 using namespace vcl; 54 using namespace com::sun::star; 55 using namespace com::sun::star::uno; 56 using namespace com::sun::star::lang; 57 using namespace com::sun::star::container; 58 using namespace com::sun::star::beans; 59 60 PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const ResId& i_rId ) 61 : Window( i_pParent, i_rId ) 62 , maOrigSize( 10, 10 ) 63 , maPageVDev( *this ) 64 , maToolTipString( String( VclResId( SV_PRINT_PRINTPREVIEW_TXT ) ) ) 65 , mbGreyscale( false ) 66 , maHorzDim( this, WB_HORZ | WB_CENTER ) 67 , maVertDim( this, WB_VERT | WB_VCENTER ) 68 { 69 SetPaintTransparent( sal_True ); 70 SetBackground(); 71 if( useHCColorReplacement() ) 72 maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); 73 else 74 maPageVDev.SetBackground( Color( COL_WHITE ) ); 75 maHorzDim.Show(); 76 maVertDim.Show(); 77 78 maHorzDim.SetText( String( RTL_CONSTASCII_USTRINGPARAM( "2.0in" ) ) ); 79 maVertDim.SetText( String( RTL_CONSTASCII_USTRINGPARAM( "2.0in" ) ) ); 80 } 81 82 PrintDialog::PrintPreviewWindow::~PrintPreviewWindow() 83 { 84 } 85 86 bool PrintDialog::PrintPreviewWindow::useHCColorReplacement() const 87 { 88 bool bRet = false; 89 if( GetSettings().GetStyleSettings().GetHighContrastMode() ) 90 { 91 try 92 { 93 // get service provider 94 Reference< XMultiServiceFactory > xSMgr( unohelper::GetMultiServiceFactory() ); 95 // create configuration hierachical access name 96 if( xSMgr.is() ) 97 { 98 try 99 { 100 Reference< XMultiServiceFactory > xConfigProvider( 101 Reference< XMultiServiceFactory >( 102 xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 103 "com.sun.star.configuration.ConfigurationProvider" ))), 104 UNO_QUERY ) 105 ); 106 if( xConfigProvider.is() ) 107 { 108 Sequence< Any > aArgs(1); 109 PropertyValue aVal; 110 aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 111 aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Accessibility" ) ); 112 aArgs.getArray()[0] <<= aVal; 113 Reference< XNameAccess > xConfigAccess( 114 Reference< XNameAccess >( 115 xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 116 "com.sun.star.configuration.ConfigurationAccess" )), 117 aArgs ), 118 UNO_QUERY ) 119 ); 120 if( xConfigAccess.is() ) 121 { 122 try 123 { 124 sal_Bool bValue = sal_False; 125 Any aAny = xConfigAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsForPagePreviews" ) ) ); 126 if( aAny >>= bValue ) 127 bRet = bool(bValue); 128 } 129 catch( NoSuchElementException& ) 130 { 131 } 132 catch( WrappedTargetException& ) 133 { 134 } 135 } 136 } 137 } 138 catch( Exception& ) 139 { 140 } 141 } 142 } 143 catch( WrappedTargetException& ) 144 { 145 } 146 } 147 return bRet; 148 } 149 150 void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt ) 151 { 152 // react on settings changed 153 if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS ) 154 { 155 if( useHCColorReplacement() ) 156 maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); 157 else 158 maPageVDev.SetBackground( Color( COL_WHITE ) ); 159 } 160 Window::DataChanged( i_rDCEvt ); 161 } 162 163 void PrintDialog::PrintPreviewWindow::Resize() 164 { 165 Size aNewSize( GetSizePixel() ); 166 long nTextHeight = maHorzDim.GetTextHeight(); 167 // leave small space for decoration 168 aNewSize.Width() -= nTextHeight + 2; 169 aNewSize.Height() -= nTextHeight + 2; 170 Size aScaledSize; 171 double fScale = 1.0; 172 173 // #i106435# catch corner case of Size(0,0) 174 Size aOrigSize( maOrigSize ); 175 if( aOrigSize.Width() < 1 ) 176 aOrigSize.Width() = aNewSize.Width(); 177 if( aOrigSize.Height() < 1 ) 178 aOrigSize.Height() = aNewSize.Height(); 179 if( aOrigSize.Width() > aOrigSize.Height() ) 180 { 181 aScaledSize = Size( aNewSize.Width(), aNewSize.Width() * aOrigSize.Height() / aOrigSize.Width() ); 182 if( aScaledSize.Height() > aNewSize.Height() ) 183 fScale = double(aNewSize.Height())/double(aScaledSize.Height()); 184 } 185 else 186 { 187 aScaledSize = Size( aNewSize.Height() * aOrigSize.Width() / aOrigSize.Height(), aNewSize.Height() ); 188 if( aScaledSize.Width() > aNewSize.Width() ) 189 fScale = double(aNewSize.Width())/double(aScaledSize.Width()); 190 } 191 aScaledSize.Width() = long(aScaledSize.Width()*fScale); 192 aScaledSize.Height() = long(aScaledSize.Height()*fScale); 193 194 maPreviewSize = aScaledSize; 195 196 // #i104784# if we render the page too small then rounding issues result in 197 // layout artifacts looking really bad. So scale the page unto a device that is not 198 // full page size but not too small either. This also results in much better visual 199 // quality of the preview, e.g. when its height approaches the number of text lines 200 // find a good scaling factor 201 Size aPreviewMMSize( maPageVDev.PixelToLogic( aScaledSize, MapMode( MAP_100TH_MM ) ) ); 202 double fZoom = double(maOrigSize.Height())/double(aPreviewMMSize.Height()); 203 while( fZoom > 10 ) 204 { 205 aScaledSize.Width() *= 2; 206 aScaledSize.Height() *= 2; 207 fZoom /= 2.0; 208 } 209 210 maPageVDev.SetOutputSizePixel( aScaledSize, sal_False ); 211 212 // position dimension lines 213 Point aRef( nTextHeight + (aNewSize.Width() - maPreviewSize.Width())/2, 214 nTextHeight + (aNewSize.Height() - maPreviewSize.Height())/2 ); 215 maHorzDim.SetPosSizePixel( Point( aRef.X(), aRef.Y() - nTextHeight ), 216 Size( maPreviewSize.Width(), nTextHeight ) ); 217 maVertDim.SetPosSizePixel( Point( aRef.X() - nTextHeight, aRef.Y() ), 218 Size( nTextHeight, maPreviewSize.Height() ) ); 219 220 } 221 222 void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) 223 { 224 long nTextHeight = maHorzDim.GetTextHeight(); 225 Size aSize( GetSizePixel() ); 226 aSize.Width() -= nTextHeight; 227 aSize.Height() -= nTextHeight; 228 if( maReplacementString.getLength() != 0 ) 229 { 230 // replacement is active 231 Push(); 232 Rectangle aTextRect( Point( nTextHeight, nTextHeight ), aSize ); 233 DecorationView aVw( this ); 234 aVw.DrawFrame( aTextRect, FRAME_DRAW_GROUP ); 235 aTextRect.Left() += 2; 236 aTextRect.Top() += 2; 237 aTextRect.Right() -= 2; 238 aTextRect.Bottom() -= 2; 239 Font aFont( GetSettings().GetStyleSettings().GetLabelFont() ); 240 SetZoomedPointFont( aFont ); 241 DrawText( aTextRect, maReplacementString, 242 TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE 243 ); 244 Pop(); 245 } 246 else 247 { 248 GDIMetaFile aMtf( maMtf ); 249 250 Point aOffset( (aSize.Width() - maPreviewSize.Width()) / 2 + nTextHeight, 251 (aSize.Height() - maPreviewSize.Height()) / 2 + nTextHeight ); 252 253 const Size aVDevSize( maPageVDev.GetOutputSizePixel() ); 254 const Size aLogicSize( maPageVDev.PixelToLogic( aVDevSize, MapMode( MAP_100TH_MM ) ) ); 255 Size aOrigSize( maOrigSize ); 256 if( aOrigSize.Width() < 1 ) 257 aOrigSize.Width() = aLogicSize.Width(); 258 if( aOrigSize.Height() < 1 ) 259 aOrigSize.Height() = aLogicSize.Height(); 260 double fScale = double(aLogicSize.Width())/double(aOrigSize.Width()); 261 262 263 maPageVDev.Erase(); 264 maPageVDev.Push(); 265 maPageVDev.SetMapMode( MAP_100TH_MM ); 266 sal_uLong nOldDrawMode = maPageVDev.GetDrawMode(); 267 if( mbGreyscale ) 268 maPageVDev.SetDrawMode( maPageVDev.GetDrawMode() | 269 ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | 270 DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); 271 aMtf.WindStart(); 272 aMtf.Scale( fScale, fScale ); 273 aMtf.WindStart(); 274 275 const sal_uInt16 nOriginalAA(maPageVDev.GetAntialiasing()); 276 static bool bNicePrintPreview(true); 277 278 if(bNicePrintPreview) 279 { 280 // replay metafile with AntiAliasing 281 maPageVDev.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW); 282 } 283 284 aMtf.Play( &maPageVDev, Point( 0, 0 ), aLogicSize ); 285 286 maPageVDev.SetAntialiasing(nOriginalAA); 287 maPageVDev.Pop(); 288 289 SetMapMode( MAP_PIXEL ); 290 maPageVDev.SetMapMode( MAP_PIXEL ); 291 292 if(bNicePrintPreview) 293 { 294 // use lanzcos scaling 295 Bitmap aContent(maPageVDev.GetBitmap(Point(0, 0), aVDevSize)); 296 aContent.Scale(maPreviewSize, BMP_SCALE_BESTQUALITY); 297 DrawBitmap(aOffset, aContent); 298 } 299 else 300 { 301 // direct paint (copy from OutDev to OutDev) is fast, but does not do 302 // any good scaling at all (currently) 303 DrawOutDev( aOffset, maPreviewSize, Point( 0, 0 ), aVDevSize, maPageVDev ); 304 } 305 306 maPageVDev.SetDrawMode( nOldDrawMode ); 307 308 DecorationView aVw( this ); 309 Rectangle aFrame( aOffset + Point( -1, -1 ), Size( maPreviewSize.Width() + 2, maPreviewSize.Height() + 2 ) ); 310 aVw.DrawFrame( aFrame, FRAME_DRAW_GROUP ); 311 } 312 } 313 314 void PrintDialog::PrintPreviewWindow::Command( const CommandEvent& rEvt ) 315 { 316 if( rEvt.GetCommand() == COMMAND_WHEEL ) 317 { 318 const CommandWheelData* pWheelData = rEvt.GetWheelData(); 319 PrintDialog* pDlg = dynamic_cast<PrintDialog*>(GetParent()); 320 if( pDlg ) 321 { 322 if( pWheelData->GetDelta() > 0 ) 323 pDlg->previewForward(); 324 else if( pWheelData->GetDelta() < 0 ) 325 pDlg->previewBackward(); 326 /* 327 else 328 huh ? 329 */ 330 } 331 } 332 } 333 334 void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview, 335 const Size& i_rOrigSize, 336 const rtl::OUString& i_rPaperName, 337 const rtl::OUString& i_rReplacement, 338 sal_Int32 i_nDPIX, 339 sal_Int32 i_nDPIY, 340 bool i_bGreyscale 341 ) 342 { 343 rtl::OUStringBuffer aBuf( 256 ); 344 aBuf.append( maToolTipString ); 345 SetQuickHelpText( aBuf.makeStringAndClear() ); 346 maMtf = i_rNewPreview; 347 if( useHCColorReplacement() ) 348 { 349 maMtf.ReplaceColors( Color( COL_BLACK ), Color( COL_WHITE ), 30 ); 350 } 351 352 maOrigSize = i_rOrigSize; 353 maReplacementString = i_rReplacement; 354 mbGreyscale = i_bGreyscale; 355 maPageVDev.SetReferenceDevice( i_nDPIX, i_nDPIY ); 356 maPageVDev.EnableOutput( sal_True ); 357 358 // use correct measurements 359 const LocaleDataWrapper& rLocWrap( GetSettings().GetLocaleDataWrapper() ); 360 MapUnit eUnit = MAP_MM; 361 int nDigits = 0; 362 if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US ) 363 { 364 eUnit = MAP_100TH_INCH; 365 nDigits = 2; 366 } 367 Size aLogicPaperSize( LogicToLogic( i_rOrigSize, MapMode( MAP_100TH_MM ), MapMode( eUnit ) ) ); 368 String aNumText( rLocWrap.getNum( aLogicPaperSize.Width(), nDigits ) ); 369 aBuf.append( aNumText ); 370 aBuf.appendAscii( eUnit == MAP_MM ? "mm" : "in" ); 371 if( i_rPaperName.getLength() ) 372 { 373 aBuf.appendAscii( " (" ); 374 aBuf.append( i_rPaperName ); 375 aBuf.append( sal_Unicode(')') ); 376 } 377 maHorzDim.SetText( aBuf.makeStringAndClear() ); 378 379 aNumText = rLocWrap.getNum( aLogicPaperSize.Height(), nDigits ); 380 aBuf.append( aNumText ); 381 aBuf.appendAscii( eUnit == MAP_MM ? "mm" : "in" ); 382 maVertDim.SetText( aBuf.makeStringAndClear() ); 383 384 Resize(); 385 Invalidate(); 386 } 387 388 PrintDialog::ShowNupOrderWindow::ShowNupOrderWindow( Window* i_pParent ) 389 : Window( i_pParent, WB_NOBORDER ) 390 , mnOrderMode( 0 ) 391 , mnRows( 1 ) 392 , mnColumns( 1 ) 393 { 394 ImplInitSettings(); 395 } 396 397 PrintDialog::ShowNupOrderWindow::~ShowNupOrderWindow() 398 { 399 } 400 401 void PrintDialog::ShowNupOrderWindow::ImplInitSettings() 402 { 403 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) ); 404 } 405 406 void PrintDialog::ShowNupOrderWindow::Paint( const Rectangle& i_rRect ) 407 { 408 Window::Paint( i_rRect ); 409 SetMapMode( MAP_PIXEL ); 410 SetTextColor( GetSettings().GetStyleSettings().GetFieldTextColor() ); 411 412 int nPages = mnRows * mnColumns; 413 Font aFont( GetSettings().GetStyleSettings().GetFieldFont() ); 414 aFont.SetSize( Size( 0, 24 ) ); 415 SetFont( aFont ); 416 Size aSampleTextSize( GetTextWidth( rtl::OUString::valueOf( sal_Int32(nPages+1) ) ), GetTextHeight() ); 417 418 Size aOutSize( GetOutputSizePixel() ); 419 Size aSubSize( aOutSize.Width() / mnColumns, aOutSize.Height() / mnRows ); 420 // calculate font size: shrink the sample text so it fits 421 double fX = double(aSubSize.Width())/double(aSampleTextSize.Width()); 422 double fY = double(aSubSize.Height())/double(aSampleTextSize.Height()); 423 double fScale = (fX < fY) ? fX : fY; 424 long nFontHeight = long(24.0*fScale) - 3; 425 if( nFontHeight < 5 ) 426 nFontHeight = 5; 427 aFont.SetSize( Size( 0, nFontHeight ) ); 428 SetFont( aFont ); 429 long nTextHeight = GetTextHeight(); 430 for( int i = 0; i < nPages; i++ ) 431 { 432 rtl::OUString aPageText( rtl::OUString::valueOf( sal_Int32(i+1) ) ); 433 int nX = 0, nY = 0; 434 switch( mnOrderMode ) 435 { 436 case SV_PRINT_PRT_NUP_ORDER_LRTB: 437 nX = (i % mnColumns); nY = (i / mnColumns); 438 break; 439 case SV_PRINT_PRT_NUP_ORDER_TBLR: 440 nX = (i / mnRows); nY = (i % mnRows); 441 break; 442 case SV_PRINT_PRT_NUP_ORDER_RLTB: 443 nX = mnColumns - 1 - (i % mnColumns); nY = (i / mnColumns); 444 break; 445 case SV_PRINT_PRT_NUP_ORDER_TBRL: 446 nX = mnColumns - 1 - (i / mnRows); nY = (i % mnRows); 447 break; 448 } 449 Size aTextSize( GetTextWidth( aPageText ), nTextHeight ); 450 int nDeltaX = (aSubSize.Width() - aTextSize.Width()) / 2; 451 int nDeltaY = (aSubSize.Height() - aTextSize.Height()) / 2; 452 DrawText( Point( nX * aSubSize.Width() + nDeltaX, 453 nY * aSubSize.Height() + nDeltaY ), 454 aPageText ); 455 } 456 DecorationView aVw( this ); 457 aVw.DrawFrame( Rectangle( Point( 0, 0), aOutSize ), FRAME_DRAW_GROUP ); 458 } 459 460 PrintDialog::NUpTabPage::NUpTabPage( Window* i_pParent, const ResId& rResId ) 461 : TabPage( i_pParent, rResId ) 462 , maNupLine( this, VclResId( SV_PRINT_PRT_NUP_LAYOUT_FL ) ) 463 , maPagesBtn( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BTN ) ) 464 , maBrochureBtn( this, VclResId( SV_PRINT_PRT_NUP_BROCHURE_BTN ) ) 465 , maPagesBoxTitleTxt( this, 0 ) 466 , maNupPagesBox( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BOX ) ) 467 , maNupNumPagesTxt( this, VclResId( SV_PRINT_PRT_NUP_NUM_PAGES_TXT ) ) 468 , maNupColEdt( this, VclResId( SV_PRINT_PRT_NUP_COLS_EDT ) ) 469 , maNupTimesTxt( this, VclResId( SV_PRINT_PRT_NUP_TIMES_TXT ) ) 470 , maNupRowsEdt( this, VclResId( SV_PRINT_PRT_NUP_ROWS_EDT ) ) 471 , maPageMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT ) ) 472 , maPageMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT ) ) 473 , maPageMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT ) ) 474 , maSheetMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_1_TXT ) ) 475 , maSheetMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT ) ) 476 , maSheetMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT ) ) 477 , maNupOrientationTxt( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_TXT ) ) 478 , maNupOrientationBox( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_BOX ) ) 479 , maNupOrderTxt( this, VclResId( SV_PRINT_PRT_NUP_ORDER_TXT ) ) 480 , maNupOrderBox( this, VclResId( SV_PRINT_PRT_NUP_ORDER_BOX ) ) 481 , maNupOrderWin( this ) 482 , maBorderCB( this, VclResId( SV_PRINT_PRT_NUP_BORDER_CB ) ) 483 { 484 FreeResource(); 485 486 maNupOrderWin.Show(); 487 maPagesBtn.Check( sal_True ); 488 maBrochureBtn.Show( sal_False ); 489 490 // setup field units for metric fields 491 const LocaleDataWrapper& rLocWrap( maPageMarginEdt.GetLocaleDataWrapper() ); 492 FieldUnit eUnit = FUNIT_MM; 493 sal_uInt16 nDigits = 0; 494 if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US ) 495 { 496 eUnit = FUNIT_INCH; 497 nDigits = 2; 498 } 499 // set units 500 maPageMarginEdt.SetUnit( eUnit ); 501 maSheetMarginEdt.SetUnit( eUnit ); 502 503 // set precision 504 maPageMarginEdt.SetDecimalDigits( nDigits ); 505 maSheetMarginEdt.SetDecimalDigits( nDigits ); 506 507 setupLayout(); 508 } 509 510 PrintDialog::NUpTabPage::~NUpTabPage() 511 { 512 } 513 514 void PrintDialog::NUpTabPage::enableNupControls( bool bEnable ) 515 { 516 maNupPagesBox.Enable( sal_True ); 517 maNupNumPagesTxt.Enable( bEnable ); 518 maNupColEdt.Enable( bEnable ); 519 maNupTimesTxt.Enable( bEnable ); 520 maNupRowsEdt.Enable( bEnable ); 521 maPageMarginTxt1.Enable( bEnable ); 522 maPageMarginEdt.Enable( bEnable ); 523 maPageMarginTxt2.Enable( bEnable ); 524 maSheetMarginTxt1.Enable( bEnable ); 525 maSheetMarginEdt.Enable( bEnable ); 526 maSheetMarginTxt2.Enable( bEnable ); 527 maNupOrientationTxt.Enable( bEnable ); 528 maNupOrientationBox.Enable( bEnable ); 529 maNupOrderTxt.Enable( bEnable ); 530 maNupOrderBox.Enable( bEnable ); 531 maNupOrderWin.Enable( bEnable ); 532 maBorderCB.Enable( bEnable ); 533 } 534 535 void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow ) 536 { 537 maNupNumPagesTxt.Show( i_bShow ); 538 maNupColEdt.Show( i_bShow ); 539 maNupTimesTxt.Show( i_bShow ); 540 maNupRowsEdt.Show( i_bShow ); 541 maPageMarginTxt1.Show( i_bShow ); 542 maPageMarginEdt.Show( i_bShow ); 543 maPageMarginTxt2.Show( i_bShow ); 544 maSheetMarginTxt1.Show( i_bShow ); 545 maSheetMarginEdt.Show( i_bShow ); 546 maSheetMarginTxt2.Show( i_bShow ); 547 maNupOrientationTxt.Show( i_bShow ); 548 maNupOrientationBox.Show( i_bShow ); 549 getLayout()->resize(); 550 } 551 552 void PrintDialog::NUpTabPage::setupLayout() 553 { 554 boost::shared_ptr<vcl::RowOrColumn> xLayout = 555 boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); 556 Size aBorder( LogicToPixel( Size( 6, 6 ), MapMode( MAP_APPFONT ) ) ); 557 /* According to OOo style guide, the horizontal indentation of child 558 elements to their parent element should always be 6 map units. */ 559 long nIndent = aBorder.Width(); 560 561 xLayout->addWindow( &maNupLine ); 562 boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( xLayout.get(), false ) ); 563 xLayout->addChild( xRow ); 564 boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xRow.get() ) ); 565 xRow->addChild( xIndent ); 566 567 boost::shared_ptr< vcl::RowOrColumn > xShowNupCol( new vcl::RowOrColumn( xRow.get() ) ); 568 xRow->addChild( xShowNupCol, -1 ); 569 xShowNupCol->setMinimumSize( xShowNupCol->addWindow( &maNupOrderWin ), Size( 70, 70 ) ); 570 boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( xShowNupCol.get() ) ); 571 xShowNupCol->addChild( xSpacer ); 572 573 boost::shared_ptr< vcl::LabelColumn > xMainCol( new vcl::LabelColumn( xIndent.get() ) ); 574 xIndent->setChild( xMainCol ); 575 576 size_t nPagesIndex = xMainCol->addRow( &maPagesBtn, &maNupPagesBox ); 577 mxPagesBtnLabel = boost::dynamic_pointer_cast<vcl::LabeledElement>( xMainCol->getChild( nPagesIndex ) ); 578 579 xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) ); 580 xMainCol->addRow( &maNupNumPagesTxt, xRow, nIndent ); 581 xRow->addWindow( &maNupColEdt ); 582 xRow->addWindow( &maNupTimesTxt ); 583 xRow->addWindow( &maNupRowsEdt ); 584 585 boost::shared_ptr< vcl::LabeledElement > xLab( new vcl::LabeledElement( xMainCol.get(), 2 ) ); 586 xLab->setLabel( &maPageMarginEdt ); 587 xLab->setElement( &maPageMarginTxt2 ); 588 xMainCol->addRow( &maPageMarginTxt1, xLab, nIndent ); 589 590 xLab.reset( new vcl::LabeledElement( xMainCol.get(), 2 ) ); 591 xLab->setLabel( &maSheetMarginEdt ); 592 xLab->setElement( &maSheetMarginTxt2 ); 593 xMainCol->addRow( &maSheetMarginTxt1, xLab, nIndent ); 594 595 xMainCol->addRow( &maNupOrientationTxt, &maNupOrientationBox, nIndent ); 596 xMainCol->addRow( &maNupOrderTxt, &maNupOrderBox, nIndent ); 597 xMainCol->setBorders( xMainCol->addWindow( &maBorderCB ), nIndent, 0, 0, 0 ); 598 599 xSpacer.reset( new vcl::Spacer( xMainCol.get(), 0, Size( 10, WindowArranger::getDefaultBorder() ) ) ); 600 xMainCol->addChild( xSpacer ); 601 602 xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) ); 603 xMainCol->addRow( &maBrochureBtn, xRow ); 604 // remember brochure row for dependencies 605 mxBrochureDep = xRow; 606 607 // initially advanced controls are not shown, rows=columns=1 608 showAdvancedControls( false ); 609 } 610 611 void PrintDialog::NUpTabPage::initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& i_rMPS ) 612 { 613 maSheetMarginEdt.SetValue( maSheetMarginEdt.Normalize( i_rMPS.nLeftMargin ), FUNIT_100TH_MM ); 614 maPageMarginEdt.SetValue( maPageMarginEdt.Normalize( i_rMPS.nHorizontalSpacing ), FUNIT_100TH_MM ); 615 maBorderCB.Check( i_rMPS.bDrawBorder ); 616 maNupRowsEdt.SetValue( i_rMPS.nRows ); 617 maNupColEdt.SetValue( i_rMPS.nColumns ); 618 maBorderCB.Check( i_rMPS.bDrawBorder ); 619 for( sal_uInt16 i = 0; i < maNupOrderBox.GetEntryCount(); i++ ) 620 { 621 if( int(sal_IntPtr(maNupOrderBox.GetEntryData( i ))) == i_rMPS.nOrder ) 622 maNupOrderBox.SelectEntryPos( i ); 623 } 624 if( i_rMPS.nRows != 1 || i_rMPS.nColumns != 1 ) 625 { 626 maNupPagesBox.SelectEntryPos( maNupPagesBox.GetEntryCount()-1 ); 627 showAdvancedControls( true ); 628 maNupOrderWin.setValues( i_rMPS.nOrder, i_rMPS.nColumns, i_rMPS.nRows ); 629 } 630 } 631 632 void PrintDialog::NUpTabPage::readFromSettings() 633 { 634 } 635 636 void PrintDialog::NUpTabPage::storeToSettings() 637 { 638 } 639 640 PrintDialog::JobTabPage::JobTabPage( Window* i_pParent, const ResId& rResId ) 641 : TabPage( i_pParent, rResId ) 642 , maPrinterFL( this, VclResId( SV_PRINT_PRINTERS_FL ) ) 643 , maPrinters( this, VclResId( SV_PRINT_PRINTERS ) ) 644 , maDetailsBtn( this, VclResId( SV_PRINT_DETAILS_BTN ) ) 645 , maStatusLabel( this, VclResId( SV_PRINT_STATUS_TXT ) ) 646 , maStatusTxt( this, 0 ) 647 , maLocationLabel( this, VclResId( SV_PRINT_LOCATION_TXT ) ) 648 , maLocationTxt( this, 0 ) 649 , maCommentLabel( this, VclResId( SV_PRINT_COMMENT_TXT ) ) 650 , maCommentTxt( this, 0 ) 651 , maSetupButton( this, VclResId( SV_PRINT_PRT_SETUP ) ) 652 , maCopies( this, VclResId( SV_PRINT_COPIES ) ) 653 , maCopySpacer( this, WB_VERT ) 654 , maCopyCount( this, VclResId( SV_PRINT_COPYCOUNT ) ) 655 , maCopyCountField( this, VclResId( SV_PRINT_COPYCOUNT_FIELD ) ) 656 , maCollateBox( this, VclResId( SV_PRINT_COLLATE ) ) 657 , maCollateImage( this, VclResId( SV_PRINT_COLLATE_IMAGE ) ) 658 , maReverseOrderBox( this, VclResId( SV_PRINT_OPT_REVERSE ) ) 659 , maCollateImg( VclResId( SV_PRINT_COLLATE_IMG ) ) 660 , maCollateHCImg( VclResId( SV_PRINT_COLLATE_HC_IMG ) ) 661 , maNoCollateImg( VclResId( SV_PRINT_NOCOLLATE_IMG ) ) 662 , maNoCollateHCImg( VclResId( SV_PRINT_NOCOLLATE_HC_IMG ) ) 663 , mnCollateUIMode( 0 ) 664 { 665 FreeResource(); 666 667 maCopySpacer.Show(); 668 maStatusTxt.Show(); 669 maCommentTxt.Show(); 670 maLocationTxt.Show(); 671 672 setupLayout(); 673 } 674 675 PrintDialog::JobTabPage::~JobTabPage() 676 { 677 } 678 679 void PrintDialog::JobTabPage::setupLayout() 680 { 681 // HACK: this is not a dropdown box, but the dropdown line count 682 // sets the results of GetOptimalSize in a normal ListBox 683 maPrinters.SetDropDownLineCount( 4 ); 684 685 boost::shared_ptr<vcl::RowOrColumn> xLayout = 686 boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); 687 688 // add printer fixed line 689 xLayout->addWindow( &maPrinterFL ); 690 // add print LB 691 xLayout->addWindow( &maPrinters, 3 ); 692 693 // create a row for details button/text and properties button 694 boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( xLayout.get(), false ) ); 695 xLayout->addChild( xDetRow ); 696 xDetRow->addWindow( &maDetailsBtn ); 697 xDetRow->addChild( new vcl::Spacer( xDetRow.get(), 2 ) ); 698 xDetRow->addWindow( &maSetupButton ); 699 700 // create an indent for details 701 boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xLayout.get() ) ); 702 xLayout->addChild( xIndent ); 703 // remember details controls 704 mxDetails = xIndent; 705 // create a column for the details 706 boost::shared_ptr< vcl::LabelColumn > xLabelCol( new vcl::LabelColumn( xIndent.get() ) ); 707 xIndent->setChild( xLabelCol ); 708 xLabelCol->addRow( &maStatusLabel, &maStatusTxt ); 709 xLabelCol->addRow( &maLocationLabel, &maLocationTxt ); 710 xLabelCol->addRow( &maCommentLabel, &maCommentTxt ); 711 712 // add print range and copies columns 713 xLayout->addWindow( &maCopies ); 714 boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( xLayout.get(), false ) ); 715 xLayout->addChild( xRangeRow ); 716 717 // create print range and add to range row 718 mxPrintRange.reset( new vcl::RowOrColumn( xRangeRow.get() ) ); 719 xRangeRow->addChild( mxPrintRange ); 720 xRangeRow->addWindow( &maCopySpacer ); 721 722 boost::shared_ptr< vcl::RowOrColumn > xCopyCollateCol( new vcl::RowOrColumn( xRangeRow.get() ) ); 723 xRangeRow->addChild( xCopyCollateCol ); 724 725 // add copies row to copy/collate column 726 boost::shared_ptr< vcl::LabeledElement > xCopiesRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) ); 727 xCopyCollateCol->addChild( xCopiesRow ); 728 xCopiesRow->setLabel( &maCopyCount ); 729 xCopiesRow->setElement( &maCopyCountField ); 730 boost::shared_ptr< vcl::LabeledElement > xCollateRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) ); 731 xCopyCollateCol->addChild( xCollateRow ); 732 xCollateRow->setLabel( &maCollateBox ); 733 xCollateRow->setElement( &maCollateImage ); 734 735 // maDetailsBtn.SetStyle( maDetailsBtn.GetStyle() | (WB_SMALLSTYLE | WB_BEVELBUTTON) ); 736 mxDetails->show( false, false ); 737 } 738 739 void PrintDialog::JobTabPage::readFromSettings() 740 { 741 SettingsConfigItem* pItem = SettingsConfigItem::get(); 742 rtl::OUString aValue; 743 744 #if 0 745 // do not actually make copy count persistent 746 // the assumption is that this would lead to a lot of unwanted copies 747 aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 748 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ) ); 749 sal_Int32 nVal = aValue.toInt32(); 750 maCopyCountField.SetValue( sal_Int64(nVal > 1 ? nVal : 1) ); 751 #endif 752 753 aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 754 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CollateBox" ) ) ); 755 if( aValue.equalsIgnoreAsciiCaseAscii( "alwaysoff" ) ) 756 { 757 mnCollateUIMode = 1; 758 maCollateBox.Check( sal_False ); 759 maCollateBox.Enable( sal_False ); 760 } 761 else 762 { 763 mnCollateUIMode = 0; 764 aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 765 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) ); 766 maCollateBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) ); 767 } 768 Resize(); 769 } 770 771 void PrintDialog::JobTabPage::storeToSettings() 772 { 773 SettingsConfigItem* pItem = SettingsConfigItem::get(); 774 pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 775 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ), 776 maCopyCountField.GetText() ); 777 pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 778 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ), 779 rtl::OUString::createFromAscii( maCollateBox.IsChecked() ? "true" : "false" ) ); 780 } 781 782 PrintDialog::OutputOptPage::OutputOptPage( Window* i_pParent, const ResId& i_rResId ) 783 : TabPage( i_pParent, i_rResId ) 784 , maOptionsLine( this, VclResId( SV_PRINT_OPT_PRINT_FL ) ) 785 , maToFileBox( this, VclResId( SV_PRINT_OPT_TOFILE ) ) 786 , maCollateSingleJobsBox( this, VclResId( SV_PRINT_OPT_SINGLEJOBS ) ) 787 { 788 FreeResource(); 789 790 setupLayout(); 791 } 792 793 PrintDialog::OutputOptPage::~OutputOptPage() 794 { 795 } 796 797 void PrintDialog::OutputOptPage::setupLayout() 798 { 799 boost::shared_ptr<vcl::RowOrColumn> xLayout = 800 boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); 801 802 xLayout->addWindow( &maOptionsLine ); 803 boost::shared_ptr<vcl::Indenter> xIndent( new vcl::Indenter( xLayout.get(), -1 ) ); 804 xLayout->addChild( xIndent ); 805 boost::shared_ptr<vcl::RowOrColumn> xCol( new vcl::RowOrColumn( xIndent.get() ) ); 806 xIndent->setChild( xCol ); 807 mxOptGroup = xCol; 808 xCol->addWindow( &maToFileBox ); 809 xCol->addWindow( &maCollateSingleJobsBox ); 810 } 811 812 void PrintDialog::OutputOptPage::readFromSettings() 813 { 814 #if 0 815 SettingsConfigItem* pItem = SettingsConfigItem::get(); 816 rtl::OUString aValue; 817 818 aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 819 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ) ); 820 maToFileBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) ); 821 #endif 822 } 823 824 void PrintDialog::OutputOptPage::storeToSettings() 825 { 826 SettingsConfigItem* pItem = SettingsConfigItem::get(); 827 pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 828 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ), 829 rtl::OUString::createFromAscii( maToFileBox.IsChecked() ? "true" : "false" ) ); 830 } 831 832 PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterController>& i_rController ) 833 : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) ) 834 , maOKButton( this, VclResId( SV_PRINT_OK ) ) 835 , maCancelButton( this, VclResId( SV_PRINT_CANCEL ) ) 836 , maHelpButton( this, VclResId( SV_PRINT_HELP ) ) 837 , maPreviewWindow( this, VclResId( SV_PRINT_PAGE_PREVIEW ) ) 838 , maPageEdit( this, VclResId( SV_PRINT_PAGE_EDIT ) ) 839 , maNumPagesText( this, VclResId( SV_PRINT_PAGE_TXT ) ) 840 , maBackwardBtn( this, VclResId( SV_PRINT_PAGE_BACKWARD ) ) 841 , maForwardBtn( this, VclResId( SV_PRINT_PAGE_FORWARD ) ) 842 , maTabCtrl( this, VclResId( SV_PRINT_TABCTRL ) ) 843 , maNUpPage( &maTabCtrl, VclResId( SV_PRINT_TAB_NUP ) ) 844 , maJobPage( &maTabCtrl, VclResId( SV_PRINT_TAB_JOB ) ) 845 , maOptionsPage( &maTabCtrl, VclResId( SV_PRINT_TAB_OPT ) ) 846 , maButtonLine( this, VclResId( SV_PRINT_BUTTONLINE ) ) 847 , maPController( i_rController ) 848 , maNoPageStr( String( VclResId( SV_PRINT_NOPAGES ) ) ) 849 , mnCurPage( 0 ) 850 , mnCachedPages( 0 ) 851 , maPrintToFileText( String( VclResId( SV_PRINT_TOFILE_TXT ) ) ) 852 , maDefPrtText( String( VclResId( SV_PRINT_DEFPRT_TXT ) ) ) 853 , mbShowLayoutPage( sal_True ) 854 { 855 FreeResource(); 856 857 // save printbutton text, gets exchanged occasionally with print to file 858 maPrintText = maOKButton.GetText(); 859 860 // setup preview controls 861 maForwardBtn.SetStyle( maForwardBtn.GetStyle() | WB_BEVELBUTTON ); 862 maBackwardBtn.SetStyle( maBackwardBtn.GetStyle() | WB_BEVELBUTTON ); 863 864 // insert the job (general) tab page first 865 maTabCtrl.InsertPage( SV_PRINT_TAB_JOB, maJobPage.GetText() ); 866 maTabCtrl.SetTabPage( SV_PRINT_TAB_JOB, &maJobPage ); 867 868 // set symbols on forward and backward button 869 maBackwardBtn.SetSymbol( SYMBOL_PREV ); 870 maForwardBtn.SetSymbol( SYMBOL_NEXT ); 871 maBackwardBtn.ImplSetSmallSymbol( sal_True ); 872 maForwardBtn.ImplSetSmallSymbol( sal_True ); 873 874 maPageStr = maNumPagesText.GetText(); 875 876 // init reverse print 877 maJobPage.maReverseOrderBox.Check( maPController->getReversePrint() ); 878 879 // fill printer listbox 880 const std::vector< rtl::OUString >& rQueues( Printer::GetPrinterQueues() ); 881 for( std::vector< rtl::OUString >::const_iterator it = rQueues.begin(); 882 it != rQueues.end(); ++it ) 883 { 884 maJobPage.maPrinters.InsertEntry( *it ); 885 } 886 // select current printer 887 if( maJobPage.maPrinters.GetEntryPos( maPController->getPrinter()->GetName() ) != LISTBOX_ENTRY_NOTFOUND ) 888 { 889 maJobPage.maPrinters.SelectEntry( maPController->getPrinter()->GetName() ); 890 } 891 else 892 { 893 // fall back to last printer 894 SettingsConfigItem* pItem = SettingsConfigItem::get(); 895 String aValue( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 896 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ) ) ); 897 if( maJobPage.maPrinters.GetEntryPos( aValue ) != LISTBOX_ENTRY_NOTFOUND ) 898 { 899 maJobPage.maPrinters.SelectEntry( aValue ); 900 maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aValue ) ) ); 901 } 902 else 903 { 904 // fall back to default printer 905 maJobPage.maPrinters.SelectEntry( Printer::GetDefaultPrinterName() ); 906 maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( Printer::GetDefaultPrinterName() ) ) ); 907 } 908 } 909 // not printing to file 910 maPController->resetPrinterOptions( false ); 911 912 // get the first page 913 preparePreview( true, true ); 914 915 // update the text fields for the printer 916 updatePrinterText(); 917 918 // set a select handler 919 maJobPage.maPrinters.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); 920 921 // setup sizes for N-Up 922 Size aNupSize( maPController->getPrinter()->PixelToLogic( 923 maPController->getPrinter()->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) ); 924 if( maPController->getPrinter()->GetOrientation() == ORIENTATION_LANDSCAPE ) 925 { 926 maNupLandscapeSize = aNupSize; 927 maNupPortraitSize = Size( aNupSize.Height(), aNupSize.Width() ); 928 } 929 else 930 { 931 maNupPortraitSize = aNupSize; 932 maNupLandscapeSize = Size( aNupSize.Height(), aNupSize.Width() ); 933 } 934 maNUpPage.initFromMultiPageSetup( maPController->getMultipage() ); 935 936 937 // setup click handler on the various buttons 938 maOKButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 939 #if OSL_DEBUG_LEVEL > 1 940 maCancelButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 941 #endif 942 maHelpButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 943 maForwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 944 maBackwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 945 maJobPage.maCollateBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 946 maJobPage.maSetupButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 947 maJobPage.maDetailsBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 948 maNUpPage.maBorderCB.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); 949 maOptionsPage.maToFileBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 950 maJobPage.maReverseOrderBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 951 maOptionsPage.maCollateSingleJobsBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 952 maNUpPage.maPagesBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 953 954 // setup modify hdl 955 maPageEdit.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); 956 maJobPage.maCopyCountField.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); 957 maNUpPage.maNupRowsEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); 958 maNUpPage.maNupColEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); 959 maNUpPage.maPageMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); 960 maNUpPage.maSheetMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); 961 962 // setup select hdl 963 maNUpPage.maNupPagesBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); 964 maNUpPage.maNupOrientationBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); 965 maNUpPage.maNupOrderBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); 966 967 // setup the layout 968 setupLayout(); 969 970 // setup optional UI options set by application 971 setupOptionalUI(); 972 973 // set change handler for UI options 974 maPController->setOptionChangeHdl( LINK( this, PrintDialog, UIOptionsChanged ) ); 975 976 // set min size pixel to current size 977 Size aOutSize( GetOutputSizePixel() ); 978 SetMinOutputSizePixel( aOutSize ); 979 980 // if there is space enough, enlarge the preview so it gets roughly as 981 // high as the tab control 982 if( aOutSize.Width() < 768 ) 983 { 984 Size aJobPageSize( getJobPageSize() ); 985 Size aTabSize( maTabCtrl.GetSizePixel() ); 986 if( aJobPageSize.Width() < 1 ) 987 aJobPageSize.Width() = aTabSize.Width(); 988 if( aJobPageSize.Height() < 1 ) 989 aJobPageSize.Height() = aTabSize.Height(); 990 long nOptPreviewWidth = aTabSize.Height() * aJobPageSize.Width() / aJobPageSize.Height(); 991 // add space for borders 992 nOptPreviewWidth += 15; 993 if( aOutSize.Width() - aTabSize.Width() < nOptPreviewWidth ) 994 { 995 aOutSize.Width() = aTabSize.Width() + nOptPreviewWidth; 996 if( aOutSize.Width() > 768 ) // don't enlarge the dialog too much 997 aOutSize.Width() = 768; 998 SetOutputSizePixel( aOutSize ); 999 } 1000 } 1001 1002 // append further tab pages 1003 if( mbShowLayoutPage ) 1004 { 1005 maTabCtrl.InsertPage( SV_PRINT_TAB_NUP, maNUpPage.GetText() ); 1006 maTabCtrl.SetTabPage( SV_PRINT_TAB_NUP, &maNUpPage ); 1007 } 1008 maTabCtrl.InsertPage( SV_PRINT_TAB_OPT, maOptionsPage.GetText() ); 1009 maTabCtrl.SetTabPage( SV_PRINT_TAB_OPT, &maOptionsPage ); 1010 1011 // restore settings from last run 1012 readFromSettings(); 1013 1014 // setup dependencies 1015 checkControlDependencies(); 1016 1017 } 1018 1019 PrintDialog::~PrintDialog() 1020 { 1021 while( ! maControls.empty() ) 1022 { 1023 delete maControls.front(); 1024 maControls.pop_front(); 1025 } 1026 } 1027 1028 void PrintDialog::setupLayout() 1029 { 1030 boost::shared_ptr<vcl::RowOrColumn> xLayout = 1031 boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); 1032 xLayout->setOuterBorder( 0 ); 1033 1034 1035 boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( xLayout.get(), false ) ); 1036 size_t nIndex = xLayout->addChild( xPreviewAndTab, 5 ); 1037 xLayout->setBorders( nIndex, -1, -1, -1, 0 ); 1038 1039 // setup column for preview and sub controls 1040 boost::shared_ptr< vcl::RowOrColumn > xPreview( new vcl::RowOrColumn( xPreviewAndTab.get() ) ); 1041 xPreviewAndTab->addChild( xPreview, 5 ); 1042 xPreview->addWindow( &maPreviewWindow, 5 ); 1043 // get a row for the preview controls 1044 mxPreviewCtrls.reset( new vcl::RowOrColumn( xPreview.get(), false ) ); 1045 nIndex = xPreview->addChild( mxPreviewCtrls ); 1046 boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) ); 1047 mxPreviewCtrls->addChild( xSpacer ); 1048 mxPreviewCtrls->addWindow( &maPageEdit ); 1049 mxPreviewCtrls->addWindow( &maNumPagesText ); 1050 xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) ); 1051 mxPreviewCtrls->addChild( xSpacer ); 1052 mxPreviewCtrls->addWindow( &maBackwardBtn ); 1053 mxPreviewCtrls->addWindow( &maForwardBtn ); 1054 xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) ); 1055 mxPreviewCtrls->addChild( xSpacer ); 1056 1057 // continue with the tab ctrl 1058 xPreviewAndTab->addWindow( &maTabCtrl ); 1059 1060 // add the button line 1061 xLayout->addWindow( &maButtonLine ); 1062 1063 // add the row for the buttons 1064 boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( xLayout.get(), false ) ); 1065 nIndex = xLayout->addChild( xButtons ); 1066 xLayout->setBorders( nIndex, -1, 0, -1, -1 ); 1067 1068 Size aMinSize( maCancelButton.GetSizePixel() ); 1069 // insert help button 1070 xButtons->setMinimumSize( xButtons->addWindow( &maHelpButton ), aMinSize ); 1071 // insert a spacer, cancel and OK buttons are right aligned 1072 xSpacer.reset( new vcl::Spacer( xButtons.get(), 2 ) ); 1073 xButtons->addChild( xSpacer ); 1074 xButtons->setMinimumSize( xButtons->addWindow( &maOKButton ), aMinSize ); 1075 xButtons->setMinimumSize( xButtons->addWindow( &maCancelButton ), aMinSize ); 1076 } 1077 1078 void PrintDialog::readFromSettings() 1079 { 1080 maJobPage.readFromSettings(); 1081 maNUpPage.readFromSettings(); 1082 maOptionsPage.readFromSettings(); 1083 1084 // read last selected tab page; if it exists, actiavte it 1085 SettingsConfigItem* pItem = SettingsConfigItem::get(); 1086 rtl::OUString aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 1087 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ) ); 1088 sal_uInt16 nCount = maTabCtrl.GetPageCount(); 1089 for( sal_uInt16 i = 0; i < nCount; i++ ) 1090 { 1091 sal_uInt16 nPageId = maTabCtrl.GetPageId( i ); 1092 if( aValue.equals( maTabCtrl.GetPageText( nPageId ) ) ) 1093 { 1094 maTabCtrl.SelectTabPage( nPageId ); 1095 break; 1096 } 1097 } 1098 maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); 1099 1100 // persistent window state 1101 rtl::OUString aWinState( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 1102 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WindowState" ) ) ) ); 1103 if( aWinState.getLength() ) 1104 SetWindowState( rtl::OUStringToOString( aWinState, RTL_TEXTENCODING_UTF8 ) ); 1105 1106 if( maOptionsPage.maToFileBox.IsChecked() ) 1107 { 1108 maPController->resetPrinterOptions( true ); 1109 preparePreview( true, true ); 1110 } 1111 } 1112 1113 void PrintDialog::storeToSettings() 1114 { 1115 maJobPage.storeToSettings(); 1116 maNUpPage.storeToSettings(); 1117 maOptionsPage.storeToSettings(); 1118 1119 // store last selected printer 1120 SettingsConfigItem* pItem = SettingsConfigItem::get(); 1121 pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 1122 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ), 1123 maJobPage.maPrinters.GetSelectEntry() ); 1124 1125 pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 1126 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ), 1127 maTabCtrl.GetPageText( maTabCtrl.GetCurPageId() ) ); 1128 pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), 1129 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WindowState" ) ), 1130 rtl::OStringToOUString( GetWindowState(), RTL_TEXTENCODING_UTF8 ) 1131 ); 1132 pItem->Commit(); 1133 } 1134 1135 bool PrintDialog::isPrintToFile() 1136 { 1137 return maOptionsPage.maToFileBox.IsChecked(); 1138 } 1139 1140 int PrintDialog::getCopyCount() 1141 { 1142 return static_cast<int>(maJobPage.maCopyCountField.GetValue()); 1143 } 1144 1145 bool PrintDialog::isCollate() 1146 { 1147 return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : sal_False; 1148 } 1149 1150 bool PrintDialog::isSingleJobs() 1151 { 1152 return maOptionsPage.maCollateSingleJobsBox.IsChecked(); 1153 } 1154 1155 void setHelpId( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpIds, sal_Int32 i_nIndex ) 1156 { 1157 if( i_nIndex >= 0 && i_nIndex < i_rHelpIds.getLength() ) 1158 i_pWindow->SetHelpId( rtl::OUStringToOString( i_rHelpIds.getConstArray()[i_nIndex], RTL_TEXTENCODING_UTF8 ) ); 1159 } 1160 1161 static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex ) 1162 { 1163 // without a help text set and the correct smartID, 1164 // help texts will be retrieved from the online help system 1165 if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() ) 1166 i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] ); 1167 } 1168 1169 void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) 1170 { 1171 if( i_rCheckSize.Width() > o_rMaxSize.Width() ) 1172 o_rMaxSize.Width() = i_rCheckSize.Width(); 1173 if( i_rCheckSize.Height() > o_rMaxSize.Height() ) 1174 o_rMaxSize.Height() = i_rCheckSize.Height(); 1175 } 1176 1177 void PrintDialog::setupOptionalUI() 1178 { 1179 std::vector< boost::shared_ptr<vcl::RowOrColumn> > aDynamicColumns; 1180 boost::shared_ptr< vcl::RowOrColumn > pCurColumn; 1181 1182 Window* pCurParent = 0, *pDynamicPageParent = 0; 1183 sal_uInt16 nOptPageId = 9, nCurSubGroup = 0; 1184 bool bOnStaticPage = false; 1185 bool bSubgroupOnStaticPage = false; 1186 1187 std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> > aPropertyToDependencyRowMap; 1188 1189 const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() ); 1190 for( int i = 0; i < rOptions.getLength(); i++ ) 1191 { 1192 Sequence< beans::PropertyValue > aOptProp; 1193 rOptions[i].Value >>= aOptProp; 1194 1195 // extract ui element 1196 bool bEnabled = true; 1197 rtl::OUString aCtrlType; 1198 rtl::OUString aText; 1199 rtl::OUString aPropertyName; 1200 Sequence< rtl::OUString > aChoices; 1201 Sequence< sal_Bool > aChoicesDisabled; 1202 Sequence< rtl::OUString > aHelpTexts; 1203 Sequence< rtl::OUString > aHelpIds; 1204 sal_Int64 nMinValue = 0, nMaxValue = 0; 1205 sal_Int32 nCurHelpText = 0; 1206 rtl::OUString aGroupingHint; 1207 rtl::OUString aDependsOnName; 1208 sal_Int32 nDependsOnValue = 0; 1209 sal_Bool bUseDependencyRow = sal_False; 1210 1211 for( int n = 0; n < aOptProp.getLength(); n++ ) 1212 { 1213 const beans::PropertyValue& rEntry( aOptProp[ n ] ); 1214 if( rEntry.Name.equalsAscii( "Text" ) ) 1215 { 1216 rEntry.Value >>= aText; 1217 } 1218 else if( rEntry.Name.equalsAscii( "ControlType" ) ) 1219 { 1220 rEntry.Value >>= aCtrlType; 1221 } 1222 else if( rEntry.Name.equalsAscii( "Choices" ) ) 1223 { 1224 rEntry.Value >>= aChoices; 1225 } 1226 else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) ) 1227 { 1228 rEntry.Value >>= aChoicesDisabled; 1229 } 1230 else if( rEntry.Name.equalsAscii( "Property" ) ) 1231 { 1232 PropertyValue aVal; 1233 rEntry.Value >>= aVal; 1234 aPropertyName = aVal.Name; 1235 } 1236 else if( rEntry.Name.equalsAscii( "Enabled" ) ) 1237 { 1238 sal_Bool bValue = sal_True; 1239 rEntry.Value >>= bValue; 1240 bEnabled = bValue; 1241 } 1242 else if( rEntry.Name.equalsAscii( "GroupingHint" ) ) 1243 { 1244 rEntry.Value >>= aGroupingHint; 1245 } 1246 else if( rEntry.Name.equalsAscii( "DependsOnName" ) ) 1247 { 1248 rEntry.Value >>= aDependsOnName; 1249 } 1250 else if( rEntry.Name.equalsAscii( "DependsOnEntry" ) ) 1251 { 1252 rEntry.Value >>= nDependsOnValue; 1253 } 1254 else if( rEntry.Name.equalsAscii( "AttachToDependency" ) ) 1255 { 1256 rEntry.Value >>= bUseDependencyRow; 1257 } 1258 else if( rEntry.Name.equalsAscii( "MinValue" ) ) 1259 { 1260 rEntry.Value >>= nMinValue; 1261 } 1262 else if( rEntry.Name.equalsAscii( "MaxValue" ) ) 1263 { 1264 rEntry.Value >>= nMaxValue; 1265 } 1266 else if( rEntry.Name.equalsAscii( "HelpText" ) ) 1267 { 1268 if( ! (rEntry.Value >>= aHelpTexts) ) 1269 { 1270 rtl::OUString aHelpText; 1271 if( (rEntry.Value >>= aHelpText) ) 1272 { 1273 aHelpTexts.realloc( 1 ); 1274 *aHelpTexts.getArray() = aHelpText; 1275 } 1276 } 1277 } 1278 else if( rEntry.Name.equalsAscii( "HelpId" ) ) 1279 { 1280 if( ! (rEntry.Value >>= aHelpIds ) ) 1281 { 1282 rtl::OUString aHelpId; 1283 if( (rEntry.Value >>= aHelpId) ) 1284 { 1285 aHelpIds.realloc( 1 ); 1286 *aHelpIds.getArray() = aHelpId; 1287 } 1288 } 1289 } 1290 else if( rEntry.Name.equalsAscii( "HintNoLayoutPage" ) ) 1291 { 1292 sal_Bool bNoLayoutPage = sal_False; 1293 rEntry.Value >>= bNoLayoutPage; 1294 mbShowLayoutPage = ! bNoLayoutPage; 1295 } 1296 } 1297 1298 // bUseDependencyRow should only be true if a dependency exists 1299 bUseDependencyRow = bUseDependencyRow && (aDependsOnName.getLength() != 0); 1300 1301 // is it necessary to switch between static and dynamic pages ? 1302 bool bSwitchPage = false; 1303 if( aGroupingHint.getLength() ) 1304 bSwitchPage = true; 1305 else if( aCtrlType.equalsAscii( "Subgroup" ) || (bOnStaticPage && ! bSubgroupOnStaticPage ) ) 1306 bSwitchPage = true; 1307 if( bSwitchPage ) 1308 { 1309 // restore to dynamic 1310 pCurParent = pDynamicPageParent; 1311 if( ! aDynamicColumns.empty() ) 1312 pCurColumn = aDynamicColumns.back(); 1313 else 1314 pCurColumn.reset(); 1315 bOnStaticPage = false; 1316 bSubgroupOnStaticPage = false; 1317 1318 if( aGroupingHint.equalsAscii( "PrintRange" ) ) 1319 { 1320 pCurColumn = maJobPage.mxPrintRange; 1321 pCurParent = &maJobPage; // set job page as current parent 1322 bOnStaticPage = true; 1323 } 1324 else if( aGroupingHint.equalsAscii( "OptionsPage" ) ) 1325 { 1326 pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maOptionsPage.getLayout()); 1327 pCurParent = &maOptionsPage; // set options page as current parent 1328 bOnStaticPage = true; 1329 } 1330 else if( aGroupingHint.equalsAscii( "OptionsPageOptGroup" ) ) 1331 { 1332 pCurColumn = maOptionsPage.mxOptGroup; 1333 pCurParent = &maOptionsPage; // set options page as current parent 1334 bOnStaticPage = true; 1335 } 1336 else if( aGroupingHint.equalsAscii( "LayoutPage" ) ) 1337 { 1338 pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maNUpPage.getLayout()); 1339 pCurParent = &maNUpPage; // set layout page as current parent 1340 bOnStaticPage = true; 1341 } 1342 else if( aGroupingHint.getLength() ) 1343 { 1344 pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maJobPage.getLayout()); 1345 pCurParent = &maJobPage; // set job page as current parent 1346 bOnStaticPage = true; 1347 } 1348 } 1349 1350 if( aCtrlType.equalsAscii( "Group" ) || 1351 ( ! pCurParent && ! (bOnStaticPage || aGroupingHint.getLength() ) ) ) 1352 { 1353 // add new tab page 1354 TabPage* pNewGroup = new TabPage( &maTabCtrl ); 1355 maControls.push_front( pNewGroup ); 1356 pDynamicPageParent = pCurParent = pNewGroup; 1357 pNewGroup->SetText( aText ); 1358 maTabCtrl.InsertPage( ++nOptPageId, aText ); 1359 maTabCtrl.SetTabPage( nOptPageId, pNewGroup ); 1360 1361 // set help id 1362 setHelpId( pNewGroup, aHelpIds, 0 ); 1363 // set help text 1364 setHelpText( pNewGroup, aHelpTexts, 0 ); 1365 1366 // reset subgroup counter 1367 nCurSubGroup = 0; 1368 1369 aDynamicColumns.push_back( boost::dynamic_pointer_cast<vcl::RowOrColumn>(pNewGroup->getLayout()) ); 1370 pCurColumn = aDynamicColumns.back(); 1371 pCurColumn->setParentWindow( pNewGroup ); 1372 bSubgroupOnStaticPage = false; 1373 bOnStaticPage = false; 1374 } 1375 else if( aCtrlType.equalsAscii( "Subgroup" ) && (pCurParent || aGroupingHint.getLength() ) ) 1376 { 1377 bSubgroupOnStaticPage = (aGroupingHint.getLength() != 0); 1378 // create group FixedLine 1379 if( ! aGroupingHint.equalsAscii( "PrintRange" ) || 1380 ! pCurColumn->countElements() == 0 1381 ) 1382 { 1383 Window* pNewSub = NULL; 1384 if( aGroupingHint.equalsAscii( "PrintRange" ) ) 1385 pNewSub = new FixedText( pCurParent, WB_VCENTER ); 1386 else 1387 pNewSub = new FixedLine( pCurParent ); 1388 maControls.push_front( pNewSub ); 1389 pNewSub->SetText( aText ); 1390 pNewSub->Show(); 1391 1392 // set help id 1393 setHelpId( pNewSub, aHelpIds, 0 ); 1394 // set help text 1395 setHelpText( pNewSub, aHelpTexts, 0 ); 1396 // add group to current column 1397 pCurColumn->addWindow( pNewSub ); 1398 } 1399 1400 // add an indent to the current column 1401 vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn.get(), -1 ); 1402 pCurColumn->addChild( pIndent ); 1403 // and create a column inside the indent 1404 pCurColumn.reset( new vcl::RowOrColumn( pIndent ) ); 1405 pIndent->setChild( pCurColumn ); 1406 } 1407 // EVIL 1408 else if( aCtrlType.equalsAscii( "Bool" ) && 1409 aGroupingHint.equalsAscii( "LayoutPage" ) && 1410 aPropertyName.equalsAscii( "PrintProspect" ) 1411 ) 1412 { 1413 maNUpPage.maBrochureBtn.SetText( aText ); 1414 maNUpPage.maBrochureBtn.Show(); 1415 setHelpText( &maNUpPage.maBrochureBtn, aHelpTexts, 0 ); 1416 1417 sal_Bool bVal = sal_False; 1418 PropertyValue* pVal = maPController->getValue( aPropertyName ); 1419 if( pVal ) 1420 pVal->Value >>= bVal; 1421 maNUpPage.maBrochureBtn.Check( bVal ); 1422 maNUpPage.maBrochureBtn.Enable( maPController->isUIOptionEnabled( aPropertyName ) && pVal != NULL ); 1423 maNUpPage.maBrochureBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); 1424 1425 maPropertyToWindowMap[ aPropertyName ].push_back( &maNUpPage.maBrochureBtn ); 1426 maControlToPropertyMap[&maNUpPage.maBrochureBtn] = aPropertyName; 1427 1428 aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, maNUpPage.mxBrochureDep ) ); 1429 } 1430 else 1431 { 1432 boost::shared_ptr<vcl::RowOrColumn> pSaveCurColumn( pCurColumn ); 1433 1434 if( bUseDependencyRow ) 1435 { 1436 // find the correct dependency row (if any) 1437 std::pair< std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >::iterator, 1438 std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >::iterator > aDepRange; 1439 aDepRange = aPropertyToDependencyRowMap.equal_range( aDependsOnName ); 1440 if( aDepRange.first != aDepRange.second ) 1441 { 1442 while( nDependsOnValue && aDepRange.first != aDepRange.second ) 1443 { 1444 nDependsOnValue--; 1445 ++aDepRange.first; 1446 } 1447 if( aDepRange.first != aPropertyToDependencyRowMap.end() ) 1448 { 1449 pCurColumn = aDepRange.first->second; 1450 maReverseDependencySet.insert( aPropertyName ); 1451 } 1452 } 1453 } 1454 if( aCtrlType.equalsAscii( "Bool" ) && pCurParent ) 1455 { 1456 // add a check box 1457 CheckBox* pNewBox = new CheckBox( pCurParent ); 1458 maControls.push_front( pNewBox ); 1459 pNewBox->SetText( aText ); 1460 pNewBox->Show(); 1461 1462 sal_Bool bVal = sal_False; 1463 PropertyValue* pVal = maPController->getValue( aPropertyName ); 1464 if( pVal ) 1465 pVal->Value >>= bVal; 1466 pNewBox->Check( bVal ); 1467 pNewBox->SetToggleHdl( LINK( this, PrintDialog, UIOption_CheckHdl ) ); 1468 1469 maPropertyToWindowMap[ aPropertyName ].push_back( pNewBox ); 1470 maControlToPropertyMap[pNewBox] = aPropertyName; 1471 1472 // set help id 1473 setHelpId( pNewBox, aHelpIds, 0 ); 1474 // set help text 1475 setHelpText( pNewBox, aHelpTexts, 0 ); 1476 1477 boost::shared_ptr<vcl::RowOrColumn> pDependencyRow( new vcl::RowOrColumn( pCurColumn.get(), false ) ); 1478 pCurColumn->addChild( pDependencyRow ); 1479 aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, pDependencyRow ) ); 1480 1481 // add checkbox to current column 1482 pDependencyRow->addWindow( pNewBox ); 1483 } 1484 else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) 1485 { 1486 boost::shared_ptr<vcl::RowOrColumn> pRadioColumn( pCurColumn ); 1487 if( aText.getLength() ) 1488 { 1489 // add a FixedText: 1490 FixedText* pHeading = new FixedText( pCurParent ); 1491 maControls.push_front( pHeading ); 1492 pHeading->SetText( aText ); 1493 pHeading->Show(); 1494 1495 // set help id 1496 setHelpId( pHeading, aHelpIds, nCurHelpText ); 1497 // set help text 1498 setHelpText( pHeading, aHelpTexts, nCurHelpText ); 1499 nCurHelpText++; 1500 // add fixed text to current column 1501 pCurColumn->addWindow( pHeading ); 1502 // add an indent to the current column 1503 vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn.get(), 15 ); 1504 pCurColumn->addChild( pIndent ); 1505 // and create a column inside the indent 1506 pRadioColumn.reset( new vcl::RowOrColumn( pIndent ) ); 1507 pIndent->setChild( pRadioColumn ); 1508 } 1509 // iterate options 1510 sal_Int32 nSelectVal = 0; 1511 PropertyValue* pVal = maPController->getValue( aPropertyName ); 1512 if( pVal && pVal->Value.hasValue() ) 1513 pVal->Value >>= nSelectVal; 1514 for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) 1515 { 1516 boost::shared_ptr<vcl::LabeledElement> pLabel( new vcl::LabeledElement( pRadioColumn.get(), 1 ) ); 1517 pRadioColumn->addChild( pLabel ); 1518 boost::shared_ptr<vcl::RowOrColumn> pDependencyRow( new vcl::RowOrColumn( pLabel.get(), false ) ); 1519 pLabel->setElement( pDependencyRow ); 1520 aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, pDependencyRow ) ); 1521 1522 RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 ); 1523 maControls.push_front( pBtn ); 1524 pBtn->SetText( aChoices[m] ); 1525 pBtn->Check( m == nSelectVal ); 1526 pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) ); 1527 if( aChoicesDisabled.getLength() > m && aChoicesDisabled[m] == sal_True ) 1528 pBtn->Enable( sal_False ); 1529 pBtn->Show(); 1530 maPropertyToWindowMap[ aPropertyName ].push_back( pBtn ); 1531 maControlToPropertyMap[pBtn] = aPropertyName; 1532 maControlToNumValMap[pBtn] = m; 1533 1534 // set help id 1535 setHelpId( pBtn, aHelpIds, nCurHelpText ); 1536 // set help text 1537 setHelpText( pBtn, aHelpTexts, nCurHelpText ); 1538 nCurHelpText++; 1539 // add the radio button to the column 1540 pLabel->setLabel( pBtn ); 1541 } 1542 } 1543 else if( ( aCtrlType.equalsAscii( "List" ) || 1544 aCtrlType.equalsAscii( "Range" ) || 1545 aCtrlType.equalsAscii( "Edit" ) 1546 ) && pCurParent ) 1547 { 1548 // create a row in the current column 1549 boost::shared_ptr<vcl::RowOrColumn> pFieldColumn( new vcl::RowOrColumn( pCurColumn.get(), false ) ); 1550 pCurColumn->addChild( pFieldColumn ); 1551 aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, pFieldColumn ) ); 1552 1553 vcl::LabeledElement* pLabel = NULL; 1554 if( aText.getLength() ) 1555 { 1556 // add a FixedText: 1557 FixedText* pHeading = new FixedText( pCurParent, WB_VCENTER ); 1558 maControls.push_front( pHeading ); 1559 pHeading->SetText( aText ); 1560 pHeading->Show(); 1561 1562 // add to row 1563 pLabel = new vcl::LabeledElement( pFieldColumn.get(), 2 ); 1564 pFieldColumn->addChild( pLabel ); 1565 pLabel->setLabel( pHeading ); 1566 } 1567 1568 if( aCtrlType.equalsAscii( "List" ) ) 1569 { 1570 ListBox* pList = new ListBox( pCurParent, WB_DROPDOWN | WB_BORDER ); 1571 maControls.push_front( pList ); 1572 1573 // iterate options 1574 for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) 1575 { 1576 pList->InsertEntry( aChoices[m] ); 1577 } 1578 sal_Int32 nSelectVal = 0; 1579 PropertyValue* pVal = maPController->getValue( aPropertyName ); 1580 if( pVal && pVal->Value.hasValue() ) 1581 pVal->Value >>= nSelectVal; 1582 pList->SelectEntryPos( static_cast<sal_uInt16>(nSelectVal) ); 1583 pList->SetSelectHdl( LINK( this, PrintDialog, UIOption_SelectHdl ) ); 1584 pList->SetDropDownLineCount( static_cast<sal_uInt16>(aChoices.getLength()) ); 1585 pList->Show(); 1586 1587 // set help id 1588 setHelpId( pList, aHelpIds, 0 ); 1589 // set help text 1590 setHelpText( pList, aHelpTexts, 0 ); 1591 1592 maPropertyToWindowMap[ aPropertyName ].push_back( pList ); 1593 maControlToPropertyMap[pList] = aPropertyName; 1594 1595 // finish the pair 1596 if( pLabel ) 1597 pLabel->setElement( pList ); 1598 else 1599 pFieldColumn->addWindow( pList ); 1600 } 1601 else if( aCtrlType.equalsAscii( "Range" ) ) 1602 { 1603 NumericField* pField = new NumericField( pCurParent, WB_BORDER | WB_SPIN ); 1604 maControls.push_front( pField ); 1605 1606 // set min/max and current value 1607 if( nMinValue != nMaxValue ) 1608 { 1609 pField->SetMin( nMinValue ); 1610 pField->SetMax( nMaxValue ); 1611 } 1612 sal_Int64 nCurVal = 0; 1613 PropertyValue* pVal = maPController->getValue( aPropertyName ); 1614 if( pVal && pVal->Value.hasValue() ) 1615 pVal->Value >>= nCurVal; 1616 pField->SetValue( nCurVal ); 1617 pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) ); 1618 pField->Show(); 1619 1620 // set help id 1621 setHelpId( pField, aHelpIds, 0 ); 1622 // set help text 1623 setHelpText( pField, aHelpTexts, 0 ); 1624 1625 maPropertyToWindowMap[ aPropertyName ].push_back( pField ); 1626 maControlToPropertyMap[pField] = aPropertyName; 1627 1628 // add to row 1629 if( pLabel ) 1630 pLabel->setElement( pField ); 1631 else 1632 pFieldColumn->addWindow( pField ); 1633 } 1634 else if( aCtrlType.equalsAscii( "Edit" ) ) 1635 { 1636 Edit* pField = new Edit( pCurParent, WB_BORDER ); 1637 maControls.push_front( pField ); 1638 1639 rtl::OUString aCurVal; 1640 PropertyValue* pVal = maPController->getValue( aPropertyName ); 1641 if( pVal && pVal->Value.hasValue() ) 1642 pVal->Value >>= aCurVal; 1643 pField->SetText( aCurVal ); 1644 pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) ); 1645 pField->Show(); 1646 1647 // set help id 1648 setHelpId( pField, aHelpIds, 0 ); 1649 // set help text 1650 setHelpText( pField, aHelpTexts, 0 ); 1651 1652 maPropertyToWindowMap[ aPropertyName ].push_back( pField ); 1653 maControlToPropertyMap[pField] = aPropertyName; 1654 1655 // add to row 1656 if( pLabel ) 1657 pLabel->setElement( pField ); 1658 else 1659 pFieldColumn->addWindow( pField, 2 ); 1660 } 1661 } 1662 else 1663 { 1664 DBG_ERROR( "Unsupported UI option" ); 1665 } 1666 1667 pCurColumn = pSaveCurColumn; 1668 } 1669 } 1670 1671 // #i106506# if no brochure button, then the singular Pages radio button 1672 // makes no sense, so replace it by a FixedText label 1673 if( ! maNUpPage.maBrochureBtn.IsVisible() ) 1674 { 1675 if( maNUpPage.mxPagesBtnLabel.get() ) 1676 { 1677 maNUpPage.maPagesBoxTitleTxt.SetText( maNUpPage.maPagesBtn.GetText() ); 1678 maNUpPage.maPagesBoxTitleTxt.Show( sal_True ); 1679 maNUpPage.mxPagesBtnLabel->setLabel( &maNUpPage.maPagesBoxTitleTxt ); 1680 maNUpPage.maPagesBtn.Show( sal_False ); 1681 } 1682 } 1683 1684 // update enable states 1685 checkOptionalControlDependencies(); 1686 1687 // print range empty (currently math only) -> hide print range and spacer line 1688 if( maJobPage.mxPrintRange->countElements() == 0 ) 1689 { 1690 maJobPage.mxPrintRange->show( false, false ); 1691 maJobPage.maCopySpacer.Show( sal_False ); 1692 maJobPage.maReverseOrderBox.Show( sal_False ); 1693 } 1694 else 1695 { 1696 // add an indent to the current column 1697 vcl::Indenter* pIndent = new vcl::Indenter( maJobPage.mxPrintRange.get(), -1 ); 1698 maJobPage.mxPrintRange->addChild( pIndent ); 1699 // and create a column inside the indent 1700 pIndent->setWindow( &maJobPage.maReverseOrderBox ); 1701 maJobPage.maReverseOrderBox.Show( sal_True ); 1702 } 1703 1704 #ifdef WNT 1705 // FIXME: the GetNativeControlRegion call on Windows has some issues 1706 // (which skew the results of GetOptimalSize()) 1707 // however fixing this thoroughly needs to take interaction with paint into 1708 // account, making the right fix less simple. Fix this the right way 1709 // at some point. For now simply add some space at the lowest element 1710 size_t nIndex = maJobPage.getLayout()->countElements(); 1711 if( nIndex > 0 ) // sanity check 1712 maJobPage.getLayout()->setBorders( nIndex-1, 0, 0, 0, -1 ); 1713 #endif 1714 1715 // create auto mnemomnics now so they can be calculated in layout 1716 ImplWindowAutoMnemonic( &maJobPage ); 1717 ImplWindowAutoMnemonic( &maNUpPage ); 1718 ImplWindowAutoMnemonic( &maOptionsPage ); 1719 ImplWindowAutoMnemonic( this ); 1720 1721 // calculate job page 1722 Size aMaxSize = maJobPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ); 1723 // and layout page 1724 updateMaxSize( maNUpPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); 1725 // and options page 1726 updateMaxSize( maOptionsPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); 1727 1728 for( std::vector< boost::shared_ptr<vcl::RowOrColumn> >::iterator it = aDynamicColumns.begin(); 1729 it != aDynamicColumns.end(); ++it ) 1730 { 1731 Size aPageSize( (*it)->getOptimalSize( WINDOWSIZE_PREFERRED ) ); 1732 updateMaxSize( aPageSize, aMaxSize ); 1733 } 1734 1735 // resize dialog if necessary 1736 Size aTabSize = maTabCtrl.GetTabPageSizePixel(); 1737 maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() ); 1738 if( aMaxSize.Height() > aTabSize.Height() || aMaxSize.Width() > aTabSize.Width() ) 1739 { 1740 Size aCurSize( GetOutputSizePixel() ); 1741 if( aMaxSize.Height() > aTabSize.Height() ) 1742 { 1743 aCurSize.Height() += aMaxSize.Height() - aTabSize.Height(); 1744 aTabSize.Height() = aMaxSize.Height(); 1745 } 1746 if( aMaxSize.Width() > aTabSize.Width() ) 1747 { 1748 aCurSize.Width() += aMaxSize.Width() - aTabSize.Width(); 1749 // and the tab ctrl needs more space, too 1750 aTabSize.Width() = aMaxSize.Width(); 1751 } 1752 maTabCtrl.SetTabPageSizePixel( aTabSize ); 1753 maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() ); 1754 } 1755 1756 Size aSz = getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ); 1757 SetOutputSizePixel( aSz ); 1758 } 1759 1760 void PrintDialog::DataChanged( const DataChangedEvent& i_rDCEvt ) 1761 { 1762 // react on settings changed 1763 if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS ) 1764 checkControlDependencies(); 1765 ModalDialog::DataChanged( i_rDCEvt ); 1766 } 1767 1768 void PrintDialog::checkControlDependencies() 1769 { 1770 if( maJobPage.maCopyCountField.GetValue() > 1 ) 1771 maJobPage.maCollateBox.Enable( maJobPage.mnCollateUIMode == 0 ); 1772 else 1773 maJobPage.maCollateBox.Enable( sal_False ); 1774 1775 Image aImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateImg : maJobPage.maNoCollateImg ); 1776 Image aHCImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateHCImg : maJobPage.maNoCollateHCImg ); 1777 bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 1778 1779 Size aImgSize( aImg.GetSizePixel() ); 1780 Size aHCImgSize( aHCImg.GetSizePixel() ); 1781 1782 if( aHCImgSize.Width() > aImgSize.Width() ) 1783 aImgSize.Width() = aHCImgSize.Width(); 1784 if( aHCImgSize.Height() > aImgSize.Height() ) 1785 aImgSize.Height() = aHCImgSize.Height(); 1786 1787 // adjust size of image 1788 maJobPage.maCollateImage.SetSizePixel( aImgSize ); 1789 maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg ); 1790 maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST ); 1791 maJobPage.getLayout()->resize(); 1792 1793 // enable setup button only for printers that can be setup 1794 bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG ); 1795 maJobPage.maSetupButton.Enable( bHaveSetup ); 1796 if( bHaveSetup ) 1797 { 1798 if( ! maJobPage.maSetupButton.IsVisible() ) 1799 { 1800 Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() ); 1801 Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() ); 1802 Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() ); 1803 aPrinterSize.Width() = aSetupPos.X() - aPrinterPos.X() - LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ).Width(); 1804 maJobPage.maPrinters.SetSizePixel( aPrinterSize ); 1805 maJobPage.maSetupButton.Show(); 1806 getLayout()->resize(); 1807 } 1808 } 1809 else 1810 { 1811 if( maJobPage.maSetupButton.IsVisible() ) 1812 { 1813 Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() ); 1814 Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() ); 1815 Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() ); 1816 Size aSetupSize( maJobPage.maSetupButton.GetSizePixel() ); 1817 aPrinterSize.Width() = aSetupPos.X() + aSetupSize.Width() - aPrinterPos.X(); 1818 maJobPage.maPrinters.SetSizePixel( aPrinterSize ); 1819 maJobPage.maSetupButton.Hide(); 1820 getLayout()->resize(); 1821 } 1822 } 1823 } 1824 1825 void PrintDialog::checkOptionalControlDependencies() 1826 { 1827 for( std::map< Window*, rtl::OUString >::iterator it = maControlToPropertyMap.begin(); 1828 it != maControlToPropertyMap.end(); ++it ) 1829 { 1830 bool bShouldbeEnabled = maPController->isUIOptionEnabled( it->second ); 1831 if( ! bShouldbeEnabled ) 1832 { 1833 // enable controls that are directly attached to a dependency anyway 1834 // if the normally disabled controls get modified, change the dependency 1835 // so the control would be enabled 1836 // example: in print range "Print All" is selected, "Page Range" is then of course 1837 // not selected and the Edit for the Page Range would be disabled 1838 // as a convenience we should enable the Edit anyway and automatically select 1839 // "Page Range" instead of "Print All" if the Edit gets modified 1840 if( maReverseDependencySet.find( it->second ) != maReverseDependencySet.end() ) 1841 { 1842 rtl::OUString aDep( maPController->getDependency( it->second ) ); 1843 // if the dependency is at least enabled, then enable this control anyway 1844 if( aDep.getLength() && maPController->isUIOptionEnabled( aDep ) ) 1845 bShouldbeEnabled = true; 1846 } 1847 } 1848 1849 if( bShouldbeEnabled && dynamic_cast<RadioButton*>(it->first) ) 1850 { 1851 std::map< Window*, sal_Int32 >::const_iterator r_it = maControlToNumValMap.find( it->first ); 1852 if( r_it != maControlToNumValMap.end() ) 1853 { 1854 bShouldbeEnabled = maPController->isUIChoiceEnabled( it->second, r_it->second ); 1855 } 1856 } 1857 1858 1859 bool bIsEnabled = it->first->IsEnabled(); 1860 // Enable does not do a change check first, so can be less cheap than expected 1861 if( bShouldbeEnabled != bIsEnabled ) 1862 it->first->Enable( bShouldbeEnabled ); 1863 } 1864 } 1865 1866 static rtl::OUString searchAndReplace( const rtl::OUString& i_rOrig, const char* i_pRepl, sal_Int32 i_nReplLen, const rtl::OUString& i_rRepl ) 1867 { 1868 sal_Int32 nPos = i_rOrig.indexOfAsciiL( i_pRepl, i_nReplLen ); 1869 if( nPos != -1 ) 1870 { 1871 rtl::OUStringBuffer aBuf( i_rOrig.getLength() ); 1872 aBuf.append( i_rOrig.getStr(), nPos ); 1873 aBuf.append( i_rRepl ); 1874 if( nPos + i_nReplLen < i_rOrig.getLength() ) 1875 aBuf.append( i_rOrig.getStr() + nPos + i_nReplLen ); 1876 return aBuf.makeStringAndClear(); 1877 } 1878 return i_rOrig; 1879 } 1880 1881 void PrintDialog::updatePrinterText() 1882 { 1883 String aDefPrt( Printer::GetDefaultPrinterName() ); 1884 const QueueInfo* pInfo = Printer::GetQueueInfo( maJobPage.maPrinters.GetSelectEntry(), true ); 1885 if( pInfo ) 1886 { 1887 maJobPage.maLocationTxt.SetText( pInfo->GetLocation() ); 1888 maJobPage.maCommentTxt.SetText( pInfo->GetComment() ); 1889 // FIXME: status text 1890 rtl::OUString aStatus; 1891 if( aDefPrt == pInfo->GetPrinterName() ) 1892 aStatus = maDefPrtText; 1893 maJobPage.maStatusTxt.SetText( aStatus ); 1894 } 1895 else 1896 { 1897 maJobPage.maLocationTxt.SetText( String() ); 1898 maJobPage.maCommentTxt.SetText( String() ); 1899 maJobPage.maStatusTxt.SetText( String() ); 1900 } 1901 } 1902 1903 void PrintDialog::setPreviewText( sal_Int32 ) 1904 { 1905 rtl::OUString aNewText( searchAndReplace( maPageStr, "%n", 2, rtl::OUString::valueOf( mnCachedPages ) ) ); 1906 maNumPagesText.SetText( aNewText ); 1907 1908 // if layout is already established the refresh layout of 1909 // preview controls since text length may have changes 1910 if( mxPreviewCtrls.get() ) 1911 mxPreviewCtrls->setManagedArea( mxPreviewCtrls->getManagedArea() ); 1912 } 1913 1914 void PrintDialog::preparePreview( bool i_bNewPage, bool i_bMayUseCache ) 1915 { 1916 // page range may have changed depending on options 1917 sal_Int32 nPages = maPController->getFilteredPageCount(); 1918 mnCachedPages = nPages; 1919 1920 if( mnCurPage >= nPages ) 1921 mnCurPage = nPages-1; 1922 if( mnCurPage < 0 ) 1923 mnCurPage = 0; 1924 1925 setPreviewText( mnCurPage ); 1926 1927 maPageEdit.SetMin( 1 ); 1928 maPageEdit.SetMax( nPages ); 1929 1930 if( i_bNewPage ) 1931 { 1932 const MapMode aMapMode( MAP_100TH_MM ); 1933 GDIMetaFile aMtf; 1934 boost::shared_ptr<Printer> aPrt( maPController->getPrinter() ); 1935 if( nPages > 0 ) 1936 { 1937 PrinterController::PageSize aPageSize = 1938 maPController->getFilteredPageFile( mnCurPage, aMtf, i_bMayUseCache ); 1939 if( ! aPageSize.bFullPaper ) 1940 { 1941 Point aOff( aPrt->PixelToLogic( aPrt->GetPageOffsetPixel(), aMapMode ) ); 1942 aMtf.Move( aOff.X(), aOff.Y() ); 1943 } 1944 } 1945 1946 Size aCurPageSize = aPrt->PixelToLogic( aPrt->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ); 1947 maPreviewWindow.setPreview( aMtf, aCurPageSize, 1948 aPrt->GetPaperName( false ), 1949 nPages > 0 ? rtl::OUString() : maNoPageStr, 1950 aPrt->ImplGetDPIX(), aPrt->ImplGetDPIY(), 1951 aPrt->GetPrinterOptions().IsConvertToGreyscales() 1952 ); 1953 1954 maForwardBtn.Enable( mnCurPage < nPages-1 ); 1955 maBackwardBtn.Enable( mnCurPage != 0 ); 1956 maPageEdit.Enable( nPages > 1 ); 1957 } 1958 } 1959 1960 Size PrintDialog::getJobPageSize() 1961 { 1962 if( maFirstPageSize.Width() == 0 && maFirstPageSize.Height() == 0) 1963 { 1964 maFirstPageSize = maNupPortraitSize; 1965 GDIMetaFile aMtf; 1966 if( maPController->getPageCountProtected() > 0 ) 1967 { 1968 PrinterController::PageSize aPageSize = maPController->getPageFile( 0, aMtf, true ); 1969 maFirstPageSize = aPageSize.aSize; 1970 } 1971 } 1972 return maFirstPageSize; 1973 } 1974 1975 void PrintDialog::updateNupFromPages() 1976 { 1977 long nPages = long(maNUpPage.maNupPagesBox.GetEntryData(maNUpPage.maNupPagesBox.GetSelectEntryPos())); 1978 int nRows = int(maNUpPage.maNupRowsEdt.GetValue()); 1979 int nCols = int(maNUpPage.maNupColEdt.GetValue()); 1980 long nPageMargin = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM ))); 1981 long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM ))); 1982 bool bCustom = false; 1983 1984 if( nPages == 1 ) 1985 { 1986 nRows = nCols = 1; 1987 nSheetMargin = 0; 1988 nPageMargin = 0; 1989 } 1990 else if( nPages == 2 || nPages == 4 || nPages == 6 || nPages == 9 || nPages == 16 ) 1991 { 1992 Size aJobPageSize( getJobPageSize() ); 1993 bool bPortrait = aJobPageSize.Width() < aJobPageSize.Height(); 1994 if( nPages == 2 ) 1995 { 1996 if( bPortrait ) 1997 nRows = 1, nCols = 2; 1998 else 1999 nRows = 2, nCols = 1; 2000 } 2001 else if( nPages == 4 ) 2002 nRows = nCols = 2; 2003 else if( nPages == 6 ) 2004 { 2005 if( bPortrait ) 2006 nRows = 2, nCols = 3; 2007 else 2008 nRows = 3, nCols = 2; 2009 } 2010 else if( nPages == 9 ) 2011 nRows = nCols = 3; 2012 else if( nPages == 16 ) 2013 nRows = nCols = 4; 2014 nPageMargin = 0; 2015 nSheetMargin = 0; 2016 } 2017 else 2018 bCustom = true; 2019 2020 if( nPages > 1 ) 2021 { 2022 // set upper limits for margins based on job page size and rows/columns 2023 Size aSize( getJobPageSize() ); 2024 2025 // maximum sheet distance: 1/2 sheet 2026 long nHorzMax = aSize.Width()/2; 2027 long nVertMax = aSize.Height()/2; 2028 if( nSheetMargin > nHorzMax ) 2029 nSheetMargin = nHorzMax; 2030 if( nSheetMargin > nVertMax ) 2031 nSheetMargin = nVertMax; 2032 2033 maNUpPage.maSheetMarginEdt.SetMax( 2034 maNUpPage.maSheetMarginEdt.Normalize( 2035 nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM ); 2036 2037 // maximum page distance 2038 nHorzMax = (aSize.Width() - 2*nSheetMargin); 2039 if( nCols > 1 ) 2040 nHorzMax /= (nCols-1); 2041 nVertMax = (aSize.Height() - 2*nSheetMargin); 2042 if( nRows > 1 ) 2043 nHorzMax /= (nRows-1); 2044 2045 if( nPageMargin > nHorzMax ) 2046 nPageMargin = nHorzMax; 2047 if( nPageMargin > nVertMax ) 2048 nPageMargin = nVertMax; 2049 2050 maNUpPage.maPageMarginEdt.SetMax( 2051 maNUpPage.maSheetMarginEdt.Normalize( 2052 nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM ); 2053 } 2054 2055 maNUpPage.maNupRowsEdt.SetValue( nRows ); 2056 maNUpPage.maNupColEdt.SetValue( nCols ); 2057 maNUpPage.maPageMarginEdt.SetValue( maNUpPage.maPageMarginEdt.Normalize( nPageMargin ), FUNIT_100TH_MM ); 2058 maNUpPage.maSheetMarginEdt.SetValue( maNUpPage.maSheetMarginEdt.Normalize( nSheetMargin ), FUNIT_100TH_MM ); 2059 2060 maNUpPage.showAdvancedControls( bCustom ); 2061 if( bCustom ) 2062 { 2063 // see if we have to enlarge the dialog to make the tab page fit 2064 Size aCurSize( maNUpPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ) ); 2065 Size aTabSize( maTabCtrl.GetTabPageSizePixel() ); 2066 if( aTabSize.Height() < aCurSize.Height() ) 2067 { 2068 Size aDlgSize( GetSizePixel() ); 2069 aDlgSize.Height() += aCurSize.Height() - aTabSize.Height(); 2070 SetSizePixel( aDlgSize ); 2071 } 2072 } 2073 2074 updateNup(); 2075 } 2076 2077 void PrintDialog::updateNup() 2078 { 2079 int nRows = int(maNUpPage.maNupRowsEdt.GetValue()); 2080 int nCols = int(maNUpPage.maNupColEdt.GetValue()); 2081 long nPageMargin = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM ))); 2082 long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM ))); 2083 2084 PrinterController::MultiPageSetup aMPS; 2085 aMPS.nRows = nRows; 2086 aMPS.nColumns = nCols; 2087 aMPS.nRepeat = 1; 2088 aMPS.nLeftMargin = 2089 aMPS.nTopMargin = 2090 aMPS.nRightMargin = 2091 aMPS.nBottomMargin = nSheetMargin; 2092 2093 aMPS.nHorizontalSpacing = 2094 aMPS.nVerticalSpacing = nPageMargin; 2095 2096 aMPS.bDrawBorder = maNUpPage.maBorderCB.IsChecked(); 2097 2098 int nOrderMode = int(sal_IntPtr(maNUpPage.maNupOrderBox.GetEntryData( 2099 maNUpPage.maNupOrderBox.GetSelectEntryPos() ))); 2100 if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_LRTB ) 2101 aMPS.nOrder = PrinterController::LRTB; 2102 else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TBLR ) 2103 aMPS.nOrder = PrinterController::TBLR; 2104 else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_RLTB ) 2105 aMPS.nOrder = PrinterController::RLTB; 2106 else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TBRL ) 2107 aMPS.nOrder = PrinterController::TBRL; 2108 2109 int nOrientationMode = int(sal_IntPtr(maNUpPage.maNupOrientationBox.GetEntryData( 2110 maNUpPage.maNupOrientationBox.GetSelectEntryPos() ))); 2111 if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE ) 2112 aMPS.aPaperSize = maNupLandscapeSize; 2113 else if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT ) 2114 aMPS.aPaperSize = maNupPortraitSize; 2115 else // automatic mode 2116 { 2117 // get size of first real page to see if it is portrait or landscape 2118 // we assume same page sizes for all the pages for this 2119 Size aPageSize = getJobPageSize(); 2120 2121 Size aMultiSize( aPageSize.Width() * nCols, aPageSize.Height() * nRows ); 2122 if( aMultiSize.Width() > aMultiSize.Height() ) // fits better on landscape 2123 aMPS.aPaperSize = maNupLandscapeSize; 2124 else 2125 aMPS.aPaperSize = maNupPortraitSize; 2126 } 2127 2128 maPController->setMultipage( aMPS ); 2129 2130 maNUpPage.maNupOrderWin.setValues( nOrderMode, nCols, nRows ); 2131 2132 preparePreview( true, true ); 2133 } 2134 2135 IMPL_LINK( PrintDialog, SelectHdl, ListBox*, pBox ) 2136 { 2137 if( pBox == &maJobPage.maPrinters ) 2138 { 2139 String aNewPrinter( pBox->GetSelectEntry() ); 2140 // set new printer 2141 maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aNewPrinter ) ) ); 2142 maPController->resetPrinterOptions( maOptionsPage.maToFileBox.IsChecked() ); 2143 // update text fields 2144 updatePrinterText(); 2145 preparePreview( true, false ); 2146 } 2147 else if( pBox == &maNUpPage.maNupOrientationBox || pBox == &maNUpPage.maNupOrderBox ) 2148 { 2149 updateNup(); 2150 } 2151 else if( pBox == &maNUpPage.maNupPagesBox ) 2152 { 2153 if( !maNUpPage.maPagesBtn.IsChecked() ) 2154 maNUpPage.maPagesBtn.Check(); 2155 updateNupFromPages(); 2156 } 2157 2158 return 0; 2159 } 2160 2161 IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) 2162 { 2163 if( pButton == &maOKButton || pButton == &maCancelButton ) 2164 { 2165 storeToSettings(); 2166 EndDialog( pButton == &maOKButton ); 2167 } 2168 else if( pButton == &maHelpButton ) 2169 { 2170 // start help system 2171 Help* pHelp = Application::GetHelp(); 2172 if( pHelp ) 2173 { 2174 pHelp->Start( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:OK" ) ), &maOKButton ); 2175 } 2176 } 2177 else if( pButton == &maForwardBtn ) 2178 { 2179 previewForward(); 2180 } 2181 else if( pButton == &maBackwardBtn ) 2182 { 2183 previewBackward(); 2184 } 2185 else if( pButton == &maOptionsPage.maToFileBox ) 2186 { 2187 maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); 2188 maPController->resetPrinterOptions( maOptionsPage.maToFileBox.IsChecked() ); 2189 getLayout()->resize(); 2190 preparePreview( true, true ); 2191 } 2192 else if( pButton == &maNUpPage.maBrochureBtn ) 2193 { 2194 PropertyValue* pVal = getValueForWindow( pButton ); 2195 if( pVal ) 2196 { 2197 sal_Bool bVal = maNUpPage.maBrochureBtn.IsChecked(); 2198 pVal->Value <<= bVal; 2199 2200 checkOptionalControlDependencies(); 2201 2202 // update preview and page settings 2203 preparePreview(); 2204 } 2205 if( maNUpPage.maBrochureBtn.IsChecked() ) 2206 { 2207 maNUpPage.maNupPagesBox.SelectEntryPos( 0 ); 2208 updateNupFromPages(); 2209 maNUpPage.showAdvancedControls( false ); 2210 maNUpPage.enableNupControls( false ); 2211 } 2212 } 2213 else if( pButton == &maNUpPage.maPagesBtn ) 2214 { 2215 maNUpPage.enableNupControls( true ); 2216 updateNupFromPages(); 2217 } 2218 else if( pButton == &maJobPage.maDetailsBtn ) 2219 { 2220 bool bShow = maJobPage.maDetailsBtn.IsChecked(); 2221 maJobPage.mxDetails->show( bShow ); 2222 if( bShow ) 2223 { 2224 maDetailsCollapsedSize = GetOutputSizePixel(); 2225 // enlarge dialog if necessary 2226 Size aMinSize( maJobPage.getLayout()->getOptimalSize( WINDOWSIZE_MINIMUM ) ); 2227 Size aCurSize( maJobPage.GetSizePixel() ); 2228 if( aCurSize.Height() < aMinSize.Height() ) 2229 { 2230 Size aDlgSize( GetOutputSizePixel() ); 2231 aDlgSize.Height() += aMinSize.Height() - aCurSize.Height(); 2232 SetOutputSizePixel( aDlgSize ); 2233 } 2234 maDetailsExpandedSize = GetOutputSizePixel(); 2235 } 2236 else if( maDetailsCollapsedSize.Width() > 0 && 2237 maDetailsCollapsedSize.Height() > 0 ) 2238 { 2239 // if the user did not resize the dialog 2240 // make it smaller again on collapsing the details 2241 Size aDlgSize( GetOutputSizePixel() ); 2242 if( aDlgSize == maDetailsExpandedSize && 2243 aDlgSize.Height() > maDetailsCollapsedSize.Height() ) 2244 { 2245 SetOutputSizePixel( maDetailsCollapsedSize ); 2246 } 2247 } 2248 } 2249 else if( pButton == &maJobPage.maCollateBox ) 2250 { 2251 maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ), 2252 makeAny( sal_Bool(isCollate()) ) ); 2253 checkControlDependencies(); 2254 } 2255 else if( pButton == &maJobPage.maReverseOrderBox ) 2256 { 2257 sal_Bool bChecked = maJobPage.maReverseOrderBox.IsChecked(); 2258 maPController->setReversePrint( bChecked ); 2259 maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintReverse" ) ), 2260 makeAny( bChecked ) ); 2261 preparePreview( true, true ); 2262 } 2263 else if( pButton == &maNUpPage.maBorderCB ) 2264 { 2265 updateNup(); 2266 } 2267 else 2268 { 2269 if( pButton == &maJobPage.maSetupButton ) 2270 { 2271 maPController->setupPrinter( this ); 2272 preparePreview( true, true ); 2273 } 2274 checkControlDependencies(); 2275 } 2276 return 0; 2277 } 2278 2279 IMPL_LINK( PrintDialog, ModifyHdl, Edit*, pEdit ) 2280 { 2281 checkControlDependencies(); 2282 if( pEdit == &maNUpPage.maNupRowsEdt || pEdit == &maNUpPage.maNupColEdt || 2283 pEdit == &maNUpPage.maSheetMarginEdt || pEdit == &maNUpPage.maPageMarginEdt 2284 ) 2285 { 2286 updateNupFromPages(); 2287 } 2288 else if( pEdit == &maPageEdit ) 2289 { 2290 mnCurPage = sal_Int32( maPageEdit.GetValue() - 1 ); 2291 preparePreview( true, true ); 2292 } 2293 else if( pEdit == &maJobPage.maCopyCountField ) 2294 { 2295 maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ), 2296 makeAny( sal_Int32(maJobPage.maCopyCountField.GetValue()) ) ); 2297 maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ), 2298 makeAny( sal_Bool(isCollate()) ) ); 2299 } 2300 return 0; 2301 } 2302 2303 IMPL_LINK( PrintDialog, UIOptionsChanged, void*, EMPTYARG ) 2304 { 2305 checkOptionalControlDependencies(); 2306 return 0; 2307 } 2308 2309 PropertyValue* PrintDialog::getValueForWindow( Window* i_pWindow ) const 2310 { 2311 PropertyValue* pVal = NULL; 2312 std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow ); 2313 if( it != maControlToPropertyMap.end() ) 2314 { 2315 pVal = maPController->getValue( it->second ); 2316 DBG_ASSERT( pVal, "property value not found" ); 2317 } 2318 else 2319 { 2320 DBG_ERROR( "changed control not in property map" ); 2321 } 2322 return pVal; 2323 } 2324 2325 void PrintDialog::updateWindowFromProperty( const rtl::OUString& i_rProperty ) 2326 { 2327 beans::PropertyValue* pValue = maPController->getValue( i_rProperty ); 2328 std::map< rtl::OUString, std::vector< Window* > >::const_iterator it = maPropertyToWindowMap.find( i_rProperty ); 2329 if( pValue && it != maPropertyToWindowMap.end() ) 2330 { 2331 const std::vector< Window* >& rWindows( it->second ); 2332 if( ! rWindows.empty() ) 2333 { 2334 sal_Bool bVal = sal_False; 2335 sal_Int32 nVal = -1; 2336 if( pValue->Value >>= bVal ) 2337 { 2338 // we should have a CheckBox for this one 2339 CheckBox* pBox = dynamic_cast< CheckBox* >( rWindows.front() ); 2340 if( pBox ) 2341 { 2342 pBox->Check( bVal ); 2343 } 2344 else if( i_rProperty.equalsAscii( "PrintProspect" ) ) 2345 { 2346 // EVIL special case 2347 if( bVal ) 2348 maNUpPage.maBrochureBtn.Check(); 2349 else 2350 maNUpPage.maPagesBtn.Check(); 2351 } 2352 else 2353 { 2354 DBG_ASSERT( 0, "missing a checkbox" ); 2355 } 2356 } 2357 else if( pValue->Value >>= nVal ) 2358 { 2359 // this could be a ListBox or a RadioButtonGroup 2360 ListBox* pList = dynamic_cast< ListBox* >( rWindows.front() ); 2361 if( pList ) 2362 { 2363 pList->SelectEntryPos( static_cast< sal_uInt16 >(nVal) ); 2364 } 2365 else if( nVal >= 0 && nVal < sal_Int32(rWindows.size() ) ) 2366 { 2367 RadioButton* pBtn = dynamic_cast< RadioButton* >( rWindows[nVal] ); 2368 DBG_ASSERT( pBtn, "unexpected control for property" ); 2369 if( pBtn ) 2370 pBtn->Check(); 2371 } 2372 } 2373 } 2374 } 2375 } 2376 2377 void PrintDialog::makeEnabled( Window* i_pWindow ) 2378 { 2379 std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow ); 2380 if( it != maControlToPropertyMap.end() ) 2381 { 2382 rtl::OUString aDependency( maPController->makeEnabled( it->second ) ); 2383 if( aDependency.getLength() ) 2384 updateWindowFromProperty( aDependency ); 2385 } 2386 } 2387 2388 IMPL_LINK( PrintDialog, UIOption_CheckHdl, CheckBox*, i_pBox ) 2389 { 2390 PropertyValue* pVal = getValueForWindow( i_pBox ); 2391 if( pVal ) 2392 { 2393 makeEnabled( i_pBox ); 2394 2395 sal_Bool bVal = i_pBox->IsChecked(); 2396 pVal->Value <<= bVal; 2397 2398 checkOptionalControlDependencies(); 2399 2400 // update preview and page settings 2401 preparePreview(); 2402 } 2403 return 0; 2404 } 2405 2406 IMPL_LINK( PrintDialog, UIOption_RadioHdl, RadioButton*, i_pBtn ) 2407 { 2408 // this handler gets called for all radiobuttons that get unchecked, too 2409 // however we only want one notificaction for the new value (that is for 2410 // the button that gets checked) 2411 if( i_pBtn->IsChecked() ) 2412 { 2413 PropertyValue* pVal = getValueForWindow( i_pBtn ); 2414 std::map< Window*, sal_Int32 >::const_iterator it = maControlToNumValMap.find( i_pBtn ); 2415 if( pVal && it != maControlToNumValMap.end() ) 2416 { 2417 makeEnabled( i_pBtn ); 2418 2419 sal_Int32 nVal = it->second; 2420 pVal->Value <<= nVal; 2421 2422 checkOptionalControlDependencies(); 2423 2424 // update preview and page settings 2425 preparePreview(); 2426 } 2427 } 2428 return 0; 2429 } 2430 2431 IMPL_LINK( PrintDialog, UIOption_SelectHdl, ListBox*, i_pBox ) 2432 { 2433 PropertyValue* pVal = getValueForWindow( i_pBox ); 2434 if( pVal ) 2435 { 2436 makeEnabled( i_pBox ); 2437 2438 sal_Int32 nVal( i_pBox->GetSelectEntryPos() ); 2439 pVal->Value <<= nVal; 2440 2441 checkOptionalControlDependencies(); 2442 2443 // update preview and page settings 2444 preparePreview(); 2445 } 2446 return 0; 2447 } 2448 2449 IMPL_LINK( PrintDialog, UIOption_ModifyHdl, Edit*, i_pBox ) 2450 { 2451 PropertyValue* pVal = getValueForWindow( i_pBox ); 2452 if( pVal ) 2453 { 2454 makeEnabled( i_pBox ); 2455 2456 NumericField* pNum = dynamic_cast<NumericField*>(i_pBox); 2457 MetricField* pMetric = dynamic_cast<MetricField*>(i_pBox); 2458 if( pNum ) 2459 { 2460 sal_Int64 nVal = pNum->GetValue(); 2461 pVal->Value <<= nVal; 2462 } 2463 else if( pMetric ) 2464 { 2465 sal_Int64 nVal = pMetric->GetValue(); 2466 pVal->Value <<= nVal; 2467 } 2468 else 2469 { 2470 rtl::OUString aVal( i_pBox->GetText() ); 2471 pVal->Value <<= aVal; 2472 } 2473 2474 checkOptionalControlDependencies(); 2475 2476 // update preview and page settings 2477 preparePreview(); 2478 } 2479 return 0; 2480 } 2481 2482 void PrintDialog::Command( const CommandEvent& rEvt ) 2483 { 2484 if( rEvt.GetCommand() == COMMAND_WHEEL ) 2485 { 2486 const CommandWheelData* pWheelData = rEvt.GetWheelData(); 2487 if( pWheelData->GetDelta() > 0 ) 2488 previewForward(); 2489 else if( pWheelData->GetDelta() < 0 ) 2490 previewBackward(); 2491 /* 2492 else 2493 huh ? 2494 */ 2495 } 2496 } 2497 2498 void PrintDialog::Resize() 2499 { 2500 // maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); 2501 // and do the preview; however the metafile does not need to be gotten anew 2502 preparePreview( false ); 2503 2504 // do an invalidate for the benefit of the grouping elements 2505 Invalidate(); 2506 } 2507 2508 void PrintDialog::previewForward() 2509 { 2510 maPageEdit.Up(); 2511 } 2512 2513 void PrintDialog::previewBackward() 2514 { 2515 maPageEdit.Down(); 2516 } 2517 2518 // ----------------------------------------------------------------------------- 2519 // 2520 // PrintProgressDialog 2521 // 2522 // ----------------------------------------------------------------------------- 2523 2524 PrintProgressDialog::PrintProgressDialog( Window* i_pParent, int i_nMax ) : 2525 ModelessDialog( i_pParent, VclResId( SV_DLG_PRINT_PROGRESS ) ), 2526 maText( this, VclResId( SV_PRINT_PROGRESS_TEXT ) ), 2527 maButton( this, VclResId( SV_PRINT_PROGRESS_CANCEL ) ), 2528 mbCanceled( false ), 2529 mnCur( 0 ), 2530 mnMax( i_nMax ), 2531 mnProgressHeight( 15 ), 2532 mbNativeProgress( false ) 2533 { 2534 FreeResource(); 2535 2536 if( mnMax < 1 ) 2537 mnMax = 1; 2538 2539 maStr = maText.GetText(); 2540 2541 maButton.SetClickHdl( LINK( this, PrintProgressDialog, ClickHdl ) ); 2542 2543 } 2544 2545 PrintProgressDialog::~PrintProgressDialog() 2546 { 2547 } 2548 2549 IMPL_LINK( PrintProgressDialog, ClickHdl, Button*, pButton ) 2550 { 2551 if( pButton == &maButton ) 2552 mbCanceled = true; 2553 2554 return 0; 2555 } 2556 2557 void PrintProgressDialog::implCalcProgressRect() 2558 { 2559 if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) 2560 { 2561 ImplControlValue aValue; 2562 Rectangle aControlRegion( Point(), Size( 100, mnProgressHeight ) ); 2563 Rectangle aNativeControlRegion, aNativeContentRegion; 2564 if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, 2565 CTRL_STATE_ENABLED, aValue, rtl::OUString(), 2566 aNativeControlRegion, aNativeContentRegion ) ) 2567 { 2568 mnProgressHeight = aNativeControlRegion.GetHeight(); 2569 } 2570 mbNativeProgress = true; 2571 } 2572 maProgressRect = Rectangle( Point( 10, maText.GetPosPixel().Y() + maText.GetSizePixel().Height() + 8 ), 2573 Size( GetSizePixel().Width() - 20, mnProgressHeight ) ); 2574 } 2575 2576 void PrintProgressDialog::setProgress( int i_nCurrent, int i_nMax ) 2577 { 2578 if( maProgressRect.IsEmpty() ) 2579 implCalcProgressRect(); 2580 2581 mnCur = i_nCurrent; 2582 if( i_nMax != -1 ) 2583 mnMax = i_nMax; 2584 2585 if( mnMax < 1 ) 2586 mnMax = 1; 2587 2588 rtl::OUString aNewText( searchAndReplace( maStr, "%p", 2, rtl::OUString::valueOf( mnCur ) ) ); 2589 aNewText = searchAndReplace( aNewText, "%n", 2, rtl::OUString::valueOf( mnMax ) ); 2590 maText.SetText( aNewText ); 2591 2592 // update progress 2593 Invalidate( maProgressRect, INVALIDATE_UPDATE ); 2594 } 2595 2596 void PrintProgressDialog::tick() 2597 { 2598 if( mnCur < mnMax ) 2599 setProgress( ++mnCur ); 2600 } 2601 2602 void PrintProgressDialog::reset() 2603 { 2604 mbCanceled = false; 2605 setProgress( 0 ); 2606 } 2607 2608 void PrintProgressDialog::Paint( const Rectangle& ) 2609 { 2610 if( maProgressRect.IsEmpty() ) 2611 implCalcProgressRect(); 2612 2613 Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 2614 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 2615 Color aPrgsColor = rStyleSettings.GetHighlightColor(); 2616 if ( aPrgsColor == rStyleSettings.GetFaceColor() ) 2617 aPrgsColor = rStyleSettings.GetDarkShadowColor(); 2618 SetLineColor(); 2619 SetFillColor( aPrgsColor ); 2620 2621 const long nOffset = 3; 2622 const long nWidth = 3*mnProgressHeight/2; 2623 const long nFullWidth = nWidth + nOffset; 2624 const long nMaxCount = maProgressRect.GetWidth() / nFullWidth; 2625 DrawProgress( this, maProgressRect.TopLeft(), 2626 nOffset, 2627 nWidth, 2628 mnProgressHeight, 2629 static_cast<sal_uInt16>(0), 2630 static_cast<sal_uInt16>(10000*mnCur/mnMax), 2631 static_cast<sal_uInt16>(10000/nMaxCount), 2632 maProgressRect 2633 ); 2634 Pop(); 2635 2636 if( ! mbNativeProgress ) 2637 { 2638 DecorationView aDecoView( this ); 2639 Rectangle aFrameRect( maProgressRect ); 2640 aFrameRect.Left() -= nOffset; 2641 aFrameRect.Right() += nOffset; 2642 aFrameRect.Top() -= nOffset; 2643 aFrameRect.Bottom() += nOffset; 2644 aDecoView.DrawFrame( aFrameRect ); 2645 } 2646 } 2647 2648