summaryrefslogtreecommitdiffstats
path: root/svx/source/editeng/impedit2.cxx
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2003-03-27 14:06:05 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2003-03-27 14:06:05 +0000
commit80204d8fcf35c14168a75765360eb61977653162 (patch)
treebef084bbf17b8e0d28743b03ea7213aafeae831e /svx/source/editeng/impedit2.cxx
parentnew version for SRX644 (diff)
downloadcore-80204d8fcf35c14168a75765360eb61977653162.tar.gz
core-80204d8fcf35c14168a75765360eb61977653162.zip
MWS_SRX644: migrate branch mws_srx644 -> HEAD
Diffstat (limited to 'svx/source/editeng/impedit2.cxx')
-rw-r--r--svx/source/editeng/impedit2.cxx359
1 files changed, 345 insertions, 14 deletions
diff --git a/svx/source/editeng/impedit2.cxx b/svx/source/editeng/impedit2.cxx
index ba7dcc7a1760..4b9204135b20 100644
--- a/svx/source/editeng/impedit2.cxx
+++ b/svx/source/editeng/impedit2.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: impedit2.cxx,v $
*
- * $Revision: 1.83 $
+ * $Revision: 1.84 $
*
- * last change: $Author: mt $ $Date: 2002-11-22 13:54:23 $
+ * last change: $Author: hr $ $Date: 2003-03-27 15:02:00 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -75,7 +75,8 @@
#include <eeobj.hxx>
#include <txtrange.hxx>
#include <svtools/urlbmk.hxx>
-
+#include <svtools/colorcfg.hxx>
+#include <svtools/ctloptions.hxx>
#include <fhgtitem.hxx>
#include <lrspitem.hxx>
@@ -188,6 +189,7 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
pUndoMarkSelection = NULL;
pTextRanger = NULL;
pColorConfig = NULL;
+ pCTLOptions = NULL;
nCurTextHeight = 0;
nBlockNotifications = 0;
@@ -266,6 +268,7 @@ ImpEditEngine::~ImpEditEngine()
delete pTextRanger;
delete mpIMEInfos;
delete pColorConfig;
+ delete pCTLOptions;
if ( bOwnerOfRefDev )
delete pRefDev;
}
@@ -867,6 +870,23 @@ EditSelection ImpEditEngine::MoveCursor( const KeyEvent& rKeyEvent, EditView* pE
BOOL bCtrl = aTranslatedKeyEvent.GetKeyCode().IsMod1() ? TRUE : FALSE;
USHORT nCode = aTranslatedKeyEvent.GetKeyCode().GetCode();
+ if ( DoVisualCursorTraveling( aPaM.GetNode() ) )
+ {
+ // Only for simple cursor movement...
+ if ( !bCtrl && ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ) )
+ {
+ aPaM = CursorVisualLeftRight( pEditView, aPaM, rKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL, rKeyEvent.GetKeyCode().GetCode() == KEY_LEFT );
+ nCode = 0; // skip switch statement
+ }
+ /*
+ else if ( !bCtrl && ( ( nCode == KEY_HOME ) || ( nCode == KEY_END ) ) )
+ {
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, nCode == KEY_HOME );
+ nCode = 0; // skip switch statement
+ }
+ */
+ }
+
switch ( nCode )
{
case KEY_UP: aPaM = CursorUp( aPaM, pEditView );
@@ -916,19 +936,273 @@ EditSelection ImpEditEngine::MoveCursor( const KeyEvent& rKeyEvent, EditView* pE
return pEditView->pImpEditView->GetEditSelection();
}
+EditPaM ImpEditEngine::CursorVisualStartEnd( EditView* pEditView, const EditPaM& rPaM, BOOL bStart )
+{
+ EditPaM aPaM( rPaM );
+
+ USHORT nPara = GetEditDoc().GetPos( aPaM.GetNode() );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+
+ USHORT nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ BOOL bEmptyLine = pLine->GetStart() == pLine->GetEnd();
+
+ pEditView->pImpEditView->nExtraCursorFlags = 0;
+
+ if ( !bEmptyLine )
+ {
+ String aLine( *aPaM.GetNode(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
+ USHORT nPosInLine = aPaM.GetIndex() - pLine->GetStart();
+
+ const sal_Unicode* pLineString = aLine.GetBuffer();
+
+ UErrorCode nError = U_ZERO_ERROR;
+ UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
+
+ const BYTE nDefaultDir = IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
+ ubidi_setPara( pBidi, pLineString, aLine.Len(), nDefaultDir, NULL, &nError );
+
+ USHORT nVisPos = bStart ? 0 : aLine.Len()-1;
+ USHORT nLogPos = (USHORT)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
+
+ ubidi_close( pBidi );
+
+ aPaM.GetIndex() = nLogPos + pLine->GetStart();
+
+ USHORT nTmp;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTmp, TRUE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ USHORT nRTLLevel = pTextPortion->GetRightToLeft();
+ BOOL bParaRTL = IsRightToLeft( nPara );
+ BOOL bPortionRTL = nRTLLevel%2 ? TRUE : FALSE;
+
+ if ( bStart )
+ {
+ pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 0 : 1 );
+ // Maybe we must be *behind* the character
+ if ( bPortionRTL && pEditView->IsInsertMode() )
+ aPaM.GetIndex()++;
+ }
+ else
+ {
+ pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 1 : 0 );
+ if ( !bPortionRTL && pEditView->IsInsertMode() )
+ aPaM.GetIndex()++;
+ }
+ }
+
+ return aPaM;
+}
+
+EditPaM ImpEditEngine::CursorVisualLeftRight( EditView* pEditView, const EditPaM& rPaM, USHORT nCharacterIteratorMode, BOOL bVisualToLeft )
+{
+ EditPaM aPaM( rPaM );
+
+ USHORT nPara = GetEditDoc().GetPos( aPaM.GetNode() );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+
+ USHORT nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
+ EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
+ BOOL bEmptyLine = pLine->GetStart() == pLine->GetEnd();
+
+ USHORT nCurrentCursorFlags = pEditView->pImpEditView->nExtraCursorFlags;
+ pEditView->pImpEditView->nExtraCursorFlags = 0;
+
+ BOOL bParaRTL = IsRightToLeft( nPara );
+
+ BOOL bDone = FALSE;
+
+ if ( bEmptyLine )
+ {
+ if ( bVisualToLeft )
+ {
+ aPaM = CursorUp( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, FALSE );
+ }
+ else
+ {
+ aPaM = CursorDown( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, TRUE );
+ }
+
+ bDone = TRUE;
+ }
+
+ BOOL bLogicalBackward = bParaRTL ? !bVisualToLeft : bVisualToLeft;
+
+ if ( !bDone && pEditView->IsInsertMode() )
+ {
+ // Check if we are within a portion and don't have overwrite mode, then it's easy...
+ USHORT nPortionStart;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, FALSE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+
+ BOOL bPortionBoundary = ( aPaM.GetIndex() == nPortionStart ) || ( aPaM.GetIndex() == (nPortionStart+pTextPortion->GetLen()) );
+ USHORT nRTLLevel = pTextPortion->GetRightToLeft();
+
+ // Portion boundary doesn't matter if both have same RTL level
+ USHORT nRTLLevelNextPortion = 0xFFFF;
+ if ( bPortionBoundary && aPaM.GetIndex() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
+ {
+ USHORT nTmp;
+ USHORT nNextTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex()+1, nTmp, bLogicalBackward ? FALSE : TRUE );
+ TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nNextTextPortion );
+ nRTLLevelNextPortion = pNextTextPortion->GetRightToLeft();
+ }
+
+ if ( !bPortionBoundary || ( nRTLLevel == nRTLLevelNextPortion ) )
+ {
+ if ( ( bVisualToLeft && !(nRTLLevel%2) ) || ( !bVisualToLeft && (nRTLLevel%2) ) )
+ {
+ aPaM = CursorLeft( aPaM, nCharacterIteratorMode );
+ pEditView->pImpEditView->SetCursorBidiLevel( 1 );
+ }
+ else
+ {
+ aPaM = CursorRight( aPaM, nCharacterIteratorMode );
+ pEditView->pImpEditView->SetCursorBidiLevel( 0 );
+ }
+ bDone = TRUE;
+ }
+ }
+
+ if ( !bDone )
+ {
+ BOOL bGotoStartOfNextLine = FALSE;
+ BOOL bGotoEndOfPrevLine = FALSE;
+
+ String aLine( *aPaM.GetNode(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
+ USHORT nPosInLine = aPaM.GetIndex() - pLine->GetStart();
+
+ const sal_Unicode* pLineString = aLine.GetBuffer();
+
+ UErrorCode nError = U_ZERO_ERROR;
+ UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
+
+ const BYTE nDefaultDir = IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
+ ubidi_setPara( pBidi, pLineString, aLine.Len(), nDefaultDir, NULL, &nError );
+
+ if ( !pEditView->IsInsertMode() )
+ {
+ BOOL bEndOfLine = nPosInLine == aLine.Len();
+ USHORT nVisPos = (USHORT)ubidi_getVisualIndex( pBidi, !bEndOfLine ? nPosInLine : nPosInLine-1, &nError );
+ if ( bVisualToLeft )
+ {
+ bGotoEndOfPrevLine = nVisPos == 0;
+ if ( !bEndOfLine )
+ nVisPos--;
+ }
+ else
+ {
+ bGotoStartOfNextLine = nVisPos == (aLine.Len() - 1);
+ if ( !bEndOfLine )
+ nVisPos++;
+ }
+
+ if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
+ {
+ USHORT nLogPos = (USHORT)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
+ aPaM.GetIndex() = pLine->GetStart() + nLogPos;
+ pEditView->pImpEditView->SetCursorBidiLevel( 0 );
+ }
+ }
+ else
+ {
+ BOOL bWasBehind = FALSE;
+ BOOL bBeforePortion = !nPosInLine || pEditView->pImpEditView->GetCursorBidiLevel() == 1;
+ if ( nPosInLine && ( !bBeforePortion ) ) // before the next portion
+ bWasBehind = TRUE; // step one back, otherwise visual will be unusable when rtl portion follows.
+
+ USHORT nPortionStart;
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, bBeforePortion );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ BOOL bRTLPortion = (pTextPortion->GetRightToLeft() % 2) != 0;
+
+ // -1: We are 'behind' the character
+ long nVisPos = (long)ubidi_getVisualIndex( pBidi, bWasBehind ? nPosInLine-1 : nPosInLine, &nError );
+ if ( bVisualToLeft )
+ {
+ if ( !bWasBehind || bRTLPortion )
+ nVisPos--;
+ }
+ else
+ {
+ if ( bWasBehind || bRTLPortion || bBeforePortion )
+ nVisPos++;
+// if ( bWasBehind && bRTLPortion )
+// nVisPos++;
+ }
+
+ bGotoEndOfPrevLine = nVisPos < 0;
+ bGotoStartOfNextLine = nVisPos >= aLine.Len();
+
+ if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
+ {
+ USHORT nLogPos = (USHORT)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
+
+/*
+ if ( nLogPos == aPaM.GetIndex() )
+ {
+ if ( bVisualToLeft )
+ bGotoEndOfPrevLine = TRUE;
+ else
+ bGotoStartOfNextLine = TRUE;
+ }
+ else
+*/
+ {
+ aPaM.GetIndex() = pLine->GetStart() + nLogPos;
+
+ // RTL portion, stay visually on the left side.
+ USHORT nPortionStart;
+ // USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, !bRTLPortion );
+ USHORT nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, TRUE );
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
+ if ( bVisualToLeft && !bRTLPortion && ( pTextPortion->GetRightToLeft() % 2 ) )
+ aPaM.GetIndex()++;
+ else if ( !bVisualToLeft && bRTLPortion && ( bWasBehind || !(pTextPortion->GetRightToLeft() % 2 )) )
+ aPaM.GetIndex()++;
+
+ pEditView->pImpEditView->SetCursorBidiLevel( nPortionStart );
+ }
+ }
+ }
+
+ ubidi_close( pBidi );
+
+ if ( bGotoEndOfPrevLine )
+ {
+ aPaM = CursorUp( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, FALSE );
+ }
+ else if ( bGotoStartOfNextLine )
+ {
+ aPaM = CursorDown( aPaM, pEditView );
+ if ( aPaM != rPaM )
+ aPaM = CursorVisualStartEnd( pEditView, aPaM, TRUE );
+ }
+ }
+ return aPaM;
+}
+
+
EditPaM ImpEditEngine::CursorLeft( const EditPaM& rPaM, USHORT nCharacterIteratorMode )
{
- EditPaM aNewPaM( rPaM );
+ EditPaM aCurPaM( rPaM );
+ EditPaM aNewPaM( aCurPaM );
- if ( rPaM.GetIndex() )
+ if ( aCurPaM.GetIndex() )
{
- uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
sal_Int32 nCount = 1;
- aNewPaM.SetIndex( (USHORT)xBI->previousCharacters( *aNewPaM.GetNode(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount ) );
+ uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
+ aNewPaM.SetIndex( (USHORT)xBI->previousCharacters( *aNewPaM.GetNode(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount ) );
}
else
{
- ContentNode* pNode = rPaM.GetNode();
+ ContentNode* pNode = aCurPaM.GetNode();
pNode = GetPrevVisNode( pNode );
if ( pNode )
{
@@ -942,8 +1216,10 @@ EditPaM ImpEditEngine::CursorLeft( const EditPaM& rPaM, USHORT nCharacterIterato
EditPaM ImpEditEngine::CursorRight( const EditPaM& rPaM, USHORT nCharacterIteratorMode )
{
- EditPaM aNewPaM( rPaM );
- if ( rPaM.GetIndex() < rPaM.GetNode()->Len() )
+ EditPaM aCurPaM( rPaM );
+ EditPaM aNewPaM( aCurPaM );
+
+ if ( aCurPaM.GetIndex() < aCurPaM.GetNode()->Len() )
{
uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
sal_Int32 nCount = 1;
@@ -951,7 +1227,7 @@ EditPaM ImpEditEngine::CursorRight( const EditPaM& rPaM, USHORT nCharacterIterat
}
else
{
- ContentNode* pNode = rPaM.GetNode();
+ ContentNode* pNode = aCurPaM.GetNode();
pNode = GetNextVisNode( pNode );
if ( pNode )
{
@@ -1545,6 +1821,27 @@ BOOL ImpEditEngine::IsRightToLeft( USHORT nPara ) const
return bR2L;
}
+BOOL ImpEditEngine::HasDifferentRTLLevels( const ContentNode* pNode )
+{
+ USHORT nPara = GetEditDoc().GetPos( (ContentNode*)pNode );
+ ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
+
+ BOOL bHasDifferentRTLLevels = FALSE;
+
+ USHORT nRTLLevel = IsRightToLeft( nPara ) ? 1 : 0;
+ for ( USHORT n = 0; n < pParaPortion->GetTextPortions().Count(); n++ )
+ {
+ TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( n );
+ if ( pTextPortion->GetRightToLeft() != nRTLLevel )
+ {
+ bHasDifferentRTLLevels = TRUE;
+ break;
+ }
+ }
+ return bHasDifferentRTLLevels;
+}
+
+
BYTE ImpEditEngine::GetRightToLeft( USHORT nPara, USHORT nPos, USHORT* pStart, USHORT* pEnd )
{
// BYTE nRightToLeft = IsRightToLeft( nPara ) ? 1 : 0;
@@ -2380,7 +2677,7 @@ BOOL ImpEditEngine::UpdateFields()
pField->Reset();
if ( aStatus.MarkFields() )
- pField->GetFldColor() = new Color( GetColorConfig().GetColorValue( svx::WRITERFIELDSHADINGS ).nColor );
+ pField->GetFldColor() = new Color( GetColorConfig().GetColorValue( svtools::WRITERFIELDSHADINGS ).nColor );
XubString aFldValue = GetEditEnginePtr()->CalcFieldValue(
(const SvxFieldItem&)*pField->GetItem(),
@@ -3789,14 +4086,48 @@ void ImpEditEngine::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTabl
EE_DLL()->GetGlobalData()->SetForbiddenCharsTable( xForbiddenChars );
}
-svx::ColorConfig& ImpEditEngine::GetColorConfig()
+svtools::ColorConfig& ImpEditEngine::GetColorConfig()
{
if ( !pColorConfig )
- pColorConfig = new svx::ColorConfig;
+ pColorConfig = new svtools::ColorConfig;
return *pColorConfig;
}
+BOOL ImpEditEngine::IsVisualCursorTravelingEnabled()
+{
+ BOOL bVisualCursorTravaling = FALSE;
+
+ if( !pCTLOptions )
+ pCTLOptions = new SvtCTLOptions;
+
+ if ( pCTLOptions->IsCTLFontEnabled() && ( pCTLOptions->GetCTLCursorMovement() == SvtCTLOptions::MOVEMENT_VISUAL ) )
+ {
+ bVisualCursorTravaling = TRUE;
+ }
+
+ return bVisualCursorTravaling;
+
+}
+
+BOOL ImpEditEngine::DoVisualCursorTraveling( const ContentNode* pNode )
+{
+ // Don't check if it's necessary, because we also need it when leaving the paragraph
+ return IsVisualCursorTravelingEnabled();
+/*
+ BOOL bDoVisualCursorTraveling = FALSE;
+
+ if ( IsVisualCursorTravelingEnabled() && pNode->Len() )
+ {
+ // Only necessary when RTL text in LTR para or LTR text in RTL para
+ bDoVisualCursorTraveling = HasDifferentRTLLevels( pNode );
+ }
+
+ return bDoVisualCursorTraveling;
+*/
+}
+
+
void ImpEditEngine::CallNotify( EENotify& rNotify )
{
if ( !nBlockNotifications )