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 // INCLUDE --------------------------------------------------------------- 34 35 #include <time.h> 36 #include "autostyl.hxx" 37 38 #include "docsh.hxx" 39 #include "attrib.hxx" 40 #include "sc.hrc" 41 42 //================================================================== 43 44 struct ScAutoStyleInitData 45 { 46 ScRange aRange; 47 String aStyle1; 48 sal_uLong nTimeout; 49 String aStyle2; 50 51 ScAutoStyleInitData( const ScRange& rR, const String& rSt1, sal_uLong nT, const String& rSt2 ) : 52 aRange(rR), aStyle1(rSt1), nTimeout(nT), aStyle2(rSt2) {} 53 }; 54 55 struct ScAutoStyleData 56 { 57 sal_uLong nTimeout; 58 ScRange aRange; 59 String aStyle; 60 61 ScAutoStyleData( sal_uLong nT, const ScRange& rR, const String& rT ) : 62 nTimeout(nT), aRange(rR), aStyle(rT) {} 63 }; 64 65 //================================================================== 66 67 inline sal_uLong TimeNow() // Sekunden 68 { 69 return (sal_uLong) time(0); 70 } 71 72 //================================================================== 73 74 ScAutoStyleList::ScAutoStyleList(ScDocShell* pShell) : 75 pDocSh( pShell ) 76 { 77 aTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, TimerHdl ) ); 78 aInitTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, InitHdl ) ); 79 aInitTimer.SetTimeout( 0 ); 80 } 81 82 ScAutoStyleList::~ScAutoStyleList() 83 { 84 sal_uLong i; 85 sal_uLong nCount = aEntries.Count(); 86 for (i=0; i<nCount; i++) 87 delete (ScAutoStyleData*) aEntries.GetObject(i); 88 nCount = aInitials.Count(); 89 for (i=0; i<nCount; i++) 90 delete (ScAutoStyleInitData*) aInitials.GetObject(i); 91 } 92 93 //================================================================== 94 95 // initial short delay (asynchronous call) 96 97 void ScAutoStyleList::AddInitial( const ScRange& rRange, const String& rStyle1, 98 sal_uLong nTimeout, const String& rStyle2 ) 99 { 100 ScAutoStyleInitData* pNew = 101 new ScAutoStyleInitData( rRange, rStyle1, nTimeout, rStyle2 ); 102 aInitials.Insert( pNew, aInitials.Count() ); 103 aInitTimer.Start(); 104 } 105 106 IMPL_LINK( ScAutoStyleList, InitHdl, Timer*, EMPTYARG ) 107 { 108 sal_uLong nCount = aInitials.Count(); 109 for (sal_uLong i=0; i<nCount; i++) 110 { 111 ScAutoStyleInitData* pData = (ScAutoStyleInitData*) aInitials.GetObject(i); 112 113 // apply first style immediately 114 pDocSh->DoAutoStyle( pData->aRange, pData->aStyle1 ); 115 116 // add second style to list 117 if ( pData->nTimeout ) 118 AddEntry( pData->nTimeout, pData->aRange, pData->aStyle2 ); 119 120 delete pData; 121 } 122 aInitials.Clear(); 123 124 return 0; 125 } 126 127 //================================================================== 128 129 void ScAutoStyleList::AddEntry( sal_uLong nTimeout, const ScRange& rRange, const String& rStyle ) 130 { 131 aTimer.Stop(); 132 sal_uLong nNow = TimeNow(); 133 134 // alten Eintrag loeschen 135 136 sal_uLong nCount = aEntries.Count(); 137 sal_uLong i; 138 for (i=0; i<nCount; i++) 139 { 140 ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i); 141 if (pData->aRange == rRange) 142 { 143 delete pData; 144 aEntries.Remove(i); 145 --nCount; 146 break; // nicht weitersuchen - es kann nur einen geben 147 } 148 } 149 150 // Timeouts von allen Eintraegen anpassen 151 152 if (nCount && nNow != nTimerStart) 153 { 154 DBG_ASSERT(nNow>nTimerStart, "Zeit laeuft rueckwaerts?"); 155 AdjustEntries((nNow-nTimerStart)*1000); 156 } 157 158 // Einfuege-Position suchen 159 160 sal_uLong nPos = LIST_APPEND; 161 for (i=0; i<nCount && nPos == LIST_APPEND; i++) 162 if (nTimeout <= ((ScAutoStyleData*) aEntries.GetObject(i))->nTimeout) 163 nPos = i; 164 165 ScAutoStyleData* pNew = new ScAutoStyleData( nTimeout, rRange, rStyle ); 166 aEntries.Insert( pNew, nPos ); 167 168 // abgelaufene ausfuehren, Timer neu starten 169 170 ExecuteEntries(); 171 StartTimer(nNow); 172 } 173 174 void ScAutoStyleList::AdjustEntries( sal_uLong nDiff ) // Millisekunden 175 { 176 sal_uLong nCount = aEntries.Count(); 177 for (sal_uLong i=0; i<nCount; i++) 178 { 179 ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i); 180 if ( pData->nTimeout <= nDiff ) 181 pData->nTimeout = 0; // abgelaufen 182 else 183 pData->nTimeout -= nDiff; // weiterzaehlen 184 } 185 } 186 187 void ScAutoStyleList::ExecuteEntries() 188 { 189 ScAutoStyleData* pData; 190 while ((pData = (ScAutoStyleData*) aEntries.GetObject(0)) != NULL && pData->nTimeout == 0) 191 { 192 pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ??? 193 194 delete pData; 195 aEntries.Remove((sal_uLong)0); 196 } 197 } 198 199 void ScAutoStyleList::ExecuteAllNow() 200 { 201 aTimer.Stop(); 202 203 sal_uLong nCount = aEntries.Count(); 204 for (sal_uLong i=0; i<nCount; i++) 205 { 206 ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i); 207 208 pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ??? 209 210 delete pData; 211 } 212 aEntries.Clear(); 213 } 214 215 void ScAutoStyleList::StartTimer( sal_uLong nNow ) // Sekunden 216 { 217 // ersten Eintrag mit Timeout != 0 suchen 218 219 sal_uLong nPos = 0; 220 ScAutoStyleData* pData; 221 while ( (pData = (ScAutoStyleData*) aEntries.GetObject(nPos)) != NULL && pData->nTimeout == 0 ) 222 ++nPos; 223 224 if (pData) 225 { 226 aTimer.SetTimeout( pData->nTimeout ); 227 aTimer.Start(); 228 } 229 nTimerStart = nNow; 230 } 231 232 IMPL_LINK( ScAutoStyleList, TimerHdl, Timer*, EMPTYARG ) 233 { 234 sal_uLong nNow = TimeNow(); 235 AdjustEntries(aTimer.GetTimeout()); // eingestellte Wartezeit 236 ExecuteEntries(); 237 StartTimer(nNow); 238 239 return 0; 240 } 241 242 243 244 245