1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
27 #include <osl/diagnose.h>
29 #include <com/sun/star/frame/XModel.hpp>
31 #define SC_PROGRESS_CXX
32 #include <progress.hxx>
33 #include <document.hxx>
35 #include <globstr.hrc>
36 #include <scresid.hxx>
38 using namespace com::sun::star
;
40 static ScProgress theDummyInterpretProgress
;
41 SfxProgress
* ScProgress::pGlobalProgress
= nullptr;
42 sal_uInt64
ScProgress::nGlobalRange
= 0;
43 sal_uInt64
ScProgress::nGlobalPercent
= 0;
44 ScProgress
* ScProgress::pInterpretProgress
= &theDummyInterpretProgress
;
45 sal_uInt64
ScProgress::nInterpretProgress
= 0;
46 ScDocument
* ScProgress::pInterpretDoc
;
47 bool ScProgress::bIdleWasEnabled
= false;
49 static bool lcl_IsHiddenDocument( const SfxObjectShell
* pObjSh
)
53 SfxMedium
* pMed
= pObjSh
->GetMedium();
56 if (const SfxBoolItem
* pItem
= pMed
->GetItemSet().GetItemIfSet(SID_HIDDEN
);
57 pItem
&& pItem
->GetValue())
64 static bool lcl_HasControllersLocked( const SfxObjectShell
& rObjSh
)
66 uno::Reference
<frame::XModel
> xModel( rObjSh
.GetBaseModel() );
68 return xModel
->hasControllersLocked();
72 ScProgress::ScProgress(SfxObjectShell
* pObjSh
, const OUString
& rText
,
73 sal_uInt64 nRange
, bool bWait
)
77 if ( pGlobalProgress
|| SfxProgress::GetActiveProgress() )
79 if ( lcl_IsHiddenDocument(pObjSh
) )
81 // loading a hidden document while a progress is active is possible - no error
86 OSL_FAIL( "ScProgress: there can be only one!" );
90 else if ( SfxGetpApp()->IsDowning() )
92 // This happens. E.g. when saving the clipboard-content as OLE when closing the app.
93 // In this case a SfxProgress would produce dirt in memory.
94 //TODO: Should that be this way ???
98 else if ( pObjSh
&& ( pObjSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
||
99 pObjSh
->GetProgress() ||
100 lcl_HasControllersLocked(*pObjSh
) ) )
102 // no own progress for embedded objects,
103 // no second progress if the document already has one
109 pProgress
.reset(new SfxProgress( pObjSh
, rText
, nRange
, bWait
));
110 pGlobalProgress
= pProgress
.get();
111 nGlobalRange
= nRange
;
116 ScProgress::ScProgress()
122 ScProgress::~ScProgress()
127 pGlobalProgress
= nullptr;
133 void ScProgress::CreateInterpretProgress( ScDocument
* pDoc
, bool bWait
)
135 if ( nInterpretProgress
)
136 nInterpretProgress
++;
137 else if ( pDoc
->GetAutoCalc() )
139 nInterpretProgress
= 1;
140 bIdleWasEnabled
= pDoc
->IsIdleEnabled();
141 pDoc
->EnableIdle(false);
142 // Interpreter may be called in many circumstances, also if another
143 // progress bar is active, for example while adapting row heights.
144 // Keep the dummy interpret progress.
145 if ( !pGlobalProgress
)
146 pInterpretProgress
= new ScProgress( pDoc
->GetDocumentShell(),
147 ScResId( STR_PROGRESS_CALCULATING
),
148 pDoc
->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE
, bWait
);
149 pInterpretDoc
= pDoc
;
153 void ScProgress::DeleteInterpretProgress()
155 if ( !nInterpretProgress
)
158 /* Do not decrement 'nInterpretProgress', before 'pInterpretProgress'
159 is deleted. In rare cases, deletion of 'pInterpretProgress' causes
160 a refresh of the sheet window which may call CreateInterpretProgress
161 and DeleteInterpretProgress again (from Output::DrawStrings),
162 resulting in double deletion of 'pInterpretProgress'. */
163 if ( nInterpretProgress
== 1 )
165 if ( pInterpretProgress
!= &theDummyInterpretProgress
)
167 // move pointer to local temporary to avoid double deletion
168 ScProgress
* pTmpProgress
= pInterpretProgress
;
169 pInterpretProgress
= &theDummyInterpretProgress
;
173 pInterpretDoc
->EnableIdle(bIdleWasEnabled
);
175 --nInterpretProgress
;
178 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */