merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / view / prnmon.cxx
blob899b082c890958256517dc5c62af8f9e950a4fef
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: prnmon.cxx,v $
10 * $Revision: 1.25.46.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"
33 #include <com/sun/star/view/PrintableState.hpp>
34 #include <com/sun/star/util/XCloseable.hpp>
35 #include <com/sun/star/util/XCloseBroadcaster.hpp>
36 #include <com/sun/star/util/XCloseListener.hpp>
37 #include <com/sun/star/util/CloseVetoException.hpp>
38 #include <vcl/fixed.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <svtools/asynclink.hxx>
42 #include <svtools/printwarningoptions.hxx>
43 #include <svtools/eitem.hxx>
45 #ifndef GCC
46 #endif
48 #include <sfx2/prnmon.hxx>
49 #include <sfx2/viewsh.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <sfx2/docfile.hxx>
53 #include "sfxtypes.hxx"
54 #include <sfx2/progress.hxx>
55 #include <sfx2/bindings.hxx>
56 #include "sfxresid.hxx"
57 #include <sfx2/event.hxx>
58 #include <sfx2/request.hxx>
59 #include <sfx2/app.hxx>
61 #include "view.hrc"
63 //------------------------------------------------------------------------
65 #define SFX_TITLE_MAXLEN_PRINTMONITOR 22
67 //------------------------------------------------------------------------
69 struct SfxPrintMonitor_Impl: public ModelessDialog
72 SfxPrintMonitor_Impl( Window *pParent, SfxViewShell *rpViewShell );
73 virtual BOOL Close();
75 SfxViewShell* pViewShell;
76 FixedText aDocName;
77 FixedText aPrinting;
78 FixedText aPrinter;
79 FixedText aPrintInfo;
80 CancelButton aCancel;
83 //-------------------------------------------------------------------------
85 struct SfxPrintProgress_Impl : public SfxListener
87 SfxPrintMonitor_Impl* pMonitor;
88 SfxViewShell* pViewShell;
89 SfxPrinter* pPrinter;
90 SfxPrinter* pOldPrinter;
91 USHORT nLastPage;
92 BOOL bRunning;
93 BOOL bCancel;
94 BOOL bDeleteOnEndPrint;
95 BOOL bShow;
96 BOOL bCallbacks;
97 BOOL bOldEnablePrintFile;
98 BOOL bOldFlag;
99 BOOL bRestoreFlag;
100 BOOL bAborted;
101 svtools::AsynchronLink aDeleteLink;
102 Link aCancelHdl;
104 private:
105 DECL_LINK( CancelHdl, Button * );
106 DECL_STATIC_LINK( SfxPrintProgress_Impl, DeleteHdl, SfxPrintProgress * );
108 public:
109 SfxPrintProgress_Impl( SfxViewShell* pTheViewShell, SfxPrinter* pThePrinter );
110 ~SfxPrintProgress_Impl();
112 void Delete( SfxPrintProgress* pAntiImpl ) { aDeleteLink.Call( pAntiImpl ); }
113 SfxViewShell* GetViewShell() const { return pViewShell; }
114 BOOL SetPage( USHORT nPage, const String &rPage );
115 void CreateMonitor();
116 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
119 void SfxPrintProgress_Impl::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
121 SfxPrintingHint* pPrintHint = PTR_CAST( SfxPrintingHint, &rHint );
122 if ( pPrintHint )
124 if ( pPrintHint->GetWhich() == -2 )
125 CancelHdl(0);
129 //------------------------------------------------------------------------
131 SfxPrintMonitor_Impl::SfxPrintMonitor_Impl( Window* pParent, SfxViewShell* rpViewShell ) :
132 ModelessDialog( pParent, SfxResId( DLG_PRINTMONITOR ) ),
133 pViewShell ( rpViewShell ),
134 aDocName ( this, SfxResId( FT_DOCNAME ) ),
135 aPrinting ( this, SfxResId( FT_PRINTING ) ),
136 aPrinter ( this, SfxResId( FT_PRINTER ) ),
137 aPrintInfo ( this, SfxResId( FT_PRINTINFO ) ),
138 aCancel ( this, SfxResId( PB_CANCELPRNMON ) )
140 if( rpViewShell->GetPrinter()->GetCapabilities( PRINTER_CAPABILITIES_EXTERNALDIALOG ) != 0 )
142 String aPrep( SfxResId( STR_FT_PREPARATION ) );
143 aPrinting.SetText( aPrep );
144 aPrinter.Show( FALSE );
146 FreeResource();
149 //------------------------------------------------------------------------
151 IMPL_STATIC_LINK_NOINSTANCE( SfxPrintProgress_Impl, DeleteHdl, SfxPrintProgress*, pAntiImpl )
153 delete pAntiImpl;
154 return 0;
157 void actualizePrintCancelState(CancelButton& rButton, const SfxObjectShell* pShell)
159 sal_Bool bEnableCancelButton = sal_True;
160 if (pShell)
161 bEnableCancelButton = pShell->Stamp_GetPrintCancelState();
163 if (!bEnableCancelButton)
164 rButton.Disable();
165 else
166 rButton.Enable();
169 //------------------------------------------------------------------------
171 SfxPrintProgress_Impl::SfxPrintProgress_Impl( SfxViewShell* pTheViewShell,
172 SfxPrinter* pThePrinter ) :
174 pMonitor ( 0 ),
175 pViewShell ( pTheViewShell ),
176 pPrinter ( pThePrinter ),
177 pOldPrinter ( NULL ),
178 nLastPage ( 0 ),
179 bRunning ( TRUE ),
180 bCancel ( FALSE ),
181 bDeleteOnEndPrint ( FALSE ),
182 bShow ( FALSE ),
183 bCallbacks ( FALSE ),
184 bOldEnablePrintFile ( FALSE ),
185 bOldFlag ( TRUE ),
186 bRestoreFlag ( FALSE ),
187 bAborted ( FALSE ),
188 aDeleteLink ( STATIC_LINK( this, SfxPrintProgress_Impl, DeleteHdl ) )
190 StartListening( *pViewShell->GetObjectShell() );
193 void SfxPrintProgress_Impl::CreateMonitor()
195 // mark monitor to been shown in first status indication
196 bShow = TRUE;
198 if ( !pMonitor )
200 Window* pParent = pViewShell->GetWindow();
201 pMonitor = new SfxPrintMonitor_Impl( pParent, pViewShell );
202 pMonitor->aDocName.SetText( pViewShell->GetObjectShell()->GetTitle( SFX_TITLE_MAXLEN_PRINTMONITOR ) );
203 pMonitor->aPrinter.SetText( pViewShell->GetPrinter()->GetName() );
205 // Stampit enable/dsiable cancel button
206 actualizePrintCancelState( pMonitor->aCancel, pViewShell->GetObjectShell() );
207 pMonitor->aCancel.SetClickHdl( LINK( this, SfxPrintProgress_Impl, CancelHdl ) );
211 //------------------------------------------------------------------------
213 SfxPrintProgress_Impl::~SfxPrintProgress_Impl()
217 //------------------------------------------------------------------------
219 BOOL SfxPrintProgress_Impl::SetPage( USHORT nPage, const String &rPage )
221 // wurde der Druckauftrag abgebrochen?
222 if ( bCancel || !pMonitor )
223 return FALSE;
225 // Stampit enable/dsiable cancel button
226 actualizePrintCancelState(pMonitor->aCancel, pViewShell->GetObjectShell());
228 nLastPage = nPage;
229 String aStrPrintInfo = String( SfxResId( STR_PAGE ) );
230 if ( !rPage.Len() )
231 aStrPrintInfo += String::CreateFromInt32( nLastPage );
232 else
233 aStrPrintInfo += rPage;
234 pMonitor->aPrintInfo.SetText( aStrPrintInfo );
235 pMonitor->Update();
236 return TRUE;
239 //------------------------------------------------------------------------
241 IMPL_LINK( SfxPrintProgress_Impl, CancelHdl, Button *, EMPTYARG )
243 if ( !pViewShell->GetPrinter()->IsJobActive() && pViewShell->GetPrinter()->IsPrinting() )
244 // we are still in StartJob, cancelling now might lead to a crash
245 return 0;
247 if ( pMonitor )
248 pMonitor->Hide();
250 pViewShell->GetObjectShell()->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_ABORTED, NULL, NULL ) );
251 pViewShell->GetPrinter()->AbortJob();
252 bCancel = TRUE;
254 if ( aCancelHdl.IsSet() )
255 aCancelHdl.Call( this );
257 bAborted = TRUE;
258 return 0;
261 BOOL SfxPrintMonitor_Impl::Close()
263 BOOL bAgree = pViewShell ? pViewShell->GetObjectShell()->Stamp_GetPrintCancelState() : TRUE;
264 if (!bAgree)
265 return FALSE;
266 else
267 return ModelessDialog::Close();
270 //--------------------------------------------------------------------
272 SfxPrintProgress::SfxPrintProgress( SfxViewShell* pViewSh, FASTBOOL bShow )
273 : SfxProgress( pViewSh->GetViewFrame()->GetObjectShell(),
274 String(SfxResId(STR_PRINTING)), 1, FALSE ),
275 pImp( new SfxPrintProgress_Impl( pViewSh, pViewSh->GetPrinter() ) )
277 pImp->pPrinter->SetEndPrintHdl( LINK( this, SfxPrintProgress, EndPrintNotify ) );
278 pImp->pPrinter->SetErrorHdl( LINK( this, SfxPrintProgress, PrintErrorNotify ) );
279 pImp->pPrinter->SetStartPrintHdl( LINK( this, SfxPrintProgress, StartPrintNotify ) );
280 pImp->bCallbacks = TRUE;
282 SfxObjectShell* pDoc = pViewSh->GetObjectShell();
283 SFX_ITEMSET_ARG( pDoc->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_HIDDEN, FALSE );
284 if ( pItem && pItem->GetValue() )
285 bShow = FALSE;
287 if ( bShow )
288 pImp->CreateMonitor();
290 Lock();
291 if ( !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() )
293 pImp->bRestoreFlag = TRUE;
294 pImp->bOldFlag = pDoc->IsEnableSetModified();
295 if ( pImp->bOldFlag )
296 pDoc->EnableSetModified( FALSE );
300 //--------------------------------------------------------------------
302 SfxPrintProgress::~SfxPrintProgress()
304 // k"onnte auch schon weg sein (in EndPrintNotify)
305 DELETEZ(pImp->pMonitor);
307 // ggf. Callbacks entfermen
308 if ( pImp->bCallbacks )
310 pImp->pPrinter->SetEndPrintHdl( Link() );
311 pImp->pPrinter->SetErrorHdl( Link() );
312 pImp->bCallbacks = FALSE;
315 // ggf. vorherigen Drucker wieder einsetzen
316 if ( pImp->pOldPrinter )
317 pImp->pViewShell->SetPrinter( pImp->pOldPrinter, SFX_PRINTER_PRINTER );
318 else
319 // ggf. vorherigen Print-To-File-Status zuruecksetzen
320 pImp->pViewShell->GetPrinter()->EnablePrintFile( pImp->bOldEnablePrintFile );
322 // EndPrint-Notification an Frame
323 //pImp->pViewShell->GetViewFrame()->GetFrame()->Lock_Impl(FALSE);
324 pImp->EndListening( *(pImp->pViewShell->GetObjectShell()) );
326 // the following call might destroy the view or even the document
327 pImp->pViewShell->CheckOwnerShip_Impl();
328 delete pImp;
331 //--------------------------------------------------------------------
333 BOOL SfxPrintProgress::SetState( ULONG nValue, ULONG nNewRange )
335 if ( pImp->bShow )
337 pImp->bShow = FALSE;
338 if ( pImp->pMonitor )
340 pImp->pMonitor->Show();
341 pImp->pMonitor->Update();
345 return pImp->SetPage( (USHORT)nValue, GetStateText_Impl() ) &&
346 SfxProgress::SetState( nValue, nNewRange );
349 //--------------------------------------------------------------------
351 void SfxPrintProgress::SetText( const String& rText )
353 if ( pImp->pMonitor )
355 pImp->pMonitor->SetText( rText );
356 pImp->pMonitor->Update();
358 SfxProgress::SetText( rText );
361 //------------------------------------------------------------------------
363 IMPL_LINK_INLINE_START( SfxPrintProgress, PrintErrorNotify, void *, EMPTYARG )
365 if ( pImp->pMonitor )
366 pImp->pMonitor->Hide();
367 // AbortJob calls EndPrint hdl, so do not delete pImp just now
368 BOOL bWasDeleteOnEndPrint = pImp->bDeleteOnEndPrint;
369 pImp->bDeleteOnEndPrint = FALSE;
370 pImp->pPrinter->AbortJob();
371 InfoBox( pImp->GetViewShell()->GetWindow(),
372 String( SfxResId(STR_ERROR_PRINT) ) ).Execute();
373 if ( pImp->bRestoreFlag && pImp->pViewShell->GetObjectShell()->IsEnableSetModified() != pImp->bOldFlag )
374 pImp->pViewShell->GetObjectShell()->EnableSetModified( pImp->bOldFlag );
375 pImp->GetViewShell()->GetObjectShell()->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_FAILED, NULL, NULL ) );
376 // now we can clean up like normally EndPrint hdl does
377 if( bWasDeleteOnEndPrint )
379 DELETEZ(pImp->pMonitor);
380 delete this;
382 return 0;
384 IMPL_LINK_INLINE_END( SfxPrintProgress, PrintErrorNotify, void *, EMPTYARG )
386 //------------------------------------------------------------------------
388 IMPL_LINK( SfxPrintProgress, StartPrintNotify, void *, EMPTYARG )
390 SfxObjectShell *pObjShell = pImp->pViewShell->GetObjectShell();
391 SFX_APP()->NotifyEvent(SfxEventHint(SFX_EVENT_PRINTDOC, GlobalEventConfig::GetEventName( STR_EVENT_PRINTDOC ), pObjShell));
392 pObjShell->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_STARTED, NULL, NULL ) );
393 return 0;
396 IMPL_LINK( SfxPrintProgress, EndPrintNotify, void *, EMPTYARG )
398 if ( pImp->pMonitor )
399 pImp->pMonitor->Hide();
401 SfxViewShell* pViewShell = pImp->pViewShell;
403 // Slots enablen
404 pViewShell->Invalidate( SID_PRINTDOC );
405 pViewShell->Invalidate( SID_PRINTDOCDIRECT );
406 pViewShell->Invalidate( SID_SETUPPRINTER );
408 // . . . falls der Printer im System umgestellt wurde, hier Aenderung
409 // nachziehen.
410 //! if( pMDI->IsPrinterChanged() ) pMDI->Changed( 0L );
412 // Callbacks rausnehmen
413 pImp->pPrinter->SetEndPrintHdl( Link() );
414 pImp->pPrinter->SetErrorHdl( Link() );
415 pImp->bCallbacks = FALSE;
417 // ggf. alten Printer wieder einsetzen
418 if ( pImp->pOldPrinter )
420 // Fix #59613#: niemals den aktuellen Printer synchron abschiessen !
421 // Da sowieso immer bDeleteOnEndPrint gesetzt wird, wird der der Drucker im
422 // dtor vom Printprogress ( dann aber asynchron !! ) zur"uckgesetzt.
424 pImp->pViewShell->SetPrinter( pImp->pOldPrinter, SFX_PRINTER_PRINTER );
425 pImp->pOldPrinter = 0;
426 pImp->pPrinter = 0;
429 else
430 // ggf. vorherigen Print-To-File-Status zuruecksetzen
431 pViewShell->GetPrinter()->EnablePrintFile( pImp->bOldEnablePrintFile );
433 // it is possible that after printing the document or view is deleted (because the VieShell got the ownership)
434 // so first clean up
435 if ( pImp->bRestoreFlag && pViewShell->GetObjectShell()->IsEnableSetModified() != pImp->bOldFlag )
436 pViewShell->GetObjectShell()->EnableSetModified( TRUE );
438 pViewShell->GetObjectShell()->Broadcast( SfxPrintingHint( com::sun::star::view::PrintableState_JOB_COMPLETED, NULL, NULL ) );
439 if ( pImp->bDeleteOnEndPrint )
441 DELETEZ(pImp->pMonitor);
442 delete this;
444 else
446 DBG_ASSERT( !pImp->pOldPrinter, "Unable to restore printer!" );
447 pImp->bRunning = FALSE;
450 return 0;
453 //------------------------------------------------------------------------
455 void SfxPrintProgress::DeleteOnEndPrint()
457 UnLock(); // jetzt schon, wg. Drucken im Thread
458 #ifndef WNT
459 // da das Drucken im 'Thread' unter Windows zu undefiniert ist bleibt der
460 // Print-Monitor dort stehen, auf den anderen Plattformen kann man dann
461 // weiterarbeiten, also kommt das Teil weg
462 DELETEZ( pImp->pMonitor );
463 #endif
465 pImp->bDeleteOnEndPrint = TRUE;
466 if ( !pImp->bRunning )
467 delete this;
470 //------------------------------------------------------------------------
472 void SfxPrintProgress::RestoreOnEndPrint( SfxPrinter *pOldPrinter,
473 BOOL bOldEnablePrintFile )
475 pImp->pOldPrinter = pOldPrinter;
476 pImp->bOldEnablePrintFile = bOldEnablePrintFile;
479 //------------------------------------------------------------------------
481 void SfxPrintProgress::RestoreOnEndPrint( SfxPrinter *pOldPrinter )
483 RestoreOnEndPrint( pOldPrinter, FALSE );
486 //------------------------------------------------------------------------
488 void SfxPrintProgress::SetCancelHdl( const Link& aCancelHdl )
490 pImp->aCancelHdl = aCancelHdl;
493 BOOL SfxPrintProgress::IsAborted() const
495 return pImp->bAborted;