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