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
ScAutoStyleInitDataScAutoStyleInitData47 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
ScAutoStyleDataScAutoStyleData57 ScAutoStyleData( sal_uLong nT, const ScRange& rR, const String& rT ) :
58 nTimeout(nT), aRange(rR), aStyle(rT) {}
59 };
60
61 //==================================================================
62
TimeNow()63 inline sal_uLong TimeNow() // Sekunden
64 {
65 return (sal_uLong) time(0);
66 }
67
68 //==================================================================
69
ScAutoStyleList(ScDocShell * pShell)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
~ScAutoStyleList()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
AddInitial(const ScRange & rRange,const String & rStyle1,sal_uLong nTimeout,const String & rStyle2)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
IMPL_LINK(ScAutoStyleList,InitHdl,Timer *,EMPTYARG)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
AddEntry(sal_uLong nTimeout,const ScRange & rRange,const String & rStyle)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
AdjustEntries(sal_uLong nDiff)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
ExecuteEntries()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
ExecuteAllNow()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
StartTimer(sal_uLong nNow)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
IMPL_LINK(ScAutoStyleList,TimerHdl,Timer *,EMPTYARG)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