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