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