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