1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include <com/sun/star/document/XDocumentProperties.hpp> 32 #include <com/sun/star/view/PrintableState.hpp> 33 #include "com/sun/star/view/XRenderable.hpp" 34 35 #include <svl/itempool.hxx> 36 #include <vcl/msgbox.hxx> 37 #include <svtools/prnsetup.hxx> 38 #include <svl/flagitem.hxx> 39 #include <svl/stritem.hxx> 40 #include <svl/intitem.hxx> 41 #include <svl/eitem.hxx> 42 #include <sfx2/app.hxx> 43 #include <unotools/useroptions.hxx> 44 #include <unotools/printwarningoptions.hxx> 45 #include <tools/datetime.hxx> 46 #include <sfx2/bindings.hxx> 47 #include <sfx2/objface.hxx> 48 #include <sfx2/viewsh.hxx> 49 #include "viewimp.hxx" 50 #include <sfx2/viewfrm.hxx> 51 #include <sfx2/prnmon.hxx> 52 #include "sfx2/sfxresid.hxx" 53 #include <sfx2/request.hxx> 54 #include <sfx2/objsh.hxx> 55 #include "sfxtypes.hxx" 56 #include <sfx2/event.hxx> 57 #include <sfx2/docfile.hxx> 58 #include <sfx2/docfilt.hxx> 59 60 #include "toolkit/awt/vclxdevice.hxx" 61 62 #include "view.hrc" 63 #include "helpid.hrc" 64 65 using namespace com::sun::star; 66 using namespace com::sun::star::uno; 67 68 TYPEINIT1(SfxPrintingHint, SfxHint); 69 70 // ----------------------------------------------------------------------- 71 class SfxPrinterController : public vcl::PrinterController, public SfxListener 72 { 73 Any maCompleteSelection; 74 Any maSelection; 75 Reference< view::XRenderable > mxRenderable; 76 mutable Printer* mpLastPrinter; 77 mutable Reference<awt::XDevice> mxDevice; 78 SfxViewShell* mpViewShell; 79 SfxObjectShell* mpObjectShell; 80 sal_Bool m_bOrigStatus; 81 sal_Bool m_bNeedsChange; 82 sal_Bool m_bApi; 83 sal_Bool m_bTempPrinter; 84 util::DateTime m_aLastPrinted; 85 ::rtl::OUString m_aLastPrintedBy; 86 87 Sequence< beans::PropertyValue > getMergedOptions() const; 88 const Any& getSelectionObject() const; 89 public: 90 SfxPrinterController( const boost::shared_ptr<Printer>& i_rPrinter, 91 const Any& i_rComplete, 92 const Any& i_rSelection, 93 const Any& i_rViewProp, 94 const Reference< view::XRenderable >& i_xRender, 95 sal_Bool i_bApi, sal_Bool i_bDirect, 96 SfxViewShell* pView, 97 const uno::Sequence< beans::PropertyValue >& rProps 98 ); 99 100 virtual ~SfxPrinterController(); 101 virtual void Notify( SfxBroadcaster&, const SfxHint& ); 102 103 virtual int getPageCount() const; 104 virtual Sequence< beans::PropertyValue > getPageParameters( int i_nPage ) const; 105 virtual void printPage( int i_nPage ) const; 106 virtual void jobStarted(); 107 virtual void jobFinished( com::sun::star::view::PrintableState ); 108 }; 109 110 SfxPrinterController::SfxPrinterController( const boost::shared_ptr<Printer>& i_rPrinter, 111 const Any& i_rComplete, 112 const Any& i_rSelection, 113 const Any& i_rViewProp, 114 const Reference< view::XRenderable >& i_xRender, 115 sal_Bool i_bApi, sal_Bool i_bDirect, 116 SfxViewShell* pView, 117 const uno::Sequence< beans::PropertyValue >& rProps 118 ) 119 : PrinterController( i_rPrinter) 120 , maCompleteSelection( i_rComplete ) 121 , maSelection( i_rSelection ) 122 , mxRenderable( i_xRender ) 123 , mpLastPrinter( NULL ) 124 , mpViewShell( pView ) 125 , mpObjectShell(0) 126 , m_bOrigStatus( sal_False ) 127 , m_bNeedsChange( sal_False ) 128 , m_bApi(i_bApi) 129 , m_bTempPrinter( i_rPrinter.get() != NULL ) 130 { 131 if ( mpViewShell ) 132 { 133 StartListening( *mpViewShell ); 134 mpObjectShell = mpViewShell->GetObjectShell(); 135 StartListening( *mpObjectShell ); 136 } 137 138 // initialize extra ui options 139 if( mxRenderable.is() ) 140 { 141 for (sal_Int32 nProp=0; nProp<rProps.getLength(); nProp++) 142 setValue( rProps[nProp].Name, rProps[nProp].Value ); 143 144 Sequence< beans::PropertyValue > aRenderOptions( 3 ); 145 aRenderOptions[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExtraPrintUIOptions" ) ); 146 aRenderOptions[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "View" ) ); 147 aRenderOptions[1].Value = i_rViewProp; 148 aRenderOptions[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) ); 149 aRenderOptions[2].Value <<= sal_True; 150 try 151 { 152 Sequence< beans::PropertyValue > aRenderParms( mxRenderable->getRenderer( 0 , getSelectionObject(), aRenderOptions ) ); 153 int nProps = aRenderParms.getLength(); 154 for( int i = 0; i < nProps; i++ ) 155 { 156 if( aRenderParms[i].Name.equalsAscii( "ExtraPrintUIOptions" ) ) 157 { 158 Sequence< beans::PropertyValue > aUIProps; 159 aRenderParms[i].Value >>= aUIProps; 160 setUIOptions( aUIProps ); 161 } 162 else if( aRenderParms[i].Name.compareToAscii( "NUp", 3 ) == 0 ) 163 { 164 setValue( aRenderParms[i].Name, aRenderParms[i].Value ); 165 } 166 } 167 } 168 catch( lang::IllegalArgumentException& ) 169 { 170 // the first renderer should always be available for the UI options, 171 // but catch the exception to be safe 172 } 173 } 174 175 // set some job parameters 176 setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsApi" ) ), makeAny( i_bApi ) ); 177 setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDirect" ) ), makeAny( i_bDirect ) ); 178 setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) ), makeAny( sal_True ) ); 179 setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "View" ) ), i_rViewProp ); 180 } 181 182 void SfxPrinterController::Notify( SfxBroadcaster& , const SfxHint& rHint ) 183 { 184 if ( rHint.IsA(TYPE(SfxSimpleHint)) ) 185 { 186 if ( ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 187 { 188 EndListening(*mpViewShell); 189 EndListening(*mpObjectShell); 190 mpViewShell = 0; 191 mpObjectShell = 0; 192 } 193 } 194 } 195 196 SfxPrinterController::~SfxPrinterController() 197 { 198 } 199 200 const Any& SfxPrinterController::getSelectionObject() const 201 { 202 const beans::PropertyValue* pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintSelectionOnly" ) ) ); 203 if( pVal ) 204 { 205 sal_Bool bSel = sal_False; 206 pVal->Value >>= bSel; 207 return bSel ? maSelection : maCompleteSelection; 208 } 209 210 sal_Int32 nChoice = 0; 211 pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ) ); 212 if( pVal ) 213 pVal->Value >>= nChoice; 214 return (nChoice > 1) ? maSelection : maCompleteSelection; 215 } 216 217 Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const 218 { 219 boost::shared_ptr<Printer> pPrinter( getPrinter() ); 220 if( pPrinter.get() != mpLastPrinter ) 221 { 222 mpLastPrinter = pPrinter.get(); 223 VCLXDevice* pXDevice = new VCLXDevice(); 224 pXDevice->SetOutputDevice( mpLastPrinter ); 225 mxDevice = Reference< awt::XDevice >( pXDevice ); 226 } 227 228 Sequence< beans::PropertyValue > aRenderOptions( 1 ); 229 aRenderOptions[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) ); 230 aRenderOptions[ 0 ].Value <<= mxDevice; 231 232 aRenderOptions = getJobProperties( aRenderOptions ); 233 return aRenderOptions; 234 } 235 236 int SfxPrinterController::getPageCount() const 237 { 238 int nPages = 0; 239 boost::shared_ptr<Printer> pPrinter( getPrinter() ); 240 if( mxRenderable.is() && pPrinter ) 241 { 242 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() ); 243 nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions ); 244 } 245 return nPages; 246 } 247 248 Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_nPage ) const 249 { 250 boost::shared_ptr<Printer> pPrinter( getPrinter() ); 251 Sequence< beans::PropertyValue > aResult; 252 253 if( mxRenderable.is() && pPrinter ) 254 { 255 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() ); 256 try 257 { 258 aResult = mxRenderable->getRenderer( i_nPage, getSelectionObject(), aJobOptions ); 259 } 260 catch( lang::IllegalArgumentException& ) 261 { 262 } 263 } 264 return aResult; 265 } 266 267 void SfxPrinterController::printPage( int i_nPage ) const 268 { 269 boost::shared_ptr<Printer> pPrinter( getPrinter() ); 270 if( mxRenderable.is() && pPrinter ) 271 { 272 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() ); 273 try 274 { 275 mxRenderable->render( i_nPage, getSelectionObject(), aJobOptions ); 276 } 277 catch( lang::IllegalArgumentException& ) 278 { 279 // don't care enough about nonexistant page here 280 // to provoke a crash 281 } 282 } 283 } 284 285 void SfxPrinterController::jobStarted() 286 { 287 if ( mpObjectShell ) 288 { 289 m_bOrigStatus = mpObjectShell->IsEnableSetModified(); 290 291 // check configuration: shall update of printing information in DocInfo set the document to "modified"? 292 if ( m_bOrigStatus && !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() ) 293 { 294 mpObjectShell->EnableSetModified( sal_False ); 295 m_bNeedsChange = sal_True; 296 } 297 298 // refresh document info 299 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties()); 300 m_aLastPrintedBy = xDocProps->getPrintedBy(); 301 m_aLastPrinted = xDocProps->getPrintDate(); 302 303 xDocProps->setPrintedBy( mpObjectShell->IsUseUserData() 304 ? ::rtl::OUString( SvtUserOptions().GetFullName() ) 305 : ::rtl::OUString() ); 306 ::DateTime now; 307 308 xDocProps->setPrintDate( util::DateTime( 309 now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(), 310 now.GetDay(), now.GetMonth(), now.GetYear() ) ); 311 312 // FIXME: how to get all print options incl. AdditionalOptions easily? 313 uno::Sequence < beans::PropertyValue > aOpts; 314 mpObjectShell->Broadcast( SfxPrintingHint( view::PrintableState_JOB_STARTED, aOpts ) ); 315 } 316 } 317 318 void SfxPrinterController::jobFinished( com::sun::star::view::PrintableState nState ) 319 { 320 if ( mpObjectShell ) 321 { 322 bool bCopyJobSetup = false; 323 mpObjectShell->Broadcast( SfxPrintingHint( nState ) ); 324 switch ( nState ) 325 { 326 case view::PrintableState_JOB_FAILED : 327 { 328 // "real" problem (not simply printing cancelled by user) 329 String aMsg( SfxResId( STR_NOSTARTPRINTER ) ); 330 if ( !m_bApi ) 331 ErrorBox( mpViewShell->GetWindow(), WB_OK | WB_DEF_OK, aMsg ).Execute(); 332 // intentionally no break 333 } 334 case view::PrintableState_JOB_ABORTED : 335 { 336 // printing not succesful, reset DocInfo 337 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties()); 338 xDocProps->setPrintedBy(m_aLastPrintedBy); 339 xDocProps->setPrintDate(m_aLastPrinted); 340 break; 341 } 342 343 case view::PrintableState_JOB_SPOOLED : 344 case view::PrintableState_JOB_COMPLETED : 345 { 346 SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings(); 347 rBind.Invalidate( SID_PRINTDOC ); 348 rBind.Invalidate( SID_PRINTDOCDIRECT ); 349 rBind.Invalidate( SID_SETUPPRINTER ); 350 bCopyJobSetup = ! m_bTempPrinter; 351 break; 352 } 353 354 default: 355 break; 356 } 357 358 if( bCopyJobSetup && mpViewShell ) 359 { 360 // #i114306# 361 // Note: this possibly creates a printer that gets immediately replaced 362 // by a new one. The reason for this is that otherwise we would not get 363 // the printer's SfxItemSet here to copy. Awkward, but at the moment there is no 364 // other way here to get the item set. 365 SfxPrinter* pDocPrt = mpViewShell->GetPrinter(sal_True); 366 if( pDocPrt ) 367 { 368 if( pDocPrt->GetName() == getPrinter()->GetName() ) 369 pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() ); 370 else 371 { 372 SfxPrinter* pNewPrt = new SfxPrinter( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() ); 373 pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() ); 374 mpViewShell->SetPrinter( pNewPrt, SFX_PRINTER_PRINTER | SFX_PRINTER_JOBSETUP ); 375 } 376 } 377 } 378 379 if ( m_bNeedsChange ) 380 mpObjectShell->EnableSetModified( m_bOrigStatus ); 381 382 if ( mpViewShell ) 383 { 384 mpViewShell->pImp->m_pPrinterController.reset(); 385 } 386 } 387 } 388 389 //==================================================================== 390 391 class SfxDialogExecutor_Impl 392 393 /* [Beschreibung] 394 395 Eine Instanz dieser Klasse wird f"ur die Laufzeit des Printer-Dialogs 396 erzeugt, um im dessen Click-Handler f"ur die Zus"atze den per 397 virtueller Methode von der abgeleiteten SfxViewShell erzeugten 398 Print-Options-Dialog zu erzeugen und die dort eingestellten Optionen 399 als SfxItemSet zu zwischenzuspeichern. 400 */ 401 402 { 403 private: 404 SfxViewShell* _pViewSh; 405 PrinterSetupDialog* _pSetupParent; 406 SfxItemSet* _pOptions; 407 sal_Bool _bModified; 408 sal_Bool _bHelpDisabled; 409 410 DECL_LINK( Execute, void * ); 411 412 public: 413 SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog* pParent ); 414 ~SfxDialogExecutor_Impl() { delete _pOptions; } 415 416 Link GetLink() const { return LINK( this, SfxDialogExecutor_Impl, Execute); } 417 const SfxItemSet* GetOptions() const { return _pOptions; } 418 void DisableHelp() { _bHelpDisabled = sal_True; } 419 }; 420 421 //-------------------------------------------------------------------- 422 423 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog* pParent ) : 424 425 _pViewSh ( pViewSh ), 426 _pSetupParent ( pParent ), 427 _pOptions ( NULL ), 428 _bModified ( sal_False ), 429 _bHelpDisabled ( sal_False ) 430 431 { 432 } 433 434 //-------------------------------------------------------------------- 435 436 IMPL_LINK( SfxDialogExecutor_Impl, Execute, void *, EMPTYARG ) 437 { 438 // Options lokal merken 439 if ( !_pOptions ) 440 { 441 DBG_ASSERT( _pSetupParent, "no dialog parent" ); 442 if( _pSetupParent ) 443 _pOptions = ( (SfxPrinter*)_pSetupParent->GetPrinter() )->GetOptions().Clone(); 444 } 445 446 // Dialog ausf"uhren 447 SfxPrintOptionsDialog* pDlg = new SfxPrintOptionsDialog( static_cast<Window*>(_pSetupParent), 448 _pViewSh, _pOptions ); 449 if ( _bHelpDisabled ) 450 pDlg->DisableHelp(); 451 if ( pDlg->Execute() == RET_OK ) 452 { 453 delete _pOptions; 454 _pOptions = pDlg->GetOptions().Clone(); 455 456 } 457 delete pDlg; 458 459 return 0; 460 } 461 462 //------------------------------------------------------------------------- 463 464 sal_Bool UseStandardPrinter_Impl( Window* /*pParent*/, SfxPrinter* pDocPrinter ) 465 { 466 // Optionen abfragen, ob gewarnt werden soll (Doc uebersteuert App) 467 sal_Bool bWarn = sal_False; 468 const SfxItemSet *pDocOptions = &pDocPrinter->GetOptions(); 469 if ( pDocOptions ) 470 { 471 sal_uInt16 nWhich = pDocOptions->GetPool()->GetWhich(SID_PRINTER_NOTFOUND_WARN); 472 const SfxBoolItem* pBoolItem = NULL; 473 pDocPrinter->GetOptions().GetItemState( nWhich, sal_False, (const SfxPoolItem**) &pBoolItem ); 474 if ( pBoolItem ) 475 bWarn = pBoolItem->GetValue(); 476 } 477 /* 478 // ggf. den User fragen 479 if ( bWarn ) 480 { 481 // Geht nicht mehr ohne OrigJobSetup! 482 String aTmp( SfxResId( STR_PRINTER_NOTAVAIL ) ); 483 QueryBox aBox( pParent, WB_OK_CANCEL | WB_DEF_OK, aTmp ); 484 return RET_OK == aBox.Execute(); 485 } 486 */ 487 // nicht gewarnt => einfach so den StandardDrucker nehmen 488 return sal_True; 489 } 490 //------------------------------------------------------------------------- 491 492 SfxPrinter* SfxViewShell::SetPrinter_Impl( SfxPrinter *pNewPrinter ) 493 494 /* Interne Methode zum Setzen der Unterschiede von 'pNewPrinter' zum 495 aktuellen Printer. pNewPrinter wird entweder "ubernommen oder gel"oscht. 496 */ 497 498 { 499 // aktuellen Printer holen 500 SfxPrinter *pDocPrinter = GetPrinter(); 501 502 // Printer-Options auswerten 503 bool bOriToDoc = false; 504 bool bSizeToDoc = false; 505 if ( &pDocPrinter->GetOptions() ) 506 { 507 sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC); 508 const SfxFlagItem *pFlagItem = 0; 509 pDocPrinter->GetOptions().GetItemState( nWhich, sal_False, (const SfxPoolItem**) &pFlagItem ); 510 bOriToDoc = pFlagItem ? (pFlagItem->GetValue() & SFX_PRINTER_CHG_ORIENTATION) : sal_False; 511 bSizeToDoc = pFlagItem ? (pFlagItem->GetValue() & SFX_PRINTER_CHG_SIZE) : sal_False; 512 } 513 514 // vorheriges Format und Size feststellen 515 Orientation eOldOri = pDocPrinter->GetOrientation(); 516 Size aOldPgSz = pDocPrinter->GetPaperSizePixel(); 517 518 // neues Format und Size feststellen 519 Orientation eNewOri = pNewPrinter->GetOrientation(); 520 Size aNewPgSz = pNewPrinter->GetPaperSizePixel(); 521 522 // "Anderungen am Seitenformat feststellen 523 sal_Bool bOriChg = (eOldOri != eNewOri) && bOriToDoc; 524 sal_Bool bPgSzChg = ( aOldPgSz.Height() != 525 ( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) || 526 aOldPgSz.Width() != 527 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) && 528 bSizeToDoc; 529 530 // Message und Flags f"ur Seitenformat-"Anderung zusammenstellen 531 String aMsg; 532 sal_uInt16 nNewOpt=0; 533 if( bOriChg && bPgSzChg ) 534 { 535 aMsg = String(SfxResId(STR_PRINT_NEWORISIZE)); 536 nNewOpt = SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE; 537 } 538 else if (bOriChg ) 539 { 540 aMsg = String(SfxResId(STR_PRINT_NEWORI)); 541 nNewOpt = SFX_PRINTER_CHG_ORIENTATION; 542 } 543 else if (bPgSzChg) 544 { 545 aMsg = String(SfxResId(STR_PRINT_NEWSIZE)); 546 nNewOpt = SFX_PRINTER_CHG_SIZE; 547 } 548 549 // in dieser Variable sammeln, was sich so ge"aendert hat 550 sal_uInt16 nChangedFlags = 0; 551 552 // ggf. Nachfrage, ob Seitenformat vom Drucker "ubernommen werden soll 553 if ( ( bOriChg || bPgSzChg ) && 554 RET_YES == QueryBox(0, WB_YES_NO | WB_DEF_OK, aMsg).Execute() ) 555 // Flags mit "Anderungen f"ur <SetPrinter(SfxPrinter*)> mitpflegen 556 nChangedFlags |= nNewOpt; 557 558 // fuer den MAC sein "temporary of class String" im naechsten if() 559 String aTempPrtName = pNewPrinter->GetName(); 560 String aDocPrtName = pDocPrinter->GetName(); 561 562 // Wurde der Drucker gewechselt oder von Default auf Specific 563 // oder umgekehrt geaendert? 564 if ( (aTempPrtName != aDocPrtName) || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) ) 565 { 566 // neuen Printer "ubernehmen 567 // pNewPrinter->SetOrigJobSetup( pNewPrinter->GetJobSetup() ); 568 nChangedFlags |= SFX_PRINTER_PRINTER|SFX_PRINTER_JOBSETUP; 569 pDocPrinter = pNewPrinter; 570 } 571 else 572 { 573 // Extra-Optionen vergleichen 574 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) ) 575 { 576 // Options haben sich geaendert 577 pDocPrinter->SetOptions( pNewPrinter->GetOptions() ); 578 nChangedFlags |= SFX_PRINTER_OPTIONS; 579 } 580 581 // JobSetups vergleichen 582 JobSetup aNewJobSetup = pNewPrinter->GetJobSetup(); 583 JobSetup aOldJobSetup = pDocPrinter->GetJobSetup(); 584 if ( aNewJobSetup != aOldJobSetup ) 585 { 586 // JobSetup hat sich geaendert (=> App mu\s neu formatieren) 587 // pDocPrinter->SetOrigJobSetup( aNewJobSetup ); 588 nChangedFlags |= SFX_PRINTER_JOBSETUP; 589 } 590 591 // alten, ver"anderten Printer behalten 592 pDocPrinter->SetPrinterProps( pNewPrinter ); 593 delete pNewPrinter; 594 } 595 596 if ( 0 != nChangedFlags ) 597 // SetPrinter will delete the old printer if it changes 598 SetPrinter( pDocPrinter, nChangedFlags ); 599 return pDocPrinter; 600 } 601 602 //------------------------------------------------------------------------- 603 // Unter WIN32 tritt leider das Problem auf, dass nichts gedruckt 604 // wird, wenn SID_PRINTDOCDIRECT auflaueft; bisher bekannte, 605 // einzige Abhilfe ist in diesem Fall das Abschalten der Optimierungen 606 // (KA 17.12.95) 607 #ifdef _MSC_VER 608 #pragma optimize ( "", off ) 609 #endif 610 611 void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, sal_Bool bIsAPI, sal_Bool bIsDirect ) 612 { 613 // get the current selection; our controller should know it 614 Reference< frame::XController > xController( GetController() ); 615 Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY ); 616 617 Any aSelection; 618 if( xSupplier.is() ) 619 aSelection = xSupplier->getSelection(); 620 else 621 aSelection <<= GetObjectShell()->GetModel(); 622 Any aComplete( makeAny( GetObjectShell()->GetModel() ) ); 623 Any aViewProp( makeAny( xController ) ); 624 boost::shared_ptr<Printer> aPrt; 625 626 const beans::PropertyValue* pVal = rProps.getConstArray(); 627 for( sal_Int32 i = 0; i < rProps.getLength(); i++ ) 628 { 629 if( pVal[i].Name.equalsAscii( "PrinterName" ) ) 630 { 631 rtl::OUString aPrinterName; 632 pVal[i].Value >>= aPrinterName; 633 aPrt.reset( new Printer( aPrinterName ) ); 634 break; 635 } 636 } 637 638 boost::shared_ptr<vcl::PrinterController> pController( new SfxPrinterController( 639 aPrt, 640 aComplete, 641 aSelection, 642 aViewProp, 643 GetRenderable(), 644 bIsAPI, 645 bIsDirect, 646 this, 647 rProps 648 ) ); 649 pImp->m_pPrinterController = pController; 650 651 SfxObjectShell *pObjShell = GetObjectShell(); 652 pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "JobName" ) ), 653 makeAny( rtl::OUString( pObjShell->GetTitle(0) ) ) ); 654 655 // FIXME: job setup 656 SfxPrinter* pDocPrt = GetPrinter(sal_False); 657 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : GetJobSetup(); 658 if( bIsDirect ) 659 aJobSetup.SetValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ), 660 String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) ); 661 662 Printer::PrintJob( pController, aJobSetup ); 663 } 664 665 Printer* SfxViewShell::GetActivePrinter() const 666 { 667 return (pImp->m_pPrinterController) 668 ? pImp->m_pPrinterController->getPrinter().get() : 0; 669 } 670 671 void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq ) 672 { 673 // sal_uInt16 nCopies=1; 674 sal_uInt16 nDialogRet = RET_CANCEL; 675 // sal_Bool bCollate=sal_False; 676 SfxPrinter* pPrinter = 0; 677 SfxDialogExecutor_Impl* pExecutor = 0; 678 bool bSilent = false; 679 sal_Bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count(); 680 if ( bIsAPI ) 681 { 682 SFX_REQUEST_ARG(rReq, pSilentItem, SfxBoolItem, SID_SILENT, sal_False); 683 bSilent = pSilentItem && pSilentItem->GetValue(); 684 } 685 686 //FIXME: how to transport "bPrintOnHelp"? 687 688 // no help button in dialogs if called from the help window 689 // (pressing help button would exchange the current page inside the help document that is going to be printed!) 690 String aHelpFilterName( DEFINE_CONST_UNICODE("writer_web_HTML_help") ); 691 SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium(); 692 const SfxFilter* pFilter = pMedium ? pMedium->GetFilter() : NULL; 693 sal_Bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == aHelpFilterName ); 694 695 const sal_uInt16 nId = rReq.GetSlot(); 696 switch( nId ) 697 { 698 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 699 case SID_PRINTDOC: 700 case SID_PRINTDOCDIRECT: 701 { 702 SfxObjectShell* pDoc = GetObjectShell(); 703 704 // derived class may decide to abort this 705 if( !pDoc->QuerySlotExecutable( nId ) ) 706 { 707 rReq.SetReturnValue( SfxBoolItem( 0, sal_False ) ); 708 return; 709 } 710 711 bool bDetectHidden = ( !bSilent && pDoc ); 712 if ( bDetectHidden && pDoc->QueryHiddenInformation( WhenPrinting, NULL ) != RET_YES ) 713 break; 714 715 SFX_REQUEST_ARG(rReq, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False); 716 sal_Bool bSelection = pSelectItem && pSelectItem->GetValue(); 717 if( pSelectItem && rReq.GetArgs()->Count() == 1 ) 718 bIsAPI = sal_False; 719 720 uno::Sequence < beans::PropertyValue > aProps; 721 if ( bIsAPI ) 722 { 723 // supported properties: 724 // String PrinterName 725 // String FileName 726 // Int16 From 727 // Int16 To 728 // In16 Copies 729 // String RangeText 730 // bool Selection 731 // bool Asynchron 732 // bool Collate 733 // bool Silent 734 TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) ); 735 for ( sal_Int32 nProp=0; nProp<aProps.getLength(); nProp++ ) 736 { 737 if ( aProps[nProp].Name.equalsAscii("Copies") ) 738 aProps[nProp]. Name = rtl::OUString::createFromAscii("CopyCount"); 739 else if ( aProps[nProp].Name.equalsAscii("RangeText") ) 740 aProps[nProp]. Name = rtl::OUString::createFromAscii("Pages"); 741 if ( aProps[nProp].Name.equalsAscii("Asynchron") ) 742 { 743 aProps[nProp]. Name = rtl::OUString::createFromAscii("Wait"); 744 sal_Bool bAsynchron = sal_False; 745 aProps[nProp].Value >>= bAsynchron; 746 aProps[nProp].Value <<= (sal_Bool) (!bAsynchron); 747 } 748 if ( aProps[nProp].Name.equalsAscii("Silent") ) 749 { 750 aProps[nProp]. Name = rtl::OUString::createFromAscii("MonitorVisible"); 751 sal_Bool bPrintSilent = sal_False; 752 aProps[nProp].Value >>= bPrintSilent; 753 aProps[nProp].Value <<= (sal_Bool) (!bPrintSilent); 754 } 755 } 756 } 757 // HACK: writer sets the SID_SELECTION item when printing directly and expects 758 // to get only the selection document in that case (see getSelectionObject) 759 // however it also reacts to the PrintContent property. We need this distinction here, too, 760 // else one of the combinations print / print direct and selection / all will not work. 761 // it would be better if writer handled this internally 762 if( nId == SID_PRINTDOCDIRECT ) 763 { 764 sal_Int32 nLen = aProps.getLength(); 765 aProps.realloc( nLen + 1 ); 766 aProps[nLen].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintSelectionOnly" ) ); 767 aProps[nLen].Value = makeAny( bSelection ); 768 } 769 770 ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT) ); 771 772 // FIXME: Recording 773 rReq.Done(); 774 break; 775 } 776 777 case SID_SETUPPRINTER : 778 case SID_PRINTER_NAME : // only for recorded macros 779 { 780 // get printer and printer settings from the document 781 SfxPrinter *pDocPrinter = GetPrinter(sal_True); 782 783 // look for printer in parameters 784 SFX_REQUEST_ARG( rReq, pPrinterItem, SfxStringItem, SID_PRINTER_NAME, sal_False ); 785 if ( pPrinterItem ) 786 { 787 // use PrinterName parameter to create a printer 788 pPrinter = new SfxPrinter( pDocPrinter->GetOptions().Clone(), ((const SfxStringItem*) pPrinterItem)->GetValue() ); 789 790 // if printer is unknown, it can't be used - now printer from document will be used 791 if ( !pPrinter->IsOriginal() ) 792 DELETEZ(pPrinter); 793 } 794 795 if ( SID_PRINTER_NAME == nId ) 796 { 797 // just set a recorded printer name 798 if ( pPrinter ) 799 SetPrinter( pPrinter, SFX_PRINTER_PRINTER ); 800 break; 801 } 802 803 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer 804 if ( !pPrinter ) 805 // use default printer from document 806 pPrinter = pDocPrinter; 807 808 if( !pPrinter || !pPrinter->IsValid() ) 809 { 810 // no valid printer either in ItemSet or at the document 811 if ( bSilent ) 812 { 813 rReq.SetReturnValue(SfxBoolItem(0,sal_False)); 814 break; 815 } 816 else 817 ErrorBox( NULL, WB_OK | WB_DEF_OK, String( SfxResId( STR_NODEFPRINTER ) ) ).Execute(); 818 } 819 820 if ( !pPrinter->IsOriginal() && rReq.GetArgs() && !UseStandardPrinter_Impl( NULL, pPrinter ) ) 821 { 822 // printer is not available, but standard printer should not be used 823 rReq.SetReturnValue(SfxBoolItem(0,sal_False)); 824 break; 825 } 826 827 // FIXME: printer isn't used for printing anymore! 828 if( pPrinter->IsPrinting() ) 829 { 830 // if printer is busy, abort printing 831 if ( !bSilent ) 832 InfoBox( NULL, String( SfxResId( STR_ERROR_PRINTER_BUSY ) ) ).Execute(); 833 rReq.SetReturnValue(SfxBoolItem(0,sal_False)); 834 break; 835 } 836 837 // if no arguments are given, retrieve them from a dialog 838 if ( !bIsAPI ) 839 { 840 // PrinterDialog needs a temporary printer 841 SfxPrinter* pDlgPrinter = pPrinter->Clone(); 842 nDialogRet = 0; 843 844 // execute PrinterSetupDialog 845 PrinterSetupDialog* pPrintSetupDlg = new PrinterSetupDialog( GetWindow() ); 846 847 if (pImp->m_bHasPrintOptions) 848 { 849 // additional controls for dialog 850 pExecutor = new SfxDialogExecutor_Impl( this, pPrintSetupDlg ); 851 if ( bPrintOnHelp ) 852 pExecutor->DisableHelp(); 853 pPrintSetupDlg->SetOptionsHdl( pExecutor->GetLink() ); 854 } 855 856 pPrintSetupDlg->SetPrinter( pDlgPrinter ); 857 nDialogRet = pPrintSetupDlg->Execute(); 858 859 if ( pExecutor && pExecutor->GetOptions() ) 860 { 861 if ( nDialogRet == RET_OK ) 862 // remark: have to be recorded if possible! 863 pDlgPrinter->SetOptions( *pExecutor->GetOptions() ); 864 else 865 { 866 pPrinter->SetOptions( *pExecutor->GetOptions() ); 867 SetPrinter( pPrinter, SFX_PRINTER_OPTIONS ); 868 } 869 } 870 871 DELETEZ( pPrintSetupDlg ); 872 873 // no recording of PrinterSetup except printer name (is printer dependent) 874 rReq.Ignore(); 875 876 if ( nDialogRet == RET_OK ) 877 { 878 if ( pPrinter->GetName() != pDlgPrinter->GetName() ) 879 { 880 // user has changed the printer -> macro recording 881 SfxRequest aReq( GetViewFrame(), SID_PRINTER_NAME ); 882 aReq.AppendItem( SfxStringItem( SID_PRINTER_NAME, pDlgPrinter->GetName() ) ); 883 aReq.Done(); 884 } 885 886 // take the changes made in the dialog 887 pPrinter = SetPrinter_Impl( pDlgPrinter ); 888 889 // forget new printer, it was taken over (as pPrinter) or deleted 890 pDlgPrinter = NULL; 891 892 } 893 else 894 { 895 // PrinterDialog is used to transfer information on printing, 896 // so it will only be deleted here if dialog was cancelled 897 DELETEZ( pDlgPrinter ); 898 rReq.Ignore(); 899 if ( SID_PRINTDOC == nId ) 900 rReq.SetReturnValue(SfxBoolItem(0,sal_False)); 901 } 902 } 903 } 904 905 break; 906 } 907 } 908 909 // Optimierungen wieder einschalten 910 #ifdef _MSC_VER 911 #pragma optimize ( "", on ) 912 #endif 913 914 //-------------------------------------------------------------------- 915 916 sal_Bool SfxViewShell::IsPrinterLocked() const 917 { 918 return pImp->m_nPrinterLocks > 0; 919 } 920 921 //-------------------------------------------------------------------- 922 923 void SfxViewShell::LockPrinter( sal_Bool bLock) 924 { 925 sal_Bool bChanged = sal_False; 926 if ( bLock ) 927 { 928 bChanged = 1 == ++pImp->m_nPrinterLocks; 929 } 930 else 931 { 932 bChanged = 0 == --pImp->m_nPrinterLocks; 933 } 934 935 if ( bChanged ) 936 { 937 Invalidate( SID_PRINTDOC ); 938 Invalidate( SID_PRINTDOCDIRECT ); 939 Invalidate( SID_SETUPPRINTER ); 940 } 941 } 942 943 //-------------------------------------------------------------------- 944 945 SfxPrinter* SfxViewShell::GetPrinter( sal_Bool /*bCreate*/ ) 946 { 947 return 0; 948 } 949 950 //-------------------------------------------------------------------- 951 952 sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, sal_uInt16 /*nDiffFlags*/, bool ) 953 { 954 return 0; 955 } 956 957 //-------------------------------------------------------------------- 958 959 SfxTabPage* SfxViewShell::CreatePrintOptionsPage 960 ( 961 Window* /*pParent*/, 962 const SfxItemSet& /*rOptions*/ 963 ) 964 { 965 return 0; 966 } 967 968 JobSetup SfxViewShell::GetJobSetup() const 969 { 970 return JobSetup(); 971 } 972 973