summaryrefslogtreecommitdiff
path: root/filter/source/xsltdialog/xmlfileview.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/xsltdialog/xmlfileview.cxx')
-rw-r--r--filter/source/xsltdialog/xmlfileview.cxx994
1 files changed, 994 insertions, 0 deletions
diff --git a/filter/source/xsltdialog/xmlfileview.cxx b/filter/source/xsltdialog/xmlfileview.cxx
new file mode 100644
index 000000000000..8bd0001dc198
--- /dev/null
+++ b/filter/source/xsltdialog/xmlfileview.cxx
@@ -0,0 +1,994 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XErrorHandler.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/XImportFilter.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <comphelper/oslfile2streamwrap.hxx>
+
+#include <rtl/tencinfo.h>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+#include <svtools/textview.hxx>
+#ifndef _SCRBAR_HXX //autogen
+#include <vcl/scrbar.hxx>
+#endif
+#include <tools/stream.hxx>
+#include <tools/time.hxx>
+#include <osl/file.hxx>
+#include <vcl/msgbox.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/txtattr.hxx>
+
+#include "xmlfilterdialogstrings.hrc"
+#include "xmlfiltersettingsdialog.hxx"
+#include "xmlfileview.hxx"
+#include "xmlfileview.hrc"
+#include "xmlfilterhelpids.hrc"
+
+#include <deque>
+
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace com::sun::star::xml;
+using namespace com::sun::star::xml::sax;
+
+
+#define MAX_SYNTAX_HIGHLIGHT 20
+#define MAX_HIGHLIGHTTIME 200
+#define SYNTAX_HIGHLIGHT_TIMEOUT 200
+
+
+struct SwTextPortion
+{
+ USHORT nLine;
+ USHORT nStart, nEnd;
+ svtools::ColorConfigEntry eType;
+};
+
+typedef std::deque<SwTextPortion> SwTextPortions;
+
+class XMLErrorHandler : public ::cppu::WeakImplHelper1< XErrorHandler >
+{
+public:
+ XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox );
+
+ // Methods
+ virtual void SAL_CALL error( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL fatalError( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL warning( const Any& aSAXParseException ) throw (SAXException, RuntimeException);
+
+private:
+ XMLSourceFileDialog* mpParent;
+ ListBox& mrListBox;
+};
+
+XMLErrorHandler::XMLErrorHandler( XMLSourceFileDialog* pParent, ListBox& rListBox )
+: mpParent( pParent ),
+ mrListBox( rListBox )
+{
+}
+
+// XMLErrorHandler
+void SAL_CALL XMLErrorHandler::error( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ SAXParseException e;
+ if( aSAXParseException >>= e )
+ {
+ String sErr( String::CreateFromInt32( e.LineNumber ) );
+ sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
+ sErr += String( e.Message );
+ USHORT nEntry = mrListBox.InsertEntry( sErr );
+ mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
+ }
+}
+
+void SAL_CALL XMLErrorHandler::fatalError( const Any& aSAXParseException ) throw (SAXException, RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ SAXParseException e;
+ if( aSAXParseException >>= e )
+ {
+ String sErr( String::CreateFromInt32( e.LineNumber ) );
+ sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
+ sErr += String( e.Message );
+ USHORT nEntry = mrListBox.InsertEntry( sErr );
+ mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
+ }
+}
+
+void SAL_CALL XMLErrorHandler::warning( const Any& /* aSAXParseException */ ) throw (SAXException, RuntimeException)
+{
+/*
+ SAXParseException e;
+ if( aSAXParseException >>= e )
+ {
+ String sErr( String::CreateFromInt32( e.LineNumber ) );
+ sErr += String( RTL_CONSTASCII_USTRINGPARAM( " : " ) );
+ sErr += String( e.Message );
+ USHORT nEntry = mrListBox.InsertEntry( sErr );
+ mrListBox.SetEntryData( nEntry, (void*)e.LineNumber );
+ }
+*/
+}
+
+
+XMLFileWindow::XMLFileWindow( Window* pParent ) :
+ Window( pParent, WB_BORDER|WB_CLIPCHILDREN ),
+ pTextEngine(0),
+ pOutWin(0),
+ pHScrollbar(0),
+ pVScrollbar(0),
+ nCurTextWidth(0),
+ nStartLine(USHRT_MAX),
+ eSourceEncoding(gsl_getSystemTextEncoding()),
+ bHighlighting(false)
+{
+ CreateTextEngine();
+}
+
+XMLFileWindow::~XMLFileWindow()
+{
+ if ( pTextEngine )
+ {
+ EndListening( *pTextEngine );
+ pTextEngine->RemoveView( pTextView );
+
+ delete pHScrollbar;
+ delete pVScrollbar;
+
+ delete pTextView;
+ delete pTextEngine;
+ }
+ delete pOutWin;
+}
+
+void XMLFileWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ switch ( rDCEvt.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ // ScrollBars neu anordnen bzw. Resize ausloesen, da sich
+ // ScrollBar-Groesse geaendert haben kann. Dazu muss dann im
+ // Resize-Handler aber auch die Groesse der ScrollBars aus
+ // den Settings abgefragt werden.
+ if( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ Resize();
+ break;
+ }
+}
+
+void XMLFileWindow::Resize()
+{
+ // ScrollBars, etc. passiert in Adjust...
+ if ( pTextView )
+ {
+ long nVisY = pTextView->GetStartDocPos().Y();
+ pTextView->ShowCursor();
+ Size aOutSz( GetOutputSizePixel() );
+ long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
+ if ( nMaxVisAreaStart < 0 )
+ nMaxVisAreaStart = 0;
+ if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart )
+ {
+ Point aStartDocPos( pTextView->GetStartDocPos() );
+ aStartDocPos.Y() = nMaxVisAreaStart;
+ pTextView->SetStartDocPos( aStartDocPos );
+ pTextView->ShowCursor();
+ }
+ long nScrollStd = GetSettings().GetStyleSettings().GetScrollBarSize();
+ Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd );
+ Point aScrollPos(0, aOutSz.Height() - nScrollStd);
+
+ pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
+
+ aScrollSz.Width() = aScrollSz.Height();
+ aScrollSz.Height() = aOutSz.Height() - aScrollSz.Height();
+ aScrollPos = Point(aOutSz.Width() - nScrollStd, 0);
+
+ pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
+ aOutSz.Width() -= nScrollStd;
+ aOutSz.Height() -= nScrollStd;
+ pOutWin->SetOutputSizePixel(aOutSz);
+ InitScrollBars();
+
+ // Zeile im ersten Resize setzen
+ if(USHRT_MAX != nStartLine)
+ {
+ if(nStartLine < pTextEngine->GetParagraphCount())
+ {
+ TextSelection aSel(TextPaM( nStartLine, 0 ), TextPaM( nStartLine, 0x0 ));
+ pTextView->SetSelection(aSel);
+ pTextView->ShowCursor();
+ }
+ nStartLine = USHRT_MAX;
+ }
+
+ if ( nVisY != pTextView->GetStartDocPos().Y() )
+ InvalidateWindow();
+ }
+
+}
+
+void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ switch( rDCEvt.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ // den Settings abgefragt werden.
+ if( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ {
+ const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
+ SetBackground( rCol );
+ Font aFont( pTextView->GetTextEngine()->GetFont() );
+ aFont.SetFillColor( rCol );
+ pTextView->GetTextEngine()->SetFont( aFont );
+ }
+ break;
+ }
+}
+
+void TextViewOutWin::MouseMove( const MouseEvent &rEvt )
+{
+ if ( pTextView )
+ pTextView->MouseMove( rEvt );
+}
+
+void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt )
+{
+ if ( pTextView )
+ pTextView->MouseButtonUp( rEvt );
+}
+
+void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt )
+{
+ GrabFocus();
+ if ( pTextView )
+ pTextView->MouseButtonDown( rEvt );
+}
+
+void TextViewOutWin::Command( const CommandEvent& rCEvt )
+{
+ switch(rCEvt.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ break;
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ {
+ const CommandWheelData* pWData = rCEvt.GetWheelData();
+ if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
+ {
+ ((XMLFileWindow*)GetParent())->HandleWheelCommand( rCEvt );
+ }
+ }
+ break;
+
+ default:
+ if ( pTextView )
+ pTextView->Command( rCEvt );
+ else
+ Window::Command(rCEvt);
+ }
+}
+
+void TextViewOutWin::KeyInput( const KeyEvent& rKEvt )
+{
+ if(!TextEngine::DoesKeyChangeText( rKEvt ))
+ pTextView->KeyInput( rKEvt );
+}
+
+void TextViewOutWin::Paint( const Rectangle& rRect )
+{
+ pTextView->Paint( rRect );
+}
+
+void XMLFileWindow::CreateTextEngine()
+{
+ const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
+ pOutWin = new TextViewOutWin(this, 0);
+ pOutWin->SetBackground(Wallpaper(rCol));
+ pOutWin->SetPointer(Pointer(POINTER_TEXT));
+ pOutWin->Show();
+
+ //Scrollbars anlegen
+ pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG);
+ pHScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
+ pHScrollbar->Show();
+
+ pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
+ pVScrollbar->SetScrollHdl(LINK(this, XMLFileWindow, ScrollHdl));
+ pHScrollbar->EnableDrag();
+ pVScrollbar->Show();
+
+ pTextEngine = new TextEngine;
+ pTextView = new TextView( pTextEngine, pOutWin );
+ pTextView->SetAutoIndentMode(TRUE);
+ pOutWin->SetTextView(pTextView);
+
+ pTextEngine->SetUpdateMode( FALSE );
+ pTextEngine->InsertView( pTextView );
+
+ Font aFont;
+ aFont.SetTransparent( FALSE );
+ aFont.SetFillColor( rCol );
+ SetPointFont( aFont );
+ aFont = GetFont();
+ aFont.SetFillColor( rCol );
+ pOutWin->SetFont( aFont );
+ pTextEngine->SetFont( aFont );
+
+ aSyntaxIdleTimer.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT );
+ aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, XMLFileWindow, SyntaxTimerHdl ) );
+
+ pTextEngine->EnableUndo( FALSE );
+ pTextEngine->SetUpdateMode( TRUE );
+
+// pTextView->ShowCursor( TRUE, TRUE );
+ pTextView->HideCursor();
+
+ InitScrollBars();
+ StartListening( *pTextEngine );
+}
+
+void XMLFileWindow::SetScrollBarRanges()
+{
+ pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) );
+ pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) );
+}
+
+void XMLFileWindow::InitScrollBars()
+{
+ SetScrollBarRanges();
+
+ Size aOutSz( pOutWin->GetOutputSizePixel() );
+ pVScrollbar->SetVisibleSize( aOutSz.Height() );
+ pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 );
+ pVScrollbar->SetLineSize( pOutWin->GetTextHeight() );
+ pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ pHScrollbar->SetVisibleSize( aOutSz.Width() );
+ pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 );
+ pHScrollbar->SetLineSize( pOutWin->GetTextWidth( 'x' ) );
+ pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
+
+}
+
+IMPL_LINK(XMLFileWindow, ScrollHdl, ScrollBar*, pScroll)
+{
+ if(pScroll == pVScrollbar)
+ {
+ long nDiff = pTextView->GetStartDocPos().Y() - pScroll->GetThumbPos();
+ GetTextView()->Scroll( 0, nDiff );
+ pTextView->ShowCursor( FALSE, TRUE );
+ pScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ }
+ else
+ {
+ long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos();
+ GetTextView()->Scroll( nDiff, 0 );
+ pTextView->ShowCursor( FALSE, TRUE );
+ pScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
+ }
+ return 0;
+}
+
+void XMLFileWindow::Notify( SfxBroadcaster& /* rBC */, const SfxHint& rHint )
+{
+ if ( rHint.ISA( TextHint ) )
+ {
+ const TextHint& rTextHint = (const TextHint&)rHint;
+ if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
+ {
+ pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
+ pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
+ {
+ if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() )
+ pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() );
+ pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ SetScrollBarRanges();
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_FORMATPARA )
+ {
+ DoDelayedSyntaxHighlight( (USHORT)rTextHint.GetValue() );
+ }
+ }
+}
+
+void XMLFileWindow::InvalidateWindow()
+{
+ pOutWin->Invalidate();
+ Window::Invalidate();
+
+}
+
+void XMLFileWindow::Command( const CommandEvent& rCEvt )
+{
+ switch(rCEvt.GetCommand())
+ {
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ {
+ const CommandWheelData* pWData = rCEvt.GetWheelData();
+ if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
+ HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
+ }
+ break;
+ default:
+ Window::Command(rCEvt);
+ }
+}
+
+void XMLFileWindow::HandleWheelCommand( const CommandEvent& rCEvt )
+{
+ pTextView->Command(rCEvt);
+ HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
+}
+
+void XMLFileWindow::GetFocus()
+{
+ pOutWin->GrabFocus();
+}
+
+void XMLFileWindow::ShowWindow( const rtl::OUString& rFileName )
+{
+ String aFileName( rFileName );
+ SvFileStream aStream( aFileName, STREAM_READ );
+
+ // since the xml files we load are utf-8 encoded, we need to set
+ // this encoding at the SvFileStream, else the TextEngine will
+ // use its default encoding which is not UTF8
+ const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
+ rtl_TextEncoding eDestEnc = rtl_getTextEncodingFromMimeCharset( pCharSet );
+ aStream.SetStreamCharSet( eDestEnc );
+
+ if( Read( aStream ) )
+ {
+ long nPrevTextWidth = nCurTextWidth;
+ nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
+ if ( nCurTextWidth != nPrevTextWidth )
+ SetScrollBarRanges();
+
+ TextPaM aPaM( pTextView->CursorStartOfDoc() );
+ TextSelection aSelection( aPaM, aPaM );
+ pTextView->SetSelection( aSelection, true );
+
+ Window::Show();
+ }
+}
+
+void XMLFileWindow::showLine( sal_Int32 nLine )
+{
+ TextPaM aPaM( pTextView->CursorStartOfDoc() );
+ while( nLine-- )
+ aPaM = pTextView->CursorDown( aPaM );
+
+ TextSelection aSelection( pTextView->CursorEndOfLine( aPaM ), aPaM );
+ pTextView->SetSelection( aSelection, true );
+}
+
+
+XMLSourceFileDialog::XMLSourceFileDialog( Window* pParent, ResMgr& rResMgr, const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxMSF )
+: WorkWindow( pParent, ResId( DLG_XML_SOURCE_FILE_DIALOG, rResMgr ) ),
+ mnOutputHeight( LogicToPixel( Size( 80, 80 ), MAP_APPFONT ).Height() ),
+ mxMSF( rxMSF ),
+ mrResMgr( rResMgr ),
+ maLBOutput( this ),
+ maPBValidate( this, ResId( PB_VALIDATE, rResMgr ) )
+{
+
+ FreeResource();
+
+ maPBValidate.SetClickHdl(LINK( this, XMLSourceFileDialog, ClickHdl_Impl ) );
+ maLBOutput.SetSelectHdl(LINK(this, XMLSourceFileDialog, SelectHdl_Impl ) );
+ mpTextWindow = new XMLFileWindow( this );
+ mpTextWindow->SetHelpId( HID_XML_FILTER_OUTPUT_WINDOW );
+ maLBOutput.SetHelpId( HID_XML_FILTER_TEST_VALIDATE_OUPUT );
+
+ Resize();
+}
+
+XMLSourceFileDialog::~XMLSourceFileDialog()
+{
+ if( maFileURL.getLength() )
+ osl::File::remove( maFileURL );
+
+ delete mpTextWindow;
+}
+
+void XMLSourceFileDialog::ShowWindow( const rtl::OUString& rFileName, const filter_info_impl* pFilterInfo )
+{
+ EnterWait();
+ if( maFileURL.getLength() )
+ {
+ osl::File::remove( maFileURL );
+ delete mpTextWindow;
+ mpTextWindow = new XMLFileWindow( this );
+ maLBOutput.Hide();
+ maLBOutput.Clear();
+ maPBValidate.Enable(TRUE);
+ Resize();
+ }
+
+ mpFilterInfo = pFilterInfo;
+ maFileURL = rFileName;
+ mpTextWindow->ShowWindow( rFileName );
+ WorkWindow::Show();
+ LeaveWait();
+}
+
+void XMLSourceFileDialog::Resize()
+{
+ bool bOutputVisible = maLBOutput.IsVisible() != 0;
+
+ Point aSpacing( LogicToPixel( Point( 6, 6 ), MAP_APPFONT ) );
+ Size aButton( maPBValidate.GetSizePixel() );
+
+ Size aDialogSize( GetOutputSizePixel() );
+
+// Point aButtonPos( aSpacing.X(), aSpacing.Y() );
+// maPBValidate.SetPosSizePixel( aButtonPos, aButton );
+
+ Size aOutputSize( aDialogSize.Width(), bOutputVisible ? mnOutputHeight : 0 );
+
+ Point aTextWindowPos( 0, 2* aSpacing.Y() + aButton.Height() );
+ Size aTextWindowSize( aDialogSize.Width(), aDialogSize.Height() - aTextWindowPos.Y() - aOutputSize.Height() );
+
+ mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
+
+ if( bOutputVisible )
+ {
+ Point aOutputPos( 0, aTextWindowPos.Y() + aTextWindowSize.Height() );
+ maLBOutput.SetPosSizePixel( aOutputPos, aOutputSize );
+ }
+}
+
+
+IMPL_LINK(XMLSourceFileDialog, SelectHdl_Impl, ListBox *, pListBox )
+{
+ USHORT nEntry = pListBox->GetSelectEntryPos();
+ if( LISTBOX_ENTRY_NOTFOUND != nEntry )
+ {
+ int nLine = (int)(sal_IntPtr)pListBox->GetEntryData(nEntry);
+ if( -1 != nLine )
+ {
+ if( nLine > 0 )
+ nLine--;
+
+ showLine( nLine );
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK(XMLSourceFileDialog, ClickHdl_Impl, PushButton *, /* pButton */ )
+{
+ onValidate();
+ return 0;
+}
+
+void XMLSourceFileDialog::onValidate()
+{
+ EnterWait();
+
+ maLBOutput.Show();
+ maPBValidate.Enable(FALSE);
+ Resize();
+
+ try
+ {
+ Reference< XImportFilter > xImporter( mxMSF->createInstance( OUString::createFromAscii( "com.sun.star.documentconversion.XSLTValidate" ) ), UNO_QUERY );
+ if( xImporter.is() )
+ {
+ osl::File aInputFile( maFileURL );
+ /* osl::File::RC rc = */ aInputFile.open( OpenFlag_Read );
+
+ Reference< XInputStream > xIS( new comphelper::OSLInputStreamWrapper( aInputFile ) );
+
+ Sequence< PropertyValue > aSourceData(3);
+ aSourceData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
+ aSourceData[0].Value <<= xIS;
+
+ aSourceData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
+ aSourceData[1].Value <<= maFileURL;
+
+ aSourceData[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorHandler" ) );
+ Reference< XErrorHandler > xHandle( new XMLErrorHandler( this, maLBOutput ) );
+ aSourceData[2].Value <<= xHandle;
+
+ Reference< XDocumentHandler > xWriter( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), UNO_QUERY );
+ Reference< XOutputStream > xOS( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pipe" ) ) ), UNO_QUERY );
+ Reference< XActiveDataSource > xDocSrc( xWriter, UNO_QUERY );
+ xDocSrc->setOutputStream( xOS );
+
+ Sequence< OUString > aFilterUserData( mpFilterInfo->getFilterUserData() );
+ xImporter->importer( aSourceData, xWriter, aFilterUserData );
+ }
+ }
+ catch(Exception& e)
+ {
+ String sErr( e.Message );
+ USHORT nEntry = maLBOutput.InsertEntry( sErr );
+ maLBOutput.SetEntryData( nEntry, (void*)-1 );
+ }
+
+ if( 0 == maLBOutput.GetEntryCount() )
+ {
+ String sErr( RESID( STR_NO_ERRORS_FOUND ) );
+ USHORT nEntry = maLBOutput.InsertEntry( sErr );
+ maLBOutput.SetEntryData( nEntry, (void*)-1 );
+ }
+
+ LeaveWait();
+}
+
+void XMLSourceFileDialog::showLine( sal_Int32 nLine )
+{
+ mpTextWindow->showLine( nLine );
+}
+
+
+///////////////////////////////////////////////////////////////////////
+
+void lcl_Highlight(const String& rSource, SwTextPortions& aPortionList)
+{
+ const sal_Unicode cOpenBracket = '<';
+ const sal_Unicode cCloseBracket= '>';
+ const sal_Unicode cSlash = '/';
+ const sal_Unicode cExclamation = '!';
+// const sal_Unicode cQuote = '"';
+// const sal_Unicode cSQuote = '\'';
+ const sal_Unicode cMinus = '-';
+ const sal_Unicode cSpace = ' ';
+ const sal_Unicode cTab = 0x09;
+ const sal_Unicode cLF = 0x0a;
+ const sal_Unicode cCR = 0x0d;
+
+
+ const USHORT nStrLen = rSource.Len();
+ USHORT nInsert = 0; // Number of inserted Portions
+ USHORT nActPos = 0; // Position, at the '<' was found
+ USHORT nOffset = 0; // Offset of nActPos for '<'
+ USHORT nPortStart = USHRT_MAX; // For the TextPortion
+ USHORT nPortEnd = 0; //
+ SwTextPortion aText;
+ while(nActPos < nStrLen)
+ {
+ svtools::ColorConfigEntry eFoundType = svtools::HTMLUNKNOWN;
+ if(rSource.GetChar(nActPos) == cOpenBracket && nActPos < nStrLen - 2 )
+ {
+ // 'leere' Portion einfuegen
+ if(nPortEnd < nActPos - 1 )
+ {
+ aText.nLine = 0;
+ // am Anfang nicht verschieben
+ aText.nStart = nPortEnd;
+ if(nInsert)
+ aText.nStart += 1;
+ aText.nEnd = nActPos - 1;
+ aText.eType = svtools::HTMLUNKNOWN;
+ aPortionList.push_back( aText );
+ nInsert++;
+ }
+ sal_Unicode cFollowFirst = rSource.GetChar((xub_StrLen)(nActPos + 1));
+ sal_Unicode cFollowNext = rSource.GetChar((xub_StrLen)(nActPos + 2));
+ if(cExclamation == cFollowFirst)
+ {
+ // "<!" SGML oder Kommentar
+ if(cMinus == cFollowNext &&
+ nActPos < nStrLen - 3 && cMinus == rSource.GetChar((xub_StrLen)(nActPos + 3)))
+ {
+ eFoundType = svtools::HTMLCOMMENT;
+ }
+ else
+ eFoundType = svtools::HTMLSGML;
+ nPortStart = nActPos;
+ nPortEnd = nActPos + 1;
+ }
+ else if(cSlash == cFollowFirst)
+ {
+ // "</" Slash ignorieren
+ nPortStart = nActPos;
+ nActPos++;
+ nOffset++;
+ }
+ if(svtools::HTMLUNKNOWN == eFoundType)
+ {
+ //jetzt koennte hier ein keyword folgen
+ USHORT nSrchPos = nActPos;
+ while(++nSrchPos < nStrLen - 1)
+ {
+ sal_Unicode cNext = rSource.GetChar(nSrchPos);
+ if( cNext == cSpace ||
+ cNext == cTab ||
+ cNext == cLF ||
+ cNext == cCR)
+ break;
+ else if(cNext == cCloseBracket)
+ {
+ break;
+ }
+ }
+ if(nSrchPos > nActPos + 1)
+ {
+ //irgend ein String wurde gefunden
+ String sToken = rSource.Copy(nActPos + 1, nSrchPos - nActPos - 1 );
+ sToken.ToUpperAscii();
+// int nToken = ::GetHTMLToken(sToken);
+// if(nToken)
+ {
+ //Token gefunden
+ eFoundType = svtools::HTMLKEYWORD;
+ nPortEnd = nSrchPos;
+ nPortStart = nActPos;
+ }
+/*
+ else
+ {
+ //was war das denn?
+#ifdef DEBUG
+ DBG_ERROR("Token nicht erkannt!")
+ DBG_ERROR(ByteString(sToken, gsl_getSystemTextEncoding()).GetBuffer())
+#endif
+ }
+*/
+
+ }
+ }
+ // jetzt muss noch '>' gesucht werden
+ if(svtools::HTMLUNKNOWN != eFoundType)
+ {
+ BOOL bFound = FALSE;
+ for(USHORT i = nPortEnd; i < nStrLen; i++)
+ if(cCloseBracket == rSource.GetChar(i))
+ {
+ bFound = TRUE;
+ nPortEnd = i;
+ break;
+ }
+ if(!bFound && (eFoundType == svtools::HTMLCOMMENT))
+ {
+ // Kommentar ohne Ende in dieser Zeile
+ bFound = TRUE;
+ nPortEnd = nStrLen - 1;
+ }
+
+ if(bFound ||(eFoundType == svtools::HTMLCOMMENT))
+ {
+ SwTextPortion aText2;
+ aText2.nLine = 0;
+ aText2.nStart = nPortStart + 1;
+ aText2.nEnd = nPortEnd;
+ aText2.eType = eFoundType;
+ aPortionList.push_back( aText2 );
+ nInsert++;
+ eFoundType = svtools::HTMLUNKNOWN;
+ }
+
+ }
+ }
+ nActPos++;
+ }
+ if(nInsert && nPortEnd < nActPos - 1)
+ {
+ aText.nLine = 0;
+ aText.nStart = nPortEnd + 1;
+ aText.nEnd = nActPos - 1;
+ aText.eType = svtools::HTMLUNKNOWN;
+ aPortionList.push_back( aText );
+ nInsert++;
+ }
+}
+
+void XMLFileWindow::DoDelayedSyntaxHighlight( USHORT nPara )
+{
+ if ( !bHighlighting )
+ {
+ aSyntaxLineTable.Insert( nPara, (void*)(USHORT)1 );
+ aSyntaxIdleTimer.Start();
+ }
+}
+
+void XMLFileWindow::ImpDoHighlight( const String& rSource, USHORT nLineOff )
+{
+ SwTextPortions aPortionList;
+ lcl_Highlight(rSource, aPortionList);
+
+ size_t nCount = aPortionList.size();
+ if ( !nCount )
+ return;
+
+ SwTextPortion& rLast = aPortionList[nCount-1];
+ if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoeben
+ {
+ nCount--;
+ aPortionList.pop_back();
+ if ( !nCount )
+ return;
+ }
+
+ // Evtl. Optimieren:
+ // Wenn haufig gleiche Farbe, dazwischen Blank ohne Farbe,
+ // ggf. zusammenfassen, oder zumindest das Blank,
+ // damit weniger Attribute
+ BOOL bOptimizeHighlight = TRUE; // war in der BasicIDE static
+ if ( bOptimizeHighlight )
+ {
+ // Es muessen nur die Blanks und Tabs mit attributiert werden.
+ // Wenn zwei gleiche Attribute hintereinander eingestellt werden,
+ // optimiert das die TextEngine.
+ USHORT nLastEnd = 0;
+ for ( size_t i = 0; i < nCount; i++ )
+ {
+ SwTextPortion& r = aPortionList[i];
+ DBG_ASSERT( r.nLine == aPortionList[0].nLine, "doch mehrere Zeilen ?" );
+ if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben
+ continue;
+
+ if ( r.nStart > nLastEnd )
+ {
+ // Kann ich mich drauf verlassen, dass alle ausser
+ // Blank und Tab gehighlightet wird ?!
+ r.nStart = nLastEnd;
+ }
+ nLastEnd = r.nEnd+1;
+ if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) )
+ r.nEnd = rSource.Len();
+ }
+ }
+
+ svtools::ColorConfig aConfig;
+ for ( size_t i = 0; i < aPortionList.size(); i++ )
+ {
+ SwTextPortion& r = aPortionList[i];
+ if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoeben
+ continue;
+// USHORT nCol = r.eType;
+ if(r.eType != svtools::HTMLSGML &&
+ r.eType != svtools::HTMLCOMMENT &&
+ r.eType != svtools::HTMLKEYWORD &&
+ r.eType != svtools::HTMLUNKNOWN)
+ r.eType = (svtools::ColorConfigEntry)svtools::HTMLUNKNOWN;
+ Color aColor((ColorData)aConfig.GetColorValue((svtools::ColorConfigEntry)r.eType).nColor);
+ USHORT nLine = nLineOff+r.nLine; //
+ pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1 );
+ }
+}
+
+IMPL_LINK( XMLFileWindow, SyntaxTimerHdl, Timer *, pTimer )
+{
+ Time aSyntaxCheckStart;
+ DBG_ASSERT( pTextView, "Noch keine View, aber Syntax-Highlight ?!" );
+ pTextEngine->SetUpdateMode( FALSE );
+
+ bHighlighting = TRUE;
+ USHORT nLine;
+ USHORT nCount = 0;
+ // zuerst wird der Bereich um dem Cursor bearbeitet
+ TextSelection aSel = pTextView->GetSelection();
+ USHORT nCur = (USHORT)aSel.GetStart().GetPara();
+ if(nCur > 40)
+ nCur -= 40;
+ else
+ nCur = 0;
+ if(aSyntaxLineTable.Count())
+ for(USHORT i = 0; i < 80 && nCount < 40; i++, nCur++)
+ {
+ void * p = aSyntaxLineTable.Get(nCur);
+ if(p)
+ {
+ DoSyntaxHighlight( nCur );
+ aSyntaxLineTable.Remove( nCur );
+ nCount++;
+ if(!aSyntaxLineTable.Count())
+ break;
+ if((Time().GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
+ {
+ pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
+ break;
+ }
+ }
+ }
+
+ // wenn dann noch etwas frei ist, wird von Beginn an weitergearbeitet
+ void* p = aSyntaxLineTable.First();
+ while ( p && nCount < MAX_SYNTAX_HIGHLIGHT)
+ {
+ nLine = (USHORT)aSyntaxLineTable.GetCurKey();
+ DoSyntaxHighlight( nLine );
+ USHORT nC = (USHORT)aSyntaxLineTable.GetCurKey();
+ p = aSyntaxLineTable.Next();
+ aSyntaxLineTable.Remove(nC);
+ nCount ++;
+ if(Time().GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
+ {
+ pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
+ break;
+ }
+ }
+ // os: #43050# hier wird ein TextView-Problem umpopelt:
+ // waehrend des Highlightings funktionierte das Scrolling nicht
+ TextView* pTmp = pTextEngine->GetActiveView();
+ pTextEngine->SetActiveView(0);
+ pTextEngine->SetUpdateMode( TRUE );
+ pTextEngine->SetActiveView(pTmp);
+ pTextView->ShowCursor(FALSE, FALSE);
+
+ if(aSyntaxLineTable.Count() && !pTimer->IsActive())
+ pTimer->Start();
+ // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung
+ // => gute Gelegenheit, Textbreite zu ermitteln!
+ long nPrevTextWidth = nCurTextWidth;
+ nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
+ if ( nCurTextWidth != nPrevTextWidth )
+ SetScrollBarRanges();
+ bHighlighting = FALSE;
+
+ return 0;
+}
+
+void XMLFileWindow::DoSyntaxHighlight( USHORT nPara )
+{
+ // Durch das DelayedSyntaxHighlight kann es passieren,
+ // dass die Zeile nicht mehr existiert!
+ if ( nPara < pTextEngine->GetParagraphCount() )
+ {
+ pTextEngine->RemoveAttribs( nPara );
+ String aSource( pTextEngine->GetText( nPara ) );
+ pTextEngine->SetUpdateMode( FALSE );
+ ImpDoHighlight( aSource, nPara );
+ // os: #43050# hier wird ein TextView-Problem umpopelt:
+ // waehrend des Highlightings funktionierte das Scrolling nicht
+ TextView* pTmp = pTextEngine->GetActiveView();
+ pTmp->SetAutoScroll(FALSE);
+ pTextEngine->SetActiveView(0);
+ pTextEngine->SetUpdateMode( TRUE );
+ pTextEngine->SetActiveView(pTmp);
+ // Bug 72887 show the cursor
+ pTmp->SetAutoScroll(TRUE);
+ pTmp->ShowCursor( FALSE/*pTmp->IsAutoScroll()*/ );
+ }
+}