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