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