xref: /AOO41X/main/sfx2/source/view/viewprn.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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 nonexistant 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 succesful, 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