blob: 06a98bcdc48b3b57f940baf990540e23fdda19aa [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// INCLUDE ---------------------------------------------------------------
#include <time.h>
#include "autostyl.hxx"
#include "docsh.hxx"
#include "attrib.hxx"
#include "sc.hrc"
//==================================================================
struct ScAutoStyleInitData
{
ScRange aRange;
String aStyle1;
sal_uLong nTimeout;
String aStyle2;
ScAutoStyleInitData( const ScRange& rR, const String& rSt1, sal_uLong nT, const String& rSt2 ) :
aRange(rR), aStyle1(rSt1), nTimeout(nT), aStyle2(rSt2) {}
};
struct ScAutoStyleData
{
sal_uLong nTimeout;
ScRange aRange;
String aStyle;
ScAutoStyleData( sal_uLong nT, const ScRange& rR, const String& rT ) :
nTimeout(nT), aRange(rR), aStyle(rT) {}
};
//==================================================================
inline sal_uLong TimeNow() // Sekunden
{
return (sal_uLong) time(0);
}
//==================================================================
ScAutoStyleList::ScAutoStyleList(ScDocShell* pShell) :
pDocSh( pShell )
{
aTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, TimerHdl ) );
aInitTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, InitHdl ) );
aInitTimer.SetTimeout( 0 );
}
ScAutoStyleList::~ScAutoStyleList()
{
sal_uLong i;
sal_uLong nCount = aEntries.Count();
for (i=0; i<nCount; i++)
delete (ScAutoStyleData*) aEntries.GetObject(i);
nCount = aInitials.Count();
for (i=0; i<nCount; i++)
delete (ScAutoStyleInitData*) aInitials.GetObject(i);
}
//==================================================================
// initial short delay (asynchronous call)
void ScAutoStyleList::AddInitial( const ScRange& rRange, const String& rStyle1,
sal_uLong nTimeout, const String& rStyle2 )
{
ScAutoStyleInitData* pNew =
new ScAutoStyleInitData( rRange, rStyle1, nTimeout, rStyle2 );
aInitials.Insert( pNew, aInitials.Count() );
aInitTimer.Start();
}
IMPL_LINK( ScAutoStyleList, InitHdl, Timer*, EMPTYARG )
{
sal_uLong nCount = aInitials.Count();
for (sal_uLong i=0; i<nCount; i++)
{
ScAutoStyleInitData* pData = (ScAutoStyleInitData*) aInitials.GetObject(i);
// apply first style immediately
pDocSh->DoAutoStyle( pData->aRange, pData->aStyle1 );
// add second style to list
if ( pData->nTimeout )
AddEntry( pData->nTimeout, pData->aRange, pData->aStyle2 );
delete pData;
}
aInitials.Clear();
return 0;
}
//==================================================================
void ScAutoStyleList::AddEntry( sal_uLong nTimeout, const ScRange& rRange, const String& rStyle )
{
aTimer.Stop();
sal_uLong nNow = TimeNow();
// alten Eintrag loeschen
sal_uLong nCount = aEntries.Count();
sal_uLong i;
for (i=0; i<nCount; i++)
{
ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i);
if (pData->aRange == rRange)
{
delete pData;
aEntries.Remove(i);
--nCount;
break; // nicht weitersuchen - es kann nur einen geben
}
}
// Timeouts von allen Eintraegen anpassen
if (nCount && nNow != nTimerStart)
{
DBG_ASSERT(nNow>nTimerStart, "Zeit laeuft rueckwaerts?");
AdjustEntries((nNow-nTimerStart)*1000);
}
// Einfuege-Position suchen
sal_uLong nPos = LIST_APPEND;
for (i=0; i<nCount && nPos == LIST_APPEND; i++)
if (nTimeout <= ((ScAutoStyleData*) aEntries.GetObject(i))->nTimeout)
nPos = i;
ScAutoStyleData* pNew = new ScAutoStyleData( nTimeout, rRange, rStyle );
aEntries.Insert( pNew, nPos );
// abgelaufene ausfuehren, Timer neu starten
ExecuteEntries();
StartTimer(nNow);
}
void ScAutoStyleList::AdjustEntries( sal_uLong nDiff ) // Millisekunden
{
sal_uLong nCount = aEntries.Count();
for (sal_uLong i=0; i<nCount; i++)
{
ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i);
if ( pData->nTimeout <= nDiff )
pData->nTimeout = 0; // abgelaufen
else
pData->nTimeout -= nDiff; // weiterzaehlen
}
}
void ScAutoStyleList::ExecuteEntries()
{
ScAutoStyleData* pData;
while ((pData = (ScAutoStyleData*) aEntries.GetObject(0)) != NULL && pData->nTimeout == 0)
{
pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ???
delete pData;
aEntries.Remove((sal_uLong)0);
}
}
void ScAutoStyleList::ExecuteAllNow()
{
aTimer.Stop();
sal_uLong nCount = aEntries.Count();
for (sal_uLong i=0; i<nCount; i++)
{
ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i);
pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ???
delete pData;
}
aEntries.Clear();
}
void ScAutoStyleList::StartTimer( sal_uLong nNow ) // Sekunden
{
// ersten Eintrag mit Timeout != 0 suchen
sal_uLong nPos = 0;
ScAutoStyleData* pData;
while ( (pData = (ScAutoStyleData*) aEntries.GetObject(nPos)) != NULL && pData->nTimeout == 0 )
++nPos;
if (pData)
{
aTimer.SetTimeout( pData->nTimeout );
aTimer.Start();
}
nTimerStart = nNow;
}
IMPL_LINK( ScAutoStyleList, TimerHdl, Timer*, EMPTYARG )
{
sal_uLong nNow = TimeNow();
AdjustEntries(aTimer.GetTimeout()); // eingestellte Wartezeit
ExecuteEntries();
StartTimer(nNow);
return 0;
}