Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / tool / progress.cxx
blobde74aaba97427268d7e58ad880fac60bc7c5e922
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/app.hxx>
21 #include <sfx2/objsh.hxx>
22 #include <sfx2/progress.hxx>
23 #include <sfx2/docfile.hxx>
24 #include <sfx2/sfxsids.hrc>
25 #include <svl/eitem.hxx>
26 #include <svl/itemset.hxx>
28 #define SC_PROGRESS_CXX
29 #include "progress.hxx"
30 #include "document.hxx"
31 #include "global.hxx"
32 #include "globstr.hrc"
34 using namespace com::sun::star;
37 static ScProgress theDummyInterpretProgress;
38 SfxProgress* ScProgress::pGlobalProgress = NULL;
39 sal_uLong ScProgress::nGlobalRange = 0;
40 sal_uLong ScProgress::nGlobalPercent = 0;
41 sal_Bool ScProgress::bGlobalNoUserBreak = sal_True;
42 ScProgress* ScProgress::pInterpretProgress = &theDummyInterpretProgress;
43 ScProgress* ScProgress::pOldInterpretProgress = NULL;
44 sal_uLong ScProgress::nInterpretProgress = 0;
45 sal_Bool ScProgress::bAllowInterpretProgress = sal_True;
46 ScDocument* ScProgress::pInterpretDoc;
47 bool ScProgress::bIdleWasEnabled = false;
50 static sal_Bool lcl_IsHiddenDocument( SfxObjectShell* pObjSh )
52 if (pObjSh)
54 SfxMedium* pMed = pObjSh->GetMedium();
55 if (pMed)
57 SfxItemSet* pSet = pMed->GetItemSet();
58 const SfxPoolItem* pItem;
59 if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_HIDDEN, sal_True, &pItem ) &&
60 ((const SfxBoolItem*)pItem)->GetValue() )
61 return sal_True;
64 return false;
67 static bool lcl_HasControllersLocked( SfxObjectShell& rObjSh )
69 uno::Reference<frame::XModel> xModel( rObjSh.GetBaseModel() );
70 if (xModel.is())
71 return xModel->hasControllersLocked();
72 return false;
75 ScProgress::ScProgress( SfxObjectShell* pObjSh, const OUString& rText,
76 sal_uLong nRange, sal_Bool bAllDocs, sal_Bool bWait )
79 if ( pGlobalProgress || SfxProgress::GetActiveProgress( NULL ) )
81 if ( lcl_IsHiddenDocument(pObjSh) )
83 // loading a hidden document while a progress is active is possible - no error
84 pProgress = NULL;
86 else
88 OSL_FAIL( "ScProgress: there can be only one!" );
89 pProgress = NULL;
92 else if ( SFX_APP()->IsDowning() )
94 // This happens. E.g. when saving the clipboard-content as OLE when closing the app.
95 // In this case a SfxProgress would produce dirt in memory.
96 //! Should that be this way ???
98 pProgress = NULL;
100 else if ( pObjSh && ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ||
101 pObjSh->GetProgress() ||
102 lcl_HasControllersLocked(*pObjSh) ) )
104 // no own progress for embedded objects,
105 // no second progress if the document already has one
107 pProgress = NULL;
109 else
111 pProgress = new SfxProgress( pObjSh, rText, nRange, bAllDocs, bWait );
112 pGlobalProgress = pProgress;
113 nGlobalRange = nRange;
114 nGlobalPercent = 0;
115 bGlobalNoUserBreak = sal_True;
120 ScProgress::ScProgress() :
121 pProgress( NULL )
122 { // DummyInterpret
126 ScProgress::~ScProgress()
128 if ( pProgress )
130 delete pProgress;
131 pGlobalProgress = NULL;
132 nGlobalRange = 0;
133 nGlobalPercent = 0;
134 bGlobalNoUserBreak = sal_True;
139 void ScProgress::CreateInterpretProgress( ScDocument* pDoc, sal_Bool bWait )
141 if ( bAllowInterpretProgress )
143 if ( nInterpretProgress )
144 nInterpretProgress++;
145 else if ( pDoc->GetAutoCalc() )
147 nInterpretProgress = 1;
148 bIdleWasEnabled = pDoc->IsIdleEnabled();
149 pDoc->EnableIdle(false);
150 // Interpreter may be called in many circumstances, also if another
151 // progress bar is active, for example while adapting row heights.
152 // Keep the dummy interpret progress.
153 if ( !pGlobalProgress )
154 pInterpretProgress = new ScProgress( pDoc->GetDocumentShell(),
155 ScGlobal::GetRscString( STR_PROGRESS_CALCULATING ),
156 pDoc->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE, false, bWait );
157 pInterpretDoc = pDoc;
164 void ScProgress::DeleteInterpretProgress()
166 if ( bAllowInterpretProgress && nInterpretProgress )
168 /* Do not decrement 'nInterpretProgress', before 'pInterpretProgress'
169 is deleted. In rare cases, deletion of 'pInterpretProgress' causes
170 a refresh of the sheet window which may call CreateInterpretProgress
171 and DeleteInterpretProgress again (from Output::DrawStrings),
172 resulting in double deletion of 'pInterpretProgress'. */
173 if ( nInterpretProgress == 1 )
175 if ( pInterpretProgress != &theDummyInterpretProgress )
177 // move pointer to local temporary to avoid double deletion
178 ScProgress* pTmpProgress = pInterpretProgress;
179 pInterpretProgress = &theDummyInterpretProgress;
180 delete pTmpProgress;
182 if ( pInterpretDoc )
183 pInterpretDoc->EnableIdle(bIdleWasEnabled);
185 --nInterpretProgress;
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */