xref: /trunk/main/sc/source/core/tool/progress.cxx (revision b3f79822)
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