xref: /AOO41X/main/sc/source/core/tool/progress.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 //------------------------------------------------------------------------
30 
31 #include <sfx2/app.hxx>
32 #include <sfx2/objsh.hxx>
33 #include <sfx2/progress.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/sfxsids.hrc>
36 #include <svl/eitem.hxx>
37 #include <svl/itemset.hxx>
38 
39 #define SC_PROGRESS_CXX
40 #include "progress.hxx"
41 #include "document.hxx"
42 #include "global.hxx"
43 #include "globstr.hrc"
44 
45 using namespace com::sun::star;
46 
47 
48 static ScProgress theDummyInterpretProgress;
49 SfxProgress*    ScProgress::pGlobalProgress = NULL;
50 sal_uLong           ScProgress::nGlobalRange = 0;
51 sal_uLong           ScProgress::nGlobalPercent = 0;
52 sal_Bool            ScProgress::bGlobalNoUserBreak = sal_True;
53 ScProgress*     ScProgress::pInterpretProgress = &theDummyInterpretProgress;
54 ScProgress*     ScProgress::pOldInterpretProgress = NULL;
55 sal_uLong           ScProgress::nInterpretProgress = 0;
56 sal_Bool            ScProgress::bAllowInterpretProgress = sal_True;
57 ScDocument*     ScProgress::pInterpretDoc;
58 sal_Bool            ScProgress::bIdleWasDisabled = sal_False;
59 
60 
lcl_IsHiddenDocument(SfxObjectShell * pObjSh)61 sal_Bool lcl_IsHiddenDocument( SfxObjectShell* pObjSh )
62 {
63     if (pObjSh)
64     {
65         SfxMedium* pMed = pObjSh->GetMedium();
66         if (pMed)
67         {
68             SfxItemSet* pSet = pMed->GetItemSet();
69             const SfxPoolItem* pItem;
70             if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_HIDDEN, sal_True, &pItem ) &&
71                         ((const SfxBoolItem*)pItem)->GetValue() )
72                 return sal_True;
73         }
74     }
75     return sal_False;
76 }
77 
lcl_HasControllersLocked(SfxObjectShell & rObjSh)78 bool lcl_HasControllersLocked( SfxObjectShell& rObjSh )
79 {
80     uno::Reference<frame::XModel> xModel( rObjSh.GetBaseModel() );
81     if (xModel.is())
82         return xModel->hasControllersLocked();
83     return false;
84 }
85 
ScProgress(SfxObjectShell * pObjSh,const String & rText,sal_uLong nRange,sal_Bool bAllDocs,sal_Bool bWait)86 ScProgress::ScProgress( SfxObjectShell* pObjSh, const String& rText,
87                         sal_uLong nRange, sal_Bool bAllDocs, sal_Bool bWait )
88 {
89 
90     if ( pGlobalProgress || SfxProgress::GetActiveProgress( NULL ) )
91     {
92         if ( lcl_IsHiddenDocument(pObjSh) )
93         {
94             // loading a hidden document while a progress is active is possible - no error
95             pProgress = NULL;
96         }
97         else
98         {
99             DBG_ERROR( "ScProgress: there can be only one!" );
100             pProgress = NULL;
101         }
102     }
103     else if ( SFX_APP()->IsDowning() )
104     {
105         //  kommt vor z.B. beim Speichern des Clipboard-Inhalts als OLE beim Beenden
106         //  Dann wuerde ein SfxProgress wild im Speicher rummuellen
107         //! Soll das so sein ???
108 
109         pProgress = NULL;
110     }
111     else if ( pObjSh && ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ||
112                           pObjSh->GetProgress() ||
113                           lcl_HasControllersLocked(*pObjSh) ) )
114     {
115         //  #62808# no own progress for embedded objects,
116         //  #73633# no second progress if the document already has one
117         //  #163566# no progress while controllers are locked (repaint disabled)
118 
119         pProgress = NULL;
120     }
121     else
122     {
123         pProgress = new SfxProgress( pObjSh, rText, nRange, bAllDocs, bWait );
124         pGlobalProgress = pProgress;
125         nGlobalRange = nRange;
126         nGlobalPercent = 0;
127         bGlobalNoUserBreak = sal_True;
128     }
129 }
130 
131 
ScProgress()132 ScProgress::ScProgress() :
133         pProgress( NULL )
134 {   // DummyInterpret
135 }
136 
137 
~ScProgress()138 ScProgress::~ScProgress()
139 {
140     if ( pProgress )
141     {
142         delete pProgress;
143         pGlobalProgress = NULL;
144         nGlobalRange = 0;
145         nGlobalPercent = 0;
146         bGlobalNoUserBreak = sal_True;
147     }
148 }
149 
150 // static
151 
CreateInterpretProgress(ScDocument * pDoc,sal_Bool bWait)152 void ScProgress::CreateInterpretProgress( ScDocument* pDoc, sal_Bool bWait )
153 {
154     if ( bAllowInterpretProgress )
155     {
156         if ( nInterpretProgress )
157             nInterpretProgress++;
158         else if ( pDoc->GetAutoCalc() )
159         {
160             nInterpretProgress = 1;
161             bIdleWasDisabled = pDoc->IsIdleDisabled();
162             pDoc->DisableIdle( sal_True );
163             // Interpreter may be called in many circumstances, also if another
164             // progress bar is active, for example while adapting row heights.
165             // Keep the dummy interpret progress.
166             if ( !pGlobalProgress )
167                 pInterpretProgress = new ScProgress( pDoc->GetDocumentShell(),
168                     ScGlobal::GetRscString( STR_PROGRESS_CALCULATING ),
169                     pDoc->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE, sal_False, bWait );
170             pInterpretDoc = pDoc;
171         }
172     }
173 }
174 
175 
176 // static
177 
DeleteInterpretProgress()178 void ScProgress::DeleteInterpretProgress()
179 {
180     if ( bAllowInterpretProgress && nInterpretProgress )
181     {
182         /*  Do not decrement 'nInterpretProgress', before 'pInterpretProgress'
183             is deleted. In rare cases, deletion of 'pInterpretProgress' causes
184             a refresh of the sheet window which may call CreateInterpretProgress
185             and DeleteInterpretProgress again (from Output::DrawStrings),
186             resulting in double deletion of 'pInterpretProgress'. */
187 //       if ( --nInterpretProgress == 0 )
188         if ( nInterpretProgress == 1 )
189         {
190             if ( pInterpretProgress != &theDummyInterpretProgress )
191             {
192                 // move pointer to local temporary to avoid double deletion
193                 ScProgress* pTmpProgress = pInterpretProgress;
194                 pInterpretProgress = &theDummyInterpretProgress;
195                 delete pTmpProgress;
196             }
197             if ( pInterpretDoc )
198                 pInterpretDoc->DisableIdle( bIdleWasDisabled );
199         }
200         --nInterpretProgress;
201     }
202 }
203 
204 
205 
206