merged tag LIBREOFFICE_3_2_99_3
[LibreOffice.git] / filter / source / xsltdialog / xmlfileview.cxx
blobdca8b7a86dbb978e46a6b576470e892c00911640
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"
57 using namespace rtl;
58 using namespace osl;
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
72 struct SwTextPortion
74 USHORT nLine;
75 USHORT nStart, nEnd;
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 >
84 public:
85 XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox );
87 // Methods
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);
92 private:
93 XMLSourceFileDialog* mpParent;
94 ListBox& mrListBox;
97 XMLErrorHandler::XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox )
98 : mpParent( pParent ),
99 mrListBox( rListBox )
103 // XMLErrorHandler
104 void SAL_CALL XMLErrorHandler::error( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
106 ::SolarMutexGuard aGuard;
108 SAXParseException e;
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;
123 SAXParseException e;
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)
137 SAXParseException e;
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 ),
152 pTextEngine(0),
153 pOutWin(0),
154 pHScrollbar(0),
155 pVScrollbar(0),
156 nCurTextWidth(0),
157 nStartLine(USHRT_MAX),
158 eSourceEncoding(gsl_getSystemTextEncoding()),
159 bHighlighting(false)
161 CreateTextEngine();
164 XMLFileWindow::~XMLFileWindow()
166 if ( pTextEngine )
168 EndListening( *pTextEngine );
169 pTextEngine->RemoveView( pTextView );
171 delete pHScrollbar;
172 delete pVScrollbar;
174 delete pTextView;
175 delete pTextEngine;
177 delete pOutWin;
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 )
192 Resize();
193 break;
197 void XMLFileWindow::Resize()
199 // ScrollBars, etc. passiert in Adjust...
200 if ( pTextView )
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);
229 InitScrollBars();
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() )
244 InvalidateWindow();
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 );
265 break;
269 void TextViewOutWin::MouseMove( const MouseEvent &rEvt )
271 if ( pTextView )
272 pTextView->MouseMove( rEvt );
275 void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt )
277 if ( pTextView )
278 pTextView->MouseButtonUp( rEvt );
281 void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt )
283 GrabFocus();
284 if ( pTextView )
285 pTextView->MouseButtonDown( rEvt );
288 void TextViewOutWin::Command( const CommandEvent& rCEvt )
290 switch(rCEvt.GetCommand())
292 case COMMAND_CONTEXTMENU:
293 break;
294 case COMMAND_WHEEL:
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 );
304 break;
306 default:
307 if ( pTextView )
308 pTextView->Command( rCEvt );
309 else
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));
331 pOutWin->Show();
333 //Scrollbars anlegen
334 pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG);
335 pHScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
336 pHScrollbar->Show();
338 pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
339 pVScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
340 pHScrollbar->EnableDrag();
341 pVScrollbar->Show();
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 );
351 Font aFont;
352 aFont.SetTransparent( FALSE );
353 aFont.SetFillColor( rCol );
354 SetPointFont( aFont );
355 aFont = GetFont();
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();
369 InitScrollBars();
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() );
404 else
406 long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos();
407 GetTextView()->Scroll( nDiff, 0 );
408 pTextView->ShowCursor( FALSE, TRUE );
409 pScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
411 return 0;
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())
449 case COMMAND_WHEEL:
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 );
457 break;
458 default:
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 );
497 Window::Show();
501 void XMLFileWindow::showLine( sal_Int32 nLine )
503 TextPaM aPaM( pTextView->CursorStartOfDoc() );
504 while( nLine-- )
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() ),
515 mxMSF( rxMSF ),
516 mrResMgr( rResMgr ),
517 maLBOutput( this ),
518 maPBValidate( this, ResId( PB_VALIDATE, rResMgr ) )
521 FreeResource();
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 );
529 Resize();
532 XMLSourceFileDialog::~XMLSourceFileDialog()
534 if( maFileURL.getLength() )
535 osl::File::remove( maFileURL );
537 delete mpTextWindow;
540 void XMLSourceFileDialog::ShowWindow( const rtl::OUString& rFileName, const filter_info_impl* pFilterInfo )
542 EnterWait();
543 if( maFileURL.getLength() )
545 osl::File::remove( maFileURL );
546 delete mpTextWindow;
547 mpTextWindow = new XMLFileWindow( this );
548 maLBOutput.Hide();
549 maLBOutput.Clear();
550 maPBValidate.Enable(TRUE);
551 Resize();
554 mpFilterInfo = pFilterInfo;
555 maFileURL = rFileName;
556 mpTextWindow->ShowWindow( rFileName );
557 WorkWindow::Show();
558 LeaveWait();
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 );
580 if( bOutputVisible )
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);
594 if( -1 != nLine )
596 if( nLine > 0 )
597 nLine--;
599 showLine( nLine );
602 return 0;
605 IMPL_LINK(XMLSourceFileDialog, ClickHdl_Impl, PushButton *, /* pButton */ )
607 onValidate();
608 return 0;
611 void XMLSourceFileDialog::onValidate()
613 EnterWait();
615 maLBOutput.Show();
616 maPBValidate.Enable(FALSE);
617 Resize();
621 Reference< XImportFilter > xImporter( mxMSF->createInstance( OUString::createFromAscii( "com.sun.star.documentconversion.XSLTValidate" ) ), UNO_QUERY );
622 if( xImporter.is() )
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 );
649 catch(Exception& e)
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 );
663 LeaveWait();
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; //
695 SwTextPortion aText;
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 )
704 aText.nLine = 0;
705 // am Anfang nicht verschieben
706 aText.nStart = nPortEnd;
707 if(nInsert)
708 aText.nStart += 1;
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;
723 else
724 eFoundType = svtools::HTMLSGML;
725 nPortStart = nActPos;
726 nPortEnd = nActPos + 1;
728 else if(cSlash == cFollowFirst)
730 // "</" Slash ignorieren
731 nPortStart = nActPos;
732 nActPos++;
733 nOffset++;
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 ||
743 cNext == cTab ||
744 cNext == cLF ||
745 cNext == cCR)
746 break;
747 else if(cNext == cCloseBracket)
749 break;
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);
758 // if(nToken)
760 //Token gefunden
761 eFoundType = svtools::HTMLKEYWORD;
762 nPortEnd = nSrchPos;
763 nPortStart = nActPos;
766 else
768 //was war das denn?
769 #ifdef DEBUG
770 DBG_ERROR("Token nicht erkannt!")
771 DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer())
772 #endif
778 // jetzt muss noch '>' gesucht werden
779 if(svtools::HTMLUNKNOWN != eFoundType)
781 BOOL bFound = FALSE;
782 for(USHORT i = nPortEnd; i < nStrLen; i++)
783 if(cCloseBracket == rSource.GetChar(i))
785 bFound = TRUE;
786 nPortEnd = i;
787 break;
789 if(!bFound && (eFoundType == svtools::HTMLCOMMENT))
791 // Kommentar ohne Ende in dieser Zeile
792 bFound = TRUE;
793 nPortEnd = nStrLen - 1;
796 if(bFound ||(eFoundType == svtools::HTMLCOMMENT))
798 SwTextPortion aText2;
799 aText2.nLine = 0;
800 aText2.nStart = nPortStart + 1;
801 aText2.nEnd = nPortEnd;
802 aText2.eType = eFoundType;
803 aPortionList.Insert(aText2, nInsert++);
804 eFoundType = svtools::HTMLUNKNOWN;
809 nActPos++;
811 if(nInsert && nPortEnd < nActPos - 1)
813 aText.nLine = 0;
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();
836 if ( !nCount )
837 return;
839 SwTextPortion& rLast = aPortionList[nCount-1];
840 if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoeben
842 nCount--;
843 aPortionList.Remove( nCount);
844 if ( !nCount )
845 return;
848 // Evtl. Optimieren:
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.
858 USHORT nLastEnd = 0;
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
864 continue;
866 if ( r.nStart > nLastEnd )
868 // Kann ich mich drauf verlassen, dass alle ausser
869 // Blank und Tab gehighlightet wird ?!
870 r.nStart = nLastEnd;
872 nLastEnd = r.nEnd+1;
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
883 continue;
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;
903 USHORT nLine;
904 USHORT nCount = 0;
905 // zuerst wird der Bereich um dem Cursor bearbeitet
906 TextSelection aSel = pTextView->GetSelection();
907 USHORT nCur = (USHORT)aSel.GetStart().GetPara();
908 if(nCur > 40)
909 nCur -= 40;
910 else
911 nCur = 0;
912 if(aSyntaxLineTable.Count())
913 for(USHORT i = 0; i < 80 && nCount < 40; i++, nCur++)
915 void * p = aSyntaxLineTable.Get(nCur);
916 if(p)
918 DoSyntaxHighlight( nCur );
919 aSyntaxLineTable.Remove( nCur );
920 nCount++;
921 if(!aSyntaxLineTable.Count())
922 break;
923 if((Time().GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
925 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
926 break;
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);
940 nCount ++;
941 if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
943 pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
944 break;
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())
956 pTimer->Start();
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;
965 return 0;
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: */