1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 //------------------------------------------------------------------------ 34 35 #include <sfx2/app.hxx> 36 #include <sfx2/objsh.hxx> 37 #include <sfx2/progress.hxx> 38 #include <sfx2/docfile.hxx> 39 #include <sfx2/sfxsids.hrc> 40 #include <svl/eitem.hxx> 41 #include <svl/itemset.hxx> 42 43 #define SC_PROGRESS_CXX 44 #include "progress.hxx" 45 #include "document.hxx" 46 #include "global.hxx" 47 #include "globstr.hrc" 48 49 using namespace com::sun::star; 50 51 52 static ScProgress theDummyInterpretProgress; 53 SfxProgress* ScProgress::pGlobalProgress = NULL; 54 sal_uLong ScProgress::nGlobalRange = 0; 55 sal_uLong ScProgress::nGlobalPercent = 0; 56 sal_Bool ScProgress::bGlobalNoUserBreak = sal_True; 57 ScProgress* ScProgress::pInterpretProgress = &theDummyInterpretProgress; 58 ScProgress* ScProgress::pOldInterpretProgress = NULL; 59 sal_uLong ScProgress::nInterpretProgress = 0; 60 sal_Bool ScProgress::bAllowInterpretProgress = sal_True; 61 ScDocument* ScProgress::pInterpretDoc; 62 sal_Bool ScProgress::bIdleWasDisabled = sal_False; 63 64 65 sal_Bool lcl_IsHiddenDocument( SfxObjectShell* pObjSh ) 66 { 67 if (pObjSh) 68 { 69 SfxMedium* pMed = pObjSh->GetMedium(); 70 if (pMed) 71 { 72 SfxItemSet* pSet = pMed->GetItemSet(); 73 const SfxPoolItem* pItem; 74 if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_HIDDEN, sal_True, &pItem ) && 75 ((const SfxBoolItem*)pItem)->GetValue() ) 76 return sal_True; 77 } 78 } 79 return sal_False; 80 } 81 82 bool lcl_HasControllersLocked( SfxObjectShell& rObjSh ) 83 { 84 uno::Reference<frame::XModel> xModel( rObjSh.GetBaseModel() ); 85 if (xModel.is()) 86 return xModel->hasControllersLocked(); 87 return false; 88 } 89 90 ScProgress::ScProgress( SfxObjectShell* pObjSh, const String& rText, 91 sal_uLong nRange, sal_Bool bAllDocs, sal_Bool bWait ) 92 { 93 94 if ( pGlobalProgress || SfxProgress::GetActiveProgress( NULL ) ) 95 { 96 if ( lcl_IsHiddenDocument(pObjSh) ) 97 { 98 // loading a hidden document while a progress is active is possible - no error 99 pProgress = NULL; 100 } 101 else 102 { 103 DBG_ERROR( "ScProgress: there can be only one!" ); 104 pProgress = NULL; 105 } 106 } 107 else if ( SFX_APP()->IsDowning() ) 108 { 109 // kommt vor z.B. beim Speichern des Clipboard-Inhalts als OLE beim Beenden 110 // Dann wuerde ein SfxProgress wild im Speicher rummuellen 111 //! Soll das so sein ??? 112 113 pProgress = NULL; 114 } 115 else if ( pObjSh && ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED || 116 pObjSh->GetProgress() || 117 lcl_HasControllersLocked(*pObjSh) ) ) 118 { 119 // #62808# no own progress for embedded objects, 120 // #73633# no second progress if the document already has one 121 // #163566# no progress while controllers are locked (repaint disabled) 122 123 pProgress = NULL; 124 } 125 else 126 { 127 pProgress = new SfxProgress( pObjSh, rText, nRange, bAllDocs, bWait ); 128 pGlobalProgress = pProgress; 129 nGlobalRange = nRange; 130 nGlobalPercent = 0; 131 bGlobalNoUserBreak = sal_True; 132 } 133 } 134 135 136 ScProgress::ScProgress() : 137 pProgress( NULL ) 138 { // DummyInterpret 139 } 140 141 142 ScProgress::~ScProgress() 143 { 144 if ( pProgress ) 145 { 146 delete pProgress; 147 pGlobalProgress = NULL; 148 nGlobalRange = 0; 149 nGlobalPercent = 0; 150 bGlobalNoUserBreak = sal_True; 151 } 152 } 153 154 // static 155 156 void ScProgress::CreateInterpretProgress( ScDocument* pDoc, sal_Bool bWait ) 157 { 158 if ( bAllowInterpretProgress ) 159 { 160 if ( nInterpretProgress ) 161 nInterpretProgress++; 162 else if ( pDoc->GetAutoCalc() ) 163 { 164 nInterpretProgress = 1; 165 bIdleWasDisabled = pDoc->IsIdleDisabled(); 166 pDoc->DisableIdle( sal_True ); 167 // Interpreter may be called in many circumstances, also if another 168 // progress bar is active, for example while adapting row heights. 169 // Keep the dummy interpret progress. 170 if ( !pGlobalProgress ) 171 pInterpretProgress = new ScProgress( pDoc->GetDocumentShell(), 172 ScGlobal::GetRscString( STR_PROGRESS_CALCULATING ), 173 pDoc->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE, sal_False, bWait ); 174 pInterpretDoc = pDoc; 175 } 176 } 177 } 178 179 180 // static 181 182 void ScProgress::DeleteInterpretProgress() 183 { 184 if ( bAllowInterpretProgress && nInterpretProgress ) 185 { 186 /* Do not decrement 'nInterpretProgress', before 'pInterpretProgress' 187 is deleted. In rare cases, deletion of 'pInterpretProgress' causes 188 a refresh of the sheet window which may call CreateInterpretProgress 189 and DeleteInterpretProgress again (from Output::DrawStrings), 190 resulting in double deletion of 'pInterpretProgress'. */ 191 // if ( --nInterpretProgress == 0 ) 192 if ( nInterpretProgress == 1 ) 193 { 194 if ( pInterpretProgress != &theDummyInterpretProgress ) 195 { 196 // move pointer to local temporary to avoid double deletion 197 ScProgress* pTmpProgress = pInterpretProgress; 198 pInterpretProgress = &theDummyInterpretProgress; 199 delete pTmpProgress; 200 } 201 if ( pInterpretDoc ) 202 pInterpretDoc->DisableIdle( bIdleWasDisabled ); 203 } 204 --nInterpretProgress; 205 } 206 } 207 208 209 210