diff options
Diffstat (limited to 'sw/source/ui/docvw/srcedtw.cxx')
-rw-r--r-- | sw/source/ui/docvw/srcedtw.cxx | 971 |
1 files changed, 971 insertions, 0 deletions
diff --git a/sw/source/ui/docvw/srcedtw.cxx b/sw/source/ui/docvw/srcedtw.cxx new file mode 100644 index 000000000000..d84c4d2d26f0 --- /dev/null +++ b/sw/source/ui/docvw/srcedtw.cxx @@ -0,0 +1,971 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <hintids.hxx> +#include <cmdid.h> + + +#include <svtools/textview.hxx> +#include <svx/svxids.hrc> +#include <vcl/scrbar.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/app.hxx> +#include <svtools/htmltokn.h> +#include <svtools/txtattr.hxx> +#include <unotools/sourceviewconfig.hxx> +#include <svtools/colorcfg.hxx> +#include <editeng/flstitem.hxx> +#include <vcl/metric.hxx> +#include <svtools/ctrltool.hxx> +#include <tools/time.hxx> +#include <swmodule.hxx> +#include <docsh.hxx> +#include <srcview.hxx> +#include <helpid.h> +#include <deque> + + + +struct SwTextPortion +{ + sal_uInt16 nLine; + sal_uInt16 nStart, nEnd; + svtools::ColorConfigEntry eType; +}; + +#define MAX_SYNTAX_HIGHLIGHT 20 +#define MAX_HIGHLIGHTTIME 200 +#define SYNTAX_HIGHLIGHT_TIMEOUT 200 + +typedef std::deque<SwTextPortion> SwTextPortions; + +static void lcl_Highlight(const String& rSource, SwTextPortions& aPortionList) +{ + const sal_Unicode cOpenBracket = '<'; + const sal_Unicode cCloseBracket= '>'; + const sal_Unicode cSlash = '/'; + const sal_Unicode cExclamation = '!'; + const sal_Unicode cMinus = '-'; + const sal_Unicode cSpace = ' '; + const sal_Unicode cTab = 0x09; + const sal_Unicode cLF = 0x0a; + const sal_Unicode cCR = 0x0d; + + + const sal_uInt16 nStrLen = rSource.Len(); + sal_uInt16 nInsert = 0; // number of inserted portions + sal_uInt16 nActPos = 0; // position, where '<' was found + sal_uInt16 nOffset = 0; // Offset of nActPos to '<' + sal_uInt16 nPortStart = USHRT_MAX; // for the TextPortion + sal_uInt16 nPortEnd = 0; // + SwTextPortion aText; + while(nActPos < nStrLen) + { + svtools::ColorConfigEntry eFoundType = svtools::HTMLUNKNOWN; + if(rSource.GetChar(nActPos) == cOpenBracket && nActPos < nStrLen - 2 ) + { + // insert 'empty' portion + if(nPortEnd < nActPos - 1 ) + { + aText.nLine = 0; + // don't move at the beginning + aText.nStart = nPortEnd; + if(nInsert) + aText.nStart += 1; + aText.nEnd = nActPos - 1; + aText.eType = svtools::HTMLUNKNOWN; + aPortionList.push_back( aText ); + nInsert++; + } + sal_Unicode cFollowFirst = rSource.GetChar((xub_StrLen)(nActPos + 1)); + sal_Unicode cFollowNext = rSource.GetChar((xub_StrLen)(nActPos + 2)); + if(cExclamation == cFollowFirst) + { + // "<!" SGML or comment + if(cMinus == cFollowNext && + nActPos < nStrLen - 3 && cMinus == rSource.GetChar((xub_StrLen)(nActPos + 3))) + { + eFoundType = svtools::HTMLCOMMENT; + } + else + eFoundType = svtools::HTMLSGML; + nPortStart = nActPos; + nPortEnd = nActPos + 1; + } + else if(cSlash == cFollowFirst) + { + // "</" ignore slash + nPortStart = nActPos; + nActPos++; + nOffset++; + } + if(svtools::HTMLUNKNOWN == eFoundType) + { + // now here a keyword could follow + sal_uInt16 nSrchPos = nActPos; + while(++nSrchPos < nStrLen - 1) + { + sal_Unicode cNext = rSource.GetChar(nSrchPos); + if( cNext == cSpace || + cNext == cTab || + cNext == cLF || + cNext == cCR) + break; + else if(cNext == cCloseBracket) + { + break; + } + } + if(nSrchPos > nActPos + 1) + { + // some string was found + String sToken = rSource.Copy(nActPos + 1, nSrchPos - nActPos - 1 ); + sToken.ToUpperAscii(); + int nToken = ::GetHTMLToken(sToken); + if(nToken) + { + // Token was found + eFoundType = svtools::HTMLKEYWORD; + nPortEnd = nSrchPos; + nPortStart = nActPos; + } + else + { + // what was that? +#if OSL_DEBUG_LEVEL > 1 + OSL_FAIL("Token not recognised!"); + OSL_FAIL(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer()); +#endif + } + + } + } + // now we still have to look for '>' + if(svtools::HTMLUNKNOWN != eFoundType) + { + sal_Bool bFound = sal_False; + for(sal_uInt16 i = nPortEnd; i < nStrLen; i++) + if(cCloseBracket == rSource.GetChar(i)) + { + bFound = sal_True; + nPortEnd = i; + break; + } + if(!bFound && (eFoundType == svtools::HTMLCOMMENT)) + { + // comment without ending in this line + bFound = sal_True; + nPortEnd = nStrLen - 1; + } + + if(bFound ||(eFoundType == svtools::HTMLCOMMENT)) + { + SwTextPortion aTextPortion; + aTextPortion.nLine = 0; + aTextPortion.nStart = nPortStart + 1; + aTextPortion.nEnd = nPortEnd; + aTextPortion.eType = eFoundType; + aPortionList.push_back( aTextPortion ); + nInsert++; + eFoundType = svtools::HTMLUNKNOWN; + } + + } + } + nActPos++; + } + if(nInsert && nPortEnd < nActPos - 1) + { + aText.nLine = 0; + aText.nStart = nPortEnd + 1; + aText.nEnd = nActPos - 1; + aText.eType = svtools::HTMLUNKNOWN; + aPortionList.push_back( aText ); + nInsert++; + } +} + +SwSrcEditWindow::SwSrcEditWindow( Window* pParent, SwSrcView* pParentView ) : + Window( pParent, WB_BORDER|WB_CLIPCHILDREN ), + + pTextEngine(0), + + pOutWin(0), + pHScrollbar(0), + pVScrollbar(0), + + pSrcView(pParentView), + pSourceViewConfig(new utl::SourceViewConfig), + + nCurTextWidth(0), + nStartLine(USHRT_MAX), + eSourceEncoding(gsl_getSystemTextEncoding()), + bDoSyntaxHighlight(sal_True), + bHighlighting(sal_False) +{ + SetHelpId(HID_SOURCE_EDITWIN); + CreateTextEngine(); + pSourceViewConfig->AddListener(this); +} + + SwSrcEditWindow::~SwSrcEditWindow() +{ + pSourceViewConfig->RemoveListener(this); + delete pSourceViewConfig; + aSyntaxIdleTimer.Stop(); + if ( pTextEngine ) + { + EndListening( *pTextEngine ); + pTextEngine->RemoveView( pTextView ); + + delete pHScrollbar; + delete pVScrollbar; + + delete pTextView; + delete pTextEngine; + } + delete pOutWin; +} + +void SwSrcEditWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + switch ( rDCEvt.GetType() ) + { + case DATACHANGED_SETTINGS: + // newly rearrange ScrollBars or trigger Resize, because + // ScrollBar size could have changed. For this, in the + // Resize handler the size of ScrollBars has to be queried + // from the settings as well. + if( rDCEvt.GetFlags() & SETTINGS_STYLE ) + Resize(); + break; + } +} + +void SwSrcEditWindow::Resize() +{ + // ScrollBars, etc. happens in Adjust... + if ( pTextView ) + { + long nVisY = pTextView->GetStartDocPos().Y(); + pTextView->ShowCursor(); + Size aOutSz( GetOutputSizePixel() ); + long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height(); + if ( nMaxVisAreaStart < 0 ) + nMaxVisAreaStart = 0; + if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart ) + { + Point aStartDocPos( pTextView->GetStartDocPos() ); + aStartDocPos.Y() = nMaxVisAreaStart; + pTextView->SetStartDocPos( aStartDocPos ); + pTextView->ShowCursor(); + } + long nScrollStd = GetSettings().GetStyleSettings().GetScrollBarSize(); + Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd ); + Point aScrollPos(0, aOutSz.Height() - nScrollStd); + + pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz); + + aScrollSz.Width() = aScrollSz.Height(); + aScrollSz.Height() = aOutSz.Height(); + aScrollPos = Point(aOutSz.Width() - nScrollStd, 0); + + pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz); + aOutSz.Width() -= nScrollStd; + aOutSz.Height() -= nScrollStd; + pOutWin->SetOutputSizePixel(aOutSz); + InitScrollBars(); + + // set line in first Resize + if(USHRT_MAX != nStartLine) + { + if(nStartLine < pTextEngine->GetParagraphCount()) + { + TextSelection aSel(TextPaM( nStartLine, 0 ), TextPaM( nStartLine, 0x0 )); + pTextView->SetSelection(aSel); + pTextView->ShowCursor(); + } + nStartLine = USHRT_MAX; + } + + if ( nVisY != pTextView->GetStartDocPos().Y() ) + Invalidate(); + } + +} + +void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + switch( rDCEvt.GetType() ) + { + case DATACHANGED_SETTINGS: + // query settings + if( rDCEvt.GetFlags() & SETTINGS_STYLE ) + { + const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor(); + SetBackground( rCol ); + Font aFont( pTextView->GetTextEngine()->GetFont() ); + aFont.SetFillColor( rCol ); + pTextView->GetTextEngine()->SetFont( aFont ); + } + break; + } +} + +void TextViewOutWin::MouseMove( const MouseEvent &rEvt ) +{ + if ( pTextView ) + pTextView->MouseMove( rEvt ); +} + +void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt ) +{ + if ( pTextView ) + { + pTextView->MouseButtonUp( rEvt ); + SfxBindings& rBindings = ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->GetBindings(); + rBindings.Invalidate( SID_TABLE_CELL ); + rBindings.Invalidate( SID_CUT ); + rBindings.Invalidate( SID_COPY ); + } +} + +void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt ) +{ + GrabFocus(); + if ( pTextView ) + pTextView->MouseButtonDown( rEvt ); +} + +void TextViewOutWin::Command( const CommandEvent& rCEvt ) +{ + switch(rCEvt.GetCommand()) + { + case COMMAND_CONTEXTMENU: + ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()-> + GetDispatcher()->ExecutePopup(); + break; + case COMMAND_WHEEL: + case COMMAND_STARTAUTOSCROLL: + case COMMAND_AUTOSCROLL: + { + const CommandWheelData* pWData = rCEvt.GetWheelData(); + if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() ) + { + ((SwSrcEditWindow*)GetParent())->HandleWheelCommand( rCEvt ); + } + } + break; + + default: + if ( pTextView ) + pTextView->Command( rCEvt ); + else + Window::Command(rCEvt); + } +} + +void TextViewOutWin::KeyInput( const KeyEvent& rKEvt ) +{ + sal_Bool bDone = sal_False; + SwSrcEditWindow* pSrcEditWin = (SwSrcEditWindow*)GetParent(); + sal_Bool bChange = !pSrcEditWin->IsReadonly() || !TextEngine::DoesKeyChangeText( rKEvt ); + if(bChange) + bDone = pTextView->KeyInput( rKEvt ); + + SfxBindings& rBindings = ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->GetBindings(); + if ( !bDone ) + { + if ( !SfxViewShell::Current()->KeyInput( rKEvt ) ) + Window::KeyInput( rKEvt ); + } + else + { + rBindings.Invalidate( SID_TABLE_CELL ); + if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) + rBindings.Update( SID_BASICIDE_STAT_POS ); + if (pSrcEditWin->GetTextEngine()->IsModified() ) + { + rBindings.Invalidate( SID_SAVEDOC ); + rBindings.Invalidate( SID_DOC_MODIFIED ); + } + if( rKEvt.GetKeyCode().GetCode() == KEY_INSERT ) + rBindings.Invalidate( SID_ATTR_INSERT ); + } + + rBindings.Invalidate( SID_CUT ); + rBindings.Invalidate( SID_COPY ); + + SwDocShell* pDocShell = pSrcEditWin->GetSrcView()->GetDocShell(); + if(pSrcEditWin->GetTextEngine()->IsModified()) + { + pDocShell->SetModified(); + } +} + +void TextViewOutWin::Paint( const Rectangle& rRect ) +{ + pTextView->Paint( rRect ); +} + +void SwSrcEditWindow::CreateTextEngine() +{ + const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor(); + pOutWin = new TextViewOutWin(this, 0); + pOutWin->SetBackground(Wallpaper(rCol)); + pOutWin->SetPointer(Pointer(POINTER_TEXT)); + pOutWin->Show(); + + // create Scrollbars + pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG); + pHScrollbar->EnableRTL( false ); // --- RTL --- no mirroring for scrollbars + pHScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, ScrollHdl)); + pHScrollbar->Show(); + + pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG); + pVScrollbar->EnableRTL( false ); // --- RTL --- no mirroring for scrollbars + pVScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, ScrollHdl)); + pHScrollbar->EnableDrag(); + pVScrollbar->Show(); + + pTextEngine = new ExtTextEngine; + pTextView = new ExtTextView( pTextEngine, pOutWin ); + pTextView->SetAutoIndentMode(sal_True); + pOutWin->SetTextView(pTextView); + + pTextEngine->SetUpdateMode( sal_False ); + pTextEngine->InsertView( pTextView ); + + Font aFont; + aFont.SetTransparent( sal_False ); + aFont.SetFillColor( rCol ); + SetPointFont( aFont ); + aFont = GetFont(); + aFont.SetFillColor( rCol ); + pOutWin->SetFont( aFont ); + pTextEngine->SetFont( aFont ); + + aSyntaxIdleTimer.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT ); + aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, SwSrcEditWindow, SyntaxTimerHdl ) ); + + pTextEngine->EnableUndo( sal_True ); + pTextEngine->SetUpdateMode( sal_True ); + + pTextView->ShowCursor( sal_True, sal_True ); + InitScrollBars(); + StartListening( *pTextEngine ); + + SfxBindings& rBind = GetSrcView()->GetViewFrame()->GetBindings(); + rBind.Invalidate( SID_TABLE_CELL ); +} + +void SwSrcEditWindow::SetScrollBarRanges() +{ + // Extra method, not InitScrollBars, because also for TextEngine events. + + pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) ); + pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) ); +} + +void SwSrcEditWindow::InitScrollBars() +{ + SetScrollBarRanges(); + + Size aOutSz( pOutWin->GetOutputSizePixel() ); + pVScrollbar->SetVisibleSize( aOutSz.Height() ); + pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 ); + pVScrollbar->SetLineSize( pOutWin->GetTextHeight() ); + pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); + pHScrollbar->SetVisibleSize( aOutSz.Width() ); + pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 ); + pHScrollbar->SetLineSize( pOutWin->GetTextWidth( 'x' ) ); + pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() ); + +} + +IMPL_LINK(SwSrcEditWindow, ScrollHdl, ScrollBar*, pScroll) +{ + if(pScroll == pVScrollbar) + { + long nDiff = pTextView->GetStartDocPos().Y() - pScroll->GetThumbPos(); + GetTextView()->Scroll( 0, nDiff ); + pTextView->ShowCursor( sal_False, sal_True ); + pScroll->SetThumbPos( pTextView->GetStartDocPos().Y() ); + } + else + { + long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos(); + GetTextView()->Scroll( nDiff, 0 ); + pTextView->ShowCursor( sal_False, sal_True ); + pScroll->SetThumbPos( pTextView->GetStartDocPos().X() ); + } + GetSrcView()->GetViewFrame()->GetBindings().Invalidate( SID_TABLE_CELL ); + return 0; +} + +IMPL_LINK( SwSrcEditWindow, SyntaxTimerHdl, Timer *, pTimer ) +{ + Time aSyntaxCheckStart; + OSL_ENSURE( pTextView, "Noch keine View, aber Syntax-Highlight ?!" ); + + bHighlighting = sal_True; + sal_uInt16 nLine; + sal_uInt16 nCount = 0; + // at first the region around the cursor is processed + TextSelection aSel = pTextView->GetSelection(); + sal_uInt16 nCur = (sal_uInt16)aSel.GetStart().GetPara(); + if(nCur > 40) + nCur -= 40; + else + nCur = 0; + if(aSyntaxLineTable.Count()) + for(sal_uInt16 i = 0; i < 80 && nCount < 40; i++, nCur++) + { + void * p = aSyntaxLineTable.Get(nCur); + if(p) + { + DoSyntaxHighlight( nCur ); + aSyntaxLineTable.Remove( nCur ); + nCount++; + if(!aSyntaxLineTable.Count()) + break; + if((Time().GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME ) + { + pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT ); + break; + } + } + } + + // when there is still anything left by then, go on from the beginning + void* p = aSyntaxLineTable.First(); + while ( p && nCount < MAX_SYNTAX_HIGHLIGHT) + { + nLine = (sal_uInt16)aSyntaxLineTable.GetCurKey(); + DoSyntaxHighlight( nLine ); + sal_uInt16 nCurKey = (sal_uInt16)aSyntaxLineTable.GetCurKey(); + p = aSyntaxLineTable.Next(); + aSyntaxLineTable.Remove(nCurKey); + nCount ++; + if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME) + { + pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT ); + break; + } + } + + if(aSyntaxLineTable.Count() && !pTimer->IsActive()) + pTimer->Start(); + // SyntaxTimerHdl is called when text changed + // => good opportunity to determine text width! + long nPrevTextWidth = nCurTextWidth; + nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz + if ( nCurTextWidth != nPrevTextWidth ) + SetScrollBarRanges(); + bHighlighting = sal_False; + + return 0; +} + +void SwSrcEditWindow::DoSyntaxHighlight( sal_uInt16 nPara ) +{ + // Because of DelayedSyntaxHighlight it could happen, + // that the line doesn't exist anymore! + if ( nPara < pTextEngine->GetParagraphCount() ) + { + sal_Bool bTempModified = IsModified(); + pTextEngine->RemoveAttribs( nPara, (sal_Bool)sal_True ); + String aSource( pTextEngine->GetText( nPara ) ); + pTextEngine->SetUpdateMode( sal_False ); + ImpDoHighlight( aSource, nPara ); + TextView* pTmp = pTextEngine->GetActiveView(); + pTmp->SetAutoScroll(sal_False); + pTextEngine->SetActiveView(0); + pTextEngine->SetUpdateMode( sal_True ); + pTextEngine->SetActiveView(pTmp); + pTmp->SetAutoScroll(sal_True); + pTmp->ShowCursor( sal_False/*pTmp->IsAutoScroll()*/ ); + + if(!bTempModified) + ClearModifyFlag(); + } +} + +void SwSrcEditWindow::DoDelayedSyntaxHighlight( sal_uInt16 nPara ) +{ + if ( !bHighlighting && bDoSyntaxHighlight ) + { + aSyntaxLineTable.Insert( nPara, (void*)(sal_uInt16)1 ); + aSyntaxIdleTimer.Start(); + } +} + +void SwSrcEditWindow::ImpDoHighlight( const String& rSource, sal_uInt16 nLineOff ) +{ + SwTextPortions aPortionList; + lcl_Highlight(rSource, aPortionList); + + size_t nCount = aPortionList.size(); + if ( !nCount ) + return; + + SwTextPortion& rLast = aPortionList[nCount-1]; + if ( rLast.nStart > rLast.nEnd ) // Only until Bug from MD is resolved + { + nCount--; + aPortionList.pop_back(); + if ( !nCount ) + return; + } + + // maybe optimize: + // If frequently the same color, blank without color in between, + // maybe summarize or at least the blank; for less attributes + sal_Bool bOptimizeHighlight = sal_True; // war in der BasicIDE static + if ( bOptimizeHighlight ) + { + // Only blanks and tabs have to be attributed along. + // When two identical attributes are placed consecutively, + // it optimises the TextEngine. + sal_uInt16 nLastEnd = 0; + + for ( size_t i = 0; i < nCount; i++ ) + { + SwTextPortion& r = aPortionList[i]; +#if OSL_DEBUG_LEVEL > 1 + sal_uInt16 nLine = aPortionList[0].nLine; + OSL_ENSURE( r.nLine == nLine, "doch mehrere Zeilen ?" ); +#endif + if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved + continue; + + if ( r.nStart > nLastEnd ) + { + // Can I rely on the fact that all except blank and tab + // are being highlighted?! + r.nStart = nLastEnd; + } + nLastEnd = r.nEnd+1; + if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) ) + r.nEnd = rSource.Len(); + } + } + + for ( size_t i = 0; i < aPortionList.size(); i++ ) + { + SwTextPortion& r = aPortionList[i]; + if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved + continue; + if(r.eType != svtools::HTMLSGML && + r.eType != svtools::HTMLCOMMENT && + r.eType != svtools::HTMLKEYWORD && + r.eType != svtools::HTMLUNKNOWN) + r.eType = svtools::HTMLUNKNOWN; + Color aColor((ColorData)SW_MOD()->GetColorConfig().GetColorValue((svtools::ColorConfigEntry)r.eType).nColor); + sal_uInt16 nLine = nLineOff+r.nLine; // + pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1, sal_True ); + } +} + +void SwSrcEditWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) +{ + if ( rHint.ISA( TextHint ) ) + { + const TextHint& rTextHint = (const TextHint&)rHint; + if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED ) + { + pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() ); + pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); + } + else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED ) + { + if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() ) + pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() ); + pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() ); + SetScrollBarRanges(); + } + else if( ( rTextHint.GetId() == TEXT_HINT_PARAINSERTED ) || + ( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED ) ) + { + DoDelayedSyntaxHighlight( (sal_uInt16)rTextHint.GetValue() ); + } + } +} + +void SwSrcEditWindow::ConfigurationChanged( utl::ConfigurationBroadcaster* pBrdCst, sal_uInt32 ) +{ + if( pBrdCst == pSourceViewConfig) + SetFont(); +} + +void SwSrcEditWindow::Invalidate(sal_uInt16 ) +{ + pOutWin->Invalidate(); + Window::Invalidate(); + +} + +void SwSrcEditWindow::Command( const CommandEvent& rCEvt ) +{ + switch(rCEvt.GetCommand()) + { + case COMMAND_WHEEL: + case COMMAND_STARTAUTOSCROLL: + case COMMAND_AUTOSCROLL: + { + const CommandWheelData* pWData = rCEvt.GetWheelData(); + if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() ) + HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar ); + } + break; + default: + Window::Command(rCEvt); + } +} + +void SwSrcEditWindow::HandleWheelCommand( const CommandEvent& rCEvt ) +{ + pTextView->Command(rCEvt); + HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar ); +} + +void SwSrcEditWindow::GetFocus() +{ + pOutWin->GrabFocus(); +} + +sal_Bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[]) +{ + switch(eEnc) + { + case RTL_TEXTENCODING_UTF7 : + case RTL_TEXTENCODING_UTF8 : + // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used + break; + + + case RTL_TEXTENCODING_ISO_8859_3: + case RTL_TEXTENCODING_ISO_8859_1 : + case RTL_TEXTENCODING_MS_1252 : + case RTL_TEXTENCODING_APPLE_ROMAN : + case RTL_TEXTENCODING_IBM_850 : + case RTL_TEXTENCODING_ISO_8859_14 : + case RTL_TEXTENCODING_ISO_8859_15 : + //fill with western languages + aLanguages[0] = LANGUAGE_GERMAN; + aLanguages[1] = LANGUAGE_FRENCH; + aLanguages[2] = LANGUAGE_ITALIAN; + aLanguages[3] = LANGUAGE_SPANISH; + break; + + case RTL_TEXTENCODING_IBM_865 : + //scandinavian + aLanguages[0] = LANGUAGE_FINNISH; + aLanguages[1] = LANGUAGE_NORWEGIAN; + aLanguages[2] = LANGUAGE_SWEDISH; + aLanguages[3] = LANGUAGE_DANISH; + break; + + case RTL_TEXTENCODING_ISO_8859_10 : + case RTL_TEXTENCODING_ISO_8859_13 : + case RTL_TEXTENCODING_ISO_8859_2 : + case RTL_TEXTENCODING_IBM_852 : + case RTL_TEXTENCODING_MS_1250 : + case RTL_TEXTENCODING_APPLE_CENTEURO : + aLanguages[0] = LANGUAGE_POLISH; + aLanguages[1] = LANGUAGE_CZECH; + aLanguages[2] = LANGUAGE_HUNGARIAN; + aLanguages[3] = LANGUAGE_SLOVAK; + break; + + case RTL_TEXTENCODING_ISO_8859_4 : + case RTL_TEXTENCODING_IBM_775 : + case RTL_TEXTENCODING_MS_1257 : + aLanguages[0] = LANGUAGE_LATVIAN ; + aLanguages[1] = LANGUAGE_LITHUANIAN; + aLanguages[2] = LANGUAGE_ESTONIAN ; + break; + + case RTL_TEXTENCODING_IBM_863 : aLanguages[0] = LANGUAGE_FRENCH_CANADIAN; break; + case RTL_TEXTENCODING_APPLE_FARSI : aLanguages[0] = LANGUAGE_FARSI; break; + case RTL_TEXTENCODING_APPLE_ROMANIAN:aLanguages[0] = LANGUAGE_ROMANIAN; break; + + case RTL_TEXTENCODING_IBM_861 : + case RTL_TEXTENCODING_APPLE_ICELAND : + aLanguages[0] = LANGUAGE_ICELANDIC; + break; + + case RTL_TEXTENCODING_APPLE_CROATIAN:aLanguages[0] = LANGUAGE_CROATIAN; break; + + case RTL_TEXTENCODING_IBM_437 : + case RTL_TEXTENCODING_ASCII_US : aLanguages[0] = LANGUAGE_ENGLISH; break; + + case RTL_TEXTENCODING_IBM_862 : + case RTL_TEXTENCODING_MS_1255 : + case RTL_TEXTENCODING_APPLE_HEBREW : + case RTL_TEXTENCODING_ISO_8859_8 : + aLanguages[0] = LANGUAGE_HEBREW; + break; + + case RTL_TEXTENCODING_IBM_857 : + case RTL_TEXTENCODING_MS_1254 : + case RTL_TEXTENCODING_APPLE_TURKISH: + case RTL_TEXTENCODING_ISO_8859_9 : + aLanguages[0] = LANGUAGE_TURKISH; + break; + + case RTL_TEXTENCODING_IBM_860 : + aLanguages[0] = LANGUAGE_PORTUGUESE; + break; + + case RTL_TEXTENCODING_IBM_869 : + case RTL_TEXTENCODING_MS_1253 : + case RTL_TEXTENCODING_APPLE_GREEK : + case RTL_TEXTENCODING_ISO_8859_7 : + case RTL_TEXTENCODING_IBM_737 : + aLanguages[0] = LANGUAGE_GREEK; + break; + + case RTL_TEXTENCODING_KOI8_R : + case RTL_TEXTENCODING_ISO_8859_5 : + case RTL_TEXTENCODING_IBM_855 : + case RTL_TEXTENCODING_MS_1251 : + case RTL_TEXTENCODING_IBM_866 : + case RTL_TEXTENCODING_APPLE_CYRILLIC : + aLanguages[0] = LANGUAGE_RUSSIAN; + break; + + case RTL_TEXTENCODING_APPLE_UKRAINIAN: + case RTL_TEXTENCODING_KOI8_U: + aLanguages[0] = LANGUAGE_UKRAINIAN; + break; + + case RTL_TEXTENCODING_IBM_864 : + case RTL_TEXTENCODING_MS_1256 : + case RTL_TEXTENCODING_ISO_8859_6 : + case RTL_TEXTENCODING_APPLE_ARABIC : + aLanguages[0] = LANGUAGE_ARABIC_SAUDI_ARABIA; + break; + + case RTL_TEXTENCODING_APPLE_CHINTRAD : + case RTL_TEXTENCODING_MS_950 : + case RTL_TEXTENCODING_GBT_12345 : + case RTL_TEXTENCODING_BIG5 : + case RTL_TEXTENCODING_EUC_TW : + case RTL_TEXTENCODING_BIG5_HKSCS : + aLanguages[0] = LANGUAGE_CHINESE_TRADITIONAL; + break; + + case RTL_TEXTENCODING_EUC_JP : + case RTL_TEXTENCODING_ISO_2022_JP : + case RTL_TEXTENCODING_JIS_X_0201 : + case RTL_TEXTENCODING_JIS_X_0208 : + case RTL_TEXTENCODING_JIS_X_0212 : + case RTL_TEXTENCODING_APPLE_JAPANESE : + case RTL_TEXTENCODING_MS_932 : + case RTL_TEXTENCODING_SHIFT_JIS : + aLanguages[0] = LANGUAGE_JAPANESE; + break; + + case RTL_TEXTENCODING_GB_2312 : + case RTL_TEXTENCODING_MS_936 : + case RTL_TEXTENCODING_GBK : + case RTL_TEXTENCODING_GB_18030 : + case RTL_TEXTENCODING_APPLE_CHINSIMP : + case RTL_TEXTENCODING_EUC_CN : + case RTL_TEXTENCODING_ISO_2022_CN : + aLanguages[0] = LANGUAGE_CHINESE_SIMPLIFIED; + break; + + case RTL_TEXTENCODING_APPLE_KOREAN : + case RTL_TEXTENCODING_MS_949 : + case RTL_TEXTENCODING_EUC_KR : + case RTL_TEXTENCODING_ISO_2022_KR : + case RTL_TEXTENCODING_MS_1361 : + aLanguages[0] = LANGUAGE_KOREAN; + break; + + case RTL_TEXTENCODING_APPLE_THAI : + case RTL_TEXTENCODING_MS_874 : + case RTL_TEXTENCODING_TIS_620 : + aLanguages[0] = LANGUAGE_THAI; + break; + default: aLanguages[0] = Application::GetSettings().GetUILanguage(); + } + return aLanguages[0] != LANGUAGE_SYSTEM; +} +void SwSrcEditWindow::SetFont() +{ + String sFontName = pSourceViewConfig->GetFontName(); + if(!sFontName.Len()) + { + LanguageType aLanguages[5] = + { + LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM + }; + Font aFont; + if(lcl_GetLanguagesForEncoding(eSourceEncoding, aLanguages)) + { + //TODO: check for multiple languages + aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_FIXED, aLanguages[0], 0, this); + } + else + aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_SANS_UNICODE, + Application::GetSettings().GetLanguage(), 0, this); + sFontName = aFont.GetName(); + } + const SvxFontListItem* pFontListItem = + (const SvxFontListItem* )pSrcView->GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST ); + const FontList* pList = pFontListItem->GetFontList(); + FontInfo aInfo = pList->Get(sFontName,WEIGHT_NORMAL, ITALIC_NONE); + + const Font& rFont = GetTextEngine()->GetFont(); + Font aFont(aInfo); + Size aSize(rFont.GetSize()); + //font height is stored in point and set in twip + aSize.Height() = pSourceViewConfig->GetFontHeight() * 20; + aFont.SetSize(pOutWin->LogicToPixel(aSize, MAP_TWIP)); + GetTextEngine()->SetFont( aFont ); + pOutWin->SetFont(aFont); +} + +void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding) +{ + eSourceEncoding = eEncoding; + SetFont(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |