xref: /aoo42x/main/sfx2/source/view/viewprn.cxx (revision cdf0e10c)
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