blob: c83bd963ce1babb18fb286dc1f656533dc6a8f1e [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 "csvcontrol.hxx"
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
#include "AccessibleCsvControl.hxx"
// ============================================================================
ScCsvLayoutData::ScCsvLayoutData() :
mnPosCount( 1 ),
mnPosOffset( 0 ),
mnWinWidth( 1 ),
mnHdrWidth( 0 ),
mnCharWidth( 1 ),
mnLineCount( 1 ),
mnLineOffset( 0 ),
mnWinHeight( 1 ),
mnHdrHeight( 0 ),
mnLineHeight( 1 ),
mnPosCursor( CSV_POS_INVALID ),
mnColCursor( 0 ),
mnNoRepaint( 0 ),
mbAppRTL( !!Application::GetSettings().GetLayoutRTL() )
{
}
ScCsvDiff ScCsvLayoutData::GetDiff( const ScCsvLayoutData& rData ) const
{
ScCsvDiff nRet = CSV_DIFF_EQUAL;
if( mnPosCount != rData.mnPosCount ) nRet |= CSV_DIFF_POSCOUNT;
if( mnPosOffset != rData.mnPosOffset ) nRet |= CSV_DIFF_POSOFFSET;
if( mnHdrWidth != rData.mnHdrWidth ) nRet |= CSV_DIFF_HDRWIDTH;
if( mnCharWidth != rData.mnCharWidth ) nRet |= CSV_DIFF_CHARWIDTH;
if( mnLineCount != rData.mnLineCount ) nRet |= CSV_DIFF_LINECOUNT;
if( mnLineOffset != rData.mnLineOffset ) nRet |= CSV_DIFF_LINEOFFSET;
if( mnHdrHeight != rData.mnHdrHeight ) nRet |= CSV_DIFF_HDRHEIGHT;
if( mnLineHeight != rData.mnLineHeight ) nRet |= CSV_DIFF_LINEHEIGHT;
if( mnPosCursor != rData.mnPosCursor ) nRet |= CSV_DIFF_RULERCURSOR;
if( mnColCursor != rData.mnColCursor ) nRet |= CSV_DIFF_GRIDCURSOR;
return nRet;
}
// ============================================================================
ScCsvControl::ScCsvControl( ScCsvControl& rParent ) :
Control( &rParent, WB_TABSTOP | WB_NODIALOGCONTROL ),
mrData( rParent.GetLayoutData() ),
mpAccessible( NULL ),
mbValidGfx( false )
{
}
ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, WinBits nStyle ) :
Control( pParent, nStyle ),
mrData( rData ),
mpAccessible( NULL ),
mbValidGfx( false )
{
}
ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, const ResId& rResId ) :
Control( pParent, rResId ),
mrData( rData ),
mpAccessible( NULL ),
mbValidGfx( false )
{
}
ScCsvControl::~ScCsvControl()
{
if( mpAccessible )
mpAccessible->dispose();
}
// event handling -------------------------------------------------------------
void ScCsvControl::GetFocus()
{
Control::GetFocus();
AccSendFocusEvent( true );
}
void ScCsvControl::LoseFocus()
{
Control::LoseFocus();
AccSendFocusEvent( false );
}
void ScCsvControl::AccSendFocusEvent( bool bFocused )
{
if( mpAccessible )
mpAccessible->SendFocusEvent( bFocused );
}
void ScCsvControl::AccSendCaretEvent()
{
if( mpAccessible )
mpAccessible->SendCaretEvent();
}
void ScCsvControl::AccSendVisibleEvent()
{
if( mpAccessible )
mpAccessible->SendVisibleEvent();
}
void ScCsvControl::AccSendSelectionEvent()
{
if( mpAccessible )
mpAccessible->SendSelectionEvent();
}
void ScCsvControl::AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
{
if( mpAccessible )
mpAccessible->SendTableUpdateEvent( nFirstColumn, nLastColumn, bAllRows );
}
void ScCsvControl::AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
{
if( mpAccessible )
mpAccessible->SendInsertColumnEvent( nFirstColumn, nLastColumn );
}
void ScCsvControl::AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
{
if( mpAccessible )
mpAccessible->SendRemoveColumnEvent( nFirstColumn, nLastColumn );
}
// repaint helpers ------------------------------------------------------------
void ScCsvControl::Repaint( bool bInvalidate )
{
if( bInvalidate )
InvalidateGfx();
if( !IsNoRepaint() )
Execute( CSVCMD_REPAINT );
}
void ScCsvControl::DisableRepaint()
{
++mrData.mnNoRepaint;
}
void ScCsvControl::EnableRepaint( bool bInvalidate )
{
DBG_ASSERT( IsNoRepaint(), "ScCsvControl::EnableRepaint - invalid call" );
--mrData.mnNoRepaint;
Repaint( bInvalidate );
}
// command handling -----------------------------------------------------------
void ScCsvControl::Execute( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 )
{
maCmd.Set( eType, nParam1, nParam2 );
maCmdHdl.Call( this );
}
// layout helpers -------------------------------------------------------------
sal_Int32 ScCsvControl::GetVisPosCount() const
{
return (mrData.mnWinWidth - GetHdrWidth()) / GetCharWidth();
}
sal_Int32 ScCsvControl::GetMaxPosOffset() const
{
return Max( GetPosCount() - GetVisPosCount() + 2L, 0L );
}
bool ScCsvControl::IsValidSplitPos( sal_Int32 nPos ) const
{
return (0 < nPos) && (nPos < GetPosCount() );
}
bool ScCsvControl::IsVisibleSplitPos( sal_Int32 nPos ) const
{
return IsValidSplitPos( nPos ) && (GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos());
}
sal_Int32 ScCsvControl::GetHdrX() const
{
return IsRTL() ? (mrData.mnWinWidth - GetHdrWidth()) : 0;
}
sal_Int32 ScCsvControl::GetFirstX() const
{
return IsRTL() ? 0 : GetHdrWidth();
}
sal_Int32 ScCsvControl::GetLastX() const
{
return mrData.mnWinWidth - (IsRTL() ? GetHdrWidth() : 0) - 1;
}
sal_Int32 ScCsvControl::GetX( sal_Int32 nPos ) const
{
return GetFirstX() + (nPos - GetFirstVisPos()) * GetCharWidth();
}
sal_Int32 ScCsvControl::GetPosFromX( sal_Int32 nX ) const
{
return (nX - GetFirstX() + GetCharWidth() / 2) / GetCharWidth() + GetFirstVisPos();
}
sal_Int32 ScCsvControl::GetVisLineCount() const
{
return (mrData.mnWinHeight - GetHdrHeight() - 2) / GetLineHeight() + 1;
}
sal_Int32 ScCsvControl::GetLastVisLine() const
{
return Min( GetFirstVisLine() + GetVisLineCount(), GetLineCount() ) - 1;
}
sal_Int32 ScCsvControl::GetMaxLineOffset() const
{
return Max( GetLineCount() - GetVisLineCount() + 1L, 0L );
}
bool ScCsvControl::IsValidLine( sal_Int32 nLine ) const
{
return (0 <= nLine) && (nLine < GetLineCount());
}
bool ScCsvControl::IsVisibleLine( sal_Int32 nLine ) const
{
return IsValidLine( nLine ) && (GetFirstVisLine() <= nLine) && (nLine <= GetLastVisLine());
}
sal_Int32 ScCsvControl::GetY( sal_Int32 nLine ) const
{
return GetHdrHeight() + (nLine - GetFirstVisLine()) * GetLineHeight();
}
sal_Int32 ScCsvControl::GetLineFromY( sal_Int32 nY ) const
{
return (nY - GetHdrHeight()) / GetLineHeight() + GetFirstVisLine();
}
// static helpers -------------------------------------------------------------
void ScCsvControl::ImplInvertRect( OutputDevice& rOutDev, const Rectangle& rRect )
{
rOutDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_RASTEROP );
rOutDev.SetLineColor( Color( COL_BLACK ) );
rOutDev.SetFillColor( Color( COL_BLACK ) );
rOutDev.SetRasterOp( ROP_INVERT );
rOutDev.DrawRect( rRect );
rOutDev.Pop();
}
ScMoveMode ScCsvControl::GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd )
{
switch( nCode )
{
case KEY_LEFT: return MOVE_PREV;
case KEY_RIGHT: return MOVE_NEXT;
}
if( bHomeEnd ) switch( nCode )
{
case KEY_HOME: return MOVE_FIRST;
case KEY_END: return MOVE_LAST;
}
return MOVE_NONE;
}
ScMoveMode ScCsvControl::GetVertDirection( sal_uInt16 nCode, bool bHomeEnd )
{
switch( nCode )
{
case KEY_UP: return MOVE_PREV;
case KEY_DOWN: return MOVE_NEXT;
case KEY_PAGEUP: return MOVE_PREVPAGE;
case KEY_PAGEDOWN: return MOVE_NEXTPAGE;
}
if( bHomeEnd ) switch( nCode )
{
case KEY_HOME: return MOVE_FIRST;
case KEY_END: return MOVE_LAST;
}
return MOVE_NONE;
}
// accessibility --------------------------------------------------------------
ScCsvControl::XAccessibleRef ScCsvControl::CreateAccessible()
{
mpAccessible = ImplCreateAccessible();
mxAccessible = mpAccessible;
return mxAccessible;
}
// ============================================================================