| /************************************************************** |
| * |
| * 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_sw.hxx" |
| |
| |
| #include <hintids.hxx> |
| #ifndef _CMDID_H |
| #include <cmdid.h> |
| #endif |
| |
| |
| #include <svtools/textview.hxx> |
| #ifndef _SVX_SVXIDS_HRC |
| #include <svx/svxids.hrc> |
| #endif |
| #ifndef _SCRBAR_HXX //autogen |
| #include <vcl/scrbar.hxx> |
| #endif |
| #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> |
| #ifndef _DOCSH_HXX |
| #include <docsh.hxx> |
| #endif |
| #ifndef _SRCVIEW_HXX |
| #include <srcview.hxx> |
| #endif |
| #ifndef _HELPID_H |
| #include <helpid.h> |
| #endif |
| #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, at the '<' was found |
| sal_uInt16 nOffset = 0; // Offset of nActPos for '<' |
| 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 ) |
| { |
| // 'leere' Portion einfuegen |
| if(nPortEnd < nActPos - 1 ) |
| { |
| aText.nLine = 0; |
| // am Anfang nicht verschieben |
| 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 oder Kommentar |
| 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) |
| { |
| // "</" Slash ignorieren |
| nPortStart = nActPos; |
| nActPos++; |
| nOffset++; |
| } |
| if(svtools::HTMLUNKNOWN == eFoundType) |
| { |
| //jetzt koennte hier ein keyword folgen |
| 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) |
| { |
| //irgend ein String wurde gefunden |
| String sToken = rSource.Copy(nActPos + 1, nSrchPos - nActPos - 1 ); |
| sToken.ToUpperAscii(); |
| int nToken = ::GetHTMLToken(sToken); |
| if(nToken) |
| { |
| //Token gefunden |
| eFoundType = svtools::HTMLKEYWORD; |
| nPortEnd = nSrchPos; |
| nPortStart = nActPos; |
| } |
| else |
| { |
| //was war das denn? |
| #if OSL_DEBUG_LEVEL > 1 |
| DBG_ERROR("Token nicht erkannt!"); |
| DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer()); |
| #endif |
| } |
| |
| } |
| } |
| // jetzt muss noch '>' gesucht werden |
| 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)) |
| { |
| // Kommentar ohne Ende in dieser Zeile |
| 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++; |
| } |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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); |
| } |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| 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; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| void SwSrcEditWindow::DataChanged( const DataChangedEvent& rDCEvt ) |
| { |
| Window::DataChanged( rDCEvt ); |
| |
| switch ( rDCEvt.GetType() ) |
| { |
| case DATACHANGED_SETTINGS: |
| // ScrollBars neu anordnen bzw. Resize ausloesen, da sich |
| // ScrollBar-Groesse geaendert haben kann. Dazu muss dann im |
| // Resize-Handler aber auch die Groesse der ScrollBars aus |
| // den Settings abgefragt werden. |
| if( rDCEvt.GetFlags() & SETTINGS_STYLE ) |
| Resize(); |
| break; |
| } |
| } |
| |
| void SwSrcEditWindow::Resize() |
| { |
| // ScrollBars, etc. passiert 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(); |
| |
| // Zeile im ersten Resize setzen |
| 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(); |
| } |
| |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt ) |
| { |
| Window::DataChanged( rDCEvt ); |
| |
| switch( rDCEvt.GetType() ) |
| { |
| case DATACHANGED_SETTINGS: |
| // den Settings abgefragt werden. |
| 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 ); |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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 ); |
| } |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt ) |
| { |
| GrabFocus(); |
| if ( pTextView ) |
| pTextView->MouseButtonDown( rEvt ); |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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); |
| } |
| } |
| |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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(); |
| } |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| void TextViewOutWin::Paint( const Rectangle& rRect ) |
| { |
| pTextView->Paint( rRect ); |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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(); |
| |
| //Scrollbars anlegen |
| pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG); |
| pHScrollbar->EnableRTL( false ); // #107300# --- 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 ); // #107300# --- 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 ); |
| // rBind.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| void SwSrcEditWindow::SetScrollBarRanges() |
| { |
| // Extra-Methode, nicht InitScrollBars, da auch fuer TextEngine-Events. |
| |
| pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) ); |
| pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) ); |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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() ); |
| |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| |
| 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; |
| } |
| |
| /*-----------------15.01.97 09.22------------------- |
| |
| --------------------------------------------------*/ |
| |
| IMPL_LINK( SwSrcEditWindow, SyntaxTimerHdl, Timer *, pTimer ) |
| { |
| Time aSyntaxCheckStart; |
| DBG_ASSERT( pTextView, "Noch keine View, aber Syntax-Highlight ?!" ); |
| // pTextEngine->SetUpdateMode( sal_False ); |
| |
| bHighlighting = sal_True; |
| sal_uInt16 nLine; |
| sal_uInt16 nCount = 0; |
| // zuerst wird der Bereich um dem Cursor bearbeitet |
| 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; |
| } |
| } |
| } |
| |
| // wenn dann noch etwas frei ist, wird von Beginn an weitergearbeitet |
| 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; |
| } |
| } |
| // os: #43050# hier wird ein TextView-Problem umpopelt: |
| // waehrend des Highlightings funktionierte das Scrolling nicht |
| /* MT: Shouldn't be a oproblem any more, using IdeFormatter in Insert/RemoveAttrib now. |
| |
| TextView* pTmp = pTextEngine->GetActiveView(); |
| pTextEngine->SetActiveView(0); |
| // pTextEngine->SetUpdateMode( sal_True ); |
| pTextEngine->SetActiveView(pTmp); |
| pTextView->ShowCursor(sal_False, sal_False); |
| */ |
| |
| if(aSyntaxLineTable.Count() && !pTimer->IsActive()) |
| pTimer->Start(); |
| // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung |
| // => gute Gelegenheit, Textbreite zu ermitteln! |
| long nPrevTextWidth = nCurTextWidth; |
| nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz |
| if ( nCurTextWidth != nPrevTextWidth ) |
| SetScrollBarRanges(); |
| bHighlighting = sal_False; |
| |
| return 0; |
| } |
| /*-----------------15.01.97 10.01------------------- |
| |
| --------------------------------------------------*/ |
| |
| void SwSrcEditWindow::DoSyntaxHighlight( sal_uInt16 nPara ) |
| { |
| // Durch das DelayedSyntaxHighlight kann es passieren, |
| // dass die Zeile nicht mehr existiert! |
| 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 ); |
| // os: #43050# hier wird ein TextView-Problem umpopelt: |
| // waehrend des Highlightings funktionierte das Scrolling nicht |
| TextView* pTmp = pTextEngine->GetActiveView(); |
| pTmp->SetAutoScroll(sal_False); |
| pTextEngine->SetActiveView(0); |
| pTextEngine->SetUpdateMode( sal_True ); |
| pTextEngine->SetActiveView(pTmp); |
| // Bug 72887 show the cursor |
| pTmp->SetAutoScroll(sal_True); |
| pTmp->ShowCursor( sal_False/*pTmp->IsAutoScroll()*/ ); |
| |
| if(!bTempModified) |
| ClearModifyFlag(); |
| } |
| } |
| |
| /*-----------------15.01.97 09.49------------------- |
| |
| --------------------------------------------------*/ |
| |
| void SwSrcEditWindow::DoDelayedSyntaxHighlight( sal_uInt16 nPara ) |
| { |
| if ( !bHighlighting && bDoSyntaxHighlight ) |
| { |
| aSyntaxLineTable.Insert( nPara, (void*)(sal_uInt16)1 ); |
| aSyntaxIdleTimer.Start(); |
| } |
| } |
| |
| /*-----------------15.01.97 11.32------------------- |
| |
| --------------------------------------------------*/ |
| |
| 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 ) // Nur bis Bug von MD behoeben |
| { |
| nCount--; |
| aPortionList.pop_back(); |
| if ( !nCount ) |
| return; |
| } |
| |
| // Evtl. Optimieren: |
| // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe, |
| // ggf. zusammenfassen, oder zumindest das Blank, |
| // damit weniger Attribute |
| sal_Bool bOptimizeHighlight = sal_True; // war in der BasicIDE static |
| if ( bOptimizeHighlight ) |
| { |
| // Es muessen nur die Blanks und Tabs mit attributiert werden. |
| // Wenn zwei gleiche Attribute hintereinander eingestellt werden, |
| // optimiert das die TextEngine. |
| sal_uInt16 nLastEnd = 0; |
| |
| #ifdef DBG_UTIL |
| sal_uInt16 nLine = aPortionList[0].nLine; |
| #endif |
| for ( size_t i = 0; i < nCount; i++ ) |
| { |
| SwTextPortion& r = aPortionList[i]; |
| DBG_ASSERT( r.nLine == nLine, "doch mehrere Zeilen ?" ); |
| if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben |
| continue; |
| |
| if ( r.nStart > nLastEnd ) |
| { |
| // Kann ich mich drauf verlassen, dass alle ausser |
| // Blank und Tab gehighlightet wird ?! |
| 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 ) // Nur bis Bug von MD behoeben |
| 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 ); |
| } |
| } |
| |
| /*-----------------30.06.97 09:12------------------- |
| |
| --------------------------------------------------*/ |
| |
| 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(); |
| } |
| |
| /*-----------------30.06.97 13:22------------------- |
| |
| --------------------------------------------------*/ |
| |
| 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(); |
| } |
| |
| /*void SwSrcEditWindow::LoseFocus() |
| { |
| Window::LoseFocus(); |
| // pOutWin->LoseFocus(); |
| // rView.LostFocus(); |
| } */ |
| /* -----------------------------29.08.2002 13:21------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| 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; |
| // case RTL_TEXTENCODING_SYMBOL : |
| // case RTL_TEXTENCODING_DONTKNOW: : |
| 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); |
| } |
| /* -----------------------------29.08.2002 13:47------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding) |
| { |
| eSourceEncoding = eEncoding; |
| SetFont(); |
| } |
| |