merged tag ooo/DEV300_m102
[LibreOffice.git] / filter / source / xsltdialog / xmlfileview.cxx
blobc3a3429542a686ddf184f284337f0669798795a5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_filter.hxx"
30 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
31 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
32 #include <com/sun/star/xml/sax/SAXParseException.hpp>
33 #include <com/sun/star/xml/XImportFilter.hpp>
34 #include <com/sun/star/io/XActiveDataSource.hpp>
35 #include <comphelper/oslfile2streamwrap.hxx>
37 #include <rtl/tencinfo.h>
38 #include <vcl/svapp.hxx>
39 #include <vos/mutex.hxx>
40 #include <svtools/textview.hxx>
41 #ifndef _SCRBAR_HXX //autogen
42 #include <vcl/scrbar.hxx>
43 #endif
44 #include <tools/stream.hxx>
45 #include <tools/time.hxx>
46 #include <osl/file.hxx>
47 #include <vcl/msgbox.hxx>
48 #include <svtools/colorcfg.hxx>
49 #include <svtools/htmltokn.h>
50 #include <svtools/txtattr.hxx>
52 #include "xmlfilterdialogstrings.hrc"
53 #include "xmlfiltersettingsdialog.hxx"
54 #include "xmlfileview.hxx"
55 #include "xmlfileview.hrc"
56 #include "xmlfilterhelpids.hrc"
58 #include <deque>
60 using namespace rtl;
61 using namespace osl;
62 using namespace com::sun::star::lang;
63 using namespace com::sun::star::beans;
64 using namespace com::sun::star::uno;
65 using namespace com::sun::star::io;
66 using namespace com::sun::star::xml;
67 using namespace com::sun::star::xml::sax;
70 #define MAX_SYNTAX_HIGHLIGHT 20
71 #define MAX_HIGHLIGHTTIME 200
72 #define SYNTAX_HIGHLIGHT_TIMEOUT 200
75 struct SwTextPortion
77 sal_uInt16 nLine;
78 sal_uInt16 nStart, nEnd;
79 svtools::ColorConfigEntry eType;
82 typedef std::deque<SwTextPortion> SwTextPortions;
84 class XMLErrorHandler : public ::cppu::WeakImplHelper1< XErrorHandler >
86 public:
87 XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox );
89 // Methods
90 virtual void SAL_CALL error( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
91 virtual void SAL_CALL fatalError( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
92 virtual void SAL_CALL warning( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
94 private:
95 XMLSourceFileDialog* mpParent;
96 ListBox& mrListBox;
99 XMLErrorHandler::XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox )
100 : mpParent( pParent ),
101 mrListBox( rListBox )
105 // XMLErrorHandler
106 void SAL_CALL XMLErrorHandler::error( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
108 vos::OGuard aGuard( Application::GetSolarMutex() );
110 SAXParseException e;
111 if( aSAXParseException >>= e )
113 String sErr( String::CreateFromInt32( e.LineNumber ) );
114 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
115 sErr += String( e.Message );
116 sal_uInt16 nEntry = mrListBox.InsertEntry( sErr );
117 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
121 void SAL_CALL XMLErrorHandler::fatalError( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
123 vos::OGuard aGuard( Application::GetSolarMutex() );
125 SAXParseException e;
126 if( aSAXParseException >>= e )
128 String sErr( String::CreateFromInt32( e.LineNumber ) );
129 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
130 sErr += String( e.Message );
131 sal_uInt16 nEntry = mrListBox.InsertEntry( sErr );
132 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
136 void SAL_CALL XMLErrorHandler::warning( const Any& /* aSAXParseException */ ) throw (SAXException, RuntimeException)
139 SAXParseException e;
140 if( aSAXParseException >>= e )
142 String sErr( String::CreateFromInt32( e.LineNumber ) );
143 sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
144 sErr += String( e.Message );
145 sal_uInt16 nEntry = mrListBox.InsertEntry( sErr );
146 mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
152 XMLFileWindow::XMLFileWindow( Window* pParent ) :
153 Window( pParent, WB_BORDER|WB_CLIPCHILDREN ),
154 pTextEngine(0),
155 pOutWin(0),
156 pHScrollbar(0),
157 pVScrollbar(0),
158 nCurTextWidth(0),
159 nStartLine(USHRT_MAX),
160 eSourceEncoding(gsl_getSystemTextEncoding()),
161 bHighlighting(false)
163 CreateTextEngine();
166 XMLFileWindow::~XMLFileWindow()
168 if ( pTextEngine )
170 EndListening( *pTextEngine );
171 pTextEngine->RemoveView( pTextView );
173 delete pHScrollbar;
174 delete pVScrollbar;
176 delete pTextView;
177 delete pTextEngine;
179 delete pOutWin;
182 void XMLFileWindow::DataChanged( const DataChangedEvent& rDCEvt )
184 Window::DataChanged( rDCEvt );
186 switch ( rDCEvt.GetType() )
188 case DATACHANGED_SETTINGS:
189 // ScrollBars neu anordnen bzw. Resize ausloesen, da sich
190 // ScrollBar-Groesse geaendert haben kann. Dazu muss dann im
191 // Resize-Handler aber auch die Groesse der ScrollBars aus
192 // den Settings abgefragt werden.
193 if( rDCEvt.GetFlags() & SETTINGS_STYLE )
194 Resize();
195 break;
199 void XMLFileWindow::Resize()
201 // ScrollBars, etc. passiert in Adjust...
202 if ( pTextView )
204 long nVisY = pTextView->GetStartDocPos().Y();
205 pTextView->ShowCursor();
206 Size aOutSz( GetOutputSizePixel() );
207 long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
208 if ( nMaxVisAreaStart < 0 )
209 nMaxVisAreaStart = 0;
210 if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart )
212 Point aStartDocPos( pTextView->GetStartDocPos() );
213 aStartDocPos.Y() = nMaxVisAreaStart;
214 pTextView->SetStartDocPos( aStartDocPos );
215 pTextView->ShowCursor();
217 long nScrollStd = GetSettings().GetStyleSettings().GetScrollBarSize();
218 Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd );
219 Point aScrollPos(0, aOutSz.Height() - nScrollStd);
221 pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
223 aScrollSz.Width() = aScrollSz.Height();
224 aScrollSz.Height() = aOutSz.Height() - aScrollSz.Height();
225 aScrollPos = Point(aOutSz.Width() - nScrollStd, 0);
227 pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
228 aOutSz.Width() -= nScrollStd;
229 aOutSz.Height() -= nScrollStd;
230 pOutWin->SetOutputSizePixel(aOutSz);
231 InitScrollBars();
233 // Zeile im ersten Resize setzen
234 if(USHRT_MAX != nStartLine)
236 if(nStartLine < pTextEngine->GetParagraphCount())
238 TextSelection aSel(TextPaM( nStartLine, 0 ), TextPaM( nStartLine, 0x0 ));
239 pTextView->SetSelection(aSel);
240 pTextView->ShowCursor();
242 nStartLine = USHRT_MAX;
245 if ( nVisY != pTextView->GetStartDocPos().Y() )
246 InvalidateWindow();
251 void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt )
253 Window::DataChanged( rDCEvt );
255 switch( rDCEvt.GetType() )
257 case DATACHANGED_SETTINGS:
258 // den Settings abgefragt werden.
259 if( rDCEvt.GetFlags() & SETTINGS_STYLE )
261 const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
262 SetBackground( rCol );
263 Font aFont( pTextView->GetTextEngine()->GetFont() );
264 aFont.SetFillColor( rCol );
265 pTextView->GetTextEngine()->SetFont( aFont );
267 break;
271 void TextViewOutWin::MouseMove( const MouseEvent &rEvt )
273 if ( pTextView )
274 pTextView->MouseMove( rEvt );
277 void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt )
279 if ( pTextView )
280 pTextView->MouseButtonUp( rEvt );
283 void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt )
285 GrabFocus();
286 if ( pTextView )
287 pTextView->MouseButtonDown( rEvt );
290 void TextViewOutWin::Command( const CommandEvent& rCEvt )
292 switch(rCEvt.GetCommand())
294 case COMMAND_CONTEXTMENU:
295 break;
296 case COMMAND_WHEEL:
297 case COMMAND_STARTAUTOSCROLL:
298 case COMMAND_AUTOSCROLL:
300 const CommandWheelData* pWData = rCEvt.GetWheelData();
301 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
303 ((XMLFileWindow*)GetParent())->HandleWheelCommand( rCEvt );
306 break;
308 default:
309 if ( pTextView )
310 pTextView->Command( rCEvt );
311 else
312 Window::Command(rCEvt);
316 void TextViewOutWin::KeyInput( const KeyEvent& rKEvt )
318 if(!TextEngine::DoesKeyChangeText( rKEvt ))
319 pTextView->KeyInput( rKEvt );
322 void TextViewOutWin::Paint( const Rectangle& rRect )
324 pTextView->Paint( rRect );
327 void XMLFileWindow::CreateTextEngine()
329 const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
330 pOutWin = new TextViewOutWin(this, 0);
331 pOutWin->SetBackground(Wallpaper(rCol));
332 pOutWin->SetPointer(Pointer(POINTER_TEXT));
333 pOutWin->Show();
335 //Scrollbars anlegen
336 pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG);
337 pHScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
338 pHScrollbar->Show();
340 pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
341 pVScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
342 pHScrollbar->EnableDrag();
343 pVScrollbar->Show();
345 pTextEngine = new TextEngine;
346 pTextView = new TextView( pTextEngine, pOutWin );
347 pTextView->SetAutoIndentMode(sal_True);
348 pOutWin->SetTextView(pTextView);
350 pTextEngine->SetUpdateMode( sal_False );
351 pTextEngine->InsertView( pTextView );
353 Font aFont;
354 aFont.SetTransparent( sal_False );
355 aFont.SetFillColor( rCol );
356 SetPointFont( aFont );
357 aFont = GetFont();
358 aFont.SetFillColor( rCol );
359 pOutWin->SetFont( aFont );
360 pTextEngine->SetFont( aFont );
362 aSyntaxIdleTimer.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT );
363 aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, XMLFileWindow, SyntaxTimerHdl ) );
365 pTextEngine->EnableUndo( sal_False );
366 pTextEngine->SetUpdateMode( sal_True );
368 // pTextView->ShowCursor( sal_True, sal_True );
369 pTextView->HideCursor();
371 InitScrollBars();
372 StartListening( *pTextEngine );
375 void XMLFileWindow::SetScrollBarRanges()
377 pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) );
378 pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) );
381 void XMLFileWindow::InitScrollBars()
383 SetScrollBarRanges();
385 Size aOutSz( pOutWin->GetOutputSizePixel() );
386 pVScrollbar->SetVisibleSize( aOutSz.Height() );
387 pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 );
388 pVScrollbar->SetLineSize( pOutWin->GetTextHeight() );
389 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
390 pHScrollbar->SetVisibleSize( aOutSz.Width() );
391 pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 );
392 pHScrollbar->SetLineSize( pOutWin->GetTextWidth( 'x' ) );
393 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
397 IMPL_LINK(XMLFileWindow, ScrollHdl, ScrollBar*, pScroll)
399 if(pScroll == pVScrollbar)
401 long nDiff = pTextView->GetStartDocPos().Y() - pScroll->GetThumbPos();
402 GetTextView()->Scroll( 0, nDiff );
403 pTextView->ShowCursor( sal_False, sal_True );
404 pScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
406 else
408 long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos();
409 GetTextView()->Scroll( nDiff, 0 );
410 pTextView->ShowCursor( sal_False, sal_True );
411 pScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
413 return 0;
416 void XMLFileWindow::Notify( SfxBroadcaster& /* rBC */, const SfxHint& rHint )
418 if ( rHint.ISA( TextHint ) )
420 const TextHint& rTextHint = (const TextHint&)rHint;
421 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
423 pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
424 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
426 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
428 if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() )
429 pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() );
430 pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
431 SetScrollBarRanges();
433 else if( rTextHint.GetId() == TEXT_HINT_FORMATPARA )
435 DoDelayedSyntaxHighlight( (sal_uInt16)rTextHint.GetValue() );
440 void XMLFileWindow::InvalidateWindow()
442 pOutWin->Invalidate();
443 Window::Invalidate();
447 void XMLFileWindow::Command( const CommandEvent& rCEvt )
449 switch(rCEvt.GetCommand())
451 case COMMAND_WHEEL:
452 case COMMAND_STARTAUTOSCROLL:
453 case COMMAND_AUTOSCROLL:
455 const CommandWheelData* pWData = rCEvt.GetWheelData();
456 if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
457 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
459 break;
460 default:
461 Window::Command(rCEvt);
465 void XMLFileWindow::HandleWheelCommand( const CommandEvent& rCEvt )
467 pTextView->Command(rCEvt);
468 HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
471 void XMLFileWindow::GetFocus()
473 pOutWin->GrabFocus();
476 void XMLFileWindow::ShowWindow( const rtl::OUString& rFileName )
478 String aFileName( rFileName );
479 SvFileStream aStream( aFileName, STREAM_READ );
481 // since the xml files we load are utf-8 encoded, we need to set
482 // this encoding at the SvFileStream, else the TextEngine will
483 // use its default encoding which is not UTF8
484 const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
485 rtl_TextEncoding eDestEnc = rtl_getTextEncodingFromMimeCharset( pCharSet );
486 aStream.SetStreamCharSet( eDestEnc );
488 if( Read( aStream ) )
490 long nPrevTextWidth = nCurTextWidth;
491 nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
492 if ( nCurTextWidth != nPrevTextWidth )
493 SetScrollBarRanges();
495 TextPaM aPaM( pTextView->CursorStartOfDoc() );
496 TextSelection aSelection( aPaM, aPaM );
497 pTextView->SetSelection( aSelection, true );
499 Window::Show();
503 void XMLFileWindow::showLine( sal_Int32 nLine )
505 TextPaM aPaM( pTextView->CursorStartOfDoc() );
506 while( nLine-- )
507 aPaM = pTextView->CursorDown( aPaM );
509 TextSelection aSelection( pTextView->CursorEndOfLine( aPaM ), aPaM );
510 pTextView->SetSelection( aSelection, true );
514 XMLSourceFileDialog::XMLSourceFileDialog( Window* pParent, ResMgr& rResMgr, const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxMSF )
515 : WorkWindow( pParent, ResId( DLG_XML_SOURCE_FILE_DIALOG, rResMgr ) ),
516 mnOutputHeight( LogicToPixel( Size( 80, 80 ), MAP_APPFONT ).Height() ),
517 mxMSF( rxMSF ),
518 mrResMgr( rResMgr ),
519 maLBOutput( this ),
520 maPBValidate( this, ResId( PB_VALIDATE, rResMgr ) )
523 FreeResource();
525 maPBValidate.SetClickHdl(LINK( this, XMLSourceFileDialog, ClickHdl_Impl ) );
526 maLBOutput.SetSelectHdl(LINK(this, XMLSourceFileDialog, SelectHdl_Impl ) );
527 mpTextWindow = new XMLFileWindow( this );
528 mpTextWindow->SetHelpId( HID_XML_FILTER_OUTPUT_WINDOW );
529 maLBOutput.SetHelpId( HID_XML_FILTER_TEST_VALIDATE_OUPUT );
531 Resize();
534 XMLSourceFileDialog::~XMLSourceFileDialog()
536 if( maFileURL.getLength() )
537 osl::File::remove( maFileURL );
539 delete mpTextWindow;
542 void XMLSourceFileDialog::ShowWindow( const rtl::OUString& rFileName, const filter_info_impl* pFilterInfo )
544 EnterWait();
545 if( maFileURL.getLength() )
547 osl::File::remove( maFileURL );
548 delete mpTextWindow;
549 mpTextWindow = new XMLFileWindow( this );
550 maLBOutput.Hide();
551 maLBOutput.Clear();
552 maPBValidate.Enable(sal_True);
553 Resize();
556 mpFilterInfo = pFilterInfo;
557 maFileURL = rFileName;
558 mpTextWindow->ShowWindow( rFileName );
559 WorkWindow::Show();
560 LeaveWait();
563 void XMLSourceFileDialog::Resize()
565 bool bOutputVisible = maLBOutput.IsVisible() != 0;
567 Point aSpacing( LogicToPixel( Point( 6, 6 ), MAP_APPFONT ) );
568 Size aButton( maPBValidate.GetSizePixel() );
570 Size aDialogSize( GetOutputSizePixel() );
572 // Point aButtonPos( aSpacing.X(), aSpacing.Y() );
573 // maPBValidate.SetPosSizePixel( aButtonPos, aButton );
575 Size aOutputSize( aDialogSize.Width(), bOutputVisible ? mnOutputHeight : 0 );
577 Point aTextWindowPos( 0, 2* aSpacing.Y() + aButton.Height() );
578 Size aTextWindowSize( aDialogSize.Width(), aDialogSize.Height() - aTextWindowPos.Y() - aOutputSize.Height() );
580 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
582 if( bOutputVisible )
584 Point aOutputPos( 0, aTextWindowPos.Y() + aTextWindowSize.Height() );
585 maLBOutput.SetPosSizePixel( aOutputPos, aOutputSize );
590 IMPL_LINK(XMLSourceFileDialog, SelectHdl_Impl, ListBox *, pListBox )
592 sal_uInt16 nEntry = pListBox->GetSelectEntryPos();
593 if( LISTBOX_ENTRY_NOTFOUND != nEntry )
595 int nLine = (int)(sal_IntPtr)pListBox->GetEntryData(nEntry);
596 if( -1 != nLine )
598 if( nLine > 0 )
599 nLine--;
601 showLine( nLine );
604 return 0;
607 IMPL_LINK(XMLSourceFileDialog, ClickHdl_Impl, PushButton *, /* pButton */ )
609 onValidate();
610 return 0;
613 void XMLSourceFileDialog::onValidate()
615 EnterWait();
617 maLBOutput.Show();
618 maPBValidate.Enable(sal_False);
619 Resize();
623 Reference< XImportFilter > xImporter( mxMSF->createInstance( OUString::createFromAscii( "com.sun.star.documentconversion.XSLTValidate" ) ), UNO_QUERY );
624 if( xImporter.is() )
626 osl::File aInputFile( maFileURL );
627 /* osl::File::RC rc = */ aInputFile.open( OpenFlag_Read );
629 Reference< XInputStream > xIS( new comphelper::OSLInputStreamWrapper( aInputFile ) );
631 Sequence< PropertyValue > aSourceData(3);
632 aSourceData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
633 aSourceData[0].Value <<= xIS;
635 aSourceData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
636 aSourceData[1].Value <<= maFileURL;
638 aSourceData[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorHandler" ) );
639 Reference< XErrorHandler > xHandle( new XMLErrorHandler( this, maLBOutput ) );
640 aSourceData[2].Value <<= xHandle;
642 Reference< XDocumentHandler > xWriter( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), UNO_QUERY );
643 Reference< XOutputStream > xOS( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pipe" ) ) ), UNO_QUERY );
644 Reference< XActiveDataSource > xDocSrc( xWriter, UNO_QUERY );
645 xDocSrc->setOutputStream( xOS );
647 Sequence< OUString > aFilterUserData( mpFilterInfo->getFilterUserData() );
648 xImporter->importer( aSourceData, xWriter, aFilterUserData );
651 catch(Exception& e)
653 String sErr( e.Message );
654 sal_uInt16 nEntry = maLBOutput.InsertEntry( sErr );
655 maLBOutput.SetEntryData( nEntry, (void*)-1 );
658 if( 0 == maLBOutput.GetEntryCount() )
660 String sErr( RESID( STR_NO_ERRORS_FOUND ) );
661 sal_uInt16 nEntry = maLBOutput.InsertEntry( sErr );
662 maLBOutput.SetEntryData( nEntry, (void*)-1 );
665 LeaveWait();
668 void XMLSourceFileDialog::showLine( sal_Int32 nLine )
670 mpTextWindow->showLine( nLine );
674 ///////////////////////////////////////////////////////////////////////
676 void lcl_Highlight(const String& rSource, SwTextPortions& aPortionList)
678 const sal_Unicode cOpenBracket = '<';
679 const sal_Unicode cCloseBracket= '>';
680 const sal_Unicode cSlash = '/';
681 const sal_Unicode cExclamation = '!';
682 // const sal_Unicode cQuote = '"';
683 // const sal_Unicode cSQuote = '\'';
684 const sal_Unicode cMinus = '-';
685 const sal_Unicode cSpace = ' ';
686 const sal_Unicode cTab = 0x09;
687 const sal_Unicode cLF = 0x0a;
688 const sal_Unicode cCR = 0x0d;
691 const sal_uInt16 nStrLen = rSource.Len();
692 sal_uInt16 nInsert = 0; // Number of inserted Portions
693 sal_uInt16 nActPos = 0; // Position, at the '<' was found
694 sal_uInt16 nOffset = 0; // Offset of nActPos for '<'
695 sal_uInt16 nPortStart = USHRT_MAX; // For the TextPortion
696 sal_uInt16 nPortEnd = 0; //
697 SwTextPortion aText;
698 while(nActPos < nStrLen)
700 svtools::ColorConfigEntry eFoundType = svtools::HTMLUNKNOWN;
701 if(rSource.GetChar(nActPos) == cOpenBracket && nActPos < nStrLen - 2 )
703 // 'leere' Portion einfuegen
704 if(nPortEnd < nActPos - 1 )
706 aText.nLine = 0;
707 // am Anfang nicht verschieben
708 aText.nStart = nPortEnd;
709 if(nInsert)
710 aText.nStart += 1;
711 aText.nEnd = nActPos - 1;
712 aText.eType = svtools::HTMLUNKNOWN;
713 aPortionList.push_back( aText );
714 nInsert++;
716 sal_Unicode cFollowFirst = rSource.GetChar((xub_StrLen)(nActPos + 1));
717 sal_Unicode cFollowNext = rSource.GetChar((xub_StrLen)(nActPos + 2));
718 if(cExclamation == cFollowFirst)
720 // "<!" SGML oder Kommentar
721 if(cMinus == cFollowNext &&
722 nActPos < nStrLen - 3 && cMinus == rSource.GetChar((xub_StrLen)(nActPos + 3)))
724 eFoundType = svtools::HTMLCOMMENT;
726 else
727 eFoundType = svtools::HTMLSGML;
728 nPortStart = nActPos;
729 nPortEnd = nActPos + 1;
731 else if(cSlash == cFollowFirst)
733 // "</" Slash ignorieren
734 nPortStart = nActPos;
735 nActPos++;
736 nOffset++;
738 if(svtools::HTMLUNKNOWN == eFoundType)
740 //jetzt koennte hier ein keyword folgen
741 sal_uInt16 nSrchPos = nActPos;
742 while(++nSrchPos < nStrLen - 1)
744 sal_Unicode cNext = rSource.GetChar(nSrchPos);
745 if( cNext == cSpace ||
746 cNext == cTab ||
747 cNext == cLF ||
748 cNext == cCR)
749 break;
750 else if(cNext == cCloseBracket)
752 break;
755 if(nSrchPos > nActPos + 1)
757 //irgend ein String wurde gefunden
758 String sToken = rSource.Copy(nActPos + 1, nSrchPos - nActPos - 1 );
759 sToken.ToUpperAscii();
760 // int nToken = ::GetHTMLToken(sToken);
761 // if(nToken)
763 //Token gefunden
764 eFoundType = svtools::HTMLKEYWORD;
765 nPortEnd = nSrchPos;
766 nPortStart = nActPos;
769 else
771 //was war das denn?
772 #ifdef DEBUG
773 DBG_ERROR("Token nicht erkannt!")
774 DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer())
775 #endif
781 // jetzt muss noch '>' gesucht werden
782 if(svtools::HTMLUNKNOWN != eFoundType)
784 sal_Bool bFound = sal_False;
785 for(sal_uInt16 i = nPortEnd; i < nStrLen; i++)
786 if(cCloseBracket == rSource.GetChar(i))
788 bFound = sal_True;
789 nPortEnd = i;
790 break;
792 if(!bFound && (eFoundType == svtools::HTMLCOMMENT))
794 // Kommentar ohne Ende in dieser Zeile
795 bFound = sal_True;
796 nPortEnd = nStrLen - 1;
799 if(bFound ||(eFoundType == svtools::HTMLCOMMENT))
801 SwTextPortion aText2;
802 aText2.nLine = 0;
803 aText2.nStart = nPortStart + 1;
804 aText2.nEnd = nPortEnd;
805 aText2.eType = eFoundType;
806 aPortionList.push_back( aText2 );
807 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.push_back( aText );
822 nInsert++;
826 void XMLFileWindow::DoDelayedSyntaxHighlight( sal_uInt16 nPara )
828 if ( !bHighlighting )
830 aSyntaxLineTable.Insert( nPara, (void*)(sal_uInt16)1 );
831 aSyntaxIdleTimer.Start();
835 void XMLFileWindow::ImpDoHighlight( const String& rSource, sal_uInt16 nLineOff )
837 SwTextPortions aPortionList;
838 lcl_Highlight(rSource, aPortionList);
840 size_t nCount = aPortionList.size();
841 if ( !nCount )
842 return;
844 SwTextPortion& rLast = aPortionList[nCount-1];
845 if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoeben
847 nCount--;
848 aPortionList.pop_back();
849 if ( !nCount )
850 return;
853 // Evtl. Optimieren:
854 // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe,
855 // ggf. zusammenfassen, oder zumindest das Blank,
856 // damit weniger Attribute
857 sal_Bool bOptimizeHighlight = sal_True; // war in der BasicIDE static
858 if ( bOptimizeHighlight )
860 // Es muessen nur die Blanks und Tabs mit attributiert werden.
861 // Wenn zwei gleiche Attribute hintereinander eingestellt werden,
862 // optimiert das die TextEngine.
863 sal_uInt16 nLastEnd = 0;
864 for ( size_t i = 0; i < nCount; i++ )
866 SwTextPortion& r = aPortionList[i];
867 DBG_ASSERT( r.nLine == aPortionList[0].nLine, "doch mehrere Zeilen ?" );
868 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben
869 continue;
871 if ( r.nStart > nLastEnd )
873 // Kann ich mich drauf verlassen, dass alle ausser
874 // Blank und Tab gehighlightet wird ?!
875 r.nStart = nLastEnd;
877 nLastEnd = r.nEnd+1;
878 if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) )
879 r.nEnd = rSource.Len();
883 svtools::ColorConfig aConfig;
884 for ( size_t i = 0; i < aPortionList.size(); i++ )
886 SwTextPortion& r = aPortionList[i];
887 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben
888 continue;
889 // sal_uInt16 nCol = r.eType;
890 if(r.eType != svtools::HTMLSGML &&
891 r.eType != svtools::HTMLCOMMENT &&
892 r.eType != svtools::HTMLKEYWORD &&
893 r.eType != svtools::HTMLUNKNOWN)
894 r.eType = (svtools::ColorConfigEntry)svtools::HTMLUNKNOWN;
895 Color aColor((ColorData)aConfig.GetColorValue((svtools::ColorConfigEntry)r.eType).nColor);
896 sal_uInt16 nLine = nLineOff+r.nLine; //
897 pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1 );
901 IMPL_LINK( XMLFileWindow, SyntaxTimerHdl, Timer *, pTimer )
903 Time aSyntaxCheckStart;
904 DBG_ASSERT( pTextView, "Noch keine View, aber Syntax-Highlight ?!" );
905 pTextEngine->SetUpdateMode( sal_False );
907 bHighlighting = sal_True;
908 sal_uInt16 nLine;
909 sal_uInt16 nCount = 0;
910 // zuerst wird der Bereich um dem Cursor bearbeitet
911 TextSelection aSel = pTextView->GetSelection();
912 sal_uInt16 nCur = (sal_uInt16)aSel.GetStart().GetPara();
913 if(nCur > 40)
914 nCur -= 40;
915 else
916 nCur = 0;
917 if(aSyntaxLineTable.Count())
918 for(sal_uInt16 i = 0; i < 80 && nCount < 40; i++, nCur++)
920 void * p = aSyntaxLineTable.Get(nCur);
921 if(p)
923 DoSyntaxHighlight( nCur );
924 aSyntaxLineTable.Remove( nCur );
925 nCount++;
926 if(!aSyntaxLineTable.Count())
927 break;
928 if((Time().GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
930 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
931 break;
936 // wenn dann noch etwas frei ist, wird von Beginn an weitergearbeitet
937 void* p = aSyntaxLineTable.First();
938 while ( p && nCount < MAX_SYNTAX_HIGHLIGHT)
940 nLine = (sal_uInt16)aSyntaxLineTable.GetCurKey();
941 DoSyntaxHighlight( nLine );
942 sal_uInt16 nC = (sal_uInt16)aSyntaxLineTable.GetCurKey();
943 p = aSyntaxLineTable.Next();
944 aSyntaxLineTable.Remove(nC);
945 nCount ++;
946 if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
948 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
949 break;
952 // os: #43050# hier wird ein TextView-Problem umpopelt:
953 // waehrend des Highlightings funktionierte das Scrolling nicht
954 TextView* pTmp = pTextEngine->GetActiveView();
955 pTextEngine->SetActiveView(0);
956 pTextEngine->SetUpdateMode( sal_True );
957 pTextEngine->SetActiveView(pTmp);
958 pTextView->ShowCursor(sal_False, sal_False);
960 if(aSyntaxLineTable.Count() && !pTimer->IsActive())
961 pTimer->Start();
962 // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung
963 // => gute Gelegenheit, Textbreite zu ermitteln!
964 long nPrevTextWidth = nCurTextWidth;
965 nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
966 if ( nCurTextWidth != nPrevTextWidth )
967 SetScrollBarRanges();
968 bHighlighting = sal_False;
970 return 0;
973 void XMLFileWindow::DoSyntaxHighlight( sal_uInt16 nPara )
975 // Durch das DelayedSyntaxHighlight kann es passieren,
976 // dass die Zeile nicht mehr existiert!
977 if ( nPara < pTextEngine->GetParagraphCount() )
979 pTextEngine->RemoveAttribs( nPara );
980 String aSource( pTextEngine->GetText( nPara ) );
981 pTextEngine->SetUpdateMode( sal_False );
982 ImpDoHighlight( aSource, nPara );
983 // os: #43050# hier wird ein TextView-Problem umpopelt:
984 // waehrend des Highlightings funktionierte das Scrolling nicht
985 TextView* pTmp = pTextEngine->GetActiveView();
986 pTmp->SetAutoScroll(sal_False);
987 pTextEngine->SetActiveView(0);
988 pTextEngine->SetUpdateMode( sal_True );
989 pTextEngine->SetActiveView(pTmp);
990 // Bug 72887 show the cursor
991 pTmp->SetAutoScroll(sal_True);
992 pTmp->ShowCursor( sal_False/*pTmp->IsAutoScroll()*/ );