merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / view / viewprn.cxx
blobd992f57c70308a2d903aa98a11d99216702a04e3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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>
40 #endif
41 #ifndef _SV_PRINTDLG_HXX //autogen
42 #include <svtools/printdlg.hxx>
43 #endif
44 #ifndef _SV_PRNSETUP_HXX //autogen
45 #include <svtools/prnsetup.hxx>
46 #endif
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>
69 #include "view.hrc"
70 #include "helpid.hrc"
72 using namespace com::sun::star;
74 TYPEINIT1(SfxPrintingHint, SfxHint);
76 // -----------------------------------------------------------------------
78 void SfxAsyncPrintExec_Impl::AddRequest( SfxRequest& rReq )
80 if ( rReq.GetArgs() )
82 // only queue API requests
83 if ( aReqs.empty() )
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();
100 aReqs.pop();
101 pView->GetViewFrame()->GetDispatcher()->Execute( pReq->GetSlot(), SFX_CALLMODE_ASYNCHRON, *pReq->GetArgs() );
102 USHORT nSlot = pReq->GetSlot();
103 delete pReq;
104 if ( nSlot == SID_PRINTDOC || nSlot == SID_PRINTDOCDIRECT )
105 // print jobs must be executed before the next command can be dispatched
106 break;
109 if ( aReqs.empty() )
110 EndListening( *pView->GetObjectShell() );
115 void DisableRanges( PrintDialog& rDlg, SfxPrinter* pPrinter )
117 /* [Beschreibung]
119 Mit dieser Funktion werden die nicht verf"ugbaren Ranges
120 vom Printer zum PrintDialog geforwarded.
124 if ( !pPrinter )
125 return;
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
141 /* [Beschreibung]
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.
151 private:
152 SfxViewShell* _pViewSh;
153 PrintDialog* _pPrintParent;
154 PrinterSetupDialog* _pSetupParent;
155 SfxItemSet* _pOptions;
156 sal_Bool _bModified;
157 sal_Bool _bHelpDisabled;
159 DECL_LINK( Execute, void * );
161 public:
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 ),
178 _pOptions ( 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 ),
190 _pOptions ( NULL ),
191 _bModified ( sal_False ),
192 _bHelpDisabled ( sal_False )
197 //--------------------------------------------------------------------
199 IMPL_LINK( SfxDialogExecutor_Impl, Execute, void *, EMPTYARG )
201 // Options lokal merken
202 if ( !_pOptions )
204 DBG_ASSERT( _pPrintParent || _pSetupParent, "no dialog parent" );
205 if( _pPrintParent )
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 ) );
222 // Dialog ausf"uhren
223 SfxPrintOptionsDialog* pDlg = new SfxPrintOptionsDialog( _pPrintParent ? static_cast<Window*>(_pPrintParent)
224 : static_cast<Window*>(_pSetupParent),
225 _pViewSh, _pOptions );
226 if ( _bHelpDisabled )
227 pDlg->DisableHelp();
228 if ( pDlg->Execute() == RET_OK )
230 delete _pOptions;
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 );
243 delete pDlg;
245 return 0;
248 //-------------------------------------------------------------------------
250 BOOL UseStandardPrinter_Impl( Window* /*pParent*/, SfxPrinter* pDocPrinter )
252 // Optionen abfragen, ob gewarnt werden soll (Doc uebersteuert App)
253 BOOL bWarn = FALSE;
254 const SfxItemSet *pDocOptions = &pDocPrinter->GetOptions();
255 if ( pDocOptions )
257 USHORT nWhich = pDocOptions->GetPool()->GetWhich(SID_PRINTER_NOTFOUND_WARN);
258 const SfxBoolItem* pBoolItem = NULL;
259 pDocPrinter->GetOptions().GetItemState( nWhich, FALSE, (const SfxPoolItem**) &pBoolItem );
260 if ( pBoolItem )
261 bWarn = pBoolItem->GetValue();
264 // ggf. den User fragen
265 if ( bWarn )
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
274 return TRUE;
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() ) ||
312 aOldPgSz.Width() !=
313 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
314 bSizeToDoc;
316 // Message und Flags f"ur Seitenformat-"Anderung zusammenstellen
317 String aMsg;
318 USHORT nNewOpt=0;
319 if( bOriChg && bPgSzChg )
321 aMsg = String(SfxResId(STR_PRINT_NEWORISIZE));
322 nNewOpt = SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE;
324 else if (bOriChg )
326 aMsg = String(SfxResId(STR_PRINT_NEWORI));
327 nNewOpt = SFX_PRINTER_CHG_ORIENTATION;
329 else if (bPgSzChg)
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;
357 else
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 );
379 delete pNewPrinter;
382 if ( 0 != nChangedFlags )
383 // SetPrinter will delete the old printer if it changes
384 SetPrinter( pDocPrinter, nChangedFlags );
385 return pDocPrinter;
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
392 // (KA 17.12.95)
393 #ifdef _MSC_VER
394 #pragma optimize ( "", off )
395 #endif
397 class SfxPrintGuard_Impl
399 SfxObjectShell* m_pObjectShell;
400 sal_Bool m_bOrigStatus;
401 sal_Bool m_bNeedsChange;
403 public:
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 )
431 USHORT nCopies=1;
432 USHORT nDialogRet = RET_CANCEL;
433 BOOL bCollate=TRUE;
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 );
443 return;
446 const USHORT nId = rReq.GetSlot();
447 switch( nId )
449 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
451 case SID_PRINTDOC:
452 case SID_SETUPPRINTER:
453 case SID_PRINTER_NAME :
455 if( nId == SID_PRINTDOC )
457 SfxObjectShell* pDoc = GetObjectShell();
458 if( pDoc )
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));
466 return;
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 );
480 if ( pPrinterItem )
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() )
487 DELETEZ(pPrinter);
490 if ( SID_PRINTER_NAME == nId )
492 // just set a recorded printer name
493 if ( pPrinter )
494 SetPrinter( pPrinter, SFX_PRINTER_PRINTER );
495 return;
498 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
499 if ( !pPrinter )
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
506 if ( bSilent )
508 rReq.SetReturnValue(SfxBoolItem(0,FALSE));
509 return;
511 else
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));
519 return;
522 if( pPrinter->IsPrinting() )
524 // if printer is busy, abort printing
525 if ( !bSilent )
526 InfoBox( NULL, String( SfxResId( STR_ERROR_PRINTER_BUSY ) ) ).Execute();
527 rReq.SetReturnValue(SfxBoolItem(0,FALSE));
528 return;
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
546 if ( !bIsAPI )
548 // PrinterDialog needs a temporary printer
549 SfxPrinter* pDlgPrinter = pPrinter->Clone();
550 nDialogRet = 0;
551 if ( SID_PRINTDOC == nId )
553 bool bDetectHidden = ( !bSilent && !bPrintOnHelp && pDoc );
554 if ( !bDetectHidden
555 || pDoc->QueryHiddenInformation( WhenPrinting, NULL ) == RET_YES )
557 // execute PrintDialog
558 pPrintDlg = CreatePrintDialog( NULL );
559 if ( bPrintOnHelp )
560 pPrintDlg->DisableHelp();
562 if ( pImp->bHasPrintOptions )
564 // additional controls for dialog
565 pExecutor = new SfxDialogExecutor_Impl( this, pPrintDlg );
566 if ( bPrintOnHelp )
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() );
581 else
583 pPrinter->SetOptions( *pExecutor->GetOptions() );
584 SetPrinter( pPrinter, SFX_PRINTER_OPTIONS );
588 DELETEZ( pExecutor );
591 else
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 );
600 if ( bPrintOnHelp )
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() );
613 else
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)
623 rReq.Ignore();
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() ) );
633 aReq.Done();
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
640 pDlgPrinter = NULL;
642 /* Now lets reset the Dialog printer, since its freed */
643 if (pPrintDlg)
644 pPrintDlg->SetPrinter (pPrinter);
646 if ( SID_PRINTDOC == nId )
648 nCopies = pPrintDlg->GetCopyCount();
649 bCollate = pPrintDlg->IsCollateChecked();
651 else
652 break;
654 else
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 );
660 rReq.Ignore();
661 if ( SID_PRINTDOC == nId )
662 rReq.SetReturnValue(SfxBoolItem(0,FALSE));
663 break;
666 // recording
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!");
688 break;
691 // PrinterDialog is used to transfer information on printing
692 pPrintDlg = CreatePrintDialog( GetWindow() );
693 if ( bPrintOnHelp )
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);
700 if ( pFileItem )
702 pPrinter->EnablePrintFile(TRUE);
703 pPrinter->SetPrintFile( pFileItem->GetValue() );
706 // Collate
707 SFX_REQUEST_ARG(rReq, pCollateItem, SfxBoolItem, SID_PRINT_COLLATE, FALSE);
708 if ( pCollateItem )
710 bCollate = pCollateItem->GetValue();
711 pPrintDlg->CheckCollate( bCollate );
714 // Selection
715 SFX_REQUEST_ARG(rReq, pSelectItem, SfxBoolItem, SID_SELECTION, FALSE);
717 // Pages (as String)
718 SFX_REQUEST_ARG(rReq, pPagesItem, SfxStringItem, SID_PRINT_PAGES, FALSE);
720 // FirstPage
721 SFX_REQUEST_ARG(rReq, pFirstPgItem, SfxInt16Item, SID_PRINT_FIRST_PAGE, FALSE);
722 USHORT nFrom = 1;
723 if ( pFirstPgItem )
724 nFrom = pFirstPgItem->GetValue();
726 // LastPage
727 SFX_REQUEST_ARG(rReq, pLastPgItem, SfxInt16Item, SID_PRINT_LAST_PAGE, FALSE);
728 USHORT nTo = 9999;
729 if ( pLastPgItem )
730 nTo = pLastPgItem->GetValue();
732 // CopyCount
733 SFX_REQUEST_ARG(rReq, pCopyItem, SfxInt16Item, SID_PRINT_COPIES, FALSE);
734 if ( pCopyItem )
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
749 // enable ranges
750 pPrintDlg->CheckRange(PRINTDIALOG_RANGE);
751 pPrintDlg->SetRangeText( pPagesItem->GetValue() );
753 else if ( pPrintDlg->IsRangeEnabled(PRINTDIALOG_RANGE) )
755 // enable ranges
756 // construct range text from page range
757 pPrintDlg->CheckRange(PRINTDIALOG_RANGE);
758 String aRange = String::CreateFromInt32( nFrom );
759 aRange += '-';
760 aRange += String::CreateFromInt32( nTo );
761 pPrintDlg->SetRangeText( aRange );
763 else
765 // print page rage
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));
789 return;
792 bool bDetectHidden = ( !bSilent && pDoc );
793 if ( bDetectHidden && pDoc->QueryHiddenInformation( WhenPrinting, NULL ) != RET_YES )
794 return;
796 // if no printer was selected before
797 if ( !pPrinter )
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 );
805 return;
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 );
814 return;
817 pPrinter->SetNextJobIsQuick();
820 // if "Collate" was checked, the SfxPrinter must handle the CopyCount itself,
821 // usually this is handled by the printer driver
822 if( bCollate )
823 // set printer to default, handle multiple copies explicitly
824 pPrinter->SetCopyCount( 1 );
825 else
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() );
845 ::DateTime now;
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();
867 rReq.Done();
869 else
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 ) );
879 if ( !bIsAPI )
880 ErrorBox( NULL, WB_OK | WB_DEF_OK, aMsg ).Execute();
881 rReq.SetReturnValue(SfxBoolItem(0,FALSE));
884 rReq.Ignore();
887 pPrinter->SetNextJobIsQuick( false );
889 delete pPrintDlg;
890 break;
895 // Optimierungen wieder einschalten
896 #ifdef _MSC_VER
897 #pragma optimize ( "", on )
898 #endif
900 //--------------------------------------------------------------------
902 PrintDialog* SfxViewShell::CreatePrintDialog( Window* pParent )
904 /* [Beschreibung]
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();
916 return pDlg;
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);
936 if ( !pPrinter )
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);
948 // Drucker starten
949 PreparePrint( pPrintDlg );
950 SfxObjectShell *pObjShell = GetViewFrame()->GetObjectShell();
951 if ( pPrinter->StartJob(pObjShell->GetTitle(0)) )
953 // Drucken
954 Print( *pProgress, bIsAPI, pPrintDlg );
955 pProgress->Stop();
956 pProgress->DeleteOnEndPrint();
957 pPrinter->EndJob();
959 else
961 // Printer konnte nicht gestartet werden
962 delete pProgress;
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;
980 if ( bLock )
981 bChanged = 1 == ++pImp->nPrinterLocks;
982 else
983 bChanged = 0 == --pImp->nPrinterLocks;
985 if ( bChanged )
987 Invalidate( SID_PRINTDOC );
988 Invalidate( SID_PRINTDOCDIRECT );
989 Invalidate( SID_SETUPPRINTER );
993 //--------------------------------------------------------------------
995 USHORT SfxViewShell::Print( SfxProgress& /*rProgress*/, BOOL /*bIsAPI*/, PrintDialog* /*pDlg*/ )
997 return 0;
1000 //--------------------------------------------------------------------
1002 SfxPrinter* SfxViewShell::GetPrinter( BOOL /*bCreate*/ )
1004 return 0;
1007 //--------------------------------------------------------------------
1009 USHORT SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, USHORT /*nDiffFlags*/, bool )
1011 return 0;
1014 //--------------------------------------------------------------------
1016 SfxTabPage* SfxViewShell::CreatePrintOptionsPage
1018 Window* /*pParent*/,
1019 const SfxItemSet& /*rOptions*/
1022 /* [Beschreibung]
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
1031 verwendet wird.
1033 Die Basisimplementierung liefert einen 0-Pointer.
1037 return 0;