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