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