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