1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewprn.cxx,v $
10 * $Revision: 1.36.84.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <com/sun/star/document/XDocumentProperties.hpp>
35 #include <com/sun/star/document/XDocumentEventCompatibleHelper.hpp>
36 #include <com/sun/star/view/PrintableState.hpp>
37 #include <svtools/itempool.hxx>
38 #ifndef _MSGBOX_HXX //autogen
39 #include <vcl/msgbox.hxx>
41 #ifndef _SV_PRINTDLG_HXX //autogen
42 #include <svtools/printdlg.hxx>
44 #ifndef _SV_PRNSETUP_HXX //autogen
45 #include <svtools/prnsetup.hxx>
47 #include <svtools/flagitem.hxx>
48 #include <svtools/stritem.hxx>
49 #include <svtools/intitem.hxx>
50 #include <svtools/eitem.hxx>
51 #include <sfx2/app.hxx>
52 #include <svtools/useroptions.hxx>
53 #include <svtools/printwarningoptions.hxx>
54 #include <tools/datetime.hxx>
56 #include <sfx2/viewsh.hxx>
57 #include <sfx2/dispatch.hxx>
58 #include "viewimp.hxx"
59 #include <sfx2/viewfrm.hxx>
60 #include <sfx2/prnmon.hxx>
61 #include "sfxresid.hxx"
62 #include <sfx2/request.hxx>
63 #include <sfx2/objsh.hxx>
64 #include "sfxtypes.hxx"
65 #include <sfx2/event.hxx>
66 #include <sfx2/docfile.hxx>
67 #include <sfx2/docfilt.hxx>
72 using namespace com::sun::star
;
74 TYPEINIT1(SfxPrintingHint
, SfxHint
);
76 // -----------------------------------------------------------------------
78 void SfxAsyncPrintExec_Impl::AddRequest( SfxRequest
& rReq
)
82 // only queue API requests
84 StartListening( *pView
->GetObjectShell() );
86 aReqs
.push( new SfxRequest( rReq
) );
90 void SfxAsyncPrintExec_Impl::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
92 if ( &rBC
== pView
->GetObjectShell() )
94 SfxPrintingHint
* pPrintHint
= PTR_CAST( SfxPrintingHint
, &rHint
);
95 if ( pPrintHint
&& pPrintHint
->GetWhich() == com::sun::star::view::PrintableState_JOB_COMPLETED
)
97 while ( aReqs
.front() )
99 SfxRequest
* pReq
= aReqs
.front();
101 pView
->GetViewFrame()->GetDispatcher()->Execute( pReq
->GetSlot(), SFX_CALLMODE_ASYNCHRON
, *pReq
->GetArgs() );
102 USHORT nSlot
= pReq
->GetSlot();
104 if ( nSlot
== SID_PRINTDOC
|| nSlot
== SID_PRINTDOCDIRECT
)
105 // print jobs must be executed before the next command can be dispatched
110 EndListening( *pView
->GetObjectShell() );
115 void DisableRanges( PrintDialog
& rDlg
, SfxPrinter
* pPrinter
)
119 Mit dieser Funktion werden die nicht verf"ugbaren Ranges
120 vom Printer zum PrintDialog geforwarded.
127 if ( !pPrinter
->IsRangeEnabled( PRINTDIALOG_ALL
) )
128 rDlg
.DisableRange( PRINTDIALOG_ALL
);
129 if ( !pPrinter
->IsRangeEnabled( PRINTDIALOG_SELECTION
) )
130 rDlg
.DisableRange( PRINTDIALOG_SELECTION
);
131 if ( !pPrinter
->IsRangeEnabled( PRINTDIALOG_FROMTO
) )
132 rDlg
.DisableRange( PRINTDIALOG_FROMTO
);
133 if ( !pPrinter
->IsRangeEnabled( PRINTDIALOG_RANGE
) )
134 rDlg
.DisableRange( PRINTDIALOG_RANGE
);
137 //====================================================================
139 class SfxDialogExecutor_Impl
143 Eine Instanz dieser Klasse wird f"ur die Laufzeit des Printer-Dialogs
144 erzeugt, um im dessen Click-Handler f"ur die Zus"atze den per
145 virtueller Methode von der abgeleiteten SfxViewShell erzeugten
146 Print-Options-Dialog zu erzeugen und die dort eingestellten Optionen
147 als SfxItemSet zu zwischenzuspeichern.
152 SfxViewShell
* _pViewSh
;
153 PrintDialog
* _pPrintParent
;
154 PrinterSetupDialog
* _pSetupParent
;
155 SfxItemSet
* _pOptions
;
157 sal_Bool _bHelpDisabled
;
159 DECL_LINK( Execute
, void * );
162 SfxDialogExecutor_Impl( SfxViewShell
* pViewSh
, PrintDialog
* pParent
);
163 SfxDialogExecutor_Impl( SfxViewShell
* pViewSh
, PrinterSetupDialog
* pParent
);
164 ~SfxDialogExecutor_Impl() { delete _pOptions
; }
166 Link
GetLink() const { return LINK( this, SfxDialogExecutor_Impl
, Execute
); }
167 const SfxItemSet
* GetOptions() const { return _pOptions
; }
168 void DisableHelp() { _bHelpDisabled
= sal_True
; }
171 //--------------------------------------------------------------------
173 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell
* pViewSh
, PrintDialog
* pParent
) :
175 _pViewSh ( pViewSh
),
176 _pPrintParent ( pParent
),
177 _pSetupParent ( NULL
),
179 _bModified ( sal_False
),
180 _bHelpDisabled ( sal_False
)
185 SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell
* pViewSh
, PrinterSetupDialog
* pParent
) :
187 _pViewSh ( pViewSh
),
188 _pPrintParent ( NULL
),
189 _pSetupParent ( pParent
),
191 _bModified ( sal_False
),
192 _bHelpDisabled ( sal_False
)
197 //--------------------------------------------------------------------
199 IMPL_LINK( SfxDialogExecutor_Impl
, Execute
, void *, EMPTYARG
)
201 // Options lokal merken
204 DBG_ASSERT( _pPrintParent
|| _pSetupParent
, "no dialog parent" );
206 _pOptions
= ( (SfxPrinter
*)_pPrintParent
->GetPrinter() )->GetOptions().Clone();
207 else if( _pSetupParent
)
208 _pOptions
= ( (SfxPrinter
*)_pSetupParent
->GetPrinter() )->GetOptions().Clone();
211 if ( _pOptions
&& _pPrintParent
&& _pPrintParent
->IsSheetRangeAvailable() )
213 SfxItemState eState
= _pOptions
->GetItemState( SID_PRINT_SELECTEDSHEET
);
214 if ( eState
!= SFX_ITEM_UNKNOWN
)
216 PrintSheetRange eRange
= _pPrintParent
->GetCheckedSheetRange();
217 BOOL bValue
= ( PRINTSHEETS_ALL
!= eRange
);
218 _pOptions
->Put( SfxBoolItem( SID_PRINT_SELECTEDSHEET
, bValue
) );
223 SfxPrintOptionsDialog
* pDlg
= new SfxPrintOptionsDialog( _pPrintParent
? static_cast<Window
*>(_pPrintParent
)
224 : static_cast<Window
*>(_pSetupParent
),
225 _pViewSh
, _pOptions
);
226 if ( _bHelpDisabled
)
228 if ( pDlg
->Execute() == RET_OK
)
231 _pOptions
= pDlg
->GetOptions().Clone();
233 if ( _pOptions
&& _pPrintParent
&& _pPrintParent
->IsSheetRangeAvailable() )
235 const SfxPoolItem
* pItem
;
236 if ( SFX_ITEM_SET
== _pOptions
->GetItemState( SID_PRINT_SELECTEDSHEET
, FALSE
, &pItem
) )
238 _pPrintParent
->CheckSheetRange( ( (const SfxBoolItem
*)pItem
)->GetValue()
239 ? PRINTSHEETS_SELECTED_SHEETS
: PRINTSHEETS_ALL
);
248 //-------------------------------------------------------------------------
250 BOOL
UseStandardPrinter_Impl( Window
* /*pParent*/, SfxPrinter
* pDocPrinter
)
252 // Optionen abfragen, ob gewarnt werden soll (Doc uebersteuert App)
254 const SfxItemSet
*pDocOptions
= &pDocPrinter
->GetOptions();
257 USHORT nWhich
= pDocOptions
->GetPool()->GetWhich(SID_PRINTER_NOTFOUND_WARN
);
258 const SfxBoolItem
* pBoolItem
= NULL
;
259 pDocPrinter
->GetOptions().GetItemState( nWhich
, FALSE
, (const SfxPoolItem
**) &pBoolItem
);
261 bWarn
= pBoolItem
->GetValue();
264 // ggf. den User fragen
267 // Geht nicht mehr ohne OrigJobSetup!
268 String aTmp( SfxResId( STR_PRINTER_NOTAVAIL ) );
269 QueryBox aBox( pParent, WB_OK_CANCEL | WB_DEF_OK, aTmp );
270 return RET_OK == aBox.Execute();
273 // nicht gewarnt => einfach so den StandardDrucker nehmen
276 //-------------------------------------------------------------------------
278 SfxPrinter
* SfxViewShell::SetPrinter_Impl( SfxPrinter
*pNewPrinter
)
280 /* Interne Methode zum Setzen der Unterschiede von 'pNewPrinter' zum
281 aktuellen Printer. pNewPrinter wird entweder "ubernommen oder gel"oscht.
285 // aktuellen Printer holen
286 SfxPrinter
*pDocPrinter
= GetPrinter();
288 // Printer-Options auswerten
289 FASTBOOL bOriToDoc
= FALSE
;
290 FASTBOOL bSizeToDoc
= FALSE
;
291 if ( &pDocPrinter
->GetOptions() )
293 USHORT nWhich
= GetPool().GetWhich(SID_PRINTER_CHANGESTODOC
);
294 const SfxFlagItem
*pFlagItem
= 0;
295 pDocPrinter
->GetOptions().GetItemState( nWhich
, FALSE
, (const SfxPoolItem
**) &pFlagItem
);
296 bOriToDoc
= pFlagItem
? (pFlagItem
->GetValue() & SFX_PRINTER_CHG_ORIENTATION
) : FALSE
;
297 bSizeToDoc
= pFlagItem
? (pFlagItem
->GetValue() & SFX_PRINTER_CHG_SIZE
) : FALSE
;
300 // vorheriges Format und Size feststellen
301 Orientation eOldOri
= pDocPrinter
->GetOrientation();
302 Size aOldPgSz
= pDocPrinter
->GetPaperSizePixel();
304 // neues Format und Size feststellen
305 Orientation eNewOri
= pNewPrinter
->GetOrientation();
306 Size aNewPgSz
= pNewPrinter
->GetPaperSizePixel();
308 // "Anderungen am Seitenformat feststellen
309 BOOL bOriChg
= (eOldOri
!= eNewOri
) && bOriToDoc
;
310 BOOL bPgSzChg
= ( aOldPgSz
.Height() !=
311 ( bOriChg
? aNewPgSz
.Width() : aNewPgSz
.Height() ) ||
313 ( bOriChg
? aNewPgSz
.Height() : aNewPgSz
.Width() ) ) &&
316 // Message und Flags f"ur Seitenformat-"Anderung zusammenstellen
319 if( bOriChg
&& bPgSzChg
)
321 aMsg
= String(SfxResId(STR_PRINT_NEWORISIZE
));
322 nNewOpt
= SFX_PRINTER_CHG_ORIENTATION
| SFX_PRINTER_CHG_SIZE
;
326 aMsg
= String(SfxResId(STR_PRINT_NEWORI
));
327 nNewOpt
= SFX_PRINTER_CHG_ORIENTATION
;
331 aMsg
= String(SfxResId(STR_PRINT_NEWSIZE
));
332 nNewOpt
= SFX_PRINTER_CHG_SIZE
;
335 // in dieser Variable sammeln, was sich so ge"aendert hat
336 USHORT nChangedFlags
= 0;
338 // ggf. Nachfrage, ob Seitenformat vom Drucker "ubernommen werden soll
339 if ( ( bOriChg
|| bPgSzChg
) &&
340 RET_YES
== QueryBox(0, WB_YES_NO
| WB_DEF_OK
, aMsg
).Execute() )
341 // Flags mit "Anderungen f"ur <SetPrinter(SfxPrinter*)> mitpflegen
342 nChangedFlags
|= nNewOpt
;
344 // fuer den MAC sein "temporary of class String" im naechsten if()
345 String aTempPrtName
= pNewPrinter
->GetName();
346 String aDocPrtName
= pDocPrinter
->GetName();
348 // Wurde der Drucker gewechselt oder von Default auf Specific
349 // oder umgekehrt geaendert?
350 if ( (aTempPrtName
!= aDocPrtName
) || (pDocPrinter
->IsDefPrinter() != pNewPrinter
->IsDefPrinter()) )
352 // neuen Printer "ubernehmen
353 // pNewPrinter->SetOrigJobSetup( pNewPrinter->GetJobSetup() );
354 nChangedFlags
|= SFX_PRINTER_PRINTER
|SFX_PRINTER_JOBSETUP
;
355 pDocPrinter
= pNewPrinter
;
359 // Extra-Optionen vergleichen
360 if ( ! (pNewPrinter
->GetOptions() == pDocPrinter
->GetOptions()) )
362 // Options haben sich geaendert
363 pDocPrinter
->SetOptions( pNewPrinter
->GetOptions() );
364 nChangedFlags
|= SFX_PRINTER_OPTIONS
;
367 // JobSetups vergleichen
368 JobSetup aNewJobSetup
= pNewPrinter
->GetJobSetup();
369 JobSetup aOldJobSetup
= pDocPrinter
->GetJobSetup();
370 if ( aNewJobSetup
!= aOldJobSetup
)
372 // JobSetup hat sich geaendert (=> App mu\s neu formatieren)
373 // pDocPrinter->SetOrigJobSetup( aNewJobSetup );
374 nChangedFlags
|= SFX_PRINTER_JOBSETUP
;
377 // alten, ver"anderten Printer behalten
378 pDocPrinter
->SetPrinterProps( pNewPrinter
);
382 if ( 0 != nChangedFlags
)
383 // SetPrinter will delete the old printer if it changes
384 SetPrinter( pDocPrinter
, nChangedFlags
);
388 //-------------------------------------------------------------------------
389 // Unter WIN32 tritt leider das Problem auf, dass nichts gedruckt
390 // wird, wenn SID_PRINTDOCDIRECT auflaueft; bisher bekannte,
391 // einzige Abhilfe ist in diesem Fall das Abschalten der Optimierungen
394 #pragma optimize ( "", off )
397 class SfxPrintGuard_Impl
399 SfxObjectShell
* m_pObjectShell
;
400 sal_Bool m_bOrigStatus
;
401 sal_Bool m_bNeedsChange
;
404 SfxPrintGuard_Impl( SfxObjectShell
* pObjectShell
)
405 : m_pObjectShell( pObjectShell
)
406 , m_bOrigStatus( sal_False
)
407 , m_bNeedsChange( sal_False
)
409 if ( m_pObjectShell
)
411 m_bOrigStatus
= m_pObjectShell
->IsEnableSetModified();
413 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
414 if ( m_bOrigStatus
&& !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() )
416 m_pObjectShell
->EnableSetModified( sal_False
);
417 m_bNeedsChange
= sal_True
;
422 ~SfxPrintGuard_Impl()
424 if ( m_pObjectShell
&& m_bNeedsChange
)
425 m_pObjectShell
->EnableSetModified( m_bOrigStatus
);
429 void SfxViewShell::ExecPrint_Impl( SfxRequest
&rReq
)
432 USHORT nDialogRet
= RET_CANCEL
;
434 SfxPrinter
* pPrinter
= 0;
435 PrintDialog
* pPrintDlg
= 0;
436 SfxDialogExecutor_Impl
* pExecutor
= 0;
437 bool bSilent
= false;
438 BOOL bIsAPI
= rReq
.GetArgs() && rReq
.GetArgs()->Count();
440 if ( bIsAPI
&& GetPrinter( FALSE
) && GetPrinter( FALSE
)->IsPrinting() )
442 pImp
->pPrinterCommandQueue
->AddRequest( rReq
);
446 const USHORT nId
= rReq
.GetSlot();
449 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
452 case SID_SETUPPRINTER
:
453 case SID_PRINTER_NAME
:
455 if( nId
== SID_PRINTDOC
)
457 SfxObjectShell
* pDoc
= GetObjectShell();
460 uno::Reference
< document::XDocumentEventCompatibleHelper
> xVbaEventHelper( pDoc
->GetModel(), uno::UNO_QUERY
);
461 if( xVbaEventHelper
.is() )
463 if( xVbaEventHelper
->processCompatibleEvent( nId
) )
465 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
471 // quiet mode (AppEvent, API call)
472 SFX_REQUEST_ARG(rReq
, pSilentItem
, SfxBoolItem
, SID_SILENT
, FALSE
);
473 bSilent
= pSilentItem
&& pSilentItem
->GetValue();
475 // get printer and printer settings from the document
476 SfxPrinter
*pDocPrinter
= GetPrinter(TRUE
);
478 // look for printer in parameters
479 SFX_REQUEST_ARG( rReq
, pPrinterItem
, SfxStringItem
, SID_PRINTER_NAME
, FALSE
);
482 // use PrinterName parameter to create a printer
483 pPrinter
= new SfxPrinter( pDocPrinter
->GetOptions().Clone(), ((const SfxStringItem
*) pPrinterItem
)->GetValue() );
485 // if printer is unknown, it can't be used - now printer from document will be used
486 if ( !pPrinter
->IsOriginal() )
490 if ( SID_PRINTER_NAME
== nId
)
492 // just set a recorded printer name
494 SetPrinter( pPrinter
, SFX_PRINTER_PRINTER
);
498 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
500 // use default printer from document
501 pPrinter
= pDocPrinter
;
503 if( !pPrinter
|| !pPrinter
->IsValid() )
505 // no valid printer either in ItemSet or at the document
508 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
512 ErrorBox( NULL
, WB_OK
| WB_DEF_OK
, String( SfxResId( STR_NODEFPRINTER
) ) ).Execute();
515 if ( !pPrinter
->IsOriginal() && rReq
.GetArgs() && !UseStandardPrinter_Impl( NULL
, pPrinter
) )
517 // printer is not available, but standard printer should not be used
518 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
522 if( pPrinter
->IsPrinting() )
524 // if printer is busy, abort printing
526 InfoBox( NULL
, String( SfxResId( STR_ERROR_PRINTER_BUSY
) ) ).Execute();
527 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
531 // the print dialog shouldn't use a help button if it is called from the help window
532 // (pressing help button would exchange the current page inside the help document that is going to be printed!)
533 String
aHelpFilterName( DEFINE_CONST_UNICODE("writer_web_HTML_help") );
534 SfxMedium
* pMedium
= GetViewFrame()->GetObjectShell()->GetMedium();
535 const SfxFilter
* pFilter
= pMedium
? pMedium
->GetFilter() : NULL
;
536 sal_Bool bPrintOnHelp
= ( pFilter
&& pFilter
->GetFilterName() == aHelpFilterName
);
538 SfxObjectShell
* pDoc
= NULL
;
539 if ( SID_PRINTDOC
== nId
)
540 pDoc
= GetObjectShell();
542 // Let the document stay nonmodified during the printing if the configuration says to do so
543 SfxPrintGuard_Impl
aGuard( pDoc
);
545 // if no arguments are given, retrieve them from a dialog
548 // PrinterDialog needs a temporary printer
549 SfxPrinter
* pDlgPrinter
= pPrinter
->Clone();
551 if ( SID_PRINTDOC
== nId
)
553 bool bDetectHidden
= ( !bSilent
&& !bPrintOnHelp
&& pDoc
);
555 || pDoc
->QueryHiddenInformation( WhenPrinting
, NULL
) == RET_YES
)
557 // execute PrintDialog
558 pPrintDlg
= CreatePrintDialog( NULL
);
560 pPrintDlg
->DisableHelp();
562 if ( pImp
->bHasPrintOptions
)
564 // additional controls for dialog
565 pExecutor
= new SfxDialogExecutor_Impl( this, pPrintDlg
);
567 pExecutor
->DisableHelp();
568 pPrintDlg
->SetOptionsHdl( pExecutor
->GetLink() );
569 pPrintDlg
->ShowOptionsButton();
572 // set printer on dialog and execute
573 pPrintDlg
->SetPrinter( pDlgPrinter
);
574 ::DisableRanges( *pPrintDlg
, pDlgPrinter
);
575 nDialogRet
= pPrintDlg
->Execute();
576 if ( pExecutor
&& pExecutor
->GetOptions() )
578 if ( nDialogRet
== RET_OK
)
579 // remark: have to be recorded if possible!
580 pDlgPrinter
->SetOptions( *pExecutor
->GetOptions() );
583 pPrinter
->SetOptions( *pExecutor
->GetOptions() );
584 SetPrinter( pPrinter
, SFX_PRINTER_OPTIONS
);
588 DELETEZ( pExecutor
);
593 // execute PrinterSetupDialog
594 PrinterSetupDialog
* pPrintSetupDlg
= new PrinterSetupDialog( GetWindow() );
596 if ( pImp
->bHasPrintOptions
)
598 // additional controls for dialog
599 pExecutor
= new SfxDialogExecutor_Impl( this, pPrintSetupDlg
);
601 pExecutor
->DisableHelp();
602 pPrintSetupDlg
->SetOptionsHdl( pExecutor
->GetLink() );
605 pPrintSetupDlg
->SetPrinter( pDlgPrinter
);
606 nDialogRet
= pPrintSetupDlg
->Execute();
608 if ( pExecutor
&& pExecutor
->GetOptions() )
610 if ( nDialogRet
== RET_OK
)
611 // remark: have to be recorded if possible!
612 pDlgPrinter
->SetOptions( *pExecutor
->GetOptions() );
615 pPrinter
->SetOptions( *pExecutor
->GetOptions() );
616 SetPrinter( pPrinter
, SFX_PRINTER_OPTIONS
);
620 DELETEZ( pPrintSetupDlg
);
622 // no recording of PrinterSetup except printer name (is printer dependent)
626 if ( nDialogRet
== RET_OK
)
628 if ( pPrinter
->GetName() != pDlgPrinter
->GetName() )
630 // user has changed the printer -> macro recording
631 SfxRequest
aReq( GetViewFrame(), SID_PRINTER_NAME
);
632 aReq
.AppendItem( SfxStringItem( SID_PRINTER_NAME
, pDlgPrinter
->GetName() ) );
636 // take the changes made in the dialog
637 pPrinter
= SetPrinter_Impl( pDlgPrinter
);
639 // forget new printer, it was taken over (as pPrinter) or deleted
642 /* Now lets reset the Dialog printer, since its freed */
644 pPrintDlg
->SetPrinter (pPrinter
);
646 if ( SID_PRINTDOC
== nId
)
648 nCopies
= pPrintDlg
->GetCopyCount();
649 bCollate
= pPrintDlg
->IsCollateChecked();
656 // PrinterDialog is used to transfer information on printing,
657 // so it will only be deleted here if dialog was cancelled
658 DELETEZ( pDlgPrinter
);
659 DELETEZ( pPrintDlg
);
661 if ( SID_PRINTDOC
== nId
)
662 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
667 rReq
.AppendItem( SfxBoolItem( SID_PRINT_COLLATE
, bCollate
) );
668 rReq
.AppendItem( SfxInt16Item( SID_PRINT_COPIES
, (INT16
) pPrintDlg
->GetCopyCount() ) );
669 if ( pPrinter
->IsPrintFileEnabled() )
670 rReq
.AppendItem( SfxStringItem( SID_FILE_NAME
, pPrinter
->GetPrintFile() ) );
671 if ( pPrintDlg
->IsRangeChecked(PRINTDIALOG_SELECTION
) )
672 rReq
.AppendItem( SfxBoolItem( SID_SELECTION
, TRUE
) );
673 else if ( pPrintDlg
->IsRangeChecked(PRINTDIALOG_RANGE
) )
674 rReq
.AppendItem( SfxStringItem( SID_PRINT_PAGES
, pPrintDlg
->GetRangeText() ) );
675 else if ( pPrintDlg
->IsRangeChecked(PRINTDIALOG_FROMTO
) )
677 // currently this doesn't seem to work -> return values of dialog are always 0
678 // seems to be encoded as range string like "1-3"
679 rReq
.AppendItem( SfxInt16Item( SID_PRINT_FIRST_PAGE
, (INT16
) pPrintDlg
->GetFirstPage() ) );
680 rReq
.AppendItem( SfxInt16Item( SID_PRINT_LAST_PAGE
, (INT16
) pPrintDlg
->GetLastPage() ) );
683 else if ( rReq
.GetArgs() )
685 if ( SID_PRINTDOC
!= nId
)
687 DBG_ERROR("Wrong slotid!");
691 // PrinterDialog is used to transfer information on printing
692 pPrintDlg
= CreatePrintDialog( GetWindow() );
694 pPrintDlg
->DisableHelp();
695 pPrintDlg
->SetPrinter( pPrinter
);
696 ::DisableRanges( *pPrintDlg
, pPrinter
);
698 // PrintToFile requested?
699 SFX_REQUEST_ARG(rReq
, pFileItem
, SfxStringItem
, SID_FILE_NAME
, FALSE
);
702 pPrinter
->EnablePrintFile(TRUE
);
703 pPrinter
->SetPrintFile( pFileItem
->GetValue() );
707 SFX_REQUEST_ARG(rReq
, pCollateItem
, SfxBoolItem
, SID_PRINT_COLLATE
, FALSE
);
710 bCollate
= pCollateItem
->GetValue();
711 pPrintDlg
->CheckCollate( bCollate
);
715 SFX_REQUEST_ARG(rReq
, pSelectItem
, SfxBoolItem
, SID_SELECTION
, FALSE
);
718 SFX_REQUEST_ARG(rReq
, pPagesItem
, SfxStringItem
, SID_PRINT_PAGES
, FALSE
);
721 SFX_REQUEST_ARG(rReq
, pFirstPgItem
, SfxInt16Item
, SID_PRINT_FIRST_PAGE
, FALSE
);
724 nFrom
= pFirstPgItem
->GetValue();
727 SFX_REQUEST_ARG(rReq
, pLastPgItem
, SfxInt16Item
, SID_PRINT_LAST_PAGE
, FALSE
);
730 nTo
= pLastPgItem
->GetValue();
733 SFX_REQUEST_ARG(rReq
, pCopyItem
, SfxInt16Item
, SID_PRINT_COPIES
, FALSE
);
736 nCopies
= pCopyItem
->GetValue();
737 pPrintDlg
->SetCopyCount( nCopies
);
740 // does the view support ranges?
741 if ( pSelectItem
&& pSelectItem
->GetValue() )
743 // print selection only
744 pPrintDlg
->CheckRange(PRINTDIALOG_SELECTION
);
746 else if ( pPagesItem
)
748 // get range text from parameter
750 pPrintDlg
->CheckRange(PRINTDIALOG_RANGE
);
751 pPrintDlg
->SetRangeText( pPagesItem
->GetValue() );
753 else if ( pPrintDlg
->IsRangeEnabled(PRINTDIALOG_RANGE
) )
756 // construct range text from page range
757 pPrintDlg
->CheckRange(PRINTDIALOG_RANGE
);
758 String aRange
= String::CreateFromInt32( nFrom
);
760 aRange
+= String::CreateFromInt32( nTo
);
761 pPrintDlg
->SetRangeText( aRange
);
766 pPrintDlg
->CheckRange(PRINTDIALOG_FROMTO
);
767 pPrintDlg
->SetFirstPage( nFrom
);
768 pPrintDlg
->SetLastPage( nTo
);
772 // intentionally no break for SID_PRINTDOC
773 // printing now proceeds like SID_PRINTDOCDIRECT
776 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
778 case SID_PRINTDOCDIRECT
:
780 if ( SID_PRINTDOCDIRECT
== nId
)
782 SfxObjectShell
* pDoc
= GetObjectShell();
783 uno::Reference
< document::XDocumentEventCompatibleHelper
> xVbaEventHelper( pDoc
->GetModel(), uno::UNO_QUERY
);
784 if( xVbaEventHelper
.is() )
786 if( xVbaEventHelper
->processCompatibleEvent( nId
) )
788 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
792 bool bDetectHidden
= ( !bSilent
&& pDoc
);
793 if ( bDetectHidden
&& pDoc
->QueryHiddenInformation( WhenPrinting
, NULL
) != RET_YES
)
796 // if no printer was selected before
798 pPrinter
= GetPrinter(TRUE
);
800 if( !pPrinter
->IsValid() )
802 // redirect slot to call the print dialog if the document's printer is not valid!
803 rReq
.SetSlot( SID_PRINTDOC
);
804 ExecPrint_Impl( rReq
);
808 if( pPrinter
->IsOriginal() && pPrinter
->GetName() != Printer::GetDefaultPrinterName() )
810 // redirect slot to call the print dialog
811 // if the document's printer is available but not system default
812 rReq
.SetSlot( SID_PRINTDOC
);
813 ExecPrint_Impl( rReq
);
817 pPrinter
->SetNextJobIsQuick();
820 // if "Collate" was checked, the SfxPrinter must handle the CopyCount itself,
821 // usually this is handled by the printer driver
823 // set printer to default, handle multiple copies explicitly
824 pPrinter
->SetCopyCount( 1 );
826 pPrinter
->SetCopyCount( nCopies
);
828 // enable background printing
829 pPrinter
->SetPageQueueSize( 1 );
831 // refresh document info
832 using namespace ::com::sun::star
;
833 SfxObjectShell
*pObjSh
= GetObjectShell();
834 uno::Reference
<document::XDocumentProperties
> xDocProps(
835 pObjSh
->getDocProperties());
836 ::rtl::OUString aLastPrintedBy
= xDocProps
->getPrintedBy();
837 util::DateTime aLastPrinted
= xDocProps
->getPrintDate();
839 // Let the document stay nonmodified during the printing if the configuration says to do so
840 SfxPrintGuard_Impl
aGuard( pObjSh
);
842 xDocProps
->setPrintedBy( GetObjectShell()->IsUseUserData()
843 ? ::rtl::OUString( SvtUserOptions().GetFullName() )
844 : ::rtl::OUString() );
846 xDocProps
->setPrintDate( util::DateTime(
847 now
.Get100Sec(), now
.GetSec(), now
.GetMin(), now
.GetHour(),
848 now
.GetDay(), now
.GetMonth(), now
.GetYear() ) );
850 GetObjectShell()->Broadcast( SfxPrintingHint( -1, pPrintDlg
, pPrinter
) );
851 ErrCode nError
= DoPrint( pPrinter
, pPrintDlg
, bSilent
, bIsAPI
);
852 if ( nError
== PRINTER_OK
)
854 Invalidate( SID_PRINTDOC
);
855 Invalidate( SID_PRINTDOCDIRECT
);
856 Invalidate( SID_SETUPPRINTER
);
857 rReq
.SetReturnValue(SfxBoolItem(0,TRUE
));
859 SFX_REQUEST_ARG(rReq
, pAsyncItem
, SfxBoolItem
, SID_ASYNCHRON
, FALSE
);
860 if ( pAsyncItem
&& !pAsyncItem
->GetValue() )
862 // synchronous execution wanted - wait for end of printing
863 while ( pPrinter
->IsPrinting())
864 Application::Yield();
871 // printing not succesful, reset DocInfo
872 xDocProps
->setPrintedBy(aLastPrintedBy
);
873 xDocProps
->setPrintDate(aLastPrinted
);
875 if ( nError
!= PRINTER_ABORT
)
877 // "real" problem (not simply printing cancelled by user)
878 String
aMsg( SfxResId( STR_NOSTARTPRINTER
) );
880 ErrorBox( NULL
, WB_OK
| WB_DEF_OK
, aMsg
).Execute();
881 rReq
.SetReturnValue(SfxBoolItem(0,FALSE
));
887 pPrinter
->SetNextJobIsQuick( false );
895 // Optimierungen wieder einschalten
897 #pragma optimize ( "", on )
900 //--------------------------------------------------------------------
902 PrintDialog
* SfxViewShell::CreatePrintDialog( Window
* pParent
)
906 Diese Methode kann "uberladen werden, um einen speziellen PrintDialog
907 zu erzeugen. Dies ist z.B. notwendig wenn spezielle <StarView> Features
908 wie drucken von Seitenbereichen.
912 PrintDialog
*pDlg
= new PrintDialog( pParent
, false );
913 pDlg
->SetFirstPage( 1 );
914 pDlg
->SetLastPage( 9999 );
915 pDlg
->EnableCollate();
919 //--------------------------------------------------------------------
921 void SfxViewShell::PreparePrint( PrintDialog
* )
925 //--------------------------------------------------------------------
928 ErrCode
SfxViewShell::DoPrint( SfxPrinter
*pPrinter
,
929 PrintDialog
*pPrintDlg
,
930 BOOL bSilent
, BOOL bIsAPI
)
932 // Printer-Dialogbox waehrend des Ausdrucks mu\s schon vor
933 // StartJob erzeugt werden, da SV bei einem Quit-Event h"angt
934 SfxPrintProgress
*pProgress
= new SfxPrintProgress( this, !bSilent
);
935 SfxPrinter
*pDocPrinter
= GetPrinter(TRUE
);
937 pPrinter
= pDocPrinter
;
938 else if ( pDocPrinter
!= pPrinter
)
940 pProgress
->RestoreOnEndPrint( pDocPrinter
->Clone() );
941 USHORT nError
= SetPrinter( pPrinter
, SFX_PRINTER_PRINTER
);
942 if ( nError
!= SFX_PRINTERROR_NONE
)
943 return PRINTER_ACCESSDENIED
;
946 pProgress
->SetWaitMode(FALSE
);
949 PreparePrint( pPrintDlg
);
950 SfxObjectShell
*pObjShell
= GetViewFrame()->GetObjectShell();
951 if ( pPrinter
->StartJob(pObjShell
->GetTitle(0)) )
954 Print( *pProgress
, bIsAPI
, pPrintDlg
);
956 pProgress
->DeleteOnEndPrint();
961 // Printer konnte nicht gestartet werden
965 return pPrinter
->GetError();
968 //--------------------------------------------------------------------
970 BOOL
SfxViewShell::IsPrinterLocked() const
972 return pImp
->nPrinterLocks
> 0;
975 //--------------------------------------------------------------------
977 void SfxViewShell::LockPrinter( BOOL bLock
)
979 BOOL bChanged
= FALSE
;
981 bChanged
= 1 == ++pImp
->nPrinterLocks
;
983 bChanged
= 0 == --pImp
->nPrinterLocks
;
987 Invalidate( SID_PRINTDOC
);
988 Invalidate( SID_PRINTDOCDIRECT
);
989 Invalidate( SID_SETUPPRINTER
);
993 //--------------------------------------------------------------------
995 USHORT
SfxViewShell::Print( SfxProgress
& /*rProgress*/, BOOL
/*bIsAPI*/, PrintDialog
* /*pDlg*/ )
1000 //--------------------------------------------------------------------
1002 SfxPrinter
* SfxViewShell::GetPrinter( BOOL
/*bCreate*/ )
1007 //--------------------------------------------------------------------
1009 USHORT
SfxViewShell::SetPrinter( SfxPrinter
* /*pNewPrinter*/, USHORT
/*nDiffFlags*/, bool )
1014 //--------------------------------------------------------------------
1016 SfxTabPage
* SfxViewShell::CreatePrintOptionsPage
1018 Window
* /*pParent*/,
1019 const SfxItemSet
& /*rOptions*/
1024 Diese Factory-Methode wird vom SFx verwendet, um die TabPage mit den
1025 Print-Optionen, welche "uber das <SfxItemSet> am <SfxPrinter>
1026 transportiert werden, zu erzeugen.
1028 Abgeleitete Klassen k"onnen diese Methode also "uberladen um die zu
1029 ihren SfxPrinter passenden Einstellungen vorzunehmen. Dieses sollte
1030 genau die <SfxTabPage> sein, die auch unter Extras/Einstellungen
1033 Die Basisimplementierung liefert einen 0-Pointer.