1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_filter.hxx"
31 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
32 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
33 #include <com/sun/star/xml/sax/SAXParseException.hpp>
34 #include <com/sun/star/xml/XImportFilter.hpp>
35 #include <com/sun/star/io/XActiveDataSource.hpp>
36 #include <comphelper/oslfile2streamwrap.hxx>
38 #include <rtl/tencinfo.h>
39 #include <vcl/svapp.hxx>
40 #include <osl/mutex.hxx>
41 #include <svtools/textview.hxx>
42 #include <vcl/scrbar.hxx>
43 #include <tools/stream.hxx>
44 #include <tools/time.hxx>
45 #include <osl/file.hxx>
46 #include <vcl/msgbox.hxx>
47 #include <svtools/colorcfg.hxx>
48 #include <svtools/htmltokn.h>
49 #include <svtools/txtattr.hxx>
51 #include "xmlfilterdialogstrings.hrc"
52 #include "xmlfiltersettingsdialog.hxx"
53 #include "xmlfileview.hxx"
54 #include "xmlfileview.hrc"
55 #include "xmlfilterhelpids.hrc"
59 using namespace com::sun::star::lang
;
60 using namespace com::sun::star::beans
;
61 using namespace com::sun::star::uno
;
62 using namespace com::sun::star::io
;
63 using namespace com::sun::star::xml
;
64 using namespace com::sun::star::xml::sax
;
67 #define MAX_SYNTAX_HIGHLIGHT 20
68 #define MAX_HIGHLIGHTTIME 200
69 #define SYNTAX_HIGHLIGHT_TIMEOUT 200
76 svtools::ColorConfigEntry eType
;
79 SV_DECL_VARARR(SwTextPortions
, SwTextPortion
,16,16)
80 SV_IMPL_VARARR(SwTextPortions
, SwTextPortion
);
82 class XMLErrorHandler
: public ::cppu::WeakImplHelper1
< XErrorHandler
>
85 XMLErrorHandler( XMLSourceFileDialog
* pParent
, ListBox
& rListBox
);
88 virtual void SAL_CALL
error( const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
);
89 virtual void SAL_CALL
fatalError( const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
);
90 virtual void SAL_CALL
warning( const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
);
93 XMLSourceFileDialog
* mpParent
;
97 XMLErrorHandler::XMLErrorHandler( XMLSourceFileDialog
* pParent
, ListBox
& rListBox
)
98 : mpParent( pParent
),
104 void SAL_CALL
XMLErrorHandler::error( const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
)
106 ::SolarMutexGuard aGuard
;
109 if( aSAXParseException
>>= e
)
111 String
sErr( String::CreateFromInt32( e
.LineNumber
) );
112 sErr
+= String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
113 sErr
+= String( e
.Message
);
114 USHORT nEntry
= mrListBox
.InsertEntry( sErr
);
115 mrListBox
.SetEntryData( nEntry
, (void*)e
.LineNumber
);
119 void SAL_CALL
XMLErrorHandler::fatalError( const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
)
121 ::SolarMutexGuard aGuard
;
124 if( aSAXParseException
>>= e
)
126 String
sErr( String::CreateFromInt32( e
.LineNumber
) );
127 sErr
+= String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
128 sErr
+= String( e
.Message
);
129 USHORT nEntry
= mrListBox
.InsertEntry( sErr
);
130 mrListBox
.SetEntryData( nEntry
, (void*)e
.LineNumber
);
134 void SAL_CALL
XMLErrorHandler::warning( const Any
& /* aSAXParseException */ ) throw (SAXException
, RuntimeException
)
138 if( aSAXParseException >>= e )
140 String sErr( String::CreateFromInt32( e.LineNumber ) );
141 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
142 sErr += String( e.Message );
143 USHORT nEntry = mrListBox.InsertEntry( sErr );
144 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
150 XMLFileWindow::XMLFileWindow( Window
* pParent
) :
151 Window( pParent
, WB_BORDER
|WB_CLIPCHILDREN
),
157 nStartLine(USHRT_MAX
),
158 eSourceEncoding(gsl_getSystemTextEncoding()),
164 XMLFileWindow::~XMLFileWindow()
168 EndListening( *pTextEngine
);
169 pTextEngine
->RemoveView( pTextView
);
180 void XMLFileWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
182 Window::DataChanged( rDCEvt
);
184 switch ( rDCEvt
.GetType() )
186 case DATACHANGED_SETTINGS
:
187 // ScrollBars neu anordnen bzw. Resize ausloesen, da sich
188 // ScrollBar-Groesse geaendert haben kann. Dazu muss dann im
189 // Resize-Handler aber auch die Groesse der ScrollBars aus
190 // den Settings abgefragt werden.
191 if( rDCEvt
.GetFlags() & SETTINGS_STYLE
)
197 void XMLFileWindow::Resize()
199 // ScrollBars, etc. passiert in Adjust...
202 long nVisY
= pTextView
->GetStartDocPos().Y();
203 pTextView
->ShowCursor();
204 Size
aOutSz( GetOutputSizePixel() );
205 long nMaxVisAreaStart
= pTextView
->GetTextEngine()->GetTextHeight() - aOutSz
.Height();
206 if ( nMaxVisAreaStart
< 0 )
207 nMaxVisAreaStart
= 0;
208 if ( pTextView
->GetStartDocPos().Y() > nMaxVisAreaStart
)
210 Point
aStartDocPos( pTextView
->GetStartDocPos() );
211 aStartDocPos
.Y() = nMaxVisAreaStart
;
212 pTextView
->SetStartDocPos( aStartDocPos
);
213 pTextView
->ShowCursor();
215 long nScrollStd
= GetSettings().GetStyleSettings().GetScrollBarSize();
216 Size
aScrollSz(aOutSz
.Width() - nScrollStd
, nScrollStd
);
217 Point
aScrollPos(0, aOutSz
.Height() - nScrollStd
);
219 pHScrollbar
->SetPosSizePixel( aScrollPos
, aScrollSz
);
221 aScrollSz
.Width() = aScrollSz
.Height();
222 aScrollSz
.Height() = aOutSz
.Height() - aScrollSz
.Height();
223 aScrollPos
= Point(aOutSz
.Width() - nScrollStd
, 0);
225 pVScrollbar
->SetPosSizePixel( aScrollPos
, aScrollSz
);
226 aOutSz
.Width() -= nScrollStd
;
227 aOutSz
.Height() -= nScrollStd
;
228 pOutWin
->SetOutputSizePixel(aOutSz
);
231 // Zeile im ersten Resize setzen
232 if(USHRT_MAX
!= nStartLine
)
234 if(nStartLine
< pTextEngine
->GetParagraphCount())
236 TextSelection
aSel(TextPaM( nStartLine
, 0 ), TextPaM( nStartLine
, 0x0 ));
237 pTextView
->SetSelection(aSel
);
238 pTextView
->ShowCursor();
240 nStartLine
= USHRT_MAX
;
243 if ( nVisY
!= pTextView
->GetStartDocPos().Y() )
249 void TextViewOutWin::DataChanged( const DataChangedEvent
& rDCEvt
)
251 Window::DataChanged( rDCEvt
);
253 switch( rDCEvt
.GetType() )
255 case DATACHANGED_SETTINGS
:
256 // den Settings abgefragt werden.
257 if( rDCEvt
.GetFlags() & SETTINGS_STYLE
)
259 const Color
&rCol
= GetSettings().GetStyleSettings().GetWindowColor();
260 SetBackground( rCol
);
261 Font
aFont( pTextView
->GetTextEngine()->GetFont() );
262 aFont
.SetFillColor( rCol
);
263 pTextView
->GetTextEngine()->SetFont( aFont
);
269 void TextViewOutWin::MouseMove( const MouseEvent
&rEvt
)
272 pTextView
->MouseMove( rEvt
);
275 void TextViewOutWin::MouseButtonUp( const MouseEvent
&rEvt
)
278 pTextView
->MouseButtonUp( rEvt
);
281 void TextViewOutWin::MouseButtonDown( const MouseEvent
&rEvt
)
285 pTextView
->MouseButtonDown( rEvt
);
288 void TextViewOutWin::Command( const CommandEvent
& rCEvt
)
290 switch(rCEvt
.GetCommand())
292 case COMMAND_CONTEXTMENU
:
295 case COMMAND_STARTAUTOSCROLL
:
296 case COMMAND_AUTOSCROLL
:
298 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
299 if( !pWData
|| COMMAND_WHEEL_ZOOM
!= pWData
->GetMode() )
301 ((XMLFileWindow
*)GetParent())->HandleWheelCommand( rCEvt
);
308 pTextView
->Command( rCEvt
);
310 Window::Command(rCEvt
);
314 void TextViewOutWin::KeyInput( const KeyEvent
& rKEvt
)
316 if(!TextEngine::DoesKeyChangeText( rKEvt
))
317 pTextView
->KeyInput( rKEvt
);
320 void TextViewOutWin::Paint( const Rectangle
& rRect
)
322 pTextView
->Paint( rRect
);
325 void XMLFileWindow::CreateTextEngine()
327 const Color
&rCol
= GetSettings().GetStyleSettings().GetWindowColor();
328 pOutWin
= new TextViewOutWin(this, 0);
329 pOutWin
->SetBackground(Wallpaper(rCol
));
330 pOutWin
->SetPointer(Pointer(POINTER_TEXT
));
334 pHScrollbar
= new ScrollBar(this, WB_3DLOOK
|WB_HSCROLL
|WB_DRAG
);
335 pHScrollbar
->SetScrollHdl(LINK(this, XMLFileWindow
, ScrollHdl
));
338 pVScrollbar
= new ScrollBar(this, WB_3DLOOK
|WB_VSCROLL
|WB_DRAG
);
339 pVScrollbar
->SetScrollHdl(LINK(this, XMLFileWindow
, ScrollHdl
));
340 pHScrollbar
->EnableDrag();
343 pTextEngine
= new TextEngine
;
344 pTextView
= new TextView( pTextEngine
, pOutWin
);
345 pTextView
->SetAutoIndentMode(TRUE
);
346 pOutWin
->SetTextView(pTextView
);
348 pTextEngine
->SetUpdateMode( FALSE
);
349 pTextEngine
->InsertView( pTextView
);
352 aFont
.SetTransparent( FALSE
);
353 aFont
.SetFillColor( rCol
);
354 SetPointFont( aFont
);
356 aFont
.SetFillColor( rCol
);
357 pOutWin
->SetFont( aFont
);
358 pTextEngine
->SetFont( aFont
);
360 aSyntaxIdleTimer
.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT
);
361 aSyntaxIdleTimer
.SetTimeoutHdl( LINK( this, XMLFileWindow
, SyntaxTimerHdl
) );
363 pTextEngine
->EnableUndo( FALSE
);
364 pTextEngine
->SetUpdateMode( TRUE
);
366 // pTextView->ShowCursor( TRUE, TRUE );
367 pTextView
->HideCursor();
370 StartListening( *pTextEngine
);
373 void XMLFileWindow::SetScrollBarRanges()
375 pHScrollbar
->SetRange( Range( 0, nCurTextWidth
-1 ) );
376 pVScrollbar
->SetRange( Range(0, pTextEngine
->GetTextHeight()-1) );
379 void XMLFileWindow::InitScrollBars()
381 SetScrollBarRanges();
383 Size
aOutSz( pOutWin
->GetOutputSizePixel() );
384 pVScrollbar
->SetVisibleSize( aOutSz
.Height() );
385 pVScrollbar
->SetPageSize( aOutSz
.Height() * 8 / 10 );
386 pVScrollbar
->SetLineSize( pOutWin
->GetTextHeight() );
387 pVScrollbar
->SetThumbPos( pTextView
->GetStartDocPos().Y() );
388 pHScrollbar
->SetVisibleSize( aOutSz
.Width() );
389 pHScrollbar
->SetPageSize( aOutSz
.Width() * 8 / 10 );
390 pHScrollbar
->SetLineSize( pOutWin
->GetTextWidth( 'x' ) );
391 pHScrollbar
->SetThumbPos( pTextView
->GetStartDocPos().X() );
395 IMPL_LINK(XMLFileWindow
, ScrollHdl
, ScrollBar
*, pScroll
)
397 if(pScroll
== pVScrollbar
)
399 long nDiff
= pTextView
->GetStartDocPos().Y() - pScroll
->GetThumbPos();
400 GetTextView()->Scroll( 0, nDiff
);
401 pTextView
->ShowCursor( FALSE
, TRUE
);
402 pScroll
->SetThumbPos( pTextView
->GetStartDocPos().Y() );
406 long nDiff
= pTextView
->GetStartDocPos().X() - pScroll
->GetThumbPos();
407 GetTextView()->Scroll( nDiff
, 0 );
408 pTextView
->ShowCursor( FALSE
, TRUE
);
409 pScroll
->SetThumbPos( pTextView
->GetStartDocPos().X() );
414 void XMLFileWindow::Notify( SfxBroadcaster
& /* rBC */, const SfxHint
& rHint
)
416 if ( rHint
.ISA( TextHint
) )
418 const TextHint
& rTextHint
= (const TextHint
&)rHint
;
419 if( rTextHint
.GetId() == TEXT_HINT_VIEWSCROLLED
)
421 pHScrollbar
->SetThumbPos( pTextView
->GetStartDocPos().X() );
422 pVScrollbar
->SetThumbPos( pTextView
->GetStartDocPos().Y() );
424 else if( rTextHint
.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED
)
426 if ( (long)pTextEngine
->GetTextHeight() < pOutWin
->GetOutputSizePixel().Height() )
427 pTextView
->Scroll( 0, pTextView
->GetStartDocPos().Y() );
428 pVScrollbar
->SetThumbPos( pTextView
->GetStartDocPos().Y() );
429 SetScrollBarRanges();
431 else if( rTextHint
.GetId() == TEXT_HINT_FORMATPARA
)
433 DoDelayedSyntaxHighlight( (USHORT
)rTextHint
.GetValue() );
438 void XMLFileWindow::InvalidateWindow()
440 pOutWin
->Invalidate();
441 Window::Invalidate();
445 void XMLFileWindow::Command( const CommandEvent
& rCEvt
)
447 switch(rCEvt
.GetCommand())
450 case COMMAND_STARTAUTOSCROLL
:
451 case COMMAND_AUTOSCROLL
:
453 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
454 if( !pWData
|| COMMAND_WHEEL_ZOOM
!= pWData
->GetMode() )
455 HandleScrollCommand( rCEvt
, pHScrollbar
, pVScrollbar
);
459 Window::Command(rCEvt
);
463 void XMLFileWindow::HandleWheelCommand( const CommandEvent
& rCEvt
)
465 pTextView
->Command(rCEvt
);
466 HandleScrollCommand( rCEvt
, pHScrollbar
, pVScrollbar
);
469 void XMLFileWindow::GetFocus()
471 pOutWin
->GrabFocus();
474 void XMLFileWindow::ShowWindow( const rtl::OUString
& rFileName
)
476 String
aFileName( rFileName
);
477 SvFileStream
aStream( aFileName
, STREAM_READ
);
479 // since the xml files we load are utf-8 encoded, we need to set
480 // this encoding at the SvFileStream, else the TextEngine will
481 // use its default encoding which is not UTF8
482 const sal_Char
*pCharSet
= rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8
);
483 rtl_TextEncoding eDestEnc
= rtl_getTextEncodingFromMimeCharset( pCharSet
);
484 aStream
.SetStreamCharSet( eDestEnc
);
486 if( Read( aStream
) )
488 long nPrevTextWidth
= nCurTextWidth
;
489 nCurTextWidth
= pTextEngine
->CalcTextWidth() + 25; // kleine Toleranz
490 if ( nCurTextWidth
!= nPrevTextWidth
)
491 SetScrollBarRanges();
493 TextPaM
aPaM( pTextView
->CursorStartOfDoc() );
494 TextSelection
aSelection( aPaM
, aPaM
);
495 pTextView
->SetSelection( aSelection
, true );
501 void XMLFileWindow::showLine( sal_Int32 nLine
)
503 TextPaM
aPaM( pTextView
->CursorStartOfDoc() );
505 aPaM
= pTextView
->CursorDown( aPaM
);
507 TextSelection
aSelection( pTextView
->CursorEndOfLine( aPaM
), aPaM
);
508 pTextView
->SetSelection( aSelection
, true );
512 XMLSourceFileDialog::XMLSourceFileDialog( Window
* pParent
, ResMgr
& rResMgr
, const com::sun::star::uno::Reference
< com::sun::star::lang::XMultiServiceFactory
>& rxMSF
)
513 : WorkWindow( pParent
, ResId( DLG_XML_SOURCE_FILE_DIALOG
, rResMgr
) ),
514 mnOutputHeight( LogicToPixel( Size( 80, 80 ), MAP_APPFONT
).Height() ),
518 maPBValidate( this, ResId( PB_VALIDATE
, rResMgr
) )
523 maPBValidate
.SetClickHdl(LINK( this, XMLSourceFileDialog
, ClickHdl_Impl
) );
524 maLBOutput
.SetSelectHdl(LINK(this, XMLSourceFileDialog
, SelectHdl_Impl
) );
525 mpTextWindow
= new XMLFileWindow( this );
526 mpTextWindow
->SetHelpId( HID_XML_FILTER_OUTPUT_WINDOW
);
527 maLBOutput
.SetHelpId( HID_XML_FILTER_TEST_VALIDATE_OUPUT
);
532 XMLSourceFileDialog::~XMLSourceFileDialog()
534 if( maFileURL
.getLength() )
535 osl::File::remove( maFileURL
);
540 void XMLSourceFileDialog::ShowWindow( const rtl::OUString
& rFileName
, const filter_info_impl
* pFilterInfo
)
543 if( maFileURL
.getLength() )
545 osl::File::remove( maFileURL
);
547 mpTextWindow
= new XMLFileWindow( this );
550 maPBValidate
.Enable(TRUE
);
554 mpFilterInfo
= pFilterInfo
;
555 maFileURL
= rFileName
;
556 mpTextWindow
->ShowWindow( rFileName
);
561 void XMLSourceFileDialog::Resize()
563 bool bOutputVisible
= maLBOutput
.IsVisible() != 0;
565 Point
aSpacing( LogicToPixel( Point( 6, 6 ), MAP_APPFONT
) );
566 Size
aButton( maPBValidate
.GetSizePixel() );
568 Size
aDialogSize( GetOutputSizePixel() );
570 // Point aButtonPos( aSpacing.X(), aSpacing.Y() );
571 // maPBValidate.SetPosSizePixel( aButtonPos, aButton );
573 Size
aOutputSize( aDialogSize
.Width(), bOutputVisible
? mnOutputHeight
: 0 );
575 Point
aTextWindowPos( 0, 2* aSpacing
.Y() + aButton
.Height() );
576 Size
aTextWindowSize( aDialogSize
.Width(), aDialogSize
.Height() - aTextWindowPos
.Y() - aOutputSize
.Height() );
578 mpTextWindow
->SetPosSizePixel( aTextWindowPos
, aTextWindowSize
);
582 Point
aOutputPos( 0, aTextWindowPos
.Y() + aTextWindowSize
.Height() );
583 maLBOutput
.SetPosSizePixel( aOutputPos
, aOutputSize
);
588 IMPL_LINK(XMLSourceFileDialog
, SelectHdl_Impl
, ListBox
*, pListBox
)
590 USHORT nEntry
= pListBox
->GetSelectEntryPos();
591 if( LISTBOX_ENTRY_NOTFOUND
!= nEntry
)
593 int nLine
= (int)(sal_IntPtr
)pListBox
->GetEntryData(nEntry
);
605 IMPL_LINK(XMLSourceFileDialog
, ClickHdl_Impl
, PushButton
*, /* pButton */ )
611 void XMLSourceFileDialog::onValidate()
616 maPBValidate
.Enable(FALSE
);
621 Reference
< XImportFilter
> xImporter( mxMSF
->createInstance( OUString::createFromAscii( "com.sun.star.documentconversion.XSLTValidate" ) ), UNO_QUERY
);
624 osl::File
aInputFile( maFileURL
);
625 /* osl::File::RC rc = */ aInputFile
.open( OpenFlag_Read
);
627 Reference
< XInputStream
> xIS( new comphelper::OSLInputStreamWrapper( aInputFile
) );
629 Sequence
< PropertyValue
> aSourceData(3);
630 aSourceData
[0].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
631 aSourceData
[0].Value
<<= xIS
;
633 aSourceData
[1].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
634 aSourceData
[1].Value
<<= maFileURL
;
636 aSourceData
[2].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorHandler" ) );
637 Reference
< XErrorHandler
> xHandle( new XMLErrorHandler( this, maLBOutput
) );
638 aSourceData
[2].Value
<<= xHandle
;
640 Reference
< XDocumentHandler
> xWriter( mxMSF
->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), UNO_QUERY
);
641 Reference
< XOutputStream
> xOS( mxMSF
->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pipe" ) ) ), UNO_QUERY
);
642 Reference
< XActiveDataSource
> xDocSrc( xWriter
, UNO_QUERY
);
643 xDocSrc
->setOutputStream( xOS
);
645 Sequence
< OUString
> aFilterUserData( mpFilterInfo
->getFilterUserData() );
646 xImporter
->importer( aSourceData
, xWriter
, aFilterUserData
);
651 String
sErr( e
.Message
);
652 USHORT nEntry
= maLBOutput
.InsertEntry( sErr
);
653 maLBOutput
.SetEntryData( nEntry
, (void*)-1 );
656 if( 0 == maLBOutput
.GetEntryCount() )
658 String
sErr( RESID( STR_NO_ERRORS_FOUND
) );
659 USHORT nEntry
= maLBOutput
.InsertEntry( sErr
);
660 maLBOutput
.SetEntryData( nEntry
, (void*)-1 );
666 void XMLSourceFileDialog::showLine( sal_Int32 nLine
)
668 mpTextWindow
->showLine( nLine
);
672 ///////////////////////////////////////////////////////////////////////
674 void lcl_Highlight(const String
& rSource
, SwTextPortions
& aPortionList
)
676 const sal_Unicode cOpenBracket
= '<';
677 const sal_Unicode cCloseBracket
= '>';
678 const sal_Unicode cSlash
= '/';
679 const sal_Unicode cExclamation
= '!';
680 // const sal_Unicode cQuote = '"';
681 // const sal_Unicode cSQuote = '\'';
682 const sal_Unicode cMinus
= '-';
683 const sal_Unicode cSpace
= ' ';
684 const sal_Unicode cTab
= 0x09;
685 const sal_Unicode cLF
= 0x0a;
686 const sal_Unicode cCR
= 0x0d;
689 const USHORT nStrLen
= rSource
.Len();
690 USHORT nInsert
= 0; // Anzahl der eingefuegten Portions
691 USHORT nActPos
= 0; //Position, an der '<' gefunden wurde
692 USHORT nOffset
= 0; //Offset von nActPos zur '<'
693 USHORT nPortStart
= USHRT_MAX
; // fuer die TextPortion
694 USHORT nPortEnd
= 0; //
696 while(nActPos
< nStrLen
)
698 svtools::ColorConfigEntry eFoundType
= svtools::HTMLUNKNOWN
;
699 if(rSource
.GetChar(nActPos
) == cOpenBracket
&& nActPos
< nStrLen
- 2 )
701 // 'leere' Portion einfuegen
702 if(nPortEnd
< nActPos
- 1 )
705 // am Anfang nicht verschieben
706 aText
.nStart
= nPortEnd
;
709 aText
.nEnd
= nActPos
- 1;
710 aText
.eType
= svtools::HTMLUNKNOWN
;
711 aPortionList
.Insert(aText
, nInsert
++);
713 sal_Unicode cFollowFirst
= rSource
.GetChar((xub_StrLen
)(nActPos
+ 1));
714 sal_Unicode cFollowNext
= rSource
.GetChar((xub_StrLen
)(nActPos
+ 2));
715 if(cExclamation
== cFollowFirst
)
717 // "<!" SGML oder Kommentar
718 if(cMinus
== cFollowNext
&&
719 nActPos
< nStrLen
- 3 && cMinus
== rSource
.GetChar((xub_StrLen
)(nActPos
+ 3)))
721 eFoundType
= svtools::HTMLCOMMENT
;
724 eFoundType
= svtools::HTMLSGML
;
725 nPortStart
= nActPos
;
726 nPortEnd
= nActPos
+ 1;
728 else if(cSlash
== cFollowFirst
)
730 // "</" Slash ignorieren
731 nPortStart
= nActPos
;
735 if(svtools::HTMLUNKNOWN
== eFoundType
)
737 //jetzt koennte hier ein keyword folgen
738 USHORT nSrchPos
= nActPos
;
739 while(++nSrchPos
< nStrLen
- 1)
741 sal_Unicode cNext
= rSource
.GetChar(nSrchPos
);
742 if( cNext
== cSpace
||
747 else if(cNext
== cCloseBracket
)
752 if(nSrchPos
> nActPos
+ 1)
754 //irgend ein String wurde gefunden
755 String sToken
= rSource
.Copy(nActPos
+ 1, nSrchPos
- nActPos
- 1 );
756 sToken
.ToUpperAscii();
757 // int nToken = ::GetHTMLToken(sToken);
761 eFoundType
= svtools::HTMLKEYWORD
;
763 nPortStart
= nActPos
;
770 DBG_ERROR("Token nicht erkannt!")
771 DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer())
778 // jetzt muss noch '>' gesucht werden
779 if(svtools::HTMLUNKNOWN
!= eFoundType
)
782 for(USHORT i
= nPortEnd
; i
< nStrLen
; i
++)
783 if(cCloseBracket
== rSource
.GetChar(i
))
789 if(!bFound
&& (eFoundType
== svtools::HTMLCOMMENT
))
791 // Kommentar ohne Ende in dieser Zeile
793 nPortEnd
= nStrLen
- 1;
796 if(bFound
||(eFoundType
== svtools::HTMLCOMMENT
))
798 SwTextPortion aText2
;
800 aText2
.nStart
= nPortStart
+ 1;
801 aText2
.nEnd
= nPortEnd
;
802 aText2
.eType
= eFoundType
;
803 aPortionList
.Insert(aText2
, nInsert
++);
804 eFoundType
= svtools::HTMLUNKNOWN
;
811 if(nInsert
&& nPortEnd
< nActPos
- 1)
814 aText
.nStart
= nPortEnd
+ 1;
815 aText
.nEnd
= nActPos
- 1;
816 aText
.eType
= svtools::HTMLUNKNOWN
;
817 aPortionList
.Insert(aText
, nInsert
++);
821 void XMLFileWindow::DoDelayedSyntaxHighlight( USHORT nPara
)
823 if ( !bHighlighting
)
825 aSyntaxLineTable
.Insert( nPara
, (void*)(USHORT
)1 );
826 aSyntaxIdleTimer
.Start();
830 void XMLFileWindow::ImpDoHighlight( const String
& rSource
, USHORT nLineOff
)
832 SwTextPortions aPortionList
;
833 lcl_Highlight(rSource
, aPortionList
);
835 USHORT nCount
= aPortionList
.Count();
839 SwTextPortion
& rLast
= aPortionList
[nCount
-1];
840 if ( rLast
.nStart
> rLast
.nEnd
) // Nur bis Bug von MD behoeben
843 aPortionList
.Remove( nCount
);
849 // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe,
850 // ggf. zusammenfassen, oder zumindest das Blank,
851 // damit weniger Attribute
852 BOOL bOptimizeHighlight
= TRUE
; // war in der BasicIDE static
853 if ( bOptimizeHighlight
)
855 // Es muessen nur die Blanks und Tabs mit attributiert werden.
856 // Wenn zwei gleiche Attribute hintereinander eingestellt werden,
857 // optimiert das die TextEngine.
859 for ( USHORT i
= 0; i
< nCount
; i
++ )
861 SwTextPortion
& r
= aPortionList
[i
];
862 DBG_ASSERT( r
.nLine
== aPortionList
[0].nLine
, "doch mehrere Zeilen ?" );
863 if ( r
.nStart
> r
.nEnd
) // Nur bis Bug von MD behoeben
866 if ( r
.nStart
> nLastEnd
)
868 // Kann ich mich drauf verlassen, dass alle ausser
869 // Blank und Tab gehighlightet wird ?!
873 if ( ( i
== (nCount
-1) ) && ( r
.nEnd
< rSource
.Len() ) )
874 r
.nEnd
= rSource
.Len();
878 svtools::ColorConfig aConfig
;
879 for ( USHORT i
= 0; i
< aPortionList
.Count(); i
++ )
881 SwTextPortion
& r
= aPortionList
[i
];
882 if ( r
.nStart
> r
.nEnd
) // Nur bis Bug von MD behoeben
884 // USHORT nCol = r.eType;
885 if(r
.eType
!= svtools::HTMLSGML
&&
886 r
.eType
!= svtools::HTMLCOMMENT
&&
887 r
.eType
!= svtools::HTMLKEYWORD
&&
888 r
.eType
!= svtools::HTMLUNKNOWN
)
889 r
.eType
= (svtools::ColorConfigEntry
)svtools::HTMLUNKNOWN
;
890 Color
aColor((ColorData
)aConfig
.GetColorValue((svtools::ColorConfigEntry
)r
.eType
).nColor
);
891 USHORT nLine
= nLineOff
+r
.nLine
; //
892 pTextEngine
->SetAttrib( TextAttribFontColor( aColor
), nLine
, r
.nStart
, r
.nEnd
+1 );
896 IMPL_LINK( XMLFileWindow
, SyntaxTimerHdl
, Timer
*, pTimer
)
898 Time aSyntaxCheckStart
;
899 DBG_ASSERT( pTextView
, "Noch keine View, aber Syntax-Highlight ?!" );
900 pTextEngine
->SetUpdateMode( FALSE
);
902 bHighlighting
= TRUE
;
905 // zuerst wird der Bereich um dem Cursor bearbeitet
906 TextSelection aSel
= pTextView
->GetSelection();
907 USHORT nCur
= (USHORT
)aSel
.GetStart().GetPara();
912 if(aSyntaxLineTable
.Count())
913 for(USHORT i
= 0; i
< 80 && nCount
< 40; i
++, nCur
++)
915 void * p
= aSyntaxLineTable
.Get(nCur
);
918 DoSyntaxHighlight( nCur
);
919 aSyntaxLineTable
.Remove( nCur
);
921 if(!aSyntaxLineTable
.Count())
923 if((Time().GetTime() - aSyntaxCheckStart
.GetTime()) > MAX_HIGHLIGHTTIME
)
925 pTimer
->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT
);
931 // wenn dann noch etwas frei ist, wird von Beginn an weitergearbeitet
932 void* p
= aSyntaxLineTable
.First();
933 while ( p
&& nCount
< MAX_SYNTAX_HIGHLIGHT
)
935 nLine
= (USHORT
)aSyntaxLineTable
.GetCurKey();
936 DoSyntaxHighlight( nLine
);
937 USHORT nC
= (USHORT
)aSyntaxLineTable
.GetCurKey();
938 p
= aSyntaxLineTable
.Next();
939 aSyntaxLineTable
.Remove(nC
);
941 if(Time().GetTime() - aSyntaxCheckStart
.GetTime() > MAX_HIGHLIGHTTIME
)
943 pTimer
->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT
);
947 // os: #43050# hier wird ein TextView-Problem umpopelt:
948 // waehrend des Highlightings funktionierte das Scrolling nicht
949 TextView
* pTmp
= pTextEngine
->GetActiveView();
950 pTextEngine
->SetActiveView(0);
951 pTextEngine
->SetUpdateMode( TRUE
);
952 pTextEngine
->SetActiveView(pTmp
);
953 pTextView
->ShowCursor(FALSE
, FALSE
);
955 if(aSyntaxLineTable
.Count() && !pTimer
->IsActive())
957 // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung
958 // => gute Gelegenheit, Textbreite zu ermitteln!
959 long nPrevTextWidth
= nCurTextWidth
;
960 nCurTextWidth
= pTextEngine
->CalcTextWidth() + 25; // kleine Toleranz
961 if ( nCurTextWidth
!= nPrevTextWidth
)
962 SetScrollBarRanges();
963 bHighlighting
= FALSE
;
968 void XMLFileWindow::DoSyntaxHighlight( USHORT nPara
)
970 // Durch das DelayedSyntaxHighlight kann es passieren,
971 // dass die Zeile nicht mehr existiert!
972 if ( nPara
< pTextEngine
->GetParagraphCount() )
974 pTextEngine
->RemoveAttribs( nPara
);
975 String
aSource( pTextEngine
->GetText( nPara
) );
976 pTextEngine
->SetUpdateMode( FALSE
);
977 ImpDoHighlight( aSource
, nPara
);
978 // os: #43050# hier wird ein TextView-Problem umpopelt:
979 // waehrend des Highlightings funktionierte das Scrolling nicht
980 TextView
* pTmp
= pTextEngine
->GetActiveView();
981 pTmp
->SetAutoScroll(FALSE
);
982 pTextEngine
->SetActiveView(0);
983 pTextEngine
->SetUpdateMode( TRUE
);
984 pTextEngine
->SetActiveView(pTmp
);
985 // Bug 72887 show the cursor
986 pTmp
->SetAutoScroll(TRUE
);
987 pTmp
->ShowCursor( FALSE
/*pTmp->IsAutoScroll()*/ );
991 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */