Files
libreoffice/sw/source/core/inc/wrong.hxx
Keith Curtis ff6f3164df Simplify DrawWave
This patch simplifies the DrawWave logic. Callers of that code would try to
figure out what size wave to draw and pass down a style integer to
DrawWaveLine, but DrawWaveLine already has logic which trims the height of the
wave so it doesn't need the hint.

This doesn't change the UNO API
(::com::sun::awt::FontUnderline::SMALLWAVE), but it does get rid of
internal usages and maps those small waves to normal.

Note that changing the zoom in Calc right now causes spelling underlines to
disappear. That bug is not related to these changes.

Conflicts:
	editeng/source/editeng/impedit3.cxx

Change-Id: I3caa2a74a0f5228b924d4e1b0a77f96eaef5fa00
Reviewed-on: https://gerrit.libreoffice.org/8168
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2014-03-05 09:01:11 -06:00

282 lines
9.3 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#ifndef INCLUDED_SW_SOURCE_CORE_INC_WRONG_HXX
#define INCLUDED_SW_SOURCE_CORE_INC_WRONG_HXX
#include <com/sun/star/container/XStringKeyMap.hpp>
#include <com/sun/star/util/Color.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <vector>
#include <tools/color.hxx>
#include <swtypes.hxx>
#include <viewopt.hxx>
class SwWrongList;
enum WrongAreaLineType
{
WRONGAREA_DASHED,
WRONGAREA_WAVE,
WRONGAREA_NONE
};
enum WrongListType
{
WRONGLIST_SPELL,
WRONGLIST_GRAMMAR,
WRONGLIST_SMARTTAG,
WRONGLIST_CHANGETRACKING
};
// ST2
class SwWrongArea
{
public:
OUString maType;
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > mxPropertyBag;
sal_Int32 mnPos;
sal_Int32 mnLen;
SwWrongList* mpSubList;
Color mColor;
WrongAreaLineType mLineType;
SwWrongArea( const OUString& rType,
WrongListType listType,
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
sal_Int32 nPos,
sal_Int32 nLen);
SwWrongArea( const OUString& rType,
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
sal_Int32 nPos,
sal_Int32 nLen,
SwWrongList* pSubList);
private:
SwWrongArea() : mnPos(0), mnLen(0), mpSubList(NULL), mColor(0,0,0), mLineType(WRONGAREA_WAVE) {}
Color getSmartColor ( com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag)
{
try
{
if (xPropertyBag.is())
{
const ::rtl::OUString colorKey("LineColor");
com::sun::star::uno::Any aLineColor = xPropertyBag->getValue(colorKey).get< com::sun::star::uno::Any>();
com::sun::star::util::Color lineColor = 0;
if (aLineColor >>= lineColor)
{
return Color( lineColor );
}
}
}
catch(const ::com::sun::star::container::NoSuchElementException&)
{
}
catch(const ::com::sun::star::uno::RuntimeException&)
{
}
return SwViewOption::GetSmarttagColor( );
}
WrongAreaLineType getSmartLineType( com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag )
{
try
{
if (xPropertyBag.is())
{
const ::rtl::OUString typeKey("LineType");
com::sun::star::uno::Any aLineType = xPropertyBag->getValue(typeKey).get< com::sun::star::uno::Any>();
::sal_Int16 lineType = 0;
if (!(aLineType >>= lineType))
{
return WRONGAREA_DASHED;
}
if (::com::sun::star::awt::FontUnderline::WAVE == lineType)
{
return WRONGAREA_WAVE;
}
if (::com::sun::star::awt::FontUnderline::SMALLWAVE == lineType)
{
return WRONGAREA_WAVE; //Code draws wave height based on space that fits.
}
}
}
catch(const ::com::sun::star::container::NoSuchElementException&)
{
}
catch(const ::com::sun::star::uno::RuntimeException&)
{
}
return WRONGAREA_DASHED;
}
Color getWrongAreaColor(WrongListType listType,
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag )
{
if (WRONGLIST_SPELL == listType)
{
return SwViewOption::GetSpellColor();
}
else if (WRONGLIST_GRAMMAR == listType)
{
return Color( COL_LIGHTBLUE );
}
else if (WRONGLIST_SMARTTAG == listType)
{
return getSmartColor(xPropertyBag);
}
return SwViewOption::GetSpellColor();
}
WrongAreaLineType getWrongAreaLineType(WrongListType listType,
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag )
{
if (WRONGLIST_SPELL == listType)
{
return WRONGAREA_WAVE;
}
else if (WRONGLIST_GRAMMAR == listType)
{
return WRONGAREA_WAVE;
}
else if (WRONGLIST_SMARTTAG == listType)
{
return getSmartLineType(xPropertyBag);
}
return WRONGAREA_WAVE;
}
};
class SwWrongList
{
std::vector<SwWrongArea> maList;
WrongListType meType;
sal_Int32 nBeginInvalid; // Start of the invalid range
sal_Int32 nEndInvalid; // End of the invalid range
void ShiftLeft( sal_Int32 &rPos, sal_Int32 nStart, sal_Int32 nEnd )
{ if( rPos > nStart ) rPos = rPos > nEnd ? rPos - nEnd + nStart : nStart; }
void ShiftRight( sal_Int32 &rPos, sal_Int32 nStart, sal_Int32 nEnd )
{ if( rPos >= nStart ) rPos += nStart - nEnd; }
void _Invalidate( sal_Int32 nBegin, sal_Int32 nEnd );
void Insert(sal_uInt16 nWhere, std::vector<SwWrongArea>::iterator startPos, std::vector<SwWrongArea>::iterator endPos);
void Remove( sal_uInt16 nIdx, sal_uInt16 nLen );
// forbidden and not implemented
SwWrongList& operator= (const SwWrongList &);
SwWrongList( const SwWrongList& rCpy );
public:
SwWrongList( WrongListType eType );
virtual ~SwWrongList();
virtual SwWrongList* Clone();
virtual void CopyFrom( const SwWrongList& rCopy );
inline WrongListType GetWrongListType() const { return meType; }
inline sal_Int32 GetBeginInv() const { return nBeginInvalid; }
inline sal_Int32 GetEndInv() const { return nEndInvalid; }
inline bool InsideInvalid( sal_Int32 nChk ) const
{ return nChk >= nBeginInvalid && nChk <= nEndInvalid; }
void SetInvalid( sal_Int32 nBegin, sal_Int32 nEnd );
inline void Validate(){ nBeginInvalid = COMPLETE_STRING; }
void Invalidate( sal_Int32 nBegin, sal_Int32 nEnd );
bool InvalidateWrong();
bool Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
sal_Int32 nLen, sal_uInt16 nIndex, sal_Int32 nCursorPos );
sal_uInt16 GetWrongPos( sal_Int32 nValue ) const;
bool Check( sal_Int32 &rChk, sal_Int32 &rLn ) const;
bool InWrongWord( sal_Int32 &rChk, sal_Int32 &rLn ) const;
sal_Int32 NextWrong( sal_Int32 nChk ) const;
void Move( sal_Int32 nPos, sal_Int32 nDiff );
void ClearList();
// Divide the list into two part, the wrong words until nSplitPos will be
// removed and transferred to a new SwWrongList.
SwWrongList* SplitList( sal_Int32 nSplitPos );
// Join the next SwWrongList, nInsertPos is my own text length, where
// the other wrong list has to be inserted.
void JoinList( SwWrongList* pNext, sal_Int32 nInsertPos );
inline sal_Int32 Len( sal_uInt16 nIdx ) const
{
return nIdx < maList.size() ? maList[nIdx].mnLen : 0;
}
inline sal_Int32 Pos( sal_uInt16 nIdx ) const
{
return nIdx < maList.size() ? maList[nIdx].mnPos : 0;
}
inline sal_uInt16 Count() const { return (sal_uInt16)maList.size(); }
inline void Insert( const OUString& rType,
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
sal_Int32 nNewPos, sal_Int32 nNewLen, sal_uInt16 nWhere )
{
std::vector<SwWrongArea>::iterator i = maList.begin();
if ( nWhere >= maList.size() )
i = maList.end(); // robust
else
i += nWhere;
maList.insert(i, SwWrongArea( rType, meType, xPropertyBag, nNewPos, nNewLen) );
}
void Insert( const OUString& rType,
com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
sal_Int32 nNewPos, sal_Int32 nNewLen );
inline SwWrongList* SubList( sal_uInt16 nIdx ) const
{
return nIdx < maList.size() ? maList[nIdx].mpSubList : 0;
}
void InsertSubList( sal_Int32 nNewPos, sal_Int32 nNewLen, sal_uInt16 nWhere, SwWrongList* pSubList );
inline const SwWrongArea* GetElement( sal_uInt16 nIdx ) const
{
return nIdx < maList.size() ? &maList[nIdx] : 0;
}
void RemoveEntry( sal_Int32 nBegin, sal_Int32 nEnd );
bool LookForEntry( sal_Int32 nBegin, sal_Int32 nEnd );
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */