Update ooo320-m1
[ooovba.git] / filter / source / xsltdialog / xmlfileview.cxx
blob197d03f577276f3fa2f957f089ad5d8cf605d002
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlfileview.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_filter.hxx"
33 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
34 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
35 #include <com/sun/star/xml/sax/SAXParseException.hpp>
36 #include <com/sun/star/xml/XImportFilter.hpp>
37 #include <com/sun/star/io/XActiveDataSource.hpp>
38 #include <comphelper/oslfile2streamwrap.hxx>
40 #include <rtl/tencinfo.h>
41 #include <vcl/svapp.hxx>
42 #include <vos/mutex.hxx>
43 #include <svtools/textview.hxx>
44 #ifndef _SCRBAR_HXX //autogen
45 #include <vcl/scrbar.hxx>
46 #endif
47 #include <tools/stream.hxx>
48 #include <tools/time.hxx>
49 #include <osl/file.hxx>
50 #include <vcl/msgbox.hxx>
51 #include <svtools/colorcfg.hxx>
52 #include <svtools/htmltokn.h>
53 #include <svtools/txtattr.hxx>
55 #include "xmlfilterdialogstrings.hrc"
56 #include "xmlfiltersettingsdialog.hxx"
57 #include "xmlfileview.hxx"
58 #include "xmlfileview.hrc"
59 #include "xmlfilterhelpids.hrc"
61 using namespace rtl;
62 using namespace osl;
63 using namespace com::sun::star::lang;
64 using namespace com::sun::star::beans;
65 using namespace com::sun::star::uno;
66 using namespace com::sun::star::io;
67 using namespace com::sun::star::xml;
68 using namespace com::sun::star::xml::sax;
71 #define MAX_SYNTAX_HIGHLIGHT 20
72 #define MAX_HIGHLIGHTTIME 200
73 #define SYNTAX_HIGHLIGHT_TIMEOUT 200
76 struct SwTextPortion
78 USHORT nLine;
79 USHORT nStart, nEnd;
80 svtools::ColorConfigEntry eType;
83 SV_DECL_VARARR(SwTextPortions, SwTextPortion,16,16)
84 SV_IMPL_VARARR(SwTextPortions, SwTextPortion);
86 class XMLErrorHandler : public ::cppu::WeakImplHelper1< XErrorHandler >
88 public:
89 XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox );
91 // Methods
92 virtual void SAL_CALL error( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
93 virtual void SAL_CALL fatalError( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
94 virtual void SAL_CALL warning( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
96 private:
97 XMLSourceFileDialog* mpParent;
98 ListBox& mrListBox;
101 XMLErrorHandler::XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox )
102 : mpParent( pParent ),
103 mrListBox( rListBox )
107 // XMLErrorHandler
108 void SAL_CALL XMLErrorHandler::error( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
110 vos::OGuard aGuard( Application::GetSolarMutex() );
112 SAXParseException e;
113 if( aSAXParseException >>= e )
115 String sErr( String::CreateFromInt32( e.LineNumber ) );
116 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
117 sErr += String( e.Message );
118 USHORT nEntry = mrListBox.InsertEntry( sErr );
119 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
123 void SAL_CALL XMLErrorHandler::fatalError( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
125 vos::OGuard aGuard( Application::GetSolarMutex() );
127 SAXParseException e;
128 if( aSAXParseException >>= e )
130 String sErr( String::CreateFromInt32( e.LineNumber ) );
131 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
132 sErr += String( e.Message );
133 USHORT nEntry = mrListBox.InsertEntry( sErr );
134 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
138 void SAL_CALL XMLErrorHandler::warning( const Any& /* aSAXParseException */ ) throw (SAXException, RuntimeException)
141 SAXParseException e;
142 if( aSAXParseException >>= e )
144 String sErr( String::CreateFromInt32( e.LineNumber ) );
145 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
146 sErr += String( e.Message );
147 USHORT nEntry = mrListBox.InsertEntry( sErr );
148 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
154 XMLFileWindow::XMLFileWindow( Window* pParent ) :
155 Window( pParent, WB_BORDER|WB_CLIPCHILDREN ),
156 pTextEngine(0),
157 pOutWin(0),
158 pHScrollbar(0),
159 pVScrollbar(0),
160 nCurTextWidth(0),
161 nStartLine(USHRT_MAX),
162 eSourceEncoding(gsl_getSystemTextEncoding()),
163 bHighlighting(false)
165 CreateTextEngine();
168 XMLFileWindow::~XMLFileWindow()
170 if ( pTextEngine )
172 EndListening( *pTextEngine );
173 pTextEngine->RemoveView( pTextView );
175 delete pHScrollbar;
176 delete pVScrollbar;
178 delete pTextView;
179 delete pTextEngine;
181 delete pOutWin;
184 void XMLFileWindow::DataChanged( const DataChangedEvent& rDCEvt )
186 Window::DataChanged( rDCEvt );
188 switch ( rDCEvt.GetType() )
190 case DATACHANGED_SETTINGS:
191 // ScrollBars neu anordnen bzw. Resize ausloesen, da sich
192 // ScrollBar-Groesse geaendert haben kann. Dazu muss dann im
193 // Resize-Handler aber auch die Groesse der ScrollBars aus
194 // den Settings abgefragt werden.
195 if( rDCEvt.GetFlags() & SETTINGS_STYLE )
196 Resize();
197 break;
201 void XMLFileWindow::Resize()
203 // ScrollBars, etc. passiert in Adjust...
204 if ( pTextView )
206 long nVisY = pTextView->GetStartDocPos().Y();
207 pTextView->ShowCursor();
208 Size aOutSz( GetOutputSizePixel() );
209 long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
210 if ( nMaxVisAreaStart < 0 )
211 nMaxVisAreaStart = 0;
212 if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart )
214 Point aStartDocPos( pTextView->GetStartDocPos() );
215 aStartDocPos.Y() = nMaxVisAreaStart;
216 pTextView->SetStartDocPos( aStartDocPos );
217 pTextView->ShowCursor();
219 long nScrollStd = GetSettings().GetStyleSettings().GetScrollBarSize();
220 Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd );
221 Point aScrollPos(0, aOutSz.Height() - nScrollStd);
223 pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
225 aScrollSz.Width() = aScrollSz.Height();
226 aScrollSz.Height() = aOutSz.Height() - aScrollSz.Height();
227 aScrollPos = Point(aOutSz.Width() - nScrollStd, 0);
229 pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
230 aOutSz.Width() -= nScrollStd;
231 aOutSz.Height() -= nScrollStd;
232 pOutWin->SetOutputSizePixel(aOutSz);
233 InitScrollBars();
235 // Zeile im ersten Resize setzen
236 if(USHRT_MAX != nStartLine)
238 if(nStartLine < pTextEngine->GetParagraphCount())
240 TextSelection aSel(TextPaM( nStartLine, 0 ), TextPaM( nStartLine, 0x0 ));
241 pTextView->SetSelection(aSel);
242 pTextView->ShowCursor();
244 nStartLine = USHRT_MAX;
247 if ( nVisY != pTextView->GetStartDocPos().Y() )
248 InvalidateWindow();
253 void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt )
255 Window::DataChanged( rDCEvt );
257 switch( rDCEvt.GetType() )
259 case DATACHANGED_SETTINGS:
260 // den Settings abgefragt werden.
261 if( rDCEvt.GetFlags() & SETTINGS_STYLE )
263 const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
264 SetBackground( rCol );
265 Font aFont( pTextView->GetTextEngine()->GetFont() );
266 aFont.SetFillColor( rCol );
267 pTextView->GetTextEngine()->SetFont( aFont );
269 break;
273 void TextViewOutWin::MouseMove( const MouseEvent &rEvt )
275 if ( pTextView )
276 pTextView->MouseMove( rEvt );
279 void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt )
281 if ( pTextView )
282 pTextView->MouseButtonUp( rEvt );
285 void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt )
287 GrabFocus();
288 if ( pTextView )
289 pTextView->MouseButtonDown( rEvt );
292 void TextViewOutWin::Command( const CommandEvent& rCEvt )
294 switch(rCEvt.GetCommand())
296 case COMMAND_CONTEXTMENU:
297 break;
298 case COMMAND_WHEEL:
299 case COMMAND_STARTAUTOSCROLL:
300 case COMMAND_AUTOSCROLL:
302 const CommandWheelData* pWData = rCEvt.GetWheelData();
303 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
305 ((XMLFileWindow*)GetParent())->HandleWheelCommand( rCEvt );
308 break;
310 default:
311 if ( pTextView )
312 pTextView->Command( rCEvt );
313 else
314 Window::Command(rCEvt);
318 void TextViewOutWin::KeyInput( const KeyEvent& rKEvt )
320 if(!TextEngine::DoesKeyChangeText( rKEvt ))
321 pTextView->KeyInput( rKEvt );
324 void TextViewOutWin::Paint( const Rectangle& rRect )
326 pTextView->Paint( rRect );
329 void XMLFileWindow::CreateTextEngine()
331 const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
332 pOutWin = new TextViewOutWin(this, 0);
333 pOutWin->SetBackground(Wallpaper(rCol));
334 pOutWin->SetPointer(Pointer(POINTER_TEXT));
335 pOutWin->Show();
337 //Scrollbars anlegen
338 pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG);
339 pHScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
340 pHScrollbar->Show();
342 pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
343 pVScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
344 pHScrollbar->EnableDrag();
345 pVScrollbar->Show();
347 pTextEngine = new TextEngine;
348 pTextView = new TextView( pTextEngine, pOutWin );
349 pTextView->SetAutoIndentMode(TRUE);
350 pOutWin->SetTextView(pTextView);
352 pTextEngine->SetUpdateMode( FALSE );
353 pTextEngine->InsertView( pTextView );
355 Font aFont;
356 aFont.SetTransparent( FALSE );
357 aFont.SetFillColor( rCol );
358 SetPointFont( aFont );
359 aFont = GetFont();
360 aFont.SetFillColor( rCol );
361 pOutWin->SetFont( aFont );
362 pTextEngine->SetFont( aFont );
364 aSyntaxIdleTimer.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT );
365 aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, XMLFileWindow, SyntaxTimerHdl ) );
367 pTextEngine->EnableUndo( FALSE );
368 pTextEngine->SetUpdateMode( TRUE );
370 // pTextView->ShowCursor( TRUE, TRUE );
371 pTextView->HideCursor();
373 InitScrollBars();
374 StartListening( *pTextEngine );
377 void XMLFileWindow::SetScrollBarRanges()
379 pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) );
380 pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) );
383 void XMLFileWindow::InitScrollBars()
385 SetScrollBarRanges();
387 Size aOutSz( pOutWin->GetOutputSizePixel() );
388 pVScrollbar->SetVisibleSize( aOutSz.Height() );
389 pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 );
390 pVScrollbar->SetLineSize( pOutWin->GetTextHeight() );
391 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
392 pHScrollbar->SetVisibleSize( aOutSz.Width() );
393 pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 );
394 pHScrollbar->SetLineSize( pOutWin->GetTextWidth( 'x' ) );
395 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
399 IMPL_LINK(XMLFileWindow, ScrollHdl, ScrollBar*, pScroll)
401 if(pScroll == pVScrollbar)
403 long nDiff = pTextView->GetStartDocPos().Y() - pScroll->GetThumbPos();
404 GetTextView()->Scroll( 0, nDiff );
405 pTextView->ShowCursor( FALSE, TRUE );
406 pScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
408 else
410 long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos();
411 GetTextView()->Scroll( nDiff, 0 );
412 pTextView->ShowCursor( FALSE, TRUE );
413 pScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
415 return 0;
418 void XMLFileWindow::Notify( SfxBroadcaster& /* rBC */, const SfxHint& rHint )
420 if ( rHint.ISA( TextHint ) )
422 const TextHint& rTextHint = (const TextHint&)rHint;
423 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
425 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
426 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
428 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
430 if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() )
431 pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() );
432 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
433 SetScrollBarRanges();
435 else if( rTextHint.GetId() == TEXT_HINT_FORMATPARA )
437 DoDelayedSyntaxHighlight( (USHORT)rTextHint.GetValue() );
442 void XMLFileWindow::InvalidateWindow()
444 pOutWin->Invalidate();
445 Window::Invalidate();
449 void XMLFileWindow::Command( const CommandEvent& rCEvt )
451 switch(rCEvt.GetCommand())
453 case COMMAND_WHEEL:
454 case COMMAND_STARTAUTOSCROLL:
455 case COMMAND_AUTOSCROLL:
457 const CommandWheelData* pWData = rCEvt.GetWheelData();
458 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
459 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
461 break;
462 default:
463 Window::Command(rCEvt);
467 void XMLFileWindow::HandleWheelCommand( const CommandEvent& rCEvt )
469 pTextView->Command(rCEvt);
470 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
473 void XMLFileWindow::GetFocus()
475 pOutWin->GrabFocus();
478 void XMLFileWindow::ShowWindow( const rtl::OUString& rFileName )
480 String aFileName( rFileName );
481 SvFileStream aStream( aFileName, STREAM_READ );
483 // since the xml files we load are utf-8 encoded, we need to set
484 // this encoding at the SvFileStream, else the TextEngine will
485 // use its default encoding which is not UTF8
486 const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
487 rtl_TextEncoding eDestEnc = rtl_getTextEncodingFromMimeCharset( pCharSet );
488 aStream.SetStreamCharSet( eDestEnc );
490 if( Read( aStream ) )
492 long nPrevTextWidth = nCurTextWidth;
493 nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
494 if ( nCurTextWidth != nPrevTextWidth )
495 SetScrollBarRanges();
497 TextPaM aPaM( pTextView->CursorStartOfDoc() );
498 TextSelection aSelection( aPaM, aPaM );
499 pTextView->SetSelection( aSelection, true );
501 Window::Show();
505 void XMLFileWindow::showLine( sal_Int32 nLine )
507 TextPaM aPaM( pTextView->CursorStartOfDoc() );
508 while( nLine-- )
509 aPaM = pTextView->CursorDown( aPaM );
511 TextSelection aSelection( pTextView->CursorEndOfLine( aPaM ), aPaM );
512 pTextView->SetSelection( aSelection, true );
516 XMLSourceFileDialog::XMLSourceFileDialog( Window* pParent, ResMgr& rResMgr, const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxMSF )
517 : WorkWindow( pParent, ResId( DLG_XML_SOURCE_FILE_DIALOG, rResMgr ) ),
518 mnOutputHeight( LogicToPixel( Size( 80, 80 ), MAP_APPFONT ).Height() ),
519 mxMSF( rxMSF ),
520 mrResMgr( rResMgr ),
521 maLBOutput( this ),
522 maPBValidate( this, ResId( PB_VALIDATE, rResMgr ) )
525 FreeResource();
527 maPBValidate.SetClickHdl(LINK( this, XMLSourceFileDialog, ClickHdl_Impl ) );
528 maLBOutput.SetSelectHdl(LINK(this, XMLSourceFileDialog, SelectHdl_Impl ) );
529 mpTextWindow = new XMLFileWindow( this );
530 mpTextWindow->SetHelpId( HID_XML_FILTER_OUTPUT_WINDOW );
531 maLBOutput.SetHelpId( HID_XML_FILTER_TEST_VALIDATE_OUPUT );
533 Resize();
536 XMLSourceFileDialog::~XMLSourceFileDialog()
538 if( maFileURL.getLength() )
539 osl::File::remove( maFileURL );
541 delete mpTextWindow;
544 void XMLSourceFileDialog::ShowWindow( const rtl::OUString& rFileName, const filter_info_impl* pFilterInfo )
546 EnterWait();
547 if( maFileURL.getLength() )
549 osl::File::remove( maFileURL );
550 delete mpTextWindow;
551 mpTextWindow = new XMLFileWindow( this );
552 maLBOutput.Hide();
553 maLBOutput.Clear();
554 maPBValidate.Enable(TRUE);
555 Resize();
558 mpFilterInfo = pFilterInfo;
559 maFileURL = rFileName;
560 mpTextWindow->ShowWindow( rFileName );
561 WorkWindow::Show();
562 LeaveWait();
565 void XMLSourceFileDialog::Resize()
567 bool bOutputVisible = maLBOutput.IsVisible() != 0;
569 Point aSpacing( LogicToPixel( Point( 6, 6 ), MAP_APPFONT ) );
570 Size aButton( maPBValidate.GetSizePixel() );
572 Size aDialogSize( GetOutputSizePixel() );
574 // Point aButtonPos( aSpacing.X(), aSpacing.Y() );
575 // maPBValidate.SetPosSizePixel( aButtonPos, aButton );
577 Size aOutputSize( aDialogSize.Width(), bOutputVisible ? mnOutputHeight : 0 );
579 Point aTextWindowPos( 0, 2* aSpacing.Y() + aButton.Height() );
580 Size aTextWindowSize( aDialogSize.Width(), aDialogSize.Height() - aTextWindowPos.Y() - aOutputSize.Height() );
582 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
584 if( bOutputVisible )
586 Point aOutputPos( 0, aTextWindowPos.Y() + aTextWindowSize.Height() );
587 maLBOutput.SetPosSizePixel( aOutputPos, aOutputSize );
592 IMPL_LINK(XMLSourceFileDialog, SelectHdl_Impl, ListBox *, pListBox )
594 USHORT nEntry = pListBox->GetSelectEntryPos();
595 if( LISTBOX_ENTRY_NOTFOUND != nEntry )
597 int nLine = (int)(sal_IntPtr)pListBox->GetEntryData(nEntry);
598 if( -1 != nLine )
600 if( nLine > 0 )
601 nLine--;
603 showLine( nLine );
606 return 0;
609 IMPL_LINK(XMLSourceFileDialog, ClickHdl_Impl, PushButton *, /* pButton */ )
611 onValidate();
612 return 0;
615 void XMLSourceFileDialog::onValidate()
617 EnterWait();
619 maLBOutput.Show();
620 maPBValidate.Enable(FALSE);
621 Resize();
625 Reference< XImportFilter > xImporter( mxMSF->createInstance( OUString::createFromAscii( "com.sun.star.documentconversion.XSLTValidate" ) ), UNO_QUERY );
626 if( xImporter.is() )
628 osl::File aInputFile( maFileURL );
629 /* osl::File::RC rc = */ aInputFile.open( OpenFlag_Read );
631 Reference< XInputStream > xIS( new comphelper::OSLInputStreamWrapper( aInputFile ) );
633 Sequence< PropertyValue > aSourceData(3);
634 aSourceData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
635 aSourceData[0].Value <<= xIS;
637 aSourceData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
638 aSourceData[1].Value <<= maFileURL;
640 aSourceData[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorHandler" ) );
641 Reference< XErrorHandler > xHandle( new XMLErrorHandler( this, maLBOutput ) );
642 aSourceData[2].Value <<= xHandle;
644 Reference< XDocumentHandler > xWriter( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), UNO_QUERY );
645 Reference< XOutputStream > xOS( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pipe" ) ) ), UNO_QUERY );
646 Reference< XActiveDataSource > xDocSrc( xWriter, UNO_QUERY );
647 xDocSrc->setOutputStream( xOS );
649 Sequence< OUString > aFilterUserData( mpFilterInfo->getFilterUserData() );
650 xImporter->importer( aSourceData, xWriter, aFilterUserData );
653 catch(Exception& e)
655 String sErr( e.Message );
656 USHORT nEntry = maLBOutput.InsertEntry( sErr );
657 maLBOutput.SetEntryData( nEntry, (void*)-1 );
660 if( 0 == maLBOutput.GetEntryCount() )
662 String sErr( RESID( STR_NO_ERRORS_FOUND ) );
663 USHORT nEntry = maLBOutput.InsertEntry( sErr );
664 maLBOutput.SetEntryData( nEntry, (void*)-1 );
667 LeaveWait();
670 void XMLSourceFileDialog::showLine( sal_Int32 nLine )
672 mpTextWindow->showLine( nLine );
676 ///////////////////////////////////////////////////////////////////////
678 void lcl_Highlight(const String& rSource, SwTextPortions& aPortionList)
680 const sal_Unicode cOpenBracket = '<';
681 const sal_Unicode cCloseBracket= '>';
682 const sal_Unicode cSlash = '/';
683 const sal_Unicode cExclamation = '!';
684 // const sal_Unicode cQuote = '"';
685 // const sal_Unicode cSQuote = '\'';
686 const sal_Unicode cMinus = '-';
687 const sal_Unicode cSpace = ' ';
688 const sal_Unicode cTab = 0x09;
689 const sal_Unicode cLF = 0x0a;
690 const sal_Unicode cCR = 0x0d;
693 const USHORT nStrLen = rSource.Len();
694 USHORT nInsert = 0; // Anzahl der eingefuegten Portions
695 USHORT nActPos = 0; //Position, an der '<' gefunden wurde
696 USHORT nOffset = 0; //Offset von nActPos zur '<'
697 USHORT nPortStart = USHRT_MAX; // fuer die TextPortion
698 USHORT nPortEnd = 0; //
699 SwTextPortion aText;
700 while(nActPos < nStrLen)
702 svtools::ColorConfigEntry eFoundType = svtools::HTMLUNKNOWN;
703 if(rSource.GetChar(nActPos) == cOpenBracket && nActPos < nStrLen - 2 )
705 // 'leere' Portion einfuegen
706 if(nPortEnd < nActPos - 1 )
708 aText.nLine = 0;
709 // am Anfang nicht verschieben
710 aText.nStart = nPortEnd;
711 if(nInsert)
712 aText.nStart += 1;
713 aText.nEnd = nActPos - 1;
714 aText.eType = svtools::HTMLUNKNOWN;
715 aPortionList.Insert(aText, nInsert++);
717 sal_Unicode cFollowFirst = rSource.GetChar((xub_StrLen)(nActPos + 1));
718 sal_Unicode cFollowNext = rSource.GetChar((xub_StrLen)(nActPos + 2));
719 if(cExclamation == cFollowFirst)
721 // "<!" SGML oder Kommentar
722 if(cMinus == cFollowNext &&
723 nActPos < nStrLen - 3 && cMinus == rSource.GetChar((xub_StrLen)(nActPos + 3)))
725 eFoundType = svtools::HTMLCOMMENT;
727 else
728 eFoundType = svtools::HTMLSGML;
729 nPortStart = nActPos;
730 nPortEnd = nActPos + 1;
732 else if(cSlash == cFollowFirst)
734 // "</" Slash ignorieren
735 nPortStart = nActPos;
736 nActPos++;
737 nOffset++;
739 if(svtools::HTMLUNKNOWN == eFoundType)
741 //jetzt koennte hier ein keyword folgen
742 USHORT nSrchPos = nActPos;
743 while(++nSrchPos < nStrLen - 1)
745 sal_Unicode cNext = rSource.GetChar(nSrchPos);
746 if( cNext == cSpace ||
747 cNext == cTab ||
748 cNext == cLF ||
749 cNext == cCR)
750 break;
751 else if(cNext == cCloseBracket)
753 break;
756 if(nSrchPos > nActPos + 1)
758 //irgend ein String wurde gefunden
759 String sToken = rSource.Copy(nActPos + 1, nSrchPos - nActPos - 1 );
760 sToken.ToUpperAscii();
761 // int nToken = ::GetHTMLToken(sToken);
762 // if(nToken)
764 //Token gefunden
765 eFoundType = svtools::HTMLKEYWORD;
766 nPortEnd = nSrchPos;
767 nPortStart = nActPos;
770 else
772 //was war das denn?
773 #ifdef DEBUG
774 DBG_ERROR("Token nicht erkannt!")
775 DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer())
776 #endif
782 // jetzt muss noch '>' gesucht werden
783 if(svtools::HTMLUNKNOWN != eFoundType)
785 BOOL bFound = FALSE;
786 for(USHORT i = nPortEnd; i < nStrLen; i++)
787 if(cCloseBracket == rSource.GetChar(i))
789 bFound = TRUE;
790 nPortEnd = i;
791 break;
793 if(!bFound && (eFoundType == svtools::HTMLCOMMENT))
795 // Kommentar ohne Ende in dieser Zeile
796 bFound = TRUE;
797 nPortEnd = nStrLen - 1;
800 if(bFound ||(eFoundType == svtools::HTMLCOMMENT))
802 SwTextPortion aText2;
803 aText2.nLine = 0;
804 aText2.nStart = nPortStart + 1;
805 aText2.nEnd = nPortEnd;
806 aText2.eType = eFoundType;
807 aPortionList.Insert(aText2, nInsert++);
808 eFoundType = svtools::HTMLUNKNOWN;
813 nActPos++;
815 if(nInsert && nPortEnd < nActPos - 1)
817 aText.nLine = 0;
818 aText.nStart = nPortEnd + 1;
819 aText.nEnd = nActPos - 1;
820 aText.eType = svtools::HTMLUNKNOWN;
821 aPortionList.Insert(aText, nInsert++);
825 void XMLFileWindow::DoDelayedSyntaxHighlight( USHORT nPara )
827 if ( !bHighlighting )
829 aSyntaxLineTable.Insert( nPara, (void*)(USHORT)1 );
830 aSyntaxIdleTimer.Start();
834 void XMLFileWindow::ImpDoHighlight( const String& rSource, USHORT nLineOff )
836 SwTextPortions aPortionList;
837 lcl_Highlight(rSource, aPortionList);
839 USHORT nCount = aPortionList.Count();
840 if ( !nCount )
841 return;
843 SwTextPortion& rLast = aPortionList[nCount-1];
844 if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoeben
846 nCount--;
847 aPortionList.Remove( nCount);
848 if ( !nCount )
849 return;
852 // Evtl. Optimieren:
853 // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe,
854 // ggf. zusammenfassen, oder zumindest das Blank,
855 // damit weniger Attribute
856 BOOL bOptimizeHighlight = TRUE; // war in der BasicIDE static
857 if ( bOptimizeHighlight )
859 // Es muessen nur die Blanks und Tabs mit attributiert werden.
860 // Wenn zwei gleiche Attribute hintereinander eingestellt werden,
861 // optimiert das die TextEngine.
862 USHORT nLastEnd = 0;
863 for ( USHORT i = 0; i < nCount; i++ )
865 SwTextPortion& r = aPortionList[i];
866 DBG_ASSERT( r.nLine == aPortionList[0].nLine, "doch mehrere Zeilen ?" );
867 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben
868 continue;
870 if ( r.nStart > nLastEnd )
872 // Kann ich mich drauf verlassen, dass alle ausser
873 // Blank und Tab gehighlightet wird ?!
874 r.nStart = nLastEnd;
876 nLastEnd = r.nEnd+1;
877 if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) )
878 r.nEnd = rSource.Len();
882 svtools::ColorConfig aConfig;
883 for ( USHORT i = 0; i < aPortionList.Count(); i++ )
885 SwTextPortion& r = aPortionList[i];
886 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben
887 continue;
888 // USHORT nCol = r.eType;
889 if(r.eType != svtools::HTMLSGML &&
890 r.eType != svtools::HTMLCOMMENT &&
891 r.eType != svtools::HTMLKEYWORD &&
892 r.eType != svtools::HTMLUNKNOWN)
893 r.eType = (svtools::ColorConfigEntry)svtools::HTMLUNKNOWN;
894 Color aColor((ColorData)aConfig.GetColorValue((svtools::ColorConfigEntry)r.eType).nColor);
895 USHORT nLine = nLineOff+r.nLine; //
896 pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1 );
900 IMPL_LINK( XMLFileWindow, SyntaxTimerHdl, Timer *, pTimer )
902 Time aSyntaxCheckStart;
903 DBG_ASSERT( pTextView, "Noch keine View, aber Syntax-Highlight ?!" );
904 pTextEngine->SetUpdateMode( FALSE );
906 bHighlighting = TRUE;
907 USHORT nLine;
908 USHORT nCount = 0;
909 // zuerst wird der Bereich um dem Cursor bearbeitet
910 TextSelection aSel = pTextView->GetSelection();
911 USHORT nCur = (USHORT)aSel.GetStart().GetPara();
912 if(nCur > 40)
913 nCur -= 40;
914 else
915 nCur = 0;
916 if(aSyntaxLineTable.Count())
917 for(USHORT i = 0; i < 80 && nCount < 40; i++, nCur++)
919 void * p = aSyntaxLineTable.Get(nCur);
920 if(p)
922 DoSyntaxHighlight( nCur );
923 aSyntaxLineTable.Remove( nCur );
924 nCount++;
925 if(!aSyntaxLineTable.Count())
926 break;
927 if((Time().GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
929 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
930 break;
935 // wenn dann noch etwas frei ist, wird von Beginn an weitergearbeitet
936 void* p = aSyntaxLineTable.First();
937 while ( p && nCount < MAX_SYNTAX_HIGHLIGHT)
939 nLine = (USHORT)aSyntaxLineTable.GetCurKey();
940 DoSyntaxHighlight( nLine );
941 USHORT nC = (USHORT)aSyntaxLineTable.GetCurKey();
942 p = aSyntaxLineTable.Next();
943 aSyntaxLineTable.Remove(nC);
944 nCount ++;
945 if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
947 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
948 break;
951 // os: #43050# hier wird ein TextView-Problem umpopelt:
952 // waehrend des Highlightings funktionierte das Scrolling nicht
953 TextView* pTmp = pTextEngine->GetActiveView();
954 pTextEngine->SetActiveView(0);
955 pTextEngine->SetUpdateMode( TRUE );
956 pTextEngine->SetActiveView(pTmp);
957 pTextView->ShowCursor(FALSE, FALSE);
959 if(aSyntaxLineTable.Count() && !pTimer->IsActive())
960 pTimer->Start();
961 // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung
962 // => gute Gelegenheit, Textbreite zu ermitteln!
963 long nPrevTextWidth = nCurTextWidth;
964 nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
965 if ( nCurTextWidth != nPrevTextWidth )
966 SetScrollBarRanges();
967 bHighlighting = FALSE;
969 return 0;
972 void XMLFileWindow::DoSyntaxHighlight( USHORT nPara )
974 // Durch das DelayedSyntaxHighlight kann es passieren,
975 // dass die Zeile nicht mehr existiert!
976 if ( nPara < pTextEngine->GetParagraphCount() )
978 pTextEngine->RemoveAttribs( nPara );
979 String aSource( pTextEngine->GetText( nPara ) );
980 pTextEngine->SetUpdateMode( FALSE );
981 ImpDoHighlight( aSource, nPara );
982 // os: #43050# hier wird ein TextView-Problem umpopelt:
983 // waehrend des Highlightings funktionierte das Scrolling nicht
984 TextView* pTmp = pTextEngine->GetActiveView();
985 pTmp->SetAutoScroll(FALSE);
986 pTextEngine->SetActiveView(0);
987 pTextEngine->SetUpdateMode( TRUE );
988 pTextEngine->SetActiveView(pTmp);
989 // Bug 72887 show the cursor
990 pTmp->SetAutoScroll(TRUE);
991 pTmp->ShowCursor( FALSE/*pTmp->IsAutoScroll()*/ );