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