diff options
Diffstat (limited to 'sdext/source')
121 files changed, 2418 insertions, 29920 deletions
diff --git a/sdext/source/minimizer/configurationaccess.cxx b/sdext/source/minimizer/configurationaccess.cxx index 0ed089e341a2..55e60c52ca96 100644 --- a/sdext/source/minimizer/configurationaccess.cxx +++ b/sdext/source/minimizer/configurationaccess.cxx @@ -25,9 +25,10 @@ #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/lang/XSingleServiceFactory.hpp> #include <comphelper/propertysequence.hxx> +#include <comphelper/propertyvalue.hxx> #include <sal/macros.h> #include <sal/log.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -139,10 +140,8 @@ bool OptimizerSettings::operator==( const OptimizerSettings& rOptimizerSettings && ( rOptimizerSettings.mbDeleteUnusedMasterPages == mbDeleteUnusedMasterPages ) && ( rOptimizerSettings.mbDeleteHiddenSlides == mbDeleteHiddenSlides ) && ( rOptimizerSettings.mbDeleteNotesPages == mbDeleteNotesPages ); -// && ( rOptimizerSettings.mbOpenNewDocument == mbOpenNewDocument ); } - ConfigurationAccess::ConfigurationAccess( const Reference< uno::XComponentContext >& rxContext ) : mxContext( rxContext ) { @@ -427,38 +426,24 @@ sal_Int32 ConfigurationAccess::GetConfigProperty( const PPPOptimizerTokenEnum eP Sequence< PropertyValue > ConfigurationAccess::GetConfigurationSequence() { - Sequence< PropertyValue > aRet( 15 ); OptimizerSettings& rSettings( maSettings.front() ); - aRet[ 0 ].Name = "JPEGCompression"; - aRet[ 0 ].Value <<= rSettings.mbJPEGCompression; - aRet[ 1 ].Name = "JPEGQuality"; - aRet[ 1 ].Value <<= rSettings.mnJPEGQuality; - aRet[ 2 ].Name = "RemoveCropArea"; - aRet[ 2 ].Value <<= rSettings.mbRemoveCropArea; - aRet[ 3 ].Name = "ImageResolution"; - aRet[ 3 ].Value <<= rSettings.mnImageResolution; - aRet[ 4 ].Name = "EmbedLinkedGraphics"; - aRet[ 4 ].Value <<= rSettings.mbEmbedLinkedGraphics; - aRet[ 5 ].Name = "OLEOptimization"; - aRet[ 5 ].Value <<= rSettings.mbOLEOptimization; - aRet[ 6 ].Name = "OLEOptimizationType"; - aRet[ 6 ].Value <<= rSettings.mnOLEOptimizationType; - aRet[ 7 ].Name = "DeleteUnusedMasterPages"; - aRet[ 7 ].Value <<= rSettings.mbDeleteUnusedMasterPages; - aRet[ 8 ].Name = "DeleteHiddenSlides"; - aRet[ 8 ].Value <<= rSettings.mbDeleteHiddenSlides; - aRet[ 9 ].Name = "DeleteNotesPages"; - aRet[ 9 ].Value <<= rSettings.mbDeleteNotesPages; - aRet[ 10].Name = "CustomShowName"; - aRet[ 10].Value <<= rSettings.maCustomShowName; - aRet[ 11].Name = "SaveAsURL"; - aRet[ 11].Value <<= rSettings.maSaveAsURL; - aRet[ 12].Name = "FilterName"; - aRet[ 12].Value <<= rSettings.maFilterName; - aRet[ 13].Name = "OpenNewDocument"; - aRet[ 13].Value <<= rSettings.mbOpenNewDocument; - aRet[ 14].Name = "EstimatedFileSize"; - aRet[ 14].Value <<= rSettings.mnEstimatedFileSize; + Sequence< PropertyValue > aRet{ + comphelper::makePropertyValue("JPEGCompression", rSettings.mbJPEGCompression), + comphelper::makePropertyValue("JPEGQuality", rSettings.mnJPEGQuality), + comphelper::makePropertyValue("RemoveCropArea", rSettings.mbRemoveCropArea), + comphelper::makePropertyValue("ImageResolution", rSettings.mnImageResolution), + comphelper::makePropertyValue("EmbedLinkedGraphics", rSettings.mbEmbedLinkedGraphics), + comphelper::makePropertyValue("OLEOptimization", rSettings.mbOLEOptimization), + comphelper::makePropertyValue("OLEOptimizationType", rSettings.mnOLEOptimizationType), + comphelper::makePropertyValue("DeleteUnusedMasterPages", rSettings.mbDeleteUnusedMasterPages), + comphelper::makePropertyValue("DeleteHiddenSlides", rSettings.mbDeleteHiddenSlides), + comphelper::makePropertyValue("DeleteNotesPages", rSettings.mbDeleteNotesPages), + comphelper::makePropertyValue("CustomShowName", rSettings.maCustomShowName), + comphelper::makePropertyValue("SaveAsURL", rSettings.maSaveAsURL), + comphelper::makePropertyValue("FilterName", rSettings.maFilterName), + comphelper::makePropertyValue("OpenNewDocument", rSettings.mbOpenNewDocument), + comphelper::makePropertyValue("EstimatedFileSize", rSettings.mnEstimatedFileSize) + }; return aRet; } diff --git a/sdext/source/minimizer/configurationaccess.hxx b/sdext/source/minimizer/configurationaccess.hxx index d4d4c4d3f898..5cf884fc13fe 100644 --- a/sdext/source/minimizer/configurationaccess.hxx +++ b/sdext/source/minimizer/configurationaccess.hxx @@ -96,14 +96,14 @@ class ConfigurationAccess std::vector< OptimizerSettings >& GetOptimizerSettings() { return maSettings; }; std::vector< OptimizerSettings >::iterator GetOptimizerSettingsByName( const OUString& rName ); - private: + protected: + css::uno::Reference< css::uno::XComponentContext > mxContext; + private: std::map < PPPOptimizerTokenEnum, OUString > maStrings; std::vector< OptimizerSettings > maSettings; - css::uno::Reference< css::uno::XComponentContext > mxContext; - void LoadStrings(); void LoadConfiguration(); css::uno::Reference< css::uno::XInterface > OpenConfiguration( bool bReadOnly ); diff --git a/sdext/source/minimizer/fileopendialog.cxx b/sdext/source/minimizer/fileopendialog.cxx index aab29c03907b..7ae877b13549 100644 --- a/sdext/source/minimizer/fileopendialog.cxx +++ b/sdext/source/minimizer/fileopendialog.cxx @@ -35,7 +35,6 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; -using namespace ::com::sun::star::view; using namespace ::com::sun::star::ui::dialogs; FileOpenDialog::FileOpenDialog( const Reference< XComponentContext >& rxContext ) @@ -67,7 +66,7 @@ FileOpenDialog::FileOpenDialog( const Reference< XComponentContext >& rxContext { FilterEntry aFilterEntry; bool bImpressFilter = false; - for ( const PropertyValue& rProperty : std::as_const(aFilterProperties) ) + for (const PropertyValue& rProperty : aFilterProperties) { bool bStop = false; switch( TKGet( rProperty.Name ) ) @@ -114,9 +113,9 @@ FileOpenDialog::FileOpenDialog( const Reference< XComponentContext >& rxContext if ( xTypes->getByName( rFilterEntry.maType ) >>= aTypeProperties ) { Sequence< OUString > aExtensions; - auto pProp = std::find_if(aTypeProperties.begin(), aTypeProperties.end(), + auto pProp = std::find_if(std::cbegin(aTypeProperties), std::cend(aTypeProperties), [](const PropertyValue& rProp) { return rProp.Name == "Extensions"; }); - if (pProp != aTypeProperties.end()) + if (pProp != std::cend(aTypeProperties)) pProp->Value >>= aExtensions; if ( aExtensions.hasElements() ) { diff --git a/sdext/source/minimizer/impoptimizer.cxx b/sdext/source/minimizer/impoptimizer.cxx index 6f9e2416ac94..abf54e296a77 100644 --- a/sdext/source/minimizer/impoptimizer.cxx +++ b/sdext/source/minimizer/impoptimizer.cxx @@ -41,6 +41,7 @@ #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> #include <com/sun/star/presentation/XPresentationPage.hpp> +#include <com/sun/star/rendering/XBitmap.hpp> #include <com/sun/star/document/XFilter.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/graphic/GraphicType.hpp> @@ -50,7 +51,8 @@ #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/util/URLTransformer.hpp> -using namespace ::std; +#include <comphelper/propertyvalue.hxx> + using namespace ::com::sun::star; using namespace ::com::sun::star::io; using namespace ::com::sun::star::awt; @@ -61,13 +63,12 @@ using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::graphic; -using namespace ::com::sun::star::document; using namespace ::com::sun::star::container; using namespace ::com::sun::star::presentation; static void ImpExtractCustomShow( const Reference< XModel >& rxModel, std::u16string_view rCustomShowName ) { - vector< Reference< XDrawPage > > vNonUsedPageList; + std::vector< Reference< XDrawPage > > vNonUsedPageList; try { PageCollector::CollectNonCustomShowPages( rxModel, rCustomShowName, vNonUsedPageList ); @@ -84,7 +85,7 @@ static void ImpExtractCustomShow( const Reference< XModel >& rxModel, std::u16st static void ImpDeleteUnusedMasterPages( const Reference< XModel >& rxModel ) { - vector< PageCollector::MasterPageEntity > aMasterPageList; + std::vector< PageCollector::MasterPageEntity > aMasterPageList; PageCollector::CollectMasterPages( rxModel, aMasterPageList ); // now master pages that are not marked can be deleted @@ -202,31 +203,22 @@ static void ImpCompressGraphic( Reference< XGraphicProvider > const & rxGraphicP { if ( rxGraphicProvider.is() && rxOutputStream.is() ) { - Sequence< PropertyValue > aFilterData( 8 ); - aFilterData[ 0 ].Name = "ImageResolution"; - aFilterData[ 0 ].Value <<= nImageResolution; - aFilterData[ 1 ].Name = "ColorMode"; // todo: jpeg color mode (0->true color, 1->greyscale) - aFilterData[ 1 ].Value <<= sal_Int32(0); - aFilterData[ 2 ].Name = "Quality"; // quality that is used if we export to jpeg - aFilterData[ 2 ].Value <<= nJPEGQuality; - aFilterData[ 3 ].Name = "Compression"; // compression that is used if we export to png - aFilterData[ 3 ].Value <<= sal_Int32(6); - aFilterData[ 4 ].Name = "Interlaced"; // interlaced is turned off if we export to png - aFilterData[ 4 ].Value <<= sal_Int32(0); - aFilterData[ 5 ].Name = "LogicalSize"; - aFilterData[ 5 ].Value <<= rLogicalSize; - aFilterData[ 6 ].Name = "RemoveCropArea"; - aFilterData[ 6 ].Value <<= bRemoveCropping; - aFilterData[ 7 ].Name = "GraphicCropLogic"; - aFilterData[ 7 ].Value <<= rGraphicCropLogic; - - Sequence< PropertyValue > aArgs( 3 ); - aArgs[ 0 ].Name = "MimeType"; // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"... - aArgs[ 0 ].Value <<= rDestMimeType; - aArgs[ 1 ].Name = "OutputStream"; - aArgs[ 1 ].Value <<= rxOutputStream; - aArgs[ 2 ].Name = "FilterData"; - aArgs[ 2 ].Value <<= aFilterData; + Sequence< PropertyValue > aFilterData{ + comphelper::makePropertyValue("ImageResolution", nImageResolution), + comphelper::makePropertyValue("ColorMode", sal_Int32(0)), // todo: jpeg color mode (0->true color, 1->greyscale) + comphelper::makePropertyValue("Quality", nJPEGQuality), // quality that is used if we export to jpeg + comphelper::makePropertyValue("Compression", sal_Int32(6)), // compression that is used if we export to png + comphelper::makePropertyValue("Interlaced", sal_Int32(0)), // interlaced is turned off if we export to png + comphelper::makePropertyValue("LogicalSize", rLogicalSize), + comphelper::makePropertyValue("RemoveCropArea", bRemoveCropping), + comphelper::makePropertyValue("GraphicCropLogic", rGraphicCropLogic) + }; + + Sequence< PropertyValue > aArgs{ + comphelper::makePropertyValue("MimeType", rDestMimeType), // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"... + comphelper::makePropertyValue("OutputStream", rxOutputStream), + comphelper::makePropertyValue("FilterData", aFilterData) + }; rxGraphicProvider->storeGraphic( rxGraphic, aArgs ); } @@ -328,9 +320,8 @@ static Reference< XGraphic > ImpCompressGraphic( const Reference< XComponentCont Reference< XInputStream > xInputStream( xTempFile->getInputStream() ); Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW ); xSeekable->seek( 0 ); - Sequence< PropertyValue > aArgs( 1 ); - aArgs[ 0 ].Name = "InputStream"; - aArgs[ 0 ].Value <<= xInputStream; + Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue( + "InputStream", xInputStream) }; xNewGraphic = xGraphicProvider->queryGraphic( aArgs ); } } @@ -347,9 +338,8 @@ static Reference< XGraphic > ImpCompressGraphic( const Reference< XComponentCont Reference< XInputStream > xInputStream( xTempFile->getInputStream() ); Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW ); xSeekable->seek( 0 ); - Sequence< PropertyValue > aArgs( 1 ); - aArgs[ 0 ].Name = "InputStream"; - aArgs[ 0 ].Value <<= xInputStream; + Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue("InputStream", + xInputStream) }; xNewGraphic = xGraphicProvider->queryGraphic( aArgs ); } } @@ -381,7 +371,7 @@ static void CompressGraphics( ImpOptimizer& rOptimizer, const Reference< XCompon Reference< XGraphic > xGraphic; if ( rGraphic.maUser[ 0 ].mbFillBitmap && rGraphic.maUser[ 0 ].mxPropertySet.is() ) { - Reference< XBitmap > xFillBitmap; + Reference< rendering::XBitmap > xFillBitmap; if ( rGraphic.maUser[ 0 ].mxPropertySet->getPropertyValue( "FillBitmap" ) >>= xFillBitmap ) xGraphic.set( xFillBitmap, UNO_QUERY_THROW ); } @@ -422,7 +412,7 @@ static void CompressGraphics( ImpOptimizer& rOptimizer, const Reference< XCompon } else if ( rGraphicUser.mxPropertySet.is() ) { - Reference< XBitmap > xFillBitmap( xNewGraphic, UNO_QUERY ); + Reference< rendering::XBitmap > xFillBitmap( xNewGraphic, UNO_QUERY ); if ( xFillBitmap.is() ) { awt::Size aSize; @@ -578,12 +568,13 @@ void ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments ) switch( TKGet( rArgument.Name ) ) { case TK_StatusDispatcher : rArgument.Value >>= mxStatusDispatcher; break; - case TK_InformationDialog: rArgument.Value >>= mxInformationDialog; break; + case TK_DocumentFrame: rArgument.Value >>= mxDocumentFrame; break; + case TK_DialogParentWindow: rArgument.Value >>= mxDialogParentWindow; break; case TK_Settings : { css::uno::Sequence< css::beans::PropertyValue > aSettings; rArgument.Value >>= aSettings; - for ( const auto& rSetting : std::as_const(aSettings) ) + for (const auto& rSetting : aSettings) { switch( TKGet( rSetting.Name ) ) { @@ -633,8 +624,9 @@ void ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments ) { int nLength = aArguments.getLength(); aArguments.realloc( nLength + 1 ); - aArguments[ nLength ].Name = "FilterName"; - aArguments[ nLength ].Value <<= maFilterName; + auto pArguments = aArguments.getArray(); + pArguments[ nLength ].Name = "FilterName"; + pArguments[ nLength ].Value <<= maFilterName; } xStorable->storeToURL( maSaveAsURL, aArguments ); if ( !nSourceSize ) @@ -648,9 +640,7 @@ void ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments ) xSelf = xDesktop->findFrame( "_blank", FrameSearchFlag::CREATE ); Reference< XComponentLoader > xComponentLoader( xSelf, UNO_QUERY ); - Sequence< PropertyValue > aLoadProps( 1 ); - aLoadProps[ 0 ].Name = "Hidden"; - aLoadProps[ 0 ].Value <<= true; + Sequence< PropertyValue > aLoadProps{ comphelper::makePropertyValue("Hidden", true) }; mxModel.set( xComponentLoader->loadComponentFromURL( maSaveAsURL, "_self", 0, aLoadProps ), UNO_QUERY ); } @@ -665,10 +655,10 @@ void ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments ) mxModel->unlockControllers(); // clearing undo stack: - Reference< XFrame > xFrame( xSelf.is() ? xSelf : mxInformationDialog ); + Reference< XFrame > xFrame( xSelf.is() ? xSelf : mxDocumentFrame ); if ( xFrame.is() ) { - DispatchURL( mxContext, "slot:27115", xFrame ); + DispatchURL(mxContext, ".uno:ClearUndoStack", xFrame); } } @@ -681,9 +671,9 @@ void ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments ) } } - if ( mxInformationDialog.is() ) + if ( mxDocumentFrame.is() ) { - InformationDialog aInformationDialog( mxContext, mxInformationDialog, maSaveAsURL, mbOpenNewDocument, nSourceSize, nDestSize, nEstimatedFileSize ); + InformationDialog aInformationDialog( mxContext, mxDialogParentWindow, maSaveAsURL, mbOpenNewDocument, nSourceSize, nDestSize, nEstimatedFileSize ); aInformationDialog.execute(); SetStatusValue( TK_OpenNewDocument, Any( mbOpenNewDocument ) ); DispatchStatus(); diff --git a/sdext/source/minimizer/impoptimizer.hxx b/sdext/source/minimizer/impoptimizer.hxx index 6a52e94986a4..98d22e71d137 100644 --- a/sdext/source/minimizer/impoptimizer.hxx +++ b/sdext/source/minimizer/impoptimizer.hxx @@ -35,6 +35,8 @@ private: css::uno::Reference< css::uno::XComponentContext > mxContext; css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< css::frame::XDispatch > mxStatusDispatcher; + css::uno::Reference<css::frame::XFrame> mxDocumentFrame; + css::uno::Reference<css::awt::XWindow> mxDialogParentWindow; bool mbJPEGCompression; sal_Int32 mnJPEGQuality; @@ -51,8 +53,6 @@ private: OUString maFilterName; bool mbOpenNewDocument; - css::uno::Reference< css::frame::XFrame > mxInformationDialog; - void Optimize(); public: diff --git a/sdext/source/minimizer/informationdialog.cxx b/sdext/source/minimizer/informationdialog.cxx index 4f823eaee75d..9872990a0f45 100644 --- a/sdext/source/minimizer/informationdialog.cxx +++ b/sdext/source/minimizer/informationdialog.cxx @@ -26,164 +26,13 @@ #include <com/sun/star/util/XURLTransformer.hpp> #include <rtl/ustrbuf.hxx> #include <sal/macros.h> - -#define DIALOG_WIDTH 240 -#define DIALOG_HEIGHT 80 -#define PAGE_POS_X 35 -#define PAGE_WIDTH ( DIALOG_WIDTH - PAGE_POS_X ) - 6 - +#include <vcl/svapp.hxx> using namespace ::com::sun::star; -using namespace ::com::sun::star::ui; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::util; using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::frame; -using namespace ::com::sun::star::beans; -using namespace ::com::sun::star::container; - - -OUString InsertFixedText( UnoDialog& rInformationDialog, const OUString& rControlName, const OUString& rLabel, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int32 nHeight, bool bMultiLine, sal_Int16 nTabIndex ) -{ - OUString pNames[] = { - OUString("Height"), - OUString("Label"), - OUString("MultiLine"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( nHeight ), - Any( rLabel ), - Any( bMultiLine ), - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - rInformationDialog.insertFixedText( rControlName, aNames, aValues ); - return rControlName; -} - -OUString InsertImage( - UnoDialog& rInformationDialog, - const OUString& rControlName, - const OUString& rURL, - sal_Int32 nPosX, - sal_Int32 nPosY, - sal_Int32 nWidth, - sal_Int32 nHeight, - bool bScale ) -{ - OUString pNames[] = { - OUString("Border"), - OUString("Height"), - OUString("ImageURL"), - OUString("PositionX"), - OUString("PositionY"), - OUString("ScaleImage"), - OUString("Width") }; - - Any pValues[] = { - Any( sal_Int16( 0 ) ), - Any( nHeight ), - Any( rURL ), - Any( nPosX ), - Any( nPosY ), - Any( bScale ), - Any( nWidth ) }; - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - rInformationDialog.insertImage( rControlName, aNames, aValues ); - return rControlName; -} - -OUString InsertCheckBox( UnoDialog& rInformationDialog, const OUString& rControlName, - const Reference< XItemListener >& rItemListener, const OUString& rLabel, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) -{ - sal_Int32 nHeight = 8; - OUString pNames[] = { - OUString("Enabled"), - OUString("Height"), - OUString("Label"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( true ), - Any( nHeight ), - Any( rLabel ), - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - Reference< XCheckBox > xCheckBox( rInformationDialog.insertCheckBox( rControlName, aNames, aValues ) ); - if ( rItemListener.is() ) - xCheckBox->addItemListener( rItemListener ); - return rControlName; -} - -OUString InsertButton( UnoDialog& rInformationDialog, const OUString& rControlName, Reference< XActionListener > const & xActionListener, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex, const OUString& rText ) -{ - sal_Int32 nHeight = 14; - OUString pNames[] = { - OUString("Enabled"), - OUString("Height"), - OUString("Label"), - OUString("PositionX"), - OUString("PositionY"), - OUString("PushButtonType"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( true ), - Any( nHeight ), - Any( rText ), - Any( nXPos ), - Any( nYPos ), - Any( static_cast< sal_Int16 >( PushButtonType_OK ) ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - rInformationDialog.insertButton( rControlName, xActionListener, aNames, aValues ); - return rControlName; -} - static OUString ImpValueOfInMB( sal_Int64 rVal ) { @@ -199,152 +48,95 @@ static OUString ImpValueOfInMB( sal_Int64 rVal ) void InformationDialog::InitDialog() { - sal_Int32 nDialogHeight = DIALOG_HEIGHT; - if ( maSaveAsURL.isEmpty() ) - nDialogHeight -= 22; - - // setting the dialog properties - OUString pNames[] = { - OUString("Closeable"), - OUString("Height"), - OUString("Moveable"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Title"), - OUString("Width") }; - - Any pValues[] = { - Any( true ), - Any( nDialogHeight ), - Any( true ), - Any( sal_Int32( 245 ) ), - Any( sal_Int32( 115 ) ), - Any( getString( STR_SUN_OPTIMIZATION_WIZARD2 ) ), - Any( sal_Int32( DIALOG_WIDTH ) ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - setPropertyValues(aNames, aValues); + set_title(getString(STR_SUN_OPTIMIZATION_WIZARD2)); sal_Int64 nSource = mnSourceSize; sal_Int64 nDest = mnDestSize; - PPPOptimizerTokenEnum eInfoString( STR_INFO_1 ); + PPPOptimizerTokenEnum eInfoString( STR_INFO_SECONDARY_1 ); if ( mnSourceSize ) { if ( mnDestSize ) - eInfoString = STR_INFO_1; + eInfoString = STR_INFO_SECONDARY_1; else { - eInfoString = STR_INFO_2; + eInfoString = STR_INFO_SECONDARY_2; nDest = mnApproxSize; } } else if ( mnDestSize ) - eInfoString = STR_INFO_3; + eInfoString = STR_INFO_SECONDARY_3; else { - eInfoString = STR_INFO_4; + eInfoString = STR_INFO_SECONDARY_4; nDest = mnApproxSize; } OUString aTitle; if ( !maSaveAsURL.isEmpty() ) { - Reference< XURLTransformer > xURLTransformer( URLTransformer::create(UnoDialog::mxContext) ); + Reference< XURLTransformer > xURLTransformer( URLTransformer::create(mxContext) ); util::URL aURL, aPresentationURL; aURL.Complete = maSaveAsURL; xURLTransformer->parseSmart( aURL, OUString() ); - static const OUStringLiteral sFileProtocol( u"file:///" ); + static constexpr OUString sFileProtocol( u"file:///"_ustr ); aPresentationURL.Complete = sFileProtocol + aURL.Name; aTitle = xURLTransformer->getPresentation( aPresentationURL, false ); if ( aTitle.match( sFileProtocol ) ) - aTitle = aTitle.replaceAt( 0, sFileProtocol.getLength(), OUString() ); + aTitle = aTitle.replaceAt( 0, sFileProtocol.getLength(), u"" ); } - OUString aInfoString( getString( eInfoString ) ); - static const OUStringLiteral aOldSizePlaceholder( u"%OLDFILESIZE" ); - static const OUStringLiteral aNewSizePlaceholder( u"%NEWFILESIZE" ); + OUString sPrimary( getString( STR_INFO_PRIMARY ) ); + OUString sSecondary( getString( eInfoString ) ); + static constexpr OUString aOldSizePlaceholder( u"%OLDFILESIZE"_ustr ); + static constexpr OUString aNewSizePlaceholder( u"%NEWFILESIZE"_ustr ); const OUString aTitlePlaceholder( !aTitle.isEmpty() ? OUString("%TITLE" ) : OUString("'%TITLE'") ); - sal_Int32 i = aInfoString.indexOf( aOldSizePlaceholder ); + sal_Int32 i = sSecondary.indexOf( aOldSizePlaceholder ); if ( i >= 0 ) - aInfoString = aInfoString.replaceAt( i, aOldSizePlaceholder.getLength(), ImpValueOfInMB( nSource ) ); + sSecondary = sSecondary.replaceAt( i, aOldSizePlaceholder.getLength(), ImpValueOfInMB( nSource ) ); - sal_Int32 j = aInfoString.indexOf( aNewSizePlaceholder ); + sal_Int32 j = sSecondary.indexOf( aNewSizePlaceholder ); if ( j >= 0 ) - aInfoString = aInfoString.replaceAt( j, aNewSizePlaceholder.getLength(), ImpValueOfInMB( nDest ) ); + sSecondary = sSecondary.replaceAt( j, aNewSizePlaceholder.getLength(), ImpValueOfInMB( nDest ) ); - sal_Int32 k = aInfoString.indexOf( aTitlePlaceholder ); + sal_Int32 k = sPrimary.indexOf( aTitlePlaceholder ); if ( k >= 0 ) - aInfoString = aInfoString.replaceAt( k, aTitlePlaceholder.getLength(), aTitle ); - - css::uno::Reference< css::awt::XItemListener > xItemListener; - InsertImage( *this, - "aboutimage", - "private:standardimage/query", - 5, 5, 25, 25, false ); - InsertFixedText( *this, "fixedtext", aInfoString, PAGE_POS_X, 6, PAGE_WIDTH, 24, true, 0 ); - if ( !maSaveAsURL.isEmpty() ) - InsertCheckBox( *this, "OpenNewDocument", xItemListener, getString( STR_AUTOMATICALLY_OPEN ), PAGE_POS_X, 42, PAGE_WIDTH, 1 ); - InsertButton( *this, "button", mxActionListener, DIALOG_WIDTH / 2 - 25, nDialogHeight - 20, 50, 2, getString( STR_OK ) ); + sPrimary = sPrimary.replaceAt( k, aTitlePlaceholder.getLength(), aTitle ); - bool bOpenNewDocument = mrbOpenNewDocument; - setControlProperty( "OpenNewDocument", "State", Any( static_cast<sal_Int16>(bOpenNewDocument) ) ); + set_primary_text(sPrimary); + set_secondary_text(sSecondary); + mxCheckBox->set_visible(!maSaveAsURL.isEmpty()); + mxCheckBox->set_active(mrbOpenNewDocument); } - -InformationDialog::InformationDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame, const OUString& rSaveAsURL, bool& rbOpenNewDocument, sal_Int64 rSourceSize, sal_Int64 rDestSize, sal_Int64 rApproxSize ) : - UnoDialog( rxContext, rxFrame ), - ConfigurationAccess( rxContext ), - mxActionListener( new OKActionListener( *this ) ), - mnSourceSize( rSourceSize ), - mnDestSize( rDestSize ), - mnApproxSize( rApproxSize ), - mrbOpenNewDocument( rbOpenNewDocument ), - maSaveAsURL( rSaveAsURL ) +InformationDialog::InformationDialog(const Reference< XComponentContext > &rxContext, const Reference<XWindow>& rxDialogParent, + const OUString& rSaveAsURL, bool& rbOpenNewDocument, + sal_Int64 rSourceSize, sal_Int64 rDestSize, sal_Int64 rApproxSize) + : MessageDialogController(Application::GetFrameWeld(rxDialogParent), "modules/simpress/ui/pminfodialog.ui", "PMInfoDialog", "ask") + , ConfigurationAccess(rxContext) + , mxCheckBox(m_xBuilder->weld_check_button("ask")) + , mnSourceSize(rSourceSize) + , mnDestSize(rDestSize) + , mnApproxSize(rApproxSize) + , mrbOpenNewDocument(rbOpenNewDocument) + , maSaveAsURL(rSaveAsURL) { InitDialog(); } - InformationDialog::~InformationDialog() { } - void InformationDialog::execute() { - UnoDialog::execute(); - - if ( !maSaveAsURL.isEmpty() ) - { - sal_Int16 nInt16 = 0; - Any aAny( getControlProperty( "OpenNewDocument", "State" ) ); - if ( aAny >>= nInt16 ) - { - bool bOpenNewDocument = static_cast< bool >( nInt16 ); - mrbOpenNewDocument = bOpenNewDocument; - } - } -} - - -void OKActionListener::actionPerformed( const ActionEvent& rEvent ) -{ - if ( rEvent.ActionCommand == "button" ) - { - mrDialog.endExecute( true ); - } -} -void OKActionListener::disposing( const css::lang::EventObject& /* Source */ ) -{ + run(); + if (!maSaveAsURL.isEmpty()) + mrbOpenNewDocument = mxCheckBox->get_active(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/informationdialog.hxx b/sdext/source/minimizer/informationdialog.hxx index 761a40e01e7e..56c6994a2c8e 100644 --- a/sdext/source/minimizer/informationdialog.hxx +++ b/sdext/source/minimizer/informationdialog.hxx @@ -17,35 +17,19 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_INFORMATIONDIALOG_HXX -#define INCLUDED_SDEXT_SOURCE_MINIMIZER_INFORMATIONDIALOG_HXX +#pragma once -#include "unodialog.hxx" #include "configurationaccess.hxx" -#include <com/sun/star/awt/XItemListener.hpp> +#include <vcl/weld.hxx> #include <com/sun/star/uno/XComponentContext.hpp> #include <cppuhelper/implbase.hxx> -OUString InsertFixedText( UnoDialog& rInformationDialog, const OUString& rControlName, const OUString& rLabel, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int32 nHeight, bool bMultiLine, sal_Int16 nTabIndex ); - -OUString InsertImage( UnoDialog& rInformationDialog, const OUString& rControlName, const OUString& rURL, - sal_Int32 nPosX, sal_Int32 nPosY, sal_Int32 nWidth, sal_Int32 nHeight, bool bScale ); - -OUString InsertCheckBox( UnoDialog& rInformationDialog, const OUString& rControlName, - const css::uno::Reference< css::awt::XItemListener >& rItemListener, const OUString& rLabel, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ); - -OUString InsertButton( UnoDialog& rInformationDialog, const OUString& rControlName, - css::uno::Reference< css::awt::XActionListener > const & xActionListener, sal_Int32 nXPos, sal_Int32 nYPos, - sal_Int32 nWidth, sal_Int16 nTabIndex, const OUString& rText ); - -class InformationDialog : public UnoDialog, public ConfigurationAccess +class InformationDialog : public weld::MessageDialogController, public ConfigurationAccess { public: InformationDialog( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - css::uno::Reference< css::frame::XFrame > const & rxFrame, const OUString& rSaveAsURL, + const css::uno::Reference<css::awt::XWindow>& rxDialogParent, const OUString& rSaveAsURL, bool& bOpenNewDocument, sal_Int64 nSourceSize, sal_Int64 nDestSize, sal_Int64 nApproxDest ); ~InformationDialog(); @@ -53,10 +37,10 @@ public: private: - css::uno::Reference< css::awt::XActionListener > mxActionListener; - void InitDialog(); + std::unique_ptr<weld::CheckButton> mxCheckBox; + sal_Int64 mnSourceSize; sal_Int64 mnDestSize; sal_Int64 mnApproxSize; @@ -64,18 +48,4 @@ private: const OUString& maSaveAsURL; }; -class OKActionListener : public ::cppu::WeakImplHelper< css::awt::XActionListener > -{ -public: - explicit OKActionListener( UnoDialog& rDialog ) : mrDialog( rDialog ){} - - virtual void SAL_CALL actionPerformed( const css::awt::ActionEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - UnoDialog& mrDialog; -}; - -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/optimizationstats.cxx b/sdext/source/minimizer/optimizationstats.cxx index deed337c712a..1deef26ac059 100644 --- a/sdext/source/minimizer/optimizationstats.cxx +++ b/sdext/source/minimizer/optimizationstats.cxx @@ -23,6 +23,10 @@ #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <comphelper/propertyvalue.hxx> + +#include <algorithm> + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -51,13 +55,10 @@ const uno::Any* OptimizationStats::GetStatusValue( const PPPOptimizerTokenEnum e css::beans::PropertyValues OptimizationStats::GetStatusSequence() { - int i = 0; uno::Sequence< PropertyValue > aStatsSequence( maStats.size() ); - for( const auto& rEntry : maStats ) - { - aStatsSequence[ i ].Name = TKGet( rEntry.first ); - aStatsSequence[ i++ ].Value = rEntry.second; - } + std::transform(maStats.begin(), maStats.end(), aStatsSequence.getArray(), + [](const auto& rEntry) + { return comphelper::makePropertyValue(TKGet( rEntry.first ), rEntry.second); }); return aStatsSequence; } diff --git a/sdext/source/minimizer/optimizerdialog.cxx b/sdext/source/minimizer/optimizerdialog.cxx index ab392266e56d..7efef618af9b 100644 --- a/sdext/source/minimizer/optimizerdialog.cxx +++ b/sdext/source/minimizer/optimizerdialog.cxx @@ -31,6 +31,8 @@ #include <com/sun/star/ucb/XSimpleFileAccess.hpp> #include <com/sun/star/io/IOException.hpp> #include <com/sun/star/util/XModifiable.hpp> + +#include <comphelper/propertyvalue.hxx> #include <sal/macros.h> #include <osl/time.h> #include <vcl/errinf.hxx> @@ -39,177 +41,232 @@ #include <svtools/sfxecode.hxx> #include <svtools/ehdl.hxx> #include <tools/urlobj.hxx> +#include <o3tl/string_view.hxx> #include <bitmaps.hlst> using namespace ::com::sun::star::io; using namespace ::com::sun::star::ui; using namespace ::com::sun::star::awt; -using namespace ::com::sun::star::ucb; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::util; -using namespace ::com::sun::star::lang; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; -using namespace ::com::sun::star::container; +IntroPage::IntroPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog) + : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmintropage.ui", "PMIntroPage") + , mrOptimizerDialog(rOptimizerDialog) + , mxComboBox(m_xBuilder->weld_combo_box("LB_SETTINGS")) + , mxButton(m_xBuilder->weld_button("STR_REMOVE")) +{ + rOptimizerDialog.SetIntroPage(this); + mxComboBox->connect_changed(LINK(this, IntroPage, ComboBoxActionPerformed)); + mxButton->connect_clicked(LINK(this, IntroPage, ButtonActionPerformed)); +} -void OptimizerDialog::InitDialog() +void IntroPage::UpdateControlStates(const std::vector<OUString>& rItemList, int nSelectedItem, bool bRemoveButtonEnabled) { - // setting the dialog properties - OUString pNames[] = { - OUString("Closeable"), - OUString("Height"), - OUString("Moveable"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Title"), - OUString("Width") }; + mxComboBox->clear(); + for (const auto& a : rItemList) + mxComboBox->append_text(a); + mxComboBox->set_active(nSelectedItem); + mxButton->set_sensitive(bRemoveButtonEnabled); +} - Any pValues[] = { - Any( true ), - Any( sal_Int32( DIALOG_HEIGHT ) ), - Any( true ), - Any( sal_Int32( 200 ) ), - Any( sal_Int32( 52 ) ), - Any( getString( STR_SUN_OPTIMIZATION_WIZARD2 ) ), - Any( sal_Int32( OD_DIALOG_WIDTH ) ) }; +SlidesPage::SlidesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog) + : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmslidespage.ui", "PMSlidesPage") + , mrOptimizerDialog(rOptimizerDialog) + , mxMasterSlides(m_xBuilder->weld_check_button("STR_DELETE_MASTER_PAGES")) + , mxHiddenSlides(m_xBuilder->weld_check_button("STR_DELETE_HIDDEN_SLIDES")) + , mxUnusedSlides(m_xBuilder->weld_check_button("STR_CUSTOM_SHOW")) + , mxComboBox(m_xBuilder->weld_combo_box("LB_SLIDES")) + , mxClearNodes(m_xBuilder->weld_check_button("STR_DELETE_NOTES_PAGES")) +{ + rOptimizerDialog.SetSlidesPage(this); + mxMasterSlides->connect_toggled(LINK(this, SlidesPage, UnusedMasterPagesActionPerformed)); + mxHiddenSlides->connect_toggled(LINK(this, SlidesPage, UnusedHiddenSlidesActionPerformed)); + mxUnusedSlides->connect_toggled(LINK(this, SlidesPage, UnusedSlidesActionPerformed)); + mxClearNodes->connect_toggled(LINK(this, SlidesPage, DeleteNotesActionPerformed)); +} - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); +void SlidesPage::Init(const css::uno::Sequence<OUString>& rCustomShowList) +{ + mxComboBox->clear(); + for (const auto& a : rCustomShowList) + mxComboBox->append_text(a); + mxUnusedSlides->set_sensitive(rCustomShowList.hasElements()); +} - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); +void SlidesPage::UpdateControlStates(bool bDeleteUnusedMasterPages, bool bDeleteHiddenSlides, bool bDeleteNotesPages) +{ + mxMasterSlides->set_active(bDeleteUnusedMasterPages); + mxHiddenSlides->set_active(bDeleteHiddenSlides); + mxClearNodes->set_active(bDeleteNotesPages); + mxComboBox->set_sensitive(mxUnusedSlides->get_sensitive()); +} - setPropertyValues(aNames, aValues); +ImagesPage::ImagesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog) + : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmimagespage.ui", "PMImagesPage") + , mrOptimizerDialog(rOptimizerDialog) + , m_xLossLessCompression(m_xBuilder->weld_radio_button("STR_LOSSLESS_COMPRESSION")) + , m_xQualityLabel(m_xBuilder->weld_label("STR_QUALITY")) + , m_xQuality(m_xBuilder->weld_spin_button("SB_QUALITY")) + , m_xJpegCompression(m_xBuilder->weld_radio_button("STR_JPEG_COMPRESSION")) + , m_xResolution(m_xBuilder->weld_combo_box("LB_RESOLUTION")) + , m_xRemoveCropArea(m_xBuilder->weld_check_button("STR_REMOVE_CROP_AREA")) + , m_xEmbedLinkedGraphics(m_xBuilder->weld_check_button("STR_EMBED_LINKED_GRAPHICS")) +{ + rOptimizerDialog.SetImagesPage(this); + m_xRemoveCropArea->connect_toggled(LINK(this, ImagesPage, RemoveCropAreaActionPerformed)); + m_xEmbedLinkedGraphics->connect_toggled(LINK(this, ImagesPage, EmbedLinkedGraphicsActionPerformed)); + m_xResolution->connect_changed(LINK(this, ImagesPage, ComboBoxActionPerformed)); + m_xQuality->connect_value_changed(LINK(this, ImagesPage, SpinButtonActionPerformed)); + + m_xJpegCompression->connect_toggled(LINK(this, ImagesPage, CompressionActionPerformed)); + m_xLossLessCompression->connect_toggled(LINK(this, ImagesPage, CompressionActionPerformed)); } +void ImagesPage::UpdateControlStates(bool bJPEGCompression, int nJPEGQuality, bool bRemoveCropArea, + int nResolution, bool bEmbedLinkedGraphics) +{ + m_xLossLessCompression->set_active(!bJPEGCompression); + m_xJpegCompression->set_active(bJPEGCompression); + m_xQualityLabel->set_sensitive(bJPEGCompression); + m_xQuality->set_sensitive(bJPEGCompression); + m_xQuality->set_value(nJPEGQuality); + m_xResolution->set_active_id(OUString::number(nResolution)); + m_xRemoveCropArea->set_active(bRemoveCropArea); + m_xEmbedLinkedGraphics->set_active(bEmbedLinkedGraphics); +} -void OptimizerDialog::InitRoadmap() +ObjectsPage::ObjectsPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog) + : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmobjectspage.ui", "PMObjectsPage") + , mrOptimizerDialog(rOptimizerDialog) + , m_xCreateStaticImage(m_xBuilder->weld_check_button("STR_OLE_REPLACE")) + , m_xAllOLEObjects(m_xBuilder->weld_radio_button("STR_ALL_OLE_OBJECTS")) + , m_xForeignOLEObjects(m_xBuilder->weld_radio_button("STR_ALIEN_OLE_OBJECTS_ONLY")) + , m_xLabel(m_xBuilder->weld_label("STR_OLE_OBJECTS_DESC")) { - try - { - OUString pNames[] = { - OUString("Height"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( sal_Int32( DIALOG_HEIGHT - 26 ) ), - Any( sal_Int32( 0 ) ), - Any( sal_Int32( 0 ) ), - Any( sal_Int32( 0 ) ), - Any( mnTabIndex++ ), - Any( sal_Int32( 85 ) ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - mxRoadmapControlModel = insertControlModel( "com.sun.star.awt.UnoControlRoadmapModel", - "rdmNavi", aNames, aValues ); - - Reference< XPropertySet > xPropertySet( mxRoadmapControlModel, UNO_QUERY_THROW ); - xPropertySet->setPropertyValue( "Name", Any( OUString("rdmNavi") ) ); - mxRoadmapControl = getControl( "rdmNavi" ); - InsertRoadmapItem( 0, getString( STR_INTRODUCTION ), ITEM_ID_INTRODUCTION ); - InsertRoadmapItem( 1, getString( STR_SLIDES ), ITEM_ID_SLIDES ); - InsertRoadmapItem( 2, getString( STR_IMAGE_OPTIMIZATION ), ITEM_ID_GRAPHIC_OPTIMIZATION ); - InsertRoadmapItem( 3, getString( STR_OLE_OBJECTS ), ITEM_ID_OLE_OPTIMIZATION ); - InsertRoadmapItem( 4, getString( STR_SUMMARY ), ITEM_ID_SUMMARY ); - - xPropertySet->setPropertyValue( "ImageURL", Any( OUString("private:graphicrepository/" BMP_PRESENTATION_MINIMIZER) ) ); - xPropertySet->setPropertyValue( "Activated", Any( true ) ); - xPropertySet->setPropertyValue( "Complete", Any( true ) ); - xPropertySet->setPropertyValue( "CurrentItemID", Any( sal_Int16(ITEM_ID_INTRODUCTION) ) ); - xPropertySet->setPropertyValue( "Text", Any( getString( STR_STEPS ) ) ); - } - catch( Exception& ) - { - } + rOptimizerDialog.SetObjectsPage(this); + m_xCreateStaticImage->connect_toggled(LINK(this, ObjectsPage, OLEOptimizationActionPerformed)); + m_xAllOLEObjects->connect_toggled(LINK(this, ObjectsPage, OLEActionPerformed)); + m_xForeignOLEObjects->connect_toggled(LINK(this, ObjectsPage, OLEActionPerformed)); } +void ObjectsPage::Init(const OUString& rDesc) +{ + m_xLabel->set_label(rDesc); +} -void OptimizerDialog::InsertRoadmapItem( const sal_Int32 nIndex, const OUString& rLabel, const sal_Int32 nItemID ) +void ObjectsPage::UpdateControlStates(bool bConvertOLEObjects, int nOLEOptimizationType) { - try - { - Reference< XSingleServiceFactory > xSFRoadmap( mxRoadmapControlModel, UNO_QUERY_THROW ); - Reference< XIndexContainer > aIndexContainerRoadmap( mxRoadmapControlModel, UNO_QUERY_THROW ); - Reference< XInterface > xRoadmapItem( xSFRoadmap->createInstance(), UNO_SET_THROW ); - Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY_THROW ); - xPropertySet->setPropertyValue( "Label", Any( rLabel ) ); - xPropertySet->setPropertyValue( "Enabled", Any( true ) ); - xPropertySet->setPropertyValue( "ID", Any( nItemID ) ); - aIndexContainerRoadmap->insertByIndex( nIndex, Any( xRoadmapItem ) ); - } - catch( Exception& ) - { + m_xCreateStaticImage->set_active(bConvertOLEObjects); + m_xAllOLEObjects->set_sensitive(bConvertOLEObjects); + m_xForeignOLEObjects->set_sensitive(bConvertOLEObjects); + m_xAllOLEObjects->set_active(nOLEOptimizationType == 0); + m_xForeignOLEObjects->set_active(nOLEOptimizationType == 1); +} - } +SummaryPage::SummaryPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog) + : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmsummarypage.ui", "PMSummaryPage") + , mrOptimizerDialog(rOptimizerDialog) + , m_xLabel1(m_xBuilder->weld_label("LABEL1")) + , m_xLabel2(m_xBuilder->weld_label("LABEL2")) + , m_xLabel3(m_xBuilder->weld_label("LABEL3")) + , m_xCurrentSize(m_xBuilder->weld_label("CURRENT_FILESIZE")) + , m_xEstimatedSize(m_xBuilder->weld_label("ESTIMATED_FILESIZE")) + , m_xStatus(m_xBuilder->weld_label("STR_STATUS")) + , m_xProgress(m_xBuilder->weld_progress_bar("PROGRESS")) + , m_xApplyToCurrent(m_xBuilder->weld_radio_button("STR_APPLY_TO_CURRENT")) + , m_xSaveToNew(m_xBuilder->weld_radio_button("STR_SAVE_AS")) + , m_xComboBox(m_xBuilder->weld_combo_box("MY_SETTINGS")) + , m_xSaveSettings(m_xBuilder->weld_check_button("STR_SAVE_SETTINGS")) +{ + rOptimizerDialog.SetSummaryPage(this); + m_xApplyToCurrent->connect_toggled(LINK(this, SummaryPage, SaveAsNewActionPerformed)); + m_xSaveToNew->connect_toggled(LINK(this, SummaryPage, SaveAsNewActionPerformed)); + m_xSaveSettings->connect_toggled(LINK(this, SummaryPage, SaveSettingsActionPerformed)); } +void SummaryPage::Init(const OUString& rSettingsName, bool bIsReadonly) +{ + m_xComboBox->set_entry_text(rSettingsName); + m_xApplyToCurrent->set_sensitive(!bIsReadonly); + m_xSaveToNew->set_sensitive(!bIsReadonly); +} -void OptimizerDialog::UpdateConfiguration() +void SummaryPage::UpdateControlStates(bool bSaveAs, bool bSaveSettingsEnabled, + const std::vector<OUString>& rItemList, + const std::vector<OUString>& rSummaryStrings, + const OUString& rCurrentFileSize, + const OUString& rEstimatedFileSize) { - sal_Int16 nInt16 = 0; - Any aAny; + m_xApplyToCurrent->set_active(!bSaveAs); + m_xSaveToNew->set_active(bSaveAs); - Sequence< sal_Int16 > aSelectedItems; - Sequence< OUString > aStringItemList; + for (const auto& a : rItemList) + m_xComboBox->append_text(a); - // page0 - aAny = getControlProperty( "ListBox0Pg0", "SelectedItems" ); - if ( aAny >>= aSelectedItems ) - { - if ( aSelectedItems.hasElements() ) - { - sal_Int16 nSelectedItem = aSelectedItems[ 0 ]; - aAny = getControlProperty( "ListBox0Pg0", "StringItemList" ); - if ( aAny >>= aStringItemList ) - { - if ( aStringItemList.getLength() > nSelectedItem ) - SetConfigProperty( TK_Name, Any( aStringItemList[ nSelectedItem ] ) ); - } - } - } + m_xSaveSettings->set_sensitive(bSaveSettingsEnabled); + m_xComboBox->set_sensitive(bSaveSettingsEnabled && m_xSaveSettings->get_active()); - aAny = getControlProperty( "CheckBox3Pg3", "State" ); - if ( !((aAny >>= nInt16) && nInt16) ) - return; + assert(rSummaryStrings.size() == 3); + m_xLabel1->set_label(rSummaryStrings[0]); + m_xLabel2->set_label(rSummaryStrings[1]); + m_xLabel3->set_label(rSummaryStrings[2]); - aAny = getControlProperty( "ListBox0Pg3", "SelectedItems" ); - if ( !(aAny >>= aSelectedItems) ) - return; + m_xCurrentSize->set_label(rCurrentFileSize); + m_xEstimatedSize->set_label(rEstimatedFileSize); +} - if ( aSelectedItems.hasElements() ) - { - sal_Int16 nSelectedItem = aSelectedItems[ 0 ]; - aAny = getControlProperty( "ListBox0Pg3", "StringItemList" ); - if ( aAny >>= aStringItemList ) - { - if ( aStringItemList.getLength() > nSelectedItem ) - SetConfigProperty( TK_CustomShowName, Any( aStringItemList[ nSelectedItem ] ) ); - } - } +void SummaryPage::UpdateStatusLabel(const OUString& rStatus) +{ + m_xStatus->set_label(rStatus); } +void SummaryPage::UpdateProgressValue(int nProgress) +{ + m_xProgress->set_percentage(nProgress); +} + +void OptimizerDialog::InitDialog() +{ + set_title(getString(STR_SUN_OPTIMIZATION_WIZARD2)); +} -OptimizerDialog::OptimizerDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame, Reference< XDispatch > const & rxStatusDispatcher ) : - UnoDialog( rxContext, rxFrame ), - ConfigurationAccess( rxContext ), - mnCurrentStep( 0 ), - mnTabIndex( 0 ), - mxFrame( rxFrame ), - mxItemListener( new ItemListener( *this ) ), - mxActionListener( new ActionListener( *this ) ), - mxActionListenerListBox0Pg0( new ActionListenerListBox0Pg0( *this ) ), - mxTextListenerFormattedField0Pg1( new TextListenerFormattedField0Pg1( *this ) ), - mxTextListenerComboBox0Pg1( new TextListenerComboBox0Pg1( *this ) ), - mxSpinListenerFormattedField0Pg1( new SpinListenerFormattedField0Pg1( *this ) ), - mxStatusDispatcher( rxStatusDispatcher ) +void OptimizerDialog::InitRoadmap() +{ + declarePath( + 0, + {ITEM_ID_INTRODUCTION, + ITEM_ID_SLIDES, + ITEM_ID_GRAPHIC_OPTIMIZATION, + ITEM_ID_OLE_OPTIMIZATION, + ITEM_ID_SUMMARY} + ); + + m_xAssistant->set_page_side_image(BMP_PRESENTATION_MINIMIZER); +} + +void OptimizerDialog::UpdateConfiguration() +{ + // page0 + OUString sTKName(mpPage0->Get_TK_Name()); + if (!sTKName.isEmpty()) + SetConfigProperty(TK_Name, Any(sTKName)); + + // page1 + OUString sTKCustomShowName(mpPage1->Get_TK_CustomShowName()); + if (!sTKCustomShowName.isEmpty()) + SetConfigProperty(TK_CustomShowName, Any(sTKCustomShowName)); +} + +OptimizerDialog::OptimizerDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame, Reference< XDispatch > const & rxStatusDispatcher ) + : vcl::RoadmapWizardMachine(Application::GetFrameWeld(rxFrame->getComponentWindow())) + , ConfigurationAccess(rxContext) + , mnEndStatus(RET_CANCEL) + , mxFrame(rxFrame) + , mxController(rxFrame->getController()) + , mxStatusDispatcher(rxStatusDispatcher) { Reference< XStorable > xStorable( mxController->getModel(), UNO_QUERY_THROW ); mbIsReadonly = xStorable->isReadonly(); @@ -222,7 +279,9 @@ OptimizerDialog::OptimizerDialog( const Reference< XComponentContext > &rxContex InitPage2(); InitPage3(); InitPage4(); - ActivatePage( 0 ); + + ActivatePage(); + m_xAssistant->set_current_page(0); OptimizationStats aStats; aStats.InitializeStatusValuesFromDocument( mxController->getModel() ); @@ -230,48 +289,66 @@ OptimizerDialog::OptimizerDialog( const Reference< XComponentContext > &rxContex UpdateStatus( aStatusSequence ); } - -OptimizerDialog::~OptimizerDialog() +OUString OptimizerDialog::getStateDisplayName(vcl::WizardTypes::WizardState nState) const { - // not saving configuration if the dialog has been finished via cancel or close window - if ( endStatus() ) - SaveConfiguration(); + switch (nState) + { + case ITEM_ID_INTRODUCTION: + return getString(STR_INTRODUCTION); + case ITEM_ID_SLIDES: + return getString(STR_SLIDES); + case ITEM_ID_GRAPHIC_OPTIMIZATION: + return getString(STR_IMAGE_OPTIMIZATION); + case ITEM_ID_OLE_OPTIMIZATION: + return getString(STR_OLE_OBJECTS); + case ITEM_ID_SUMMARY: + return getString(STR_SUMMARY); + } + return OUString(); } - -void OptimizerDialog::execute() +std::unique_ptr<BuilderPage> OptimizerDialog::createPage(vcl::WizardTypes::WizardState nState) { - Reference< XItemEventBroadcaster > xRoadmapBroadcaster( mxRoadmapControl, UNO_QUERY_THROW ); - xRoadmapBroadcaster->addItemListener( mxItemListener ); - UnoDialog::execute(); - UpdateConfiguration(); // taking actual control settings for the configuration - xRoadmapBroadcaster->removeItemListener( mxItemListener ); -} + OUString sIdent(OUString::number(nState)); + weld::Container* pPageContainer = m_xAssistant->append_page(sIdent); + std::unique_ptr<vcl::OWizardPage> xRet; -void OptimizerDialog::SwitchPage( sal_Int16 nNewStep ) -{ - if ( !(( nNewStep != mnCurrentStep ) && ( nNewStep <= MAX_STEP ) && ( nNewStep >= 0 )) ) - return; - - sal_Int16 nOldStep = mnCurrentStep; - if ( nNewStep == 0 ) - disableControl( "btnNavBack" ); - else if ( nOldStep == 0 ) - enableControl( "btnNavBack" ); + switch (nState) + { + case ITEM_ID_INTRODUCTION: + xRet.reset(new IntroPage(pPageContainer, *this)); + break; + case ITEM_ID_SLIDES: + xRet.reset(new SlidesPage(pPageContainer, *this)); + break; + case ITEM_ID_GRAPHIC_OPTIMIZATION: + xRet.reset(new ImagesPage(pPageContainer, *this)); + break; + case ITEM_ID_OLE_OPTIMIZATION: + xRet.reset(new ObjectsPage(pPageContainer, *this)); + break; + case ITEM_ID_SUMMARY: + xRet.reset(new SummaryPage(pPageContainer, *this)); + break; + } - if ( nNewStep == MAX_STEP ) - disableControl( "btnNavNext" ); - else if ( nOldStep == MAX_STEP ) - enableControl( "btnNavNext" ); + m_xAssistant->set_page_title(sIdent, getStateDisplayName(nState)); - setControlProperty( "rdmNavi", "CurrentItemID", Any( nNewStep ) ); + return xRet; +} - DeactivatePage( nOldStep ); - UpdateControlStates( nNewStep ); +OptimizerDialog::~OptimizerDialog() +{ + // not saving configuration if the dialog has been finished via cancel or close window + if (mnEndStatus == RET_OK) + SaveConfiguration(); +} - ActivatePage( nNewStep ); - mnCurrentStep = nNewStep; +void OptimizerDialog::execute() +{ + mnEndStatus = run(); + UpdateConfiguration(); // taking actual control settings for the configuration } void OptimizerDialog::UpdateControlStates( sal_Int16 nPage ) @@ -294,27 +371,6 @@ void OptimizerDialog::UpdateControlStates( sal_Int16 nPage ) } } - -OUString OptimizerDialog::GetSelectedString( OUString const & token ) -{ - OUString aSelectedItem; - Sequence< sal_Int16 > sSelectedItems; - Sequence< OUString > sItemList; - - if ( ( getControlProperty( token, "SelectedItems" ) >>= sSelectedItems ) && - ( getControlProperty( token, "StringItemList" ) >>= sItemList ) ) - { - if ( sSelectedItems.getLength() == 1 ) - { - sal_Int16 nSelectedItem = sSelectedItems[ 0 ]; - if ( nSelectedItem < sItemList.getLength() ) - aSelectedItem = sItemList[ nSelectedItem ]; - } - } - return aSelectedItem; -} - - void OptimizerDialog::UpdateStatus( const css::uno::Sequence< css::beans::PropertyValue >& rStatus ) { maStats.InitializeStatusValues( rStatus ); @@ -324,8 +380,7 @@ void OptimizerDialog::UpdateStatus( const css::uno::Sequence< css::beans::Proper OUString sStatus; if ( *pVal >>= sStatus ) { - setControlProperty( "FixedText1Pg4", "Enabled", Any( true ) ); - setControlProperty( "FixedText1Pg4", "Label", Any( getString( TKGet( sStatus ) ) ) ); + mpPage4->UpdateStatusLabel(getString(TKGet(sStatus))); } } pVal = maStats.GetStatusValue( TK_Progress ); @@ -333,448 +388,285 @@ void OptimizerDialog::UpdateStatus( const css::uno::Sequence< css::beans::Proper { sal_Int32 nProgress = 0; if ( *pVal >>= nProgress ) - setControlProperty( "Progress", "ProgressValue", Any( nProgress ) ); + mpPage4->UpdateProgressValue(nProgress); } pVal = maStats.GetStatusValue( TK_OpenNewDocument ); if ( pVal ) SetConfigProperty( TK_OpenNewDocument, *pVal ); - reschedule(); + Application::Reschedule(true); } - -void ItemListener::itemStateChanged( const ItemEvent& Event ) +IMPL_LINK(SummaryPage, SaveAsNewActionPerformed, weld::Toggleable&, rBox, void) { - try - { - sal_Int16 nState; - Reference< XControl > xControl; - Any aSource( Event.Source ); - if ( aSource >>= xControl ) - { - Reference< XPropertySet > xPropertySet( xControl->getModel(), UNO_QUERY_THROW ); - OUString aControlName; - xPropertySet->getPropertyValue( "Name" ) >>= aControlName; - PPPOptimizerTokenEnum eControl( TKGet( aControlName ) ); - switch( eControl ) - { - case TK_rdmNavi : - { - mrOptimizerDialog.SwitchPage( static_cast< sal_Int16 >( Event.ItemId ) ); - } - break; - case TK_CheckBox1Pg1 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_RemoveCropArea, Any( nState != 0 ) ); - } - break; - case TK_CheckBox2Pg1 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_EmbedLinkedGraphics, Any( nState != 0 ) ); - } - break; - case TK_CheckBox0Pg2 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - { - mrOptimizerDialog.SetConfigProperty( TK_OLEOptimization, Any( nState != 0 ) ); - mrOptimizerDialog.setControlProperty( "RadioButton0Pg2", "Enabled", Any( nState != 0 ) ); - mrOptimizerDialog.setControlProperty( "RadioButton1Pg2", "Enabled", Any( nState != 0 ) ); - } - } - break; - case TK_RadioButton0Pg1 : - { - sal_Int16 nInt16 = 0; - if ( xPropertySet->getPropertyValue( "State" ) >>= nInt16 ) - { - nInt16 ^= 1; - mrOptimizerDialog.SetConfigProperty( TK_JPEGCompression, Any( nInt16 != 0 ) ); - mrOptimizerDialog.setControlProperty( "FixedText1Pg1", "Enabled", Any( nInt16 != 0 ) ); - mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "Enabled", Any( nInt16 != 0 ) ); - } - } - break; - case TK_RadioButton1Pg1 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - { - mrOptimizerDialog.SetConfigProperty( TK_JPEGCompression, Any( nState != 0 ) ); - mrOptimizerDialog.setControlProperty( "FixedText1Pg1", "Enabled", Any( nState != 0 ) ); - mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "Enabled", Any( nState != 0 ) ); - } - } - break; - case TK_RadioButton0Pg2 : - { - sal_Int16 nInt16; - if ( xPropertySet->getPropertyValue( "State" ) >>= nInt16 ) - { - nInt16 ^= 1; - mrOptimizerDialog.SetConfigProperty( TK_OLEOptimizationType, Any( nInt16 ) ); - } - } - break; - case TK_RadioButton1Pg2 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_OLEOptimizationType, Any( nState ) ); - } - break; - case TK_CheckBox0Pg3 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_DeleteUnusedMasterPages, Any( nState != 0 ) ); - } - break; - case TK_CheckBox1Pg3 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_DeleteNotesPages, Any( nState != 0 ) ); - } - break; - case TK_CheckBox2Pg3 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_DeleteHiddenSlides, Any( nState != 0 ) ); - } - break; - case TK_CheckBox3Pg3 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.setControlProperty( "ListBox0Pg3", "Enabled", Any( nState != 0 ) ); - } - break; - case TK_CheckBox1Pg4 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.setControlProperty( "ComboBox0Pg4", "Enabled", Any( nState != 0 ) ); - } - break; - case TK_RadioButton0Pg4 : - case TK_RadioButton1Pg4 : - { - if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) - mrOptimizerDialog.SetConfigProperty( TK_SaveAs, Any( eControl == TK_RadioButton1Pg4 ? nState != 0 : nState == 0 ) ); - } - break; - default: - break; - } - } - } - catch ( Exception& ) - { + if (!rBox.get_active()) + return; - } + const bool bSaveToNew = &rBox == m_xSaveToNew.get(); + mrOptimizerDialog.SetConfigProperty( TK_SaveAs, Any(bSaveToNew) ); } -void ItemListener::disposing( const css::lang::EventObject& /* Source */ ) + +IMPL_LINK(SummaryPage, SaveSettingsActionPerformed, weld::Toggleable&, rBox, void) { + m_xComboBox->set_sensitive(rBox.get_active()); } -void ActionListener::actionPerformed( const ActionEvent& rEvent ) +IMPL_LINK(ObjectsPage, OLEActionPerformed, weld::Toggleable&, rBox, void) { - switch( TKGet( rEvent.ActionCommand ) ) - { - case TK_btnNavBack : mrOptimizerDialog.SwitchPage( mrOptimizerDialog.mnCurrentStep - 1 ); break; - case TK_btnNavNext : mrOptimizerDialog.SwitchPage( mrOptimizerDialog.mnCurrentStep + 1 ); break; - case TK_btnNavFinish : - { - mrOptimizerDialog.UpdateConfiguration(); - - mrOptimizerDialog.SwitchPage( ITEM_ID_SUMMARY ); - mrOptimizerDialog.DisablePage( ITEM_ID_SUMMARY ); - mrOptimizerDialog.setControlProperty( "btnNavBack", "Enabled", Any( false ) ); - mrOptimizerDialog.setControlProperty( "btnNavNext", "Enabled", Any( false ) ); - mrOptimizerDialog.setControlProperty( "btnNavFinish", "Enabled", Any( false ) ); - mrOptimizerDialog.setControlProperty( "btnNavCancel", "Enabled", Any( false ) ); - mrOptimizerDialog.setControlProperty( "FixedText0Pg4", "Enabled", Any( true ) ); - - // check if we have to open the FileDialog - bool bSuccessfullyExecuted = true; - sal_Int16 nInt16 = 0; - mrOptimizerDialog.getControlProperty( "RadioButton1Pg4", "State" ) >>= nInt16; - if ( nInt16 ) - { - // Duplicate presentation before applying changes - OUString aSaveAsURL; - FileOpenDialog aFileOpenDialog( mrOptimizerDialog.GetComponentContext() ); - - // generating default file name - OUString aName; - Reference< XStorable > xStorable( mrOptimizerDialog.controller()->getModel(), UNO_QUERY ); - if ( xStorable.is() && xStorable->hasLocation() ) - { - INetURLObject aURLObj( xStorable->getLocation() ); - if ( !aURLObj.hasFinalSlash() ) - { - // tdf#105382 uri-decode file name - aURLObj.removeExtension(INetURLObject::LAST_SEGMENT, false); - aName = aURLObj.getName(INetURLObject::LAST_SEGMENT, false, - INetURLObject::DecodeMechanism::WithCharset); - } - } - else - { - // If no filename, try to use model title ("Untitled 1" or something like this) - Reference<XTitle> xTitle( - mrOptimizerDialog.GetFrame()->getController()->getModel(), UNO_QUERY); - aName = xTitle->getTitle(); - } - - if (!aName.isEmpty()) - { - aName += " " + mrOptimizerDialog.getString(STR_FILENAME_SUFFIX); - aFileOpenDialog.setDefaultName(aName); - } - - if (aFileOpenDialog.execute() == dialogs::ExecutableDialogResults::OK) - { - aSaveAsURL = aFileOpenDialog.getURL(); - mrOptimizerDialog.SetConfigProperty( TK_SaveAsURL, Any( aSaveAsURL ) ); - mrOptimizerDialog.SetConfigProperty( TK_FilterName, Any( aFileOpenDialog.getFilterName() ) ); - } - if ( aSaveAsURL.isEmpty() ) - { - // something goes wrong... - bSuccessfullyExecuted = false; - } - - // waiting for 500ms - mrOptimizerDialog.reschedule(); - for ( sal_uInt32 i = osl_getGlobalTimer(); ( i + 500 ) > ( osl_getGlobalTimer() ); ) - mrOptimizerDialog.reschedule(); - } - else - { - // Apply changes to current presentation - Reference<XModifiable> xModifiable(mrOptimizerDialog.controller()->getModel(), - UNO_QUERY_THROW ); - if ( xModifiable->isModified() ) - { - SolarMutexGuard aSolarGuard; - std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog( - nullptr, VclMessageType::Question, VclButtonsType::YesNo, - mrOptimizerDialog.getString(STR_WARN_UNSAVED_PRESENTATION))); - if (popupDlg->run() != RET_YES) - { - // Selected not "yes" ("no" or dialog was cancelled) so return to previous step - mrOptimizerDialog.setControlProperty("btnNavBack", "Enabled", - Any(true)); - mrOptimizerDialog.setControlProperty("btnNavNext", "Enabled", Any(false)); - mrOptimizerDialog.setControlProperty("btnNavFinish", "Enabled", Any(true)); - mrOptimizerDialog.setControlProperty("btnNavCancel", "Enabled", Any(true)); - mrOptimizerDialog.EnablePage(ITEM_ID_SUMMARY); - return; - } - } - } - if ( bSuccessfullyExecuted ) - { // now check if we have to store a session template - nInt16 = 0; - OUString aSettingsName; - mrOptimizerDialog.getControlProperty( "CheckBox1Pg4", "State" ) >>= nInt16; - mrOptimizerDialog.getControlProperty( "ComboBox0Pg4", "Text" ) >>= aSettingsName; - if ( nInt16 && !aSettingsName.isEmpty() ) - { - std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( aSettingsName ) ); - std::vector< OptimizerSettings >& rSettings( mrOptimizerDialog.GetOptimizerSettings() ); - OptimizerSettings aNewSettings( rSettings[ 0 ] ); - aNewSettings.maName = aSettingsName; - if ( aIter == rSettings.end() ) - rSettings.push_back( aNewSettings ); - else - *aIter = aNewSettings; - } - } - if ( bSuccessfullyExecuted ) - { - URL aURL; - aURL.Protocol = "vnd.com.sun.star.comp.PPPOptimizer:"; - aURL.Path = "optimize"; - - Sequence< PropertyValue > lArguments( 3 ); - lArguments[ 0 ].Name = "Settings"; - lArguments[ 0 ].Value <<= mrOptimizerDialog.GetConfigurationSequence(); - lArguments[ 1 ].Name = "StatusDispatcher"; - lArguments[ 1 ].Value <<= mrOptimizerDialog.GetStatusDispatcher(); - lArguments[ 2 ].Name = "InformationDialog"; - lArguments[ 2 ].Value <<= mrOptimizerDialog.GetFrame(); - - - ErrCode errorCode; - try - { - ImpOptimizer aOptimizer( - mrOptimizerDialog.GetComponentContext(), - mrOptimizerDialog.GetFrame()->getController()->getModel()); - aOptimizer.Optimize(lArguments); - } - catch (css::io::IOException&) - { - // We always receive just ERRCODE_IO_CANTWRITE in case of problems, so no need to bother - // about extracting error code from exception text - errorCode = ERRCODE_IO_CANTWRITE; - } - catch (css::uno::Exception&) - { - // Other general exception - errorCode = ERRCODE_IO_GENERAL; - } - - if (errorCode != ERRCODE_NONE) - { - // Restore wizard controls - mrOptimizerDialog.maStats.SetStatusValue(TK_Progress, - Any(static_cast<sal_Int32>(0))); - mrOptimizerDialog.setControlProperty("btnNavBack", "Enabled", Any(true)); - mrOptimizerDialog.setControlProperty("btnNavNext", "Enabled", Any(false)); - mrOptimizerDialog.setControlProperty("btnNavFinish", "Enabled", Any(true)); - mrOptimizerDialog.setControlProperty("btnNavCancel", "Enabled", Any(true)); - - OUString aFileName; - mrOptimizerDialog.GetConfigProperty(TK_SaveAsURL) >>= aFileName; - SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, aFileName); - ErrorHandler::HandleError(errorCode); - break; - } - - mrOptimizerDialog.endExecute( bSuccessfullyExecuted ); - } - else - { - mrOptimizerDialog.setControlProperty( "btnNavBack", "Enabled", Any( true ) ); - mrOptimizerDialog.setControlProperty( "btnNavNext", "Enabled", Any( false ) ); - mrOptimizerDialog.setControlProperty( "btnNavFinish", "Enabled", Any( true ) ); - mrOptimizerDialog.setControlProperty( "btnNavCancel", "Enabled", Any( true ) ); - mrOptimizerDialog.EnablePage( ITEM_ID_SUMMARY ); - } - } - break; - case TK_btnNavCancel : mrOptimizerDialog.endExecute( false ); break; - case TK_Button0Pg0 : // delete configuration - { - OUString aSelectedItem( mrOptimizerDialog.GetSelectedString( "ListBox0Pg0" ) ); - if ( !aSelectedItem.isEmpty() ) - { - std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( aSelectedItem ) ); - std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() ); - if ( aIter != rList.end() ) - { - rList.erase( aIter ); - mrOptimizerDialog.UpdateControlStates(); - } - } - } - break; - default: break; - } + if (!rBox.get_active()) + return; + + const bool bALLOles = &rBox == m_xAllOLEObjects.get(); + sal_Int16 nInt16 = bALLOles ? 0 : 1; + mrOptimizerDialog.SetConfigProperty( TK_OLEOptimizationType, Any( nInt16 ) ); } -void ActionListener::disposing( const css::lang::EventObject& /* Source */ ) + +IMPL_LINK(ObjectsPage, OLEOptimizationActionPerformed, weld::Toggleable&, rBox, void) { + const bool bOLEOptimization = rBox.get_active(); + mrOptimizerDialog.SetConfigProperty( TK_OLEOptimization, Any(bOLEOptimization) ); + m_xAllOLEObjects->set_sensitive(bOLEOptimization); + m_xForeignOLEObjects->set_sensitive(bOLEOptimization); } - -void ActionListenerListBox0Pg0::actionPerformed( const ActionEvent& rEvent ) +IMPL_LINK(ImagesPage, CompressionActionPerformed, weld::Toggleable&, rBox, void) { - if ( !rEvent.ActionCommand.isEmpty() ) - { - std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( rEvent.ActionCommand ) ); - std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() ); - if ( aIter != rList.end() ) - rList[ 0 ] = *aIter; - } - mrOptimizerDialog.UpdateControlStates(); + if (!rBox.get_active()) + return; + + const bool bJPEGCompression = &rBox == m_xJpegCompression.get(); + mrOptimizerDialog.SetConfigProperty(TK_JPEGCompression, Any(bJPEGCompression)); + m_xQualityLabel->set_sensitive(bJPEGCompression); + m_xQuality->set_sensitive(bJPEGCompression); } -void ActionListenerListBox0Pg0::disposing( const css::lang::EventObject& /* Source */ ) + +IMPL_LINK(ImagesPage, RemoveCropAreaActionPerformed, weld::Toggleable&, rBox, void) { + mrOptimizerDialog.SetConfigProperty(TK_RemoveCropArea, Any(rBox.get_active())); } - -void TextListenerFormattedField0Pg1::textChanged( const TextEvent& /* rEvent */ ) +IMPL_LINK(ImagesPage, EmbedLinkedGraphicsActionPerformed, weld::Toggleable&, rBox, void) { - double fDouble = 0; - Any aAny = mrOptimizerDialog.getControlProperty( "FormattedField0Pg1", "EffectiveValue" ); - if ( aAny >>= fDouble ) - mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(fDouble) ) ); + mrOptimizerDialog.SetConfigProperty(TK_EmbedLinkedGraphics, Any(rBox.get_active())); } -void TextListenerFormattedField0Pg1::disposing( const css::lang::EventObject& /* Source */ ) + +IMPL_LINK(SlidesPage, UnusedHiddenSlidesActionPerformed, weld::Toggleable&, rBox, void) { + mrOptimizerDialog.SetConfigProperty(TK_DeleteHiddenSlides, Any(rBox.get_active())); } -namespace +IMPL_LINK(SlidesPage, UnusedMasterPagesActionPerformed, weld::Toggleable&, rBox, void) { + mrOptimizerDialog.SetConfigProperty(TK_DeleteUnusedMasterPages, Any(rBox.get_active())); +} -bool lcl_mapResolution(OUString& rResolution, const OUString& rImageResolution) +IMPL_LINK(SlidesPage, DeleteNotesActionPerformed, weld::Toggleable&, rBox, void) { - if (rImageResolution.getToken(1, ';')!=rResolution) - return false; - rResolution = rImageResolution.getToken(0, ';'); - return true; + mrOptimizerDialog.SetConfigProperty(TK_DeleteNotesPages, Any(rBox.get_active())); } +IMPL_LINK(SlidesPage, UnusedSlidesActionPerformed, weld::Toggleable&, rBox, void) +{ + mxComboBox->set_sensitive(rBox.get_active()); } -void TextListenerComboBox0Pg1::textChanged( const TextEvent& /* rEvent */ ) +bool OptimizerDialog::onFinish() { - OUString aString; - Any aAny = mrOptimizerDialog.getControlProperty( "ComboBox0Pg1", "Text" ); - if ( !(aAny >>= aString) ) - return; + UpdateConfiguration(); - for (int nIR{ STR_IMAGE_RESOLUTION_0 }; nIR <= STR_IMAGE_RESOLUTION_3; ++nIR) + ShowPage(ITEM_ID_SUMMARY); + m_xPrevPage->set_sensitive(false); + m_xNextPage->set_sensitive(false); + m_xFinish->set_sensitive(false); + m_xCancel->set_sensitive(false); + + // check if we have to open the FileDialog + bool bSuccessfullyExecuted = true; + if (mpPage4->GetSaveAsNew()) { - if (lcl_mapResolution(aString, mrOptimizerDialog.getString(static_cast<PPPOptimizerTokenEnum>(nIR)))) - break; - } + // Duplicate presentation before applying changes + OUString aSaveAsURL; + FileOpenDialog aFileOpenDialog(mxContext); + + // generating default file name + OUString aName; + Reference< XStorable > xStorable( mxController->getModel(), UNO_QUERY ); + if ( xStorable.is() && xStorable->hasLocation() ) + { + INetURLObject aURLObj( xStorable->getLocation() ); + if ( !aURLObj.hasFinalSlash() ) + { + // tdf#105382 uri-decode file name + aURLObj.removeExtension(INetURLObject::LAST_SEGMENT, false); + aName = aURLObj.getName(INetURLObject::LAST_SEGMENT, false, + INetURLObject::DecodeMechanism::WithCharset); + } + } + else + { + // If no filename, try to use model title ("Untitled 1" or something like this) + Reference<XTitle> xTitle( + GetFrame()->getController()->getModel(), UNO_QUERY); + aName = xTitle->getTitle(); + } - mrOptimizerDialog.SetConfigProperty( TK_ImageResolution, Any( aString.toInt32() ) ); -} -void TextListenerComboBox0Pg1::disposing( const css::lang::EventObject& /* Source */ ) -{ -} + if (!aName.isEmpty()) + { + aName += " " + getString(STR_FILENAME_SUFFIX); + aFileOpenDialog.setDefaultName(aName); + } + if (aFileOpenDialog.execute() == dialogs::ExecutableDialogResults::OK) + { + aSaveAsURL = aFileOpenDialog.getURL(); + SetConfigProperty( TK_SaveAsURL, Any( aSaveAsURL ) ); + SetConfigProperty( TK_FilterName, Any( aFileOpenDialog.getFilterName() ) ); + } + if ( aSaveAsURL.isEmpty() ) + { + // something goes wrong... + bSuccessfullyExecuted = false; + } -void SpinListenerFormattedField0Pg1::up( const SpinEvent& /* rEvent */ ) -{ - double fDouble; - Any aAny = mrOptimizerDialog.getControlProperty( "FormattedField0Pg1", "EffectiveValue" ); - if ( aAny >>= fDouble ) + // waiting for 500ms + Application::Reschedule(true); + for ( sal_uInt32 i = osl_getGlobalTimer(); ( i + 500 ) > ( osl_getGlobalTimer() ); ) + Application::Reschedule(true); + } + else { - fDouble += 9; - if ( fDouble > 100 ) - fDouble = 100; - mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( fDouble ) ); - mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(fDouble) ) ); + // Apply changes to current presentation + Reference<XModifiable> xModifiable(mxController->getModel(), + UNO_QUERY_THROW ); + if ( xModifiable->isModified() ) + { + SolarMutexGuard aSolarGuard; + std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog( + m_xAssistant.get(), VclMessageType::Question, VclButtonsType::YesNo, + getString(STR_WARN_UNSAVED_PRESENTATION))); + if (popupDlg->run() != RET_YES) + { + // Selected not "yes" ("no" or dialog was cancelled) so return to previous step + m_xPrevPage->set_sensitive(true); + m_xNextPage->set_sensitive(true); + m_xFinish->set_sensitive(true); + m_xCancel->set_sensitive(true); + return false; + } + } } + if ( bSuccessfullyExecuted ) + { + // now check if we have to store a session template + const bool bSaveSettings = mpPage4->GetSaveSettings(); + OUString aSettingsName = mpPage4->GetSettingsName(); + if (bSaveSettings && !aSettingsName.isEmpty()) + { + std::vector< OptimizerSettings >::iterator aIter( GetOptimizerSettingsByName( aSettingsName ) ); + std::vector< OptimizerSettings >& rSettings( GetOptimizerSettings() ); + OptimizerSettings aNewSettings( rSettings[ 0 ] ); + aNewSettings.maName = aSettingsName; + if ( aIter == rSettings.end() ) + rSettings.push_back( aNewSettings ); + else + *aIter = aNewSettings; + } + } + if ( bSuccessfullyExecuted ) + { + URL aURL; + aURL.Protocol = "vnd.com.sun.star.comp.PPPOptimizer:"; + aURL.Path = "optimize"; + + Sequence< PropertyValue > lArguments{ + comphelper::makePropertyValue("Settings", GetConfigurationSequence()), + comphelper::makePropertyValue("StatusDispatcher", GetStatusDispatcher()), + comphelper::makePropertyValue("DocumentFrame", GetFrame()), + comphelper::makePropertyValue("DialogParentWindow", m_xAssistant->GetXWindow()) + }; + + ErrCode errorCode; + try + { + ImpOptimizer aOptimizer(mxContext, GetFrame()->getController()->getModel()); + aOptimizer.Optimize(lArguments); + } + catch (css::io::IOException&) + { + // We always receive just ERRCODE_IO_CANTWRITE in case of problems, so no need to bother + // about extracting error code from exception text + errorCode = ERRCODE_IO_CANTWRITE; + } + catch (css::uno::Exception&) + { + // Other general exception + errorCode = ERRCODE_IO_GENERAL; + } + + if (errorCode != ERRCODE_NONE) + { + // Restore wizard controls + maStats.SetStatusValue(TK_Progress, Any(static_cast<sal_Int32>(0))); + m_xPrevPage->set_sensitive(true); + m_xNextPage->set_sensitive(false); + m_xFinish->set_sensitive(true); + m_xCancel->set_sensitive(true); + + OUString aFileName; + GetConfigProperty(TK_SaveAsURL) >>= aFileName; + SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, aFileName); + ErrorHandler::HandleError(errorCode); + return false; + } + } + else + { + m_xPrevPage->set_sensitive(true); + m_xNextPage->set_sensitive(false); + m_xFinish->set_sensitive(true); + m_xCancel->set_sensitive(true); + } + + return vcl::RoadmapWizardMachine::onFinish(); } -void SpinListenerFormattedField0Pg1::down( const SpinEvent& /* rEvent */ ) + +IMPL_LINK_NOARG(IntroPage, ButtonActionPerformed, weld::Button&, void) { - double fDouble; - Any aAny = mrOptimizerDialog.getControlProperty( "FormattedField0Pg1", "EffectiveValue" ); - if ( aAny >>= fDouble ) + // delete configuration + OUString aSelectedItem(mxComboBox->get_active_text()); + if ( !aSelectedItem.isEmpty() ) { - fDouble -= 9; - if ( fDouble < 0 ) - fDouble = 0; - mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( fDouble ) ); - mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(fDouble) ) ); + std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( aSelectedItem ) ); + std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() ); + if ( aIter != rList.end() ) + { + rList.erase( aIter ); + mrOptimizerDialog.UpdateControlStates(); + } } } -void SpinListenerFormattedField0Pg1::first( const SpinEvent& /* rEvent */ ) + +IMPL_LINK(IntroPage, ComboBoxActionPerformed, weld::ComboBox&, rBox, void) { - mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( static_cast< double >( 0 ) ) ); - mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( sal_Int32(0) ) ); + OUString sActionCommand(rBox.get_active_text()); + if (!sActionCommand.isEmpty()) + { + std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName(sActionCommand) ); + std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() ); + if ( aIter != rList.end() ) + rList[ 0 ] = *aIter; + } + mrOptimizerDialog.UpdateControlStates(); } -void SpinListenerFormattedField0Pg1::last( const SpinEvent& /* rEvent */ ) + +IMPL_LINK(ImagesPage, SpinButtonActionPerformed, weld::SpinButton&, rBox, void) { - mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( static_cast< double >( 100 ) ) ); - mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( sal_Int32(100) ) ); + mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(rBox.get_value()) ) ); } -void SpinListenerFormattedField0Pg1::disposing( const css::lang::EventObject& /* Source */ ) + +IMPL_LINK_NOARG(ImagesPage, ComboBoxActionPerformed, weld::ComboBox&, void) { + mrOptimizerDialog.SetConfigProperty( TK_ImageResolution, Any( m_xResolution->get_active_id().toInt32() ) ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/optimizerdialog.hxx b/sdext/source/minimizer/optimizerdialog.hxx index 4ea28eb7590a..88c01b54300b 100644 --- a/sdext/source/minimizer/optimizerdialog.hxx +++ b/sdext/source/minimizer/optimizerdialog.hxx @@ -17,19 +17,16 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_OPTIMIZERDIALOG_HXX -#define INCLUDED_SDEXT_SOURCE_MINIMIZER_OPTIMIZERDIALOG_HXX +#pragma once + #include <vector> -#include "unodialog.hxx" #include "optimizationstats.hxx" #include "configurationaccess.hxx" -#include <com/sun/star/awt/XItemListener.hpp> -#include <com/sun/star/awt/XSpinListener.hpp> -#include <com/sun/star/awt/XTextListener.hpp> #include <com/sun/star/uno/Sequence.h> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/frame/XDispatch.hpp> #include <cppuhelper/implbase.hxx> +#include <vcl/roadmapwizard.hxx> #define MAX_STEP 4 #define OD_DIALOG_WIDTH 330 @@ -48,35 +45,162 @@ #define ITEM_ID_OLE_OPTIMIZATION 3 #define ITEM_ID_SUMMARY 4 -class OptimizerDialog : public UnoDialog, public ConfigurationAccess +class OptimizerDialog; + +class IntroPage : public vcl::OWizardPage +{ +private: + OptimizerDialog& mrOptimizerDialog; + std::unique_ptr<weld::ComboBox> mxComboBox; + std::unique_ptr<weld::Button> mxButton; + + DECL_LINK(ComboBoxActionPerformed, weld::ComboBox&, void); + DECL_LINK(ButtonActionPerformed, weld::Button&, void); + +public: + IntroPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog); + void UpdateControlStates(const std::vector<OUString>& rItemList, int nSelectedItem, bool bRemoveButtonEnabled); + OUString Get_TK_Name() const + { + return mxComboBox->get_active_text(); + } +}; + +class SlidesPage : public vcl::OWizardPage +{ +private: + OptimizerDialog& mrOptimizerDialog; + std::unique_ptr<weld::CheckButton> mxMasterSlides; + std::unique_ptr<weld::CheckButton> mxHiddenSlides; + std::unique_ptr<weld::CheckButton> mxUnusedSlides; + std::unique_ptr<weld::ComboBox> mxComboBox; + std::unique_ptr<weld::CheckButton> mxClearNodes; + + DECL_LINK(UnusedMasterPagesActionPerformed, weld::Toggleable&, void); + DECL_LINK(UnusedHiddenSlidesActionPerformed, weld::Toggleable&, void); + DECL_LINK(UnusedSlidesActionPerformed, weld::Toggleable&, void); + DECL_LINK(DeleteNotesActionPerformed, weld::Toggleable&, void); + +public: + SlidesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog); + void Init(const css::uno::Sequence<OUString>& rCustomShowList); + void UpdateControlStates(bool bDeleteUnusedMasterPages, bool bDeleteHiddenSlides, bool bDeleteNotesPages); + OUString Get_TK_CustomShowName() const + { + if (!mxUnusedSlides->get_sensitive()) + return OUString(); + return mxComboBox->get_active_text(); + } +}; + +class ImagesPage : public vcl::OWizardPage +{ +private: + OptimizerDialog& mrOptimizerDialog; + std::unique_ptr<weld::RadioButton> m_xLossLessCompression; + std::unique_ptr<weld::Label> m_xQualityLabel; + std::unique_ptr<weld::SpinButton> m_xQuality; + std::unique_ptr<weld::RadioButton> m_xJpegCompression; + std::unique_ptr<weld::ComboBox> m_xResolution; + std::unique_ptr<weld::CheckButton> m_xRemoveCropArea; + std::unique_ptr<weld::CheckButton> m_xEmbedLinkedGraphics; + + DECL_LINK(EmbedLinkedGraphicsActionPerformed, weld::Toggleable&, void); + DECL_LINK(RemoveCropAreaActionPerformed, weld::Toggleable&, void); + DECL_LINK(ComboBoxActionPerformed, weld::ComboBox&, void); + DECL_LINK(CompressionActionPerformed, weld::Toggleable&, void); + DECL_LINK(SpinButtonActionPerformed, weld::SpinButton&, void); + +public: + ImagesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog); + + void UpdateControlStates(bool bJPEGCompression, int nJPEGQuality, bool bRemoveCropArea, + int nResolution, bool bEmbedLinkedGraphics); +}; + +class ObjectsPage : public vcl::OWizardPage +{ +private: + OptimizerDialog& mrOptimizerDialog; + std::unique_ptr<weld::CheckButton> m_xCreateStaticImage; + std::unique_ptr<weld::RadioButton> m_xAllOLEObjects; + std::unique_ptr<weld::RadioButton> m_xForeignOLEObjects; + std::unique_ptr<weld::Label> m_xLabel; + + DECL_LINK(OLEOptimizationActionPerformed, weld::Toggleable&, void); + DECL_LINK(OLEActionPerformed, weld::Toggleable&, void); + +public: + ObjectsPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog); + + void Init(const OUString& rDesc); + + void UpdateControlStates(bool bConvertOLEObjects, int nOLEOptimizationType); +}; + +class SummaryPage : public vcl::OWizardPage +{ +private: + OptimizerDialog& mrOptimizerDialog; + std::unique_ptr<weld::Label> m_xLabel1; + std::unique_ptr<weld::Label> m_xLabel2; + std::unique_ptr<weld::Label> m_xLabel3; + std::unique_ptr<weld::Label> m_xCurrentSize; + std::unique_ptr<weld::Label> m_xEstimatedSize; + std::unique_ptr<weld::Label> m_xStatus; + std::unique_ptr<weld::ProgressBar> m_xProgress; + std::unique_ptr<weld::RadioButton> m_xApplyToCurrent; + std::unique_ptr<weld::RadioButton> m_xSaveToNew; + std::unique_ptr<weld::ComboBox> m_xComboBox; + std::unique_ptr<weld::CheckButton> m_xSaveSettings; + + DECL_LINK(SaveSettingsActionPerformed, weld::Toggleable&, void); + DECL_LINK(SaveAsNewActionPerformed, weld::Toggleable&, void); + +public: + SummaryPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog); + + void Init(const OUString& rSettingsName, bool bIsReadonly); + + void UpdateControlStates(bool bSaveAs, bool bSaveSettingsEnabled, + const std::vector<OUString>& rItemList, + const std::vector<OUString>& rSummaryStrings, + const OUString& rCurrentFileSize, + const OUString& rEstimatedFileSize); + + void UpdateStatusLabel(const OUString& rStatus); + void UpdateProgressValue(int nProgress); + + bool GetSaveAsNew() const { return m_xSaveToNew->get_active(); } + bool GetSaveSettings() const { return m_xSaveSettings->get_active(); } + OUString GetSettingsName() const { return m_xComboBox->get_active_text(); } +}; + +class OptimizerDialog : public vcl::RoadmapWizardMachine, public ConfigurationAccess { public: OptimizerDialog( const css::uno::Reference< css::uno::XComponentContext >& rxContext, css::uno::Reference< css::frame::XFrame > const & rxFrame, css::uno::Reference< css::frame::XDispatch > const & rxStatusDispatcher ); + std::unique_ptr<BuilderPage> createPage(vcl::WizardTypes::WizardState nState) override; ~OptimizerDialog(); void execute(); - sal_Int16 mnCurrentStep; - sal_Int16 mnTabIndex; + short mnEndStatus; bool mbIsReadonly; private: css::uno::Reference< css::frame::XFrame > mxFrame; + css::uno::Reference< css::frame::XController > mxController; - css::uno::Reference< css::uno::XInterface > mxRoadmapControl; - css::uno::Reference< css::uno::XInterface > mxRoadmapControlModel; - - css::uno::Reference< css::awt::XItemListener > mxItemListener; - css::uno::Reference< css::awt::XActionListener > mxActionListener; - css::uno::Reference< css::awt::XActionListener > mxActionListenerListBox0Pg0; - css::uno::Reference< css::awt::XTextListener > mxTextListenerFormattedField0Pg1; - css::uno::Reference< css::awt::XTextListener > mxTextListenerComboBox0Pg1; - css::uno::Reference< css::awt::XSpinListener > mxSpinListenerFormattedField0Pg1; css::uno::Reference< css::frame::XDispatch > mxStatusDispatcher; - std::vector< std::vector< OUString > > maControlPages; + IntroPage* mpPage0; + SlidesPage* mpPage1; + ImagesPage* mpPage2; + ObjectsPage* mpPage3; + SummaryPage* mpPage4; void InitDialog(); void InitRoadmap(); @@ -92,9 +216,9 @@ private: void UpdateControlStatesPage3(); void UpdateControlStatesPage4(); - void ActivatePage( sal_Int16 nStep ); - void DeactivatePage( sal_Int16 nStep ); - void InsertRoadmapItem( const sal_Int32 nIndex, const OUString& rLabel, const sal_Int32 nItemID ); + virtual OUString getStateDisplayName(vcl::WizardTypes::WizardState nState) const override; + + virtual bool onFinish() override; public: @@ -105,99 +229,16 @@ public: // the ConfigurationAccess is updated to actual control settings void UpdateConfiguration(); - void EnablePage( sal_Int16 nStep ); - void DisablePage( sal_Int16 nStep ); - - void SwitchPage( sal_Int16 nNewStep ); void UpdateControlStates( sal_Int16 nStep = -1 ); - OUString GetSelectedString( OUString const & token ); + void SetIntroPage(IntroPage* pPage0) { mpPage0 = pPage0; } + void SetSlidesPage(SlidesPage* pPage1) { mpPage1 = pPage1; } + void SetImagesPage(ImagesPage* pPage2) { mpPage2 = pPage2; } + void SetObjectsPage(ObjectsPage* pPage3) { mpPage3 = pPage3; } + void SetSummaryPage(SummaryPage* pPage4) { mpPage4 = pPage4; } + css::uno::Reference< css::frame::XDispatch >& GetStatusDispatcher() { return mxStatusDispatcher; }; css::uno::Reference< css::frame::XFrame>& GetFrame() { return mxFrame; }; - const css::uno::Reference< css::uno::XComponentContext >& GetComponentContext() const { return UnoDialog::mxContext; }; -}; - - -class ItemListener : public ::cppu::WeakImplHelper< css::awt::XItemListener > -{ -public: - explicit ItemListener( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} - - virtual void SAL_CALL itemStateChanged( const css::awt::ItemEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - OptimizerDialog& mrOptimizerDialog; }; - -class ActionListener : public ::cppu::WeakImplHelper< css::awt::XActionListener > -{ -public: - explicit ActionListener( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} - - virtual void SAL_CALL actionPerformed( const css::awt::ActionEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - OptimizerDialog& mrOptimizerDialog; -}; - - -class ActionListenerListBox0Pg0 : public ::cppu::WeakImplHelper< css::awt::XActionListener > -{ -public: - explicit ActionListenerListBox0Pg0( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} - - virtual void SAL_CALL actionPerformed( const css::awt::ActionEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - OptimizerDialog& mrOptimizerDialog; -}; - - -class TextListenerFormattedField0Pg1 : public ::cppu::WeakImplHelper< css::awt::XTextListener > -{ -public: - explicit TextListenerFormattedField0Pg1( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} - - virtual void SAL_CALL textChanged( const css::awt::TextEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - OptimizerDialog& mrOptimizerDialog; -}; - - -class TextListenerComboBox0Pg1 : public ::cppu::WeakImplHelper< css::awt::XTextListener > -{ -public: - explicit TextListenerComboBox0Pg1( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} - - virtual void SAL_CALL textChanged( const css::awt::TextEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - OptimizerDialog& mrOptimizerDialog; -}; - - -class SpinListenerFormattedField0Pg1 : public ::cppu::WeakImplHelper< css::awt::XSpinListener > -{ -public: - explicit SpinListenerFormattedField0Pg1( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} - - virtual void SAL_CALL up( const css::awt::SpinEvent& Event ) override; - virtual void SAL_CALL down( const css::awt::SpinEvent& Event ) override; - virtual void SAL_CALL first( const css::awt::SpinEvent& Event ) override; - virtual void SAL_CALL last( const css::awt::SpinEvent& Event ) override; - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; -private: - - OptimizerDialog& mrOptimizerDialog; -}; - -#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_OPTIMIZERDIALOG_HXX - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/optimizerdialogcontrols.cxx b/sdext/source/minimizer/optimizerdialogcontrols.cxx index 79832c36fb2f..d2c4e49f3b95 100644 --- a/sdext/source/minimizer/optimizerdialogcontrols.cxx +++ b/sdext/source/minimizer/optimizerdialogcontrols.cxx @@ -35,367 +35,30 @@ #include <com/sun/star/frame/XStorable.hpp> #include <rtl/ustrbuf.hxx> #include <sal/macros.h> +#include <o3tl/string_view.hxx> -using namespace ::com::sun::star::awt; using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::util; -using namespace ::com::sun::star::lang; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::container; using namespace ::com::sun::star::presentation; - -static void SetBold( OptimizerDialog& rOptimizerDialog, const OUString& rControl ) -{ - FontDescriptor aFontDescriptor; - if ( rOptimizerDialog.getControlProperty( rControl, "FontDescriptor" ) >>= aFontDescriptor ) - { - aFontDescriptor.Weight = com::sun::star::awt::FontWeight::BOLD; - rOptimizerDialog.setControlProperty( rControl, "FontDescriptor", Any( aFontDescriptor ) ); - } -} - - -static OUString InsertSeparator( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, sal_Int32 nOrientation, - sal_Int32 nPosX, sal_Int32 nPosY, sal_Int32 nWidth, sal_Int32 nHeight ) -{ - OUString pNames[] = { - OUString("Height"), - OUString("Orientation"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("Width") }; - - Any pValues[] = { - Any( nHeight ), - Any( nOrientation ), - Any( nPosX ), - Any( nPosY ), - Any( sal_Int16( 0 ) ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - rOptimizerDialog.insertControlModel( "com.sun.star.awt.UnoControlFixedLineModel", - rControlName, aNames, aValues ); - return rControlName; -} - - -static OUString InsertButton( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, Reference< XActionListener > const & xActionListener, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex, bool bEnabled, PPPOptimizerTokenEnum nResID, css::awt::PushButtonType nPushButtonType ) -{ - sal_Int32 nHeight = BUTTON_HEIGHT; - OUString pNames[] = { - OUString("Enabled"), - OUString("Height"), - OUString("Label"), - OUString("PositionX"), - OUString("PositionY"), - OUString("PushButtonType"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( bEnabled ), - Any( nHeight ), - Any( rOptimizerDialog.getString( nResID ) ), - Any( nXPos ), - Any( nYPos ), - Any( static_cast< sal_Int16 >(nPushButtonType) ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - rOptimizerDialog.insertButton( rControlName, xActionListener, aNames, aValues ); - return rControlName; -} - - -static OUString InsertFixedText( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, const OUString& rLabel, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int32 nHeight, bool bMultiLine, bool bBold, sal_Int16 nTabIndex ) -{ - OUString pNames[] = { - OUString("Height"), - OUString("Label"), - OUString("MultiLine"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( nHeight ), - Any( rLabel ), - Any( bMultiLine ), - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - rOptimizerDialog.insertFixedText( rControlName, aNames, aValues ); - if ( bBold ) - SetBold( rOptimizerDialog, rControlName ); - return rControlName; -} - - -static OUString InsertCheckBox( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, - const Reference< XItemListener >& xItemListener, const OUString& rLabel, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) -{ - sal_Int32 nHeight = 8; - OUString pNames[] = { - OUString("Enabled"), - OUString("Height"), - OUString("Label"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( true ), - Any( nHeight ), - Any( rLabel ), - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - Reference< XCheckBox > xCheckBox( rOptimizerDialog.insertCheckBox( rControlName, aNames, aValues ) ); - if ( xItemListener.is() ) - xCheckBox->addItemListener( xItemListener ); - return rControlName; -} - - -static OUString InsertFormattedField( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, - const Reference< XTextListener >& xTextListener, const Reference< XSpinListener >& xSpinListener, sal_Int32 nXPos, sal_Int32 nYPos, - double fEffectiveMin, double fEffectiveMax, sal_Int16 nTabIndex ) -{ - sal_Int32 nWidth = 50; - OUString pNames[] = { - OUString("EffectiveMax"), - OUString("EffectiveMin"), - OUString("Enabled"), - OUString("Height"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Repeat"), - OUString("Spin"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( fEffectiveMax ), - Any( fEffectiveMin ), - Any( true ), - Any( sal_Int32(12) ), - Any( nXPos ), - Any( nYPos ), - Any( true ), - Any( true ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - Reference< XTextComponent > xTextComponent( rOptimizerDialog.insertFormattedField( rControlName, aNames, aValues ), UNO_QUERY_THROW ); - if ( xTextListener.is() ) - xTextComponent->addTextListener( xTextListener ); - if ( xSpinListener.is() ) - { - Reference< XSpinField > xSpinField( xTextComponent, UNO_QUERY_THROW ); - xSpinField->addSpinListener( xSpinListener ); - } - return rControlName; -} - - -static OUString InsertComboBox( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, - const Reference< XTextListener >& rTextListener, const bool bEnabled, const Sequence< OUString >& rItemList, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int16 nTabIndex ) -{ - sal_Int32 nHeight = 12; - sal_Int32 nWidth = 100; - OUString pNames[] = { - OUString("Dropdown"), - OUString("Enabled"), - OUString("Height"), - OUString("LineCount"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("StringItemList"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( true ), - Any( bEnabled ), - Any( nHeight ), - Any( sal_Int16(8)), - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( rItemList ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - Reference< XTextComponent > xTextComponent( rOptimizerDialog.insertComboBox( rControlName, aNames, aValues ), UNO_QUERY_THROW ); - if ( rTextListener.is() ) - xTextComponent->addTextListener( rTextListener ); - return rControlName; -} - - -static OUString InsertRadioButton( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, const Reference< XItemListener >& rItemListener, - const OUString& rLabel, sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) -{ - sal_Int32 nHeight = 8; - OUString pNames[] = { - OUString("Height"), - OUString("Label"), - OUString("MultiLine"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( nHeight ), - Any( rLabel ), - Any( false ), // bMultiLine - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - Reference< XRadioButton > xRadioButton( rOptimizerDialog.insertRadioButton( rControlName, aNames, aValues ) ); - if ( rItemListener.is() ) - xRadioButton->addItemListener( rItemListener ); - return rControlName; -} - - -static OUString InsertListBox( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, - const Reference< XActionListener >& rActionListener, const bool bEnabled, const Sequence< OUString >& rItemList, - sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) -{ - sal_Int32 nHeight = 12; - OUString pNames[] = { - OUString("Dropdown"), - OUString("Enabled"), - OUString("Height"), - OUString("LineCount"), - OUString("MultiSelection"), - OUString("PositionX"), - OUString("PositionY"), - OUString("Step"), - OUString("StringItemList"), - OUString("TabIndex"), - OUString("Width") }; - - Any pValues[] = { - Any( true ), - Any( bEnabled ), - Any( nHeight ), - Any( sal_Int16(8)), - Any( false ), - Any( nXPos ), - Any( nYPos ), - Any( sal_Int16(0) ), - Any( rItemList ), - Any( nTabIndex ), - Any( nWidth ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - Reference< XListBox > xListBox( rOptimizerDialog.insertListBox( rControlName, aNames, aValues ) ); - if ( xListBox.is() ) - xListBox->addActionListener( rActionListener ); - return rControlName; -} - - void OptimizerDialog::InitNavigationBar() { - sal_Int32 nCancelPosX = OD_DIALOG_WIDTH - BUTTON_WIDTH - 6; - sal_Int32 nFinishPosX = nCancelPosX - 6 - BUTTON_WIDTH; - sal_Int32 nNextPosX = nFinishPosX - 6 - BUTTON_WIDTH; - sal_Int32 nBackPosX = nNextPosX - 3 - BUTTON_WIDTH; - - InsertSeparator( *this, "lnNavSep1", 0, 0, DIALOG_HEIGHT - 26, OD_DIALOG_WIDTH, 1 ); - InsertSeparator( *this, "lnNavSep2", 1, 85, 0, 1, BUTTON_POS_Y - 6 ); - - InsertButton( *this, "btnNavBack", mxActionListener, nBackPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, false, STR_BACK, PushButtonType_STANDARD ); - InsertButton( *this, "btnNavNext", mxActionListener, nNextPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, true, STR_NEXT, PushButtonType_STANDARD ); - InsertButton( *this, "btnNavFinish", mxActionListener, nFinishPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, true, STR_FINISH, PushButtonType_STANDARD ); - InsertButton( *this, "btnNavCancel", mxActionListener, nCancelPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, true, STR_CANCEL, PushButtonType_STANDARD ); - - setControlProperty( "btnNavNext", "DefaultButton", Any( true ) ); + m_xHelp->hide(); } - void OptimizerDialog::UpdateControlStatesPage0() { - short nSelectedItem = -1; - Sequence< OUString > aItemList; + int nSelectedItem = -1; + std::vector<OUString> aItemList; const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() ); if ( rList.size() > 1 ) // the first session in the list is the actual one -> skipping first one { - aItemList.realloc( rList.size() - 1 ); for ( std::vector<OptimizerSettings>::size_type i = 1; i < rList.size(); i++ ) { - aItemList[ i - 1 ] = rList[ i ].maName; + aItemList.push_back(rList[i].maName); if ( nSelectedItem < 0 ) { if ( rList[ i ] == rList[ 0 ] ) @@ -404,44 +67,27 @@ void OptimizerDialog::UpdateControlStatesPage0() } } bool bRemoveButtonEnabled = false; - Sequence< short > aSelectedItems; if ( nSelectedItem >= 0 ) { - aSelectedItems.realloc( 1 ); - aSelectedItems[ 0 ] = nSelectedItem; if ( nSelectedItem > 2 ) // only allowing to delete custom themes, the first can|t be deleted bRemoveButtonEnabled = true; } - setControlProperty( "ListBox0Pg0", "StringItemList", Any( aItemList ) ); - setControlProperty( "ListBox0Pg0", "SelectedItems", Any( aSelectedItems ) ); - setControlProperty( "Button0Pg0", "Enabled", Any( bRemoveButtonEnabled ) ); + mpPage0->UpdateControlStates(aItemList, nSelectedItem, bRemoveButtonEnabled); } + void OptimizerDialog::InitPage0() { - Sequence< OUString > aItemList; - std::vector< OUString > aControlList; - aControlList.push_back( InsertFixedText( *this, "FixedText0Pg0", getString( STR_INTRODUCTION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText1Pg0", getString( STR_INTRODUCTION_T ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 100, true, false, mnTabIndex++ ) ); - aControlList.push_back( InsertSeparator( *this, "Separator1Pg0", 0, PAGE_POS_X + 6, DIALOG_HEIGHT - 66, PAGE_WIDTH - 12, 1 ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText2Pg0", getString( STR_CHOSE_SETTINGS ), PAGE_POS_X + 6, DIALOG_HEIGHT - 60, PAGE_WIDTH - 12, 8, true, false, mnTabIndex++ ) ); - aControlList.push_back( InsertListBox( *this, "ListBox0Pg0", mxActionListenerListBox0Pg0, true, aItemList, PAGE_POS_X + 6, DIALOG_HEIGHT - 48, ( OD_DIALOG_WIDTH - 50 ) - ( PAGE_POS_X + 6 ), mnTabIndex++ ) ); - aControlList.push_back( InsertButton( *this, "Button0Pg0", mxActionListener, OD_DIALOG_WIDTH - 46, DIALOG_HEIGHT - 49, 40, mnTabIndex++, true, STR_REMOVE, PushButtonType_STANDARD ) ); - maControlPages.push_back( aControlList ); - DeactivatePage( 0 ); UpdateControlStatesPage0(); } - void OptimizerDialog::UpdateControlStatesPage1() { bool bDeleteUnusedMasterPages( GetConfigProperty( TK_DeleteUnusedMasterPages, false ) ); bool bDeleteHiddenSlides( GetConfigProperty( TK_DeleteHiddenSlides, false ) ); bool bDeleteNotesPages( GetConfigProperty( TK_DeleteNotesPages, false ) ); - - setControlProperty( "CheckBox0Pg3", "State", Any( static_cast<sal_Int16>(bDeleteUnusedMasterPages) ) ); - setControlProperty( "CheckBox1Pg3", "State", Any( static_cast<sal_Int16>(bDeleteNotesPages) ) ); - setControlProperty( "CheckBox2Pg3", "State", Any( static_cast<sal_Int16>(bDeleteHiddenSlides) ) ); + mpPage1->UpdateControlStates(bDeleteUnusedMasterPages, bDeleteHiddenSlides, bDeleteNotesPages); } + void OptimizerDialog::InitPage1() { Sequence< OUString > aCustomShowList; @@ -453,99 +99,35 @@ void OptimizerDialog::InitPage1() if ( aXCont.is() ) aCustomShowList = aXCont->getElementNames(); } - std::vector< OUString > aControlList; - aControlList.push_back( InsertFixedText( *this, "FixedText0Pg3", getString( STR_CHOOSE_SLIDES ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox0Pg3", mxItemListener, getString( STR_DELETE_MASTER_PAGES ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox2Pg3", mxItemListener, getString( STR_DELETE_HIDDEN_SLIDES ), PAGE_POS_X + 6, PAGE_POS_Y + 28, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox3Pg3", mxItemListener, getString( STR_CUSTOM_SHOW ), PAGE_POS_X + 6, PAGE_POS_Y + 42, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertListBox( *this, "ListBox0Pg3", mxActionListener, true, aCustomShowList, PAGE_POS_X + 14, PAGE_POS_Y + 54, 150, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox1Pg3", mxItemListener, getString( STR_DELETE_NOTES_PAGES ), PAGE_POS_X + 6, PAGE_POS_Y + 70, PAGE_WIDTH - 12, mnTabIndex++ ) ); - maControlPages.push_back( aControlList ); - DeactivatePage( 1 ); - - setControlProperty( "CheckBox3Pg3", "State", Any( false ) ); - setControlProperty( "CheckBox3Pg3", "Enabled", Any( aCustomShowList.hasElements() ) ); - setControlProperty( "ListBox0Pg3", "Enabled", Any( false ) ); + mpPage1->Init(aCustomShowList); UpdateControlStatesPage1(); } -namespace -{ - -bool lcl_getResolutionText(OUString& rResolutionText, const OUString& rImageResolution, sal_Int32 nTargetRes) -{ - sal_Int32 nIdx{ 0 }; - if (rImageResolution.getToken(0, ';', nIdx).toInt32()!=nTargetRes) - return false; - rResolutionText = rImageResolution.getToken(0, ';', nIdx); - return true; -} - -} - void OptimizerDialog::UpdateControlStatesPage2() { bool bJPEGCompression( GetConfigProperty( TK_JPEGCompression, false ) ); bool bRemoveCropArea( GetConfigProperty( TK_RemoveCropArea, false ) ); bool bEmbedLinkedGraphics( GetConfigProperty( TK_EmbedLinkedGraphics, true ) ); sal_Int32 nJPEGQuality( GetConfigProperty( TK_JPEGQuality, sal_Int32(90) ) ); - sal_Int32 nImageResolution( GetConfigProperty( TK_ImageResolution, sal_Int32(0) ) ); - OUString aResolutionText; - for (int nIR{ STR_IMAGE_RESOLUTION_0 }; nIR<=STR_IMAGE_RESOLUTION_3; ++nIR) - { - if (lcl_getResolutionText(aResolutionText, getString(static_cast<PPPOptimizerTokenEnum>(nIR)), nImageResolution)) - break; - } - if ( aResolutionText.isEmpty() ) - aResolutionText = OUString::number( nImageResolution ); - - setControlProperty( "RadioButton0Pg1", "State", Any( static_cast<sal_Int16>( !bJPEGCompression ) ) ); - setControlProperty( "RadioButton1Pg1", "State", Any( static_cast<sal_Int16>(bJPEGCompression) ) ); - setControlProperty( "FixedText1Pg1", "Enabled", Any( bJPEGCompression ) ); - setControlProperty( "FormattedField0Pg1", "Enabled", Any( bJPEGCompression ) ); - setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( static_cast<double>(nJPEGQuality) ) ); - setControlProperty( "CheckBox1Pg1", "State", Any( static_cast<sal_Int16>(bRemoveCropArea) ) ); - setControlProperty( "ComboBox0Pg1", "Text", Any( aResolutionText ) ); - setControlProperty( "CheckBox2Pg1", "State", Any( static_cast<sal_Int16>(bEmbedLinkedGraphics) ) ); + mpPage2->UpdateControlStates(bJPEGCompression, nJPEGQuality, bRemoveCropArea, nImageResolution, bEmbedLinkedGraphics); } + void OptimizerDialog::InitPage2() { - Sequence< OUString > aResolutionItemList( 4 ); - aResolutionItemList[ 0 ] = getString( STR_IMAGE_RESOLUTION_0 ).getToken( 1, ';' ); - aResolutionItemList[ 1 ] = getString( STR_IMAGE_RESOLUTION_1 ).getToken( 1, ';' ); - aResolutionItemList[ 2 ] = getString( STR_IMAGE_RESOLUTION_2 ).getToken( 1, ';' ); - aResolutionItemList[ 3 ] = getString( STR_IMAGE_RESOLUTION_3 ).getToken( 1, ';' ); - - std::vector< OUString > aControlList; - aControlList.push_back( InsertFixedText( *this, "FixedText0Pg1", getString( STR_GRAPHIC_OPTIMIZATION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ) ); - aControlList.push_back( InsertRadioButton( *this, "RadioButton0Pg1", mxItemListener, getString( STR_LOSSLESS_COMPRESSION ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertRadioButton( *this, "RadioButton1Pg1", mxItemListener, getString( STR_JPEG_COMPRESSION ), PAGE_POS_X + 6, PAGE_POS_Y + 28, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText1Pg1", getString( STR_QUALITY ), PAGE_POS_X + 20, PAGE_POS_Y + 40, 72, 8, false, false, mnTabIndex++ ) ); - aControlList.push_back( InsertFormattedField( *this, "FormattedField0Pg1", mxTextListenerFormattedField0Pg1, mxSpinListenerFormattedField0Pg1, PAGE_POS_X + 106, PAGE_POS_Y + 38, 0, 100, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText2Pg1", getString( STR_IMAGE_RESOLUTION ), PAGE_POS_X + 6, PAGE_POS_Y + 54, 94, 8, false, false, mnTabIndex++ ) ); - aControlList.push_back( InsertComboBox( *this, "ComboBox0Pg1", mxTextListenerComboBox0Pg1, true, aResolutionItemList, PAGE_POS_X + 106, PAGE_POS_Y + 52, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox1Pg1", mxItemListener, getString( STR_REMOVE_CROP_AREA ), PAGE_POS_X + 6, PAGE_POS_Y + 68, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox2Pg1", mxItemListener, getString( STR_EMBED_LINKED_GRAPHICS ), PAGE_POS_X + 6, PAGE_POS_Y + 82, PAGE_WIDTH - 12, mnTabIndex++ ) ); - maControlPages.push_back( aControlList ); - DeactivatePage( 2 ); UpdateControlStatesPage2(); } - void OptimizerDialog::UpdateControlStatesPage3() { bool bConvertOLEObjects( GetConfigProperty( TK_OLEOptimization, false ) ); sal_Int16 nOLEOptimizationType( GetConfigProperty( TK_OLEOptimizationType, sal_Int16(0) ) ); - setControlProperty( "CheckBox0Pg2", "State", Any( static_cast<sal_Int16>(bConvertOLEObjects) ) ); - setControlProperty( "RadioButton0Pg2", "Enabled", Any( bConvertOLEObjects ) ); - setControlProperty( "RadioButton0Pg2", "State", Any( static_cast<sal_Int16>( nOLEOptimizationType == 0 ) ) ); - setControlProperty( "RadioButton1Pg2", "Enabled", Any( bConvertOLEObjects ) ); - setControlProperty( "RadioButton1Pg2", "State", Any( static_cast<sal_Int16>( nOLEOptimizationType == 1 ) ) ); + mpPage3->UpdateControlStates(bConvertOLEObjects, nOLEOptimizationType); } + void OptimizerDialog::InitPage3() { int nOLECount = 0; @@ -563,18 +145,11 @@ void OptimizerDialog::InitPage3() } } - std::vector< OUString > aControlList; - aControlList.push_back( InsertFixedText( *this, "FixedText0Pg2", getString( STR_OLE_OPTIMIZATION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox0Pg2", mxItemListener, getString( STR_OLE_REPLACE ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertRadioButton( *this, "RadioButton0Pg2", mxItemListener, getString( STR_ALL_OLE_OBJECTS ), PAGE_POS_X + 14, PAGE_POS_Y + 28, PAGE_WIDTH - 22, mnTabIndex++ ) ); - aControlList.push_back( InsertRadioButton( *this, "RadioButton1Pg2", mxItemListener, getString( STR_ALIEN_OLE_OBJECTS_ONLY ), PAGE_POS_X + 14, PAGE_POS_Y + 40, PAGE_WIDTH - 22, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText1Pg2", nOLECount ? getString( STR_OLE_OBJECTS_DESC ) : getString( STR_NO_OLE_OBJECTS_DESC ), PAGE_POS_X + 6, PAGE_POS_Y + 64, PAGE_WIDTH - 22, 50, true, false, mnTabIndex++ ) ); - maControlPages.push_back( aControlList ); - DeactivatePage( 3 ); + mpPage3->Init(nOLECount ? getString(STR_OLE_OBJECTS_DESC) : getString(STR_NO_OLE_OBJECTS_DESC)); + UpdateControlStatesPage3(); } - static OUString ImpValueOfInMB( sal_Int64 rVal, sal_Unicode nSeparator ) { double fVal( static_cast<double>( rVal ) ); @@ -595,26 +170,15 @@ void OptimizerDialog::UpdateControlStatesPage4() { bool bSaveAs( GetConfigProperty( TK_SaveAs, true ) ); if ( mbIsReadonly ) - { - setControlProperty( "RadioButton0Pg4", "State", Any( sal_Int16(false) ) ); - setControlProperty( "RadioButton1Pg4", "State", Any( sal_Int16(true) ) ); - } - else - { - setControlProperty( "RadioButton0Pg4", "State", Any( static_cast<sal_Int16>( !bSaveAs ) ) ); - setControlProperty( "RadioButton1Pg4", "State", Any( static_cast<sal_Int16>(bSaveAs) ) ); - } - setControlProperty( "ComboBox0Pg4", "Enabled", Any( false ) ); + bSaveAs = true; - Sequence< OUString > aItemList; + std::vector<OUString> aItemList; const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() ); if ( rList.size() > 1 ) // the first session in the list is the actual one -> skipping first one { - aItemList.realloc( rList.size() - 1 ); for ( std::vector<OptimizerSettings>::size_type w = 1; w < rList.size(); w++ ) - aItemList[ w - 1 ] = rList[ w ].maName; + aItemList.push_back(rList[ w ].maName); } - setControlProperty( "ComboBox0Pg4", "StringItemList", Any( aItemList ) ); // now check if it is sensible to enable the combo box bool bSaveSettingsEnabled = true; @@ -629,37 +193,14 @@ void OptimizerDialog::UpdateControlStatesPage4() } } } - sal_Int16 nInt16 = 0; - getControlProperty( "CheckBox1Pg4", "State" ) >>= nInt16; - setControlProperty( "CheckBox1Pg4", "Enabled", Any( bSaveSettingsEnabled ) ); - setControlProperty( "ComboBox0Pg4", "Enabled", Any( bSaveSettingsEnabled && nInt16 ) ); std::vector< OUString > aSummaryStrings; // taking care of deleted slides sal_Int32 nDeletedSlides = 0; - if ( getControlProperty( "CheckBox3Pg3", "State" ) >>= nInt16 ) - { - if ( nInt16 ) - { - Sequence< short > aSelectedItems; - Sequence< OUString > aStringItemList; - Any aAny = getControlProperty( "ListBox0Pg3", "SelectedItems" ); - if ( aAny >>= aSelectedItems ) - { - if ( aSelectedItems.hasElements() ) - { - sal_Int16 nSelectedItem = aSelectedItems[ 0 ]; - aAny = getControlProperty( "ListBox0Pg3", "StringItemList" ); - if ( aAny >>= aStringItemList ) - { - if ( aStringItemList.getLength() > nSelectedItem ) - SetConfigProperty( TK_CustomShowName, Any( aStringItemList[ nSelectedItem ] ) ); - } - } - } - } - } + OUString sTKCustomShowName(mpPage1->Get_TK_CustomShowName()); + if (!sTKCustomShowName.isEmpty()) + SetConfigProperty(TK_CustomShowName, Any(sTKCustomShowName)); if ( GetConfigProperty( TK_DeleteHiddenSlides, false ) ) { Reference< XDrawPagesSupplier > xDrawPagesSupplier( mxController->getModel(), UNO_QUERY_THROW ); @@ -703,7 +244,7 @@ void OptimizerDialog::UpdateControlStatesPage4() sal_Int32 nImageResolution( GetConfigProperty( TK_ImageResolution, sal_Int32(0) ) ); GraphicSettings aGraphicSettings( bJPEGCompression, nJPEGQuality, GetConfigProperty( TK_RemoveCropArea, false ), nImageResolution, GetConfigProperty( TK_EmbedLinkedGraphics, true ) ); - GraphicCollector::CountGraphics( UnoDialog::mxContext, mxController->getModel(), aGraphicSettings, nGraphics ); + GraphicCollector::CountGraphics( mxContext, mxController->getModel(), aGraphicSettings, nGraphics ); if ( nGraphics > 1 ) { OUString aStr( getString( STR_OPTIMIZE_IMAGES ) ); @@ -752,9 +293,6 @@ void OptimizerDialog::UpdateControlStatesPage4() } while( aSummaryStrings.size() < 3 ) aSummaryStrings.emplace_back( ); - setControlProperty( "FixedText4Pg4", "Label", Any( aSummaryStrings[ 0 ] ) ); - setControlProperty( "FixedText5Pg4", "Label", Any( aSummaryStrings[ 1 ] ) ); - setControlProperty( "FixedText6Pg4", "Label", Any( aSummaryStrings[ 2 ] ) ); sal_Int64 nCurrentFileSize = 0; sal_Int64 nEstimatedFileSize = 0; @@ -782,69 +320,15 @@ void OptimizerDialog::UpdateControlStatesPage4() OUString aStr( getString( STR_FILESIZESEPARATOR ) ); if ( !aStr.isEmpty() ) nSeparator = aStr[ 0 ]; - setControlProperty( "FixedText7Pg4", "Label", Any( ImpValueOfInMB( nCurrentFileSize, nSeparator ) ) ); - setControlProperty( "FixedText8Pg4", "Label", Any( ImpValueOfInMB( nEstimatedFileSize, nSeparator ) ) ); + mpPage4->UpdateControlStates(bSaveAs, bSaveSettingsEnabled, aItemList, + aSummaryStrings, + ImpValueOfInMB(nCurrentFileSize, nSeparator), + ImpValueOfInMB(nEstimatedFileSize, nSeparator)); SetConfigProperty( TK_EstimatedFileSize, Any( nEstimatedFileSize ) ); } void OptimizerDialog::InitPage4() { - { // creating progress bar: - OUString pNames[] = { - OUString("Height"), - OUString("Name"), - OUString("PositionX"), - OUString("PositionY"), - OUString("ProgressValue"), - OUString("ProgressValueMax"), - OUString("ProgressValueMin"), - OUString("Width") }; - - Any pValues[] = { - Any( sal_Int32(12) ), - Any( OUString("STR_SAVE_AS") ), - Any( sal_Int32( PAGE_POS_X + 6 ) ), - Any( sal_Int32( DIALOG_HEIGHT - 75 ) ), - Any( sal_Int32(0) ), - Any( sal_Int32(100) ), - Any( sal_Int32(0) ), - Any( sal_Int32( PAGE_WIDTH - 12 ) ) }; - - sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); - - Sequence< OUString > aNames( pNames, nCount ); - Sequence< Any > aValues( pValues, nCount ); - - insertControlModel( "com.sun.star.awt.UnoControlProgressBarModel", - "Progress", aNames, aValues ); - } - Reference< XTextListener > xTextListener; - Sequence< OUString > aItemList; - std::vector< OUString > aControlList; - aControlList.push_back( InsertFixedText( *this, "FixedText0Pg4", getString( STR_SUMMARY_TITLE ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ) ); -// aControlList.push_back( InsertSeparator( *this, "Separator0Pg4", 0, PAGE_POS_X + 6, PAGE_POS_Y + 90, PAGE_WIDTH - 12, 1 ) ); - - aControlList.push_back( InsertFixedText( *this, "FixedText4Pg4", OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 8, false, false, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText5Pg4", OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 22, PAGE_WIDTH - 12, 8, false, false, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText6Pg4", OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 30, PAGE_WIDTH - 12, 8, false, false, mnTabIndex++ ) ); - - aControlList.push_back( InsertFixedText( *this, "FixedText2Pg4", getString( STR_CURRENT_FILESIZE ), PAGE_POS_X + 6, PAGE_POS_Y + 50, 88, 8, false, false, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText7Pg4", OUString(), PAGE_POS_X + 100, PAGE_POS_Y + 50, 30, 8, false, false, mnTabIndex++ ) ); - setControlProperty( "FixedText7Pg4", "Align", Any( static_cast< short >( 2 ) ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText3Pg4", getString( STR_ESTIMATED_FILESIZE ), PAGE_POS_X + 6, PAGE_POS_Y + 58, 88, 8, false, false, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText8Pg4", OUString(), PAGE_POS_X + 100, PAGE_POS_Y + 58, 30, 8, false, false, mnTabIndex++ ) ); - setControlProperty( "FixedText8Pg4", "Align", Any( static_cast< short >( 2 ) ) ); - - aControlList.push_back( InsertRadioButton( *this, "RadioButton0Pg4", mxItemListener, getString( STR_APPLY_TO_CURRENT ), PAGE_POS_X + 6, PAGE_POS_Y + 78, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertRadioButton( *this, "RadioButton1Pg4", mxItemListener, getString( STR_SAVE_AS ), PAGE_POS_X + 6, PAGE_POS_Y + 90, PAGE_WIDTH - 12, mnTabIndex++ ) ); - aControlList.push_back( InsertFixedText( *this, "FixedText1Pg4", OUString(), PAGE_POS_X + 6, DIALOG_HEIGHT - 87, PAGE_WIDTH - 12, 8, true, false, mnTabIndex++ ) ); - aControlList.emplace_back("Progress" ); - aControlList.push_back( InsertSeparator( *this, "Separator1Pg4", 0, PAGE_POS_X + 6, DIALOG_HEIGHT - 58, PAGE_WIDTH - 12, 1 ) ); - aControlList.push_back( InsertCheckBox( *this, "CheckBox1Pg4", mxItemListener, getString( STR_SAVE_SETTINGS ), PAGE_POS_X + 6, DIALOG_HEIGHT - 47, 100, mnTabIndex++ ) ); - aControlList.push_back( InsertComboBox( *this, "ComboBox0Pg4", xTextListener, true, aItemList, PAGE_POS_X + 106, DIALOG_HEIGHT - 48, mnTabIndex++ ) ); - maControlPages.push_back( aControlList ); - DeactivatePage( 4 ); - // creating a default session name that hasn't been used yet OUString aSettingsName; OUString aDefault( getString( STR_MY_SETTINGS ) ); @@ -864,33 +348,9 @@ void OptimizerDialog::InitPage4() } while( aSettingsName.isEmpty() ); - setControlProperty( "ComboBox0Pg4", "Text", Any( aSettingsName ) ); - setControlProperty( "RadioButton0Pg4", "Enabled", Any( !mbIsReadonly ) ); - setControlProperty( "RadioButton1Pg4", "Enabled", Any( !mbIsReadonly ) ); + mpPage4->Init(aSettingsName, mbIsReadonly); UpdateControlStatesPage4(); } - -void OptimizerDialog::EnablePage( sal_Int16 nStep ) -{ - for( const auto& rItem : maControlPages[ nStep ] ) - setControlProperty( rItem, "Enabled", Any( true ) ); -} -void OptimizerDialog::DisablePage( sal_Int16 nStep ) -{ - for( const auto& rItem : maControlPages[ nStep ] ) - setControlProperty( rItem, "Enabled", Any( false ) ); -} -void OptimizerDialog::ActivatePage( sal_Int16 nStep ) -{ - for( const auto& rItem : maControlPages[ nStep ] ) - setVisible( rItem, true ); -} -void OptimizerDialog::DeactivatePage( sal_Int16 nStep ) -{ - for( const auto& rItem : maControlPages[ nStep ] ) - setVisible( rItem, false ); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/pagecollector.cxx b/sdext/source/minimizer/pagecollector.cxx index f42c7d271a1a..f86444abbfae 100644 --- a/sdext/source/minimizer/pagecollector.cxx +++ b/sdext/source/minimizer/pagecollector.cxx @@ -28,10 +28,8 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::awt; using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::frame; -using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; using namespace ::com::sun::star::presentation; diff --git a/sdext/source/minimizer/pppoptimizerdialog.cxx b/sdext/source/minimizer/pppoptimizerdialog.cxx index 30e1b621f2b0..74a89bfbac1a 100644 --- a/sdext/source/minimizer/pppoptimizerdialog.cxx +++ b/sdext/source/minimizer/pppoptimizerdialog.cxx @@ -78,7 +78,7 @@ Sequence< Reference< css::frame::XDispatch > > SAL_CALL PPPOptimizerDialog::quer const Sequence< css::frame::DispatchDescriptor >& aDescripts ) { Sequence< Reference< css::frame::XDispatch> > aReturn( aDescripts.getLength() ); - std::transform(aDescripts.begin(), aDescripts.end(), aReturn.begin(), + std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(), [this](const css::frame::DispatchDescriptor& rDescr) -> Reference<css::frame::XDispatch> { return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); }); return aReturn; diff --git a/sdext/source/minimizer/pppoptimizertoken.cxx b/sdext/source/minimizer/pppoptimizertoken.cxx index 9130621ff762..472992551b81 100644 --- a/sdext/source/minimizer/pppoptimizertoken.cxx +++ b/sdext/source/minimizer/pppoptimizertoken.cxx @@ -45,34 +45,15 @@ struct TokenTable const TokenTable pTokenTableArray[] = { - { "rdmNavi", TK_rdmNavi }, - { "btnNavBack", TK_btnNavBack }, - { "btnNavNext", TK_btnNavNext }, { "btnNavFinish", TK_btnNavFinish }, - { "btnNavCancel", TK_btnNavCancel }, - - { "Button0Pg0", TK_Button0Pg0 }, - { "RadioButton0Pg1", TK_RadioButton0Pg1 }, - { "RadioButton1Pg1", TK_RadioButton1Pg1 }, - { "CheckBox1Pg1", TK_CheckBox1Pg1 }, - { "CheckBox2Pg1", TK_CheckBox2Pg1 }, - { "CheckBox0Pg2", TK_CheckBox0Pg2 }, - { "RadioButton0Pg2", TK_RadioButton0Pg2 }, - { "RadioButton1Pg2", TK_RadioButton1Pg2 }, - { "CheckBox0Pg3", TK_CheckBox0Pg3 }, - { "CheckBox1Pg3", TK_CheckBox1Pg3 }, - { "CheckBox2Pg3", TK_CheckBox2Pg3 }, - { "CheckBox3Pg3", TK_CheckBox3Pg3 }, - { "RadioButton0Pg4", TK_RadioButton0Pg4 }, - { "RadioButton1Pg4", TK_RadioButton1Pg4 }, - { "CheckBox1Pg4", TK_CheckBox1Pg4 }, { "DocumentService", TK_DocumentService }, { "FileSizeDestination",TK_FileSizeDestination }, { "FileSizeSource", TK_FileSizeSource }, { "FilterName", TK_FilterName }, { "Flags", TK_Flags }, - { "InformationDialog", TK_InformationDialog }, + { "DocumentFrame", TK_DocumentFrame }, + { "DialogParentWindow", TK_DialogParentWindow }, { "Name", TK_Name }, { "Progress", TK_Progress }, { "Settings", TK_Settings }, @@ -100,57 +81,23 @@ const TokenTable pTokenTableArray[] = { "Pages", TK_Pages }, { "STR_SUN_OPTIMIZATION_WIZARD2",STR_SUN_OPTIMIZATION_WIZARD2 }, - { "STR_STEPS", STR_STEPS }, - { "STR_BACK", STR_BACK }, - { "STR_NEXT", STR_NEXT }, - { "STR_FINISH", STR_FINISH }, - { "STR_CANCEL", STR_CANCEL }, { "STR_INTRODUCTION", STR_INTRODUCTION }, - { "STR_INTRODUCTION_T", STR_INTRODUCTION_T }, - { "STR_CHOSE_SETTINGS", STR_CHOSE_SETTINGS }, - { "STR_REMOVE", STR_REMOVE }, - { "STR_GRAPHIC_OPTIMIZATION", STR_GRAPHIC_OPTIMIZATION }, { "STR_IMAGE_OPTIMIZATION", STR_IMAGE_OPTIMIZATION }, - { "STR_LOSSLESS_COMPRESSION", STR_LOSSLESS_COMPRESSION }, - { "STR_JPEG_COMPRESSION", STR_JPEG_COMPRESSION }, - { "STR_QUALITY", STR_QUALITY }, - { "STR_REMOVE_CROP_AREA", STR_REMOVE_CROP_AREA }, - { "STR_IMAGE_RESOLUTION", STR_IMAGE_RESOLUTION }, - { "STR_IMAGE_RESOLUTION_0", STR_IMAGE_RESOLUTION_0 }, - { "STR_IMAGE_RESOLUTION_1", STR_IMAGE_RESOLUTION_1 }, - { "STR_IMAGE_RESOLUTION_2", STR_IMAGE_RESOLUTION_2 }, - { "STR_IMAGE_RESOLUTION_3", STR_IMAGE_RESOLUTION_3 }, - { "STR_EMBED_LINKED_GRAPHICS", STR_EMBED_LINKED_GRAPHICS }, { "STR_OLE_OBJECTS", STR_OLE_OBJECTS }, - { "STR_OLE_OPTIMIZATION", STR_OLE_OPTIMIZATION }, - { "STR_OLE_REPLACE", STR_OLE_REPLACE }, - { "STR_ALL_OLE_OBJECTS", STR_ALL_OLE_OBJECTS }, - { "STR_ALIEN_OLE_OBJECTS_ONLY", STR_ALIEN_OLE_OBJECTS_ONLY }, - { "STR__OLE_OBJECTS_DESC", STR_OLE_OBJECTS_DESC }, + { "STR_OLE_OBJECTS_DESC", STR_OLE_OBJECTS_DESC }, { "STR_NO_OLE_OBJECTS_DESC", STR_NO_OLE_OBJECTS_DESC }, { "STR_SLIDES", STR_SLIDES }, - { "STR_CHOOSE_SLIDES", STR_CHOOSE_SLIDES }, - { "STR_DELETE_MASTER_PAGES", STR_DELETE_MASTER_PAGES }, - { "STR_DELETE_NOTES_PAGES", STR_DELETE_NOTES_PAGES }, - { "STR_DELETE_HIDDEN_SLIDES", STR_DELETE_HIDDEN_SLIDES }, - { "STR_CUSTOM_SHOW", STR_CUSTOM_SHOW }, { "STR_SUMMARY", STR_SUMMARY }, - { "STR_SUMMARY_TITLE", STR_SUMMARY_TITLE }, - { "STR_APPLY_TO_CURRENT", STR_APPLY_TO_CURRENT }, - { "STR_AUTOMATICALLY_OPEN", STR_AUTOMATICALLY_OPEN }, - { "STR_SAVE_SETTINGS", STR_SAVE_SETTINGS }, - { "STR_SAVE_AS", STR_SAVE_AS }, { "STR_DELETE_SLIDES", STR_DELETE_SLIDES }, { "STR_OPTIMIZE_IMAGES", STR_OPTIMIZE_IMAGES }, { "STR_CREATE_REPLACEMENT", STR_CREATE_REPLACEMENT }, - { "STR_CURRENT_FILESIZE", STR_CURRENT_FILESIZE }, - { "STR_ESTIMATED_FILESIZE", STR_ESTIMATED_FILESIZE }, { "MY_SETTINGS", STR_MY_SETTINGS }, { "STR_OK", STR_OK }, - { "STR_INFO_1", STR_INFO_1 }, - { "STR_INFO_2", STR_INFO_2 }, - { "STR_INFO_3", STR_INFO_3 }, - { "STR_INFO_4", STR_INFO_4 }, + { "STR_INFO_PRIMARY", STR_INFO_PRIMARY }, + { "STR_INFO_SECONDARY_1", STR_INFO_SECONDARY_1 }, + { "STR_INFO_SECONDARY_2", STR_INFO_SECONDARY_2 }, + { "STR_INFO_SECONDARY_3", STR_INFO_SECONDARY_3 }, + { "STR_INFO_SECONDARY_4", STR_INFO_SECONDARY_4 }, { "STR_DUPLICATING_PRESENTATION",STR_DUPLICATING_PRESENTATION }, { "STR_DELETING_SLIDES", STR_DELETING_SLIDES }, { "STR_OPTIMIZING_GRAPHICS", STR_OPTIMIZING_GRAPHICS }, @@ -163,11 +110,11 @@ const TokenTable pTokenTableArray[] = { "NotFound", TK_NotFound } }; -PPPOptimizerTokenEnum TKGet( const OUString& rToken ) +PPPOptimizerTokenEnum TKGet( std::u16string_view rToken ) { if ( !pHashMap ) { // init hash map - std::lock_guard aGuard( getHashMapMutex() ); + std::scoped_lock aGuard( getHashMapMutex() ); if ( !pHashMap ) { TypeNameHashMap* pH = new TypeNameHashMap; @@ -179,7 +126,7 @@ PPPOptimizerTokenEnum TKGet( const OUString& rToken ) } } PPPOptimizerTokenEnum eRetValue = TK_NotFound; - int i, nLen = rToken.getLength(); + size_t i, nLen = rToken.size(); std::unique_ptr<char[]> pBuf(new char[ nLen + 1 ]); for ( i = 0; i < nLen; i++ ) pBuf[ i ] = static_cast<char>(rToken[ i ]); diff --git a/sdext/source/minimizer/pppoptimizertoken.hxx b/sdext/source/minimizer/pppoptimizertoken.hxx index d0ae65ed74ab..f665e82ece1c 100644 --- a/sdext/source/minimizer/pppoptimizertoken.hxx +++ b/sdext/source/minimizer/pppoptimizertoken.hxx @@ -24,34 +24,15 @@ enum PPPOptimizerTokenEnum { - TK_rdmNavi, - TK_btnNavBack, - TK_btnNavNext, TK_btnNavFinish, - TK_btnNavCancel, - - TK_Button0Pg0, - TK_RadioButton0Pg1, - TK_RadioButton1Pg1, - TK_CheckBox1Pg1, - TK_CheckBox2Pg1, - TK_CheckBox0Pg2, - TK_RadioButton0Pg2, - TK_RadioButton1Pg2, - TK_CheckBox0Pg3, - TK_CheckBox1Pg3, - TK_CheckBox2Pg3, - TK_CheckBox3Pg3, - TK_RadioButton0Pg4, - TK_RadioButton1Pg4, - TK_CheckBox1Pg4, TK_DocumentService, TK_FileSizeDestination, TK_FileSizeSource, TK_FilterName, TK_Flags, - TK_InformationDialog, + TK_DocumentFrame, + TK_DialogParentWindow, TK_Name, TK_Progress, TK_Settings, @@ -79,57 +60,23 @@ enum PPPOptimizerTokenEnum TK_Pages, STR_SUN_OPTIMIZATION_WIZARD2, - STR_STEPS, - STR_BACK, - STR_NEXT, - STR_FINISH, - STR_CANCEL, STR_INTRODUCTION, - STR_INTRODUCTION_T, - STR_CHOSE_SETTINGS, - STR_REMOVE, - STR_GRAPHIC_OPTIMIZATION, STR_IMAGE_OPTIMIZATION, - STR_LOSSLESS_COMPRESSION, - STR_JPEG_COMPRESSION, - STR_QUALITY, - STR_REMOVE_CROP_AREA, - STR_IMAGE_RESOLUTION, - STR_IMAGE_RESOLUTION_0, - STR_IMAGE_RESOLUTION_1, - STR_IMAGE_RESOLUTION_2, - STR_IMAGE_RESOLUTION_3, - STR_EMBED_LINKED_GRAPHICS, STR_OLE_OBJECTS, - STR_OLE_OPTIMIZATION, - STR_OLE_REPLACE, - STR_ALL_OLE_OBJECTS, - STR_ALIEN_OLE_OBJECTS_ONLY, STR_OLE_OBJECTS_DESC, STR_NO_OLE_OBJECTS_DESC, STR_SLIDES, - STR_CHOOSE_SLIDES, - STR_DELETE_MASTER_PAGES, - STR_DELETE_NOTES_PAGES, - STR_DELETE_HIDDEN_SLIDES, - STR_CUSTOM_SHOW, STR_SUMMARY, - STR_SUMMARY_TITLE, - STR_APPLY_TO_CURRENT, - STR_AUTOMATICALLY_OPEN, - STR_SAVE_SETTINGS, - STR_SAVE_AS, STR_DELETE_SLIDES, STR_OPTIMIZE_IMAGES, STR_CREATE_REPLACEMENT, - STR_CURRENT_FILESIZE, - STR_ESTIMATED_FILESIZE, STR_MY_SETTINGS, STR_OK, - STR_INFO_1, - STR_INFO_2, - STR_INFO_3, - STR_INFO_4, + STR_INFO_PRIMARY, + STR_INFO_SECONDARY_1, + STR_INFO_SECONDARY_2, + STR_INFO_SECONDARY_3, + STR_INFO_SECONDARY_4, STR_DUPLICATING_PRESENTATION, STR_DELETING_SLIDES, STR_OPTIMIZING_GRAPHICS, @@ -140,7 +87,7 @@ enum PPPOptimizerTokenEnum TK_NotFound }; -PPPOptimizerTokenEnum TKGet(const OUString&); +PPPOptimizerTokenEnum TKGet(std::u16string_view); OUString TKGet(const PPPOptimizerTokenEnum); #endif diff --git a/sdext/source/minimizer/unodialog.cxx b/sdext/source/minimizer/unodialog.cxx deleted file mode 100644 index a635d102e3b9..000000000000 --- a/sdext/source/minimizer/unodialog.cxx +++ /dev/null @@ -1,309 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - - -#include "unodialog.hxx" - -#include <com/sun/star/awt/Toolkit.hpp> -#include <com/sun/star/awt/UnoControlDialog.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/view/XSelectionSupplier.hpp> - - -using namespace ::com::sun::star::awt; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::util; -using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::view; -using namespace ::com::sun::star::frame; -using namespace ::com::sun::star::beans; - -UnoDialog::UnoDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame ) : - mxContext( rxContext ), - mxController( rxFrame->getController() ), - mxDialogModel( mxContext->getServiceManager()->createInstanceWithContext( - "com.sun.star.awt.UnoControlDialogModel", mxContext ), UNO_SET_THROW ), - mxDialogModelMultiPropertySet( mxDialogModel, UNO_QUERY_THROW ), - mxDialogModelMSF( mxDialogModel, UNO_QUERY_THROW ), - mxDialogModelNameContainer( mxDialogModel, UNO_QUERY_THROW ), - mxDialogModelNameAccess( mxDialogModel, UNO_QUERY_THROW ), - mxControlModel( mxDialogModel, UNO_QUERY_THROW ), - mxDialog( UnoControlDialog::create(rxContext) ), - mxControl( mxDialog, UNO_QUERY_THROW ), - mbStatus( false ) -{ - mxControl->setModel( mxControlModel ); - - Reference< XFrame > xFrame( mxController->getFrame() ); - Reference< XWindow > xContainerWindow( xFrame->getContainerWindow() ); - Reference< XWindowPeer > xWindowPeer( xContainerWindow, UNO_QUERY_THROW ); - - // set the main loop handle to update GUI while busy - Reference< XToolkit > xToolkit( Toolkit::create( mxContext ), UNO_QUERY_THROW ); - mxReschedule.set( xToolkit, UNO_QUERY ); - - // allocate the real window resources - mxDialog->createPeer(xToolkit, - xWindowPeer.is() ? xWindowPeer : xToolkit->getDesktopWindow()); -} - -UnoDialog::~UnoDialog() -{ - // free the resources - Reference<XComponent> xDialogComponent(mxDialog, UNO_QUERY_THROW); - xDialogComponent->dispose(); -} - -void UnoDialog::execute() -{ - mxDialog->setEnable( true ); - mxDialog->setVisible( true ); - mxDialog->execute(); -} - -void UnoDialog::endExecute( bool bStatus ) -{ - mbStatus = bStatus; - mxDialog->endExecute(); -} - -Reference< XInterface > UnoDialog::insertControlModel( const OUString& rServiceName, const OUString& rName, - const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XInterface > xControlModel; - try - { - xControlModel = mxDialogModelMSF->createInstance( rServiceName ); - Reference< XMultiPropertySet > xMultiPropSet( xControlModel, UNO_QUERY_THROW ); - xMultiPropSet->setPropertyValues( rPropertyNames, rPropertyValues ); - mxDialogModelNameContainer->insertByName( rName, Any( xControlModel ) ); - } - catch( Exception& ) - { - } - return xControlModel; -} - - -void UnoDialog::setVisible( const OUString& rName, bool bVisible ) -{ - try - { - Reference< XInterface > xControl( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - Reference< XWindow > xWindow( xControl, UNO_QUERY_THROW ); - xWindow->setVisible( bVisible ); - } - catch ( Exception& ) - { - } -} - - -Reference< XButton > UnoDialog::insertButton( const OUString& rName, const Reference< XActionListener >& xActionListener, - const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XButton > xButton; - try - { - Reference< XInterface > xButtonModel( insertControlModel( "com.sun.star.awt.UnoControlButtonModel", - rName, rPropertyNames, rPropertyValues ) ); - Reference< XPropertySet > xPropertySet( xButtonModel, UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xButton.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - - if ( xActionListener.is() ) - { - xButton->addActionListener( xActionListener ); - xButton->setActionCommand( rName ); - } - return xButton; - } - catch( Exception& ) - { - } - return xButton; -} - - -Reference< XFixedText > UnoDialog::insertFixedText( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XFixedText > xFixedText; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlFixedTextModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xFixedText.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - } - catch ( Exception& ) - { - } - return xFixedText; -} - - -Reference< XCheckBox > UnoDialog::insertCheckBox( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XCheckBox > xCheckBox; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlCheckBoxModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xCheckBox.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - } - catch ( Exception& ) - { - } - return xCheckBox; -} - - -Reference< XControl > UnoDialog::insertFormattedField( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XControl > xControl; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlFormattedFieldModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xControl.set( mxDialog->getControl( rName ), UNO_SET_THROW ); - } - catch ( Exception& ) - { - } - return xControl; -} - - -Reference< XComboBox > UnoDialog::insertComboBox( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XComboBox > xControl; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlComboBoxModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xControl.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - } - catch ( Exception& ) - { - } - return xControl; -} - - -Reference< XRadioButton > UnoDialog::insertRadioButton( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XRadioButton > xControl; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlRadioButtonModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xControl.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - } - catch ( Exception& ) - { - } - return xControl; -} - - -Reference< XListBox > UnoDialog::insertListBox( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XListBox > xControl; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlListBoxModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xControl.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); - } - catch ( Exception& ) - { - } - return xControl; -} - - -Reference< XControl > UnoDialog::insertImage( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) -{ - Reference< XControl > xControl; - try - { - Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlImageControlModel", - rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue("Name", Any( rName ) ); - xControl.set( mxDialog->getControl( rName ), UNO_SET_THROW ); - } - catch ( Exception& ) - { - } - return xControl; -} - - -void UnoDialog::setControlProperty( const OUString& rControlName, const OUString& rPropertyName, const Any& rPropertyValue ) -{ - try - { - if ( mxDialogModelNameAccess->hasByName( rControlName ) ) - { - Reference< XPropertySet > xPropertySet( mxDialogModelNameAccess->getByName( rControlName ), UNO_QUERY_THROW ); - xPropertySet->setPropertyValue( rPropertyName, rPropertyValue ); - } - } - catch ( Exception& ) - { - } -} - - -Any UnoDialog::getControlProperty( const OUString& rControlName, const OUString& rPropertyName ) -{ - Any aRet; - try - { - if ( mxDialogModelNameAccess->hasByName( rControlName ) ) - { - Reference< XPropertySet > xPropertySet( mxDialogModelNameAccess->getByName( rControlName ), UNO_QUERY_THROW ); - aRet = xPropertySet->getPropertyValue( rPropertyName ); - } - } - catch ( Exception& ) - { - } - return aRet; -} - - -void UnoDialog::enableControl( const OUString& rControlName ) -{ - setControlProperty( rControlName, "Enabled", Any( true ) ); -} - - -void UnoDialog::disableControl( const OUString& rControlName ) -{ - setControlProperty( rControlName, "Enabled", Any( false ) ); -} - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/unodialog.hxx b/sdext/source/minimizer/unodialog.hxx deleted file mode 100644 index 3bf908cf15a9..000000000000 --- a/sdext/source/minimizer/unodialog.hxx +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_UNODIALOG_HXX -#define INCLUDED_SDEXT_SOURCE_MINIMIZER_UNODIALOG_HXX - -#include <com/sun/star/uno/Sequence.h> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/frame/XFrame.hpp> -#include <com/sun/star/beans/XMultiPropertySet.hpp> -#include <com/sun/star/awt/XControl.hpp> -#include <com/sun/star/awt/XControlModel.hpp> -#include <com/sun/star/container/XNameContainer.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/awt/XActionListener.hpp> -#include <com/sun/star/awt/XButton.hpp> -#include <com/sun/star/awt/XCheckBox.hpp> -#include <com/sun/star/awt/XComboBox.hpp> -#include <com/sun/star/awt/XRadioButton.hpp> -#include <com/sun/star/awt/XListBox.hpp> -#include <com/sun/star/awt/XFixedText.hpp> -#include <com/sun/star/awt/XUnoControlDialog.hpp> -#include <com/sun/star/awt/XReschedule.hpp> - - -class UnoDialog -{ -public: - - UnoDialog( const css::uno::Reference< css::uno::XComponentContext >& rxMSF, css::uno::Reference< css::frame::XFrame > const & rxFrame ); - ~UnoDialog(); - - void execute(); - void endExecute( bool bStatus ); - - css::uno::Reference< css::uno::XInterface > insertControlModel( const OUString& rServiceName, const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - void setVisible( const OUString& rName, bool bVisible ); - - css::uno::Reference< css::awt::XButton > insertButton( const OUString& rName, - const css::uno::Reference< css::awt::XActionListener >& xActionListener, const css::uno::Sequence< OUString >& rPropertyNames, - const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XFixedText > insertFixedText( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XCheckBox > insertCheckBox( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XControl > insertFormattedField( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XComboBox > insertComboBox( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XRadioButton > insertRadioButton( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XListBox > insertListBox( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - css::uno::Reference< css::awt::XControl > insertImage( const OUString& rName, - const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); - - void setControlProperty( const OUString& rControlName, const OUString& rPropertyName, const css::uno::Any& rPropertyValue ); - css::uno::Any getControlProperty( const OUString& rControlName, const OUString& rPropertyName ); - - void enableControl( const OUString& rControlName ); - void disableControl( const OUString& rControlName ); - - void reschedule() const { mxReschedule->reschedule(); } - bool endStatus() const { return mbStatus; } - css::uno::Reference<css::awt::XControl> getControl(const OUString& rControlName) const { return mxDialog->getControl(rControlName); } - const css::uno::Reference<css::frame::XController>& controller() const { return mxController; } - void setPropertyValues(const css::uno::Sequence<OUString>& rNameSeq, const css::uno::Sequence<css::uno::Any>& rValueSeq) - { mxDialogModelMultiPropertySet->setPropertyValues(rNameSeq, rValueSeq); } - -protected: - css::uno::Reference< css::uno::XComponentContext > mxContext; - css::uno::Reference< css::frame::XController > mxController; - -private: - css::uno::Reference< css::awt::XReschedule > mxReschedule; - css::uno::Reference< css::uno::XInterface > mxDialogModel; - css::uno::Reference< css::beans::XMultiPropertySet > mxDialogModelMultiPropertySet; - css::uno::Reference< css::lang::XMultiServiceFactory > mxDialogModelMSF; - css::uno::Reference< css::container::XNameContainer > mxDialogModelNameContainer; - css::uno::Reference< css::container::XNameAccess > mxDialogModelNameAccess; - - css::uno::Reference< css::awt::XControlModel > mxControlModel; - - css::uno::Reference< css::awt::XUnoControlDialog > mxDialog; - css::uno::Reference< css::awt::XControl > mxControl; - bool mbStatus; -}; - -#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_UNODIALOG_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/dialogs/xpdfimport_err.pdf b/sdext/source/pdfimport/dialogs/xpdfimport_err.pdf Binary files differdeleted file mode 100644 index dc0f9292c680..000000000000 --- a/sdext/source/pdfimport/dialogs/xpdfimport_err.pdf +++ /dev/null diff --git a/sdext/source/pdfimport/filterdet.cxx b/sdext/source/pdfimport/filterdet.cxx index 7e6e72f4d707..d9fdcc03c6ab 100644 --- a/sdext/source/pdfimport/filterdet.cxx +++ b/sdext/source/pdfimport/filterdet.cxx @@ -35,8 +35,10 @@ #include <comphelper/fileurl.hxx> #include <comphelper/hash.hxx> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> +#include <tools/stream.hxx> #include <memory> +#include <utility> #include <string.h> using namespace com::sun::star; @@ -78,10 +80,7 @@ FileEmitContext::FileEmitContext( const OUString& rOr const pdfparse::PDFContainer* pTop ) : pdfparse::EmitContext( pTop ), m_aReadHandle(nullptr), - m_nReadLen(0), - m_xContextStream(), - m_xSeek(), - m_xOut() + m_nReadLen(0) { m_xContextStream.set( io::TempFile::create(xContext), uno::UNO_QUERY_THROW ); m_xOut = m_xContextStream->getOutputStream(); @@ -185,200 +184,250 @@ unsigned int FileEmitContext::readOrigBytes( unsigned int nOrigOffset, unsigned } -PDFDetector::PDFDetector( const uno::Reference< uno::XComponentContext >& xContext) : - PDFDetectorBase( m_aMutex ), - m_xContext( xContext ) +PDFDetector::PDFDetector( uno::Reference< uno::XComponentContext > xContext) : + m_xContext(std::move( xContext )) {} -// XExtendedFilterDetection -OUString SAL_CALL PDFDetector::detect( uno::Sequence< beans::PropertyValue >& rFilterData ) +namespace { - osl::MutexGuard const guard( m_aMutex ); - bool bSuccess = false; - // get the InputStream carrying the PDF content - uno::Reference< io::XInputStream > xInput; - uno::Reference< io::XStream > xEmbedStream; - OUString aOutFilterName, aOutTypeName; - OUString aURL; - OUString aPwd; +sal_Int32 fillAttributes(uno::Sequence<beans::PropertyValue> const& rFilterData, uno::Reference<io::XInputStream>& xInput, OUString& aURL, sal_Int32& nFilterNamePos, sal_Int32& nPasswordPos, OUString& aPassword) +{ const beans::PropertyValue* pAttribs = rFilterData.getConstArray(); sal_Int32 nAttribs = rFilterData.getLength(); - sal_Int32 nFilterNamePos = -1; - sal_Int32 nPwdPos = -1; - for( sal_Int32 i = 0; i < nAttribs; i++ ) + for (sal_Int32 i = 0; i < nAttribs; i++) { OUString aVal( "<no string>" ); pAttribs[i].Value >>= aVal; - SAL_INFO( "sdext.pdfimport", "doDetection: Attrib: " + pAttribs[i].Name + " = " + aVal); + SAL_INFO("sdext.pdfimport", "doDetection: Attrib: " + pAttribs[i].Name + " = " + aVal); - if ( pAttribs[i].Name == "InputStream" ) + if (pAttribs[i].Name == "InputStream") pAttribs[i].Value >>= xInput; - else if ( pAttribs[i].Name == "URL" ) + else if (pAttribs[i].Name == "URL") pAttribs[i].Value >>= aURL; - else if ( pAttribs[i].Name == "FilterName" ) + else if (pAttribs[i].Name == "FilterName") nFilterNamePos = i; - else if ( pAttribs[i].Name == "Password" ) + else if (pAttribs[i].Name == "Password") { - nPwdPos = i; - pAttribs[i].Value >>= aPwd; + nPasswordPos = i; + pAttribs[i].Value >>= aPassword; } } - if( xInput.is() ) + return nAttribs; +} + +// read the first 1024 byte (see PDF reference implementation note 12) +constexpr const sal_Int32 constHeaderSize = 1024; + +bool detectPDF(uno::Reference<io::XInputStream> const& xInput, uno::Sequence<sal_Int8>& aHeader, sal_uInt64& nHeaderReadSize) +{ + try { - oslFileHandle aFile = nullptr; - try { - uno::Reference< io::XSeekable > xSeek( xInput, uno::UNO_QUERY ); - if( xSeek.is() ) - xSeek->seek( 0 ); - // read the first 1024 byte (see PDF reference implementation note 12) - const sal_Int32 nHeaderSize = 1024; - uno::Sequence< sal_Int8 > aBuf( nHeaderSize ); - sal_uInt64 nBytes = xInput->readBytes( aBuf, nHeaderSize ); - if( nBytes > 5 ) + uno::Reference<io::XSeekable> xSeek(xInput, uno::UNO_QUERY); + if (xSeek.is()) + xSeek->seek(0); + + nHeaderReadSize = xInput->readBytes(aHeader, constHeaderSize); + if (nHeaderReadSize <= 5) + return false; + + const sal_Int8* pBytes = aHeader.getConstArray(); + for (sal_uInt64 i = 0; i < nHeaderReadSize - 5; i++) + { + if (pBytes[i+0] == '%' && + pBytes[i+1] == 'P' && + pBytes[i+2] == 'D' && + pBytes[i+3] == 'F' && + pBytes[i+4] == '-') { - const sal_Int8* pBytes = aBuf.getConstArray(); - for( sal_uInt64 i = 0; i < nBytes-5; i++ ) - { - if( pBytes[i] == '%' && - pBytes[i+1] == 'P' && - pBytes[i+2] == 'D' && - pBytes[i+3] == 'F' && - pBytes[i+4] == '-' ) - { - bSuccess = true; - break; - } - } + return true; } + } + } + catch (const css::io::IOException &) + { + TOOLS_WARN_EXCEPTION("sdext.pdfimport", "caught"); + } + return false; +} - // check for hybrid PDF - if( bSuccess && - ( aURL.isEmpty() || !comphelper::isFileUrl(aURL) ) - ) +bool copyToTemp(uno::Reference<io::XInputStream> const& xInput, oslFileHandle& rFileHandle, uno::Sequence<sal_Int8> const& aHeader, sal_uInt64 nHeaderReadSize) +{ + try + { + sal_uInt64 nWritten = 0; + osl_writeFile(rFileHandle, aHeader.getConstArray(), nHeaderReadSize, &nWritten); + + const sal_uInt64 nBufferSize = 4096; + uno::Sequence<sal_Int8> aBuffer(nBufferSize); + + // copy the bytes + sal_uInt64 nRead = 0; + do + { + nRead = xInput->readBytes(aBuffer, nBufferSize); + if (nRead > 0) { - sal_uInt64 nWritten = 0; - if( osl_createTempFile( nullptr, &aFile, &aURL.pData ) != osl_File_E_None ) - { - bSuccess = false; - } - else - { - SAL_INFO( "sdext.pdfimport", "created temp file " + aURL ); + osl_writeFile(rFileHandle, aBuffer.getConstArray(), nRead, &nWritten); + if (nWritten != nRead) + return false; + } + } + while (nRead == nBufferSize); + } + catch (const css::io::IOException &) + { + TOOLS_WARN_EXCEPTION("sdext.pdfimport", "caught"); + } + return false; +} - osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten ); +} // end anonymous namespace - SAL_WARN_IF( nWritten != nBytes, "sdext.pdfimport", "writing of header bytes failed" ); +// XExtendedFilterDetection +OUString SAL_CALL PDFDetector::detect( uno::Sequence< beans::PropertyValue >& rFilterData ) +{ + std::unique_lock guard( m_aMutex ); + bool bSuccess = false; - if( nWritten == nBytes ) - { - const sal_uInt32 nBufSize = 4096; - aBuf = uno::Sequence<sal_Int8>(nBufSize); - // copy the bytes - do - { - nBytes = xInput->readBytes( aBuf, nBufSize ); - if( nBytes > 0 ) - { - osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten ); - if( nWritten != nBytes ) - { - bSuccess = false; - break; - } - } - } while( nBytes == nBufSize ); - } - } - osl_closeFile( aFile ); - } - } catch (const css::io::IOException &) { - TOOLS_WARN_EXCEPTION("sdext.pdfimport", "caught"); - return OUString(); + // get the InputStream carrying the PDF content + uno::Reference<io::XInputStream> xInput; + uno::Reference<io::XStream> xEmbedStream; + OUString aOutFilterName; + OUString aOutTypeName; + OUString aURL; + OUString aPassword; + + sal_Int32 nFilterNamePos = -1; + sal_Int32 nPasswordPos = -1; + sal_Int32 nAttribs = fillAttributes(rFilterData, xInput, aURL, nFilterNamePos, nPasswordPos, aPassword); + + if (!xInput.is()) + return OUString(); + + + uno::Sequence<sal_Int8> aHeader(constHeaderSize); + sal_uInt64 nHeaderReadSize = 0; + bSuccess = detectPDF(xInput, aHeader, nHeaderReadSize); + + if (!bSuccess) + return OUString(); + + oslFileHandle aFileHandle = nullptr; + + // check for hybrid PDF + if (bSuccess && (aURL.isEmpty() || !comphelper::isFileUrl(aURL))) + { + if (osl_createTempFile(nullptr, &aFileHandle, &aURL.pData) != osl_File_E_None) + { + bSuccess = false; } - OUString aEmbedMimetype; - xEmbedStream = getAdditionalStream( aURL, aEmbedMimetype, aPwd, m_xContext, rFilterData, false ); - if( aFile ) - osl_removeFile( aURL.pData ); - if( !aEmbedMimetype.isEmpty() ) + else { - if( aEmbedMimetype == "application/vnd.oasis.opendocument.text" - || aEmbedMimetype == "application/vnd.oasis.opendocument.text-master" ) - aOutFilterName = "writer_pdf_addstream_import"; - else if ( aEmbedMimetype == "application/vnd.oasis.opendocument.presentation" ) - aOutFilterName = "impress_pdf_addstream_import"; - else if( aEmbedMimetype == "application/vnd.oasis.opendocument.graphics" - || aEmbedMimetype == "application/vnd.oasis.opendocument.drawing" ) - aOutFilterName = "draw_pdf_addstream_import"; - else if ( aEmbedMimetype == "application/vnd.oasis.opendocument.spreadsheet" ) - aOutFilterName = "calc_pdf_addstream_import"; + SAL_INFO( "sdext.pdfimport", "created temp file " + aURL); + bSuccess = copyToTemp(xInput, aFileHandle, aHeader, nHeaderReadSize); } + osl_closeFile(aFileHandle); } - if( bSuccess ) + if (!bSuccess) + { + if (aFileHandle) + osl_removeFile(aURL.pData); + return OUString(); + } + + OUString aEmbedMimetype; + xEmbedStream = getAdditionalStream(aURL, aEmbedMimetype, aPassword, m_xContext, rFilterData, false); + + if (aFileHandle) + osl_removeFile(aURL.pData); + + if (!aEmbedMimetype.isEmpty()) { - if( !aOutFilterName.isEmpty() ) + if( aEmbedMimetype == "application/vnd.oasis.opendocument.text" + || aEmbedMimetype == "application/vnd.oasis.opendocument.text-master" ) + aOutFilterName = "writer_pdf_addstream_import"; + else if ( aEmbedMimetype == "application/vnd.oasis.opendocument.presentation" ) + aOutFilterName = "impress_pdf_addstream_import"; + else if( aEmbedMimetype == "application/vnd.oasis.opendocument.graphics" + || aEmbedMimetype == "application/vnd.oasis.opendocument.drawing" ) + aOutFilterName = "draw_pdf_addstream_import"; + else if ( aEmbedMimetype == "application/vnd.oasis.opendocument.spreadsheet" ) + aOutFilterName = "calc_pdf_addstream_import"; + } + + if (!aOutFilterName.isEmpty()) + { + if( nFilterNamePos == -1 ) { - if( nFilterNamePos == -1 ) - { - nFilterNamePos = nAttribs; - rFilterData.realloc( ++nAttribs ); - rFilterData[ nFilterNamePos ].Name = "FilterName"; - } - aOutTypeName = "pdf_Portable_Document_Format"; + nFilterNamePos = nAttribs; + rFilterData.realloc( ++nAttribs ); + rFilterData.getArray()[ nFilterNamePos ].Name = "FilterName"; + } + auto pFilterData = rFilterData.getArray(); + aOutTypeName = "pdf_Portable_Document_Format"; - rFilterData[nFilterNamePos].Value <<= aOutFilterName; - if( xEmbedStream.is() ) - { - rFilterData.realloc( ++nAttribs ); - rFilterData[nAttribs-1].Name = "EmbeddedSubstream"; - rFilterData[nAttribs-1].Value <<= xEmbedStream; - } - if( !aPwd.isEmpty() ) - { - if( nPwdPos == -1 ) - { - nPwdPos = nAttribs; - rFilterData.realloc( ++nAttribs ); - rFilterData[ nPwdPos ].Name = "Password"; - } - rFilterData[ nPwdPos ].Value <<= aPwd; - } + pFilterData[nFilterNamePos].Value <<= aOutFilterName; + if( xEmbedStream.is() ) + { + rFilterData.realloc( ++nAttribs ); + pFilterData = rFilterData.getArray(); + pFilterData[nAttribs-1].Name = "EmbeddedSubstream"; + pFilterData[nAttribs-1].Value <<= xEmbedStream; } - else + if (!aPassword.isEmpty()) { - if( nFilterNamePos == -1 ) + if (nPasswordPos == -1) { - nFilterNamePos = nAttribs; - rFilterData.realloc( ++nAttribs ); - rFilterData[ nFilterNamePos ].Name = "FilterName"; + nPasswordPos = nAttribs; + rFilterData.realloc(++nAttribs); + pFilterData = rFilterData.getArray(); + pFilterData[nPasswordPos].Name = "Password"; } + pFilterData[nPasswordPos].Value <<= aPassword; + } + } + else + { + css::beans::PropertyValue* pFilterData; + if( nFilterNamePos == -1 ) + { + nFilterNamePos = nAttribs; + rFilterData.realloc( ++nAttribs ); + pFilterData = rFilterData.getArray(); + pFilterData[ nFilterNamePos ].Name = "FilterName"; + } + else + pFilterData = rFilterData.getArray(); - const sal_Int32 nDocumentType = 0; //const sal_Int32 nDocumentType = queryDocumentTypeDialog(m_xContext,aURL); - if( nDocumentType < 0 ) - { - return OUString(); - } - else switch( nDocumentType ) + const sal_Int32 nDocumentType = 0; //const sal_Int32 nDocumentType = queryDocumentTypeDialog(m_xContext,aURL); + if( nDocumentType < 0 ) + { + return OUString(); + } + else + { + switch (nDocumentType) { case 0: - rFilterData[nFilterNamePos].Value <<= OUString( "draw_pdf_import" ); + pFilterData[nFilterNamePos].Value <<= OUString( "draw_pdf_import" ); break; case 1: - rFilterData[nFilterNamePos].Value <<= OUString( "impress_pdf_import" ); + pFilterData[nFilterNamePos].Value <<= OUString( "impress_pdf_import" ); break; case 2: - rFilterData[nFilterNamePos].Value <<= OUString( "writer_pdf_import" ); + pFilterData[nFilterNamePos].Value <<= OUString( "writer_pdf_import" ); break; default: assert(!"Unexpected case"); } - - aOutTypeName = "pdf_Portable_Document_Format"; } + + aOutTypeName = "pdf_Portable_Document_Format"; } return aOutTypeName; @@ -464,6 +513,40 @@ bool checkDocChecksum( const OUString& rInPDFFileURL, && (0 == memcmp(nChecksum.data(), nTestChecksum, nChecksum.size())); } +/* https://github.com/CollaboraOnline/online/issues/7307 + + Light-weight detection to determine if this is a hybrid + pdf document worth parsing to get its AdditionalStream + and mimetype. + + TODO: a) do we really ignore the contents of the AdditionalStream + and re-parse to get it in the final importer? + b) in which case we could presumably parse the mimetype in + AdditionalStream here and drop the extraction of the stream. +*/ +static bool detectHasAdditionalStreams(const OUString& rSysUPath) +{ + SvFileStream aHybridDetect(rSysUPath, StreamMode::READ); + std::vector<OString> aTrailingLines; + const sal_uInt64 nLen = aHybridDetect.remainingSize(); + aHybridDetect.Seek(nLen - std::min<sal_uInt64>(nLen, 4096)); + OString aLine; + while (aHybridDetect.ReadLine(aLine)) + aTrailingLines.push_back(aLine); + bool bAdditionalStreams(false); + for (auto it = aTrailingLines.rbegin(); it != aTrailingLines.rend(); ++it) + { + if (*it == "trailer") + break; + if (it->startsWith("/AdditionalStreams ")) + { + bAdditionalStreams = true; + break; + } + } + return bAdditionalStreams; +} + uno::Reference< io::XStream > getAdditionalStream( const OUString& rInPDFFileURL, OUString& rOutMimetype, OUString& io_rPwd, @@ -472,13 +555,14 @@ uno::Reference< io::XStream > getAdditionalStream( const OUString& bool bMayUseUI ) { uno::Reference< io::XStream > xEmbed; - OString aPDFFile; OUString aSysUPath; if( osl_getSystemPathFromFileURL( rInPDFFileURL.pData, &aSysUPath.pData ) != osl_File_E_None ) return xEmbed; - aPDFFile = OUStringToOString( aSysUPath, osl_getThreadTextEncoding() ); - std::unique_ptr<pdfparse::PDFEntry> pEntry( pdfparse::PDFReader::read( aPDFFile.getStr() )); + if (!detectHasAdditionalStreams(aSysUPath)) + return xEmbed; + + std::unique_ptr<pdfparse::PDFEntry> pEntry(pdfparse::PDFReader::read(aSysUPath)); if( pEntry ) { pdfparse::PDFFile* pPDFFile = dynamic_cast<pdfparse::PDFFile*>(pEntry.get()); @@ -491,7 +575,7 @@ uno::Reference< io::XStream > getAdditionalStream( const OUString& if( pTrailer && pTrailer->m_pDict ) { // search document checksum entry - auto chk = pTrailer->m_pDict->m_aMap.find( "DocChecksum" ); + auto chk = pTrailer->m_pDict->m_aMap.find( "DocChecksum"_ostr ); if( chk == pTrailer->m_pDict->m_aMap.end() ) { SAL_INFO( "sdext.pdfimport", "no DocChecksum entry" ); @@ -505,7 +589,7 @@ uno::Reference< io::XStream > getAdditionalStream( const OUString& } // search for AdditionalStreams entry - auto add_stream = pTrailer->m_pDict->m_aMap.find( "AdditionalStreams" ); + auto add_stream = pTrailer->m_pDict->m_aMap.find( "AdditionalStreams"_ostr ); if( add_stream == pTrailer->m_pDict->m_aMap.end() ) { SAL_INFO( "sdext.pdfimport", "no AdditionalStreams entry" ); @@ -543,7 +627,7 @@ uno::Reference< io::XStream > getAdditionalStream( const OUString& { OString aIsoPwd = OUStringToOString( io_rPwd, RTL_TEXTENCODING_ISO_8859_1 ); - bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() ); + bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd ); } if( ! bAuthenticated ) { @@ -568,7 +652,7 @@ uno::Reference< io::XStream > getAdditionalStream( const OUString& bEntered = getPassword( xIntHdl, io_rPwd, ! bEntered, aDocName ); OString aIsoPwd = OUStringToOString( io_rPwd, RTL_TEXTENCODING_ISO_8859_1 ); - bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() ); + bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd ); } while( bEntered && ! bAuthenticated ); } diff --git a/sdext/source/pdfimport/filterdet.hxx b/sdext/source/pdfimport/filterdet.hxx index 6ed195d3bb03..48bc8ca4e12a 100644 --- a/sdext/source/pdfimport/filterdet.hxx +++ b/sdext/source/pdfimport/filterdet.hxx @@ -17,34 +17,32 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_FILTERDET_HXX -#define INCLUDED_SDEXT_SOURCE_PDFIMPORT_FILTERDET_HXX +#pragma once #include <com/sun/star/document/XExtendedFilterDetection.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/io/XStream.hpp> -#include <cppuhelper/compbase.hxx> +#include <comphelper/compbase.hxx> #include <cppuhelper/basemutex.hxx> namespace pdfi { -typedef ::cppu::WeakComponentImplHelper< +typedef ::comphelper::WeakComponentImplHelper< css::document::XExtendedFilterDetection, css::lang::XServiceInfo> PDFDetectorBase; -class PDFDetector : private cppu::BaseMutex, - public PDFDetectorBase +class PDFDetector : public PDFDetectorBase { private: css::uno::Reference< css::uno::XComponentContext > m_xContext; public: - explicit PDFDetector( const css::uno::Reference< - css::uno::XComponentContext >& xContext ); + explicit PDFDetector( css::uno::Reference< + css::uno::XComponentContext > xContext ); // XExtendedFilterDetection virtual OUString SAL_CALL detect( css::uno::Sequence< @@ -100,6 +98,4 @@ bool checkDocChecksum( const OUString& rInPDFFileURL, } -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/inc/contentsink.hxx b/sdext/source/pdfimport/inc/contentsink.hxx index dbe1b0e08808..5354e4370f14 100644 --- a/sdext/source/pdfimport/inc/contentsink.hxx +++ b/sdext/source/pdfimport/inc/contentsink.hxx @@ -48,14 +48,14 @@ namespace pdfi { struct FontAttributes { - FontAttributes( const OUString& familyName_, - bool isBold_, + FontAttributes( OUString familyName_, + OUString sFontWeight, bool isItalic_, bool isUnderline_, double size_, double ascent_) : - familyName(familyName_), - isBold(isBold_), + familyName(std::move(familyName_)), + fontWeight(std::move(sFontWeight)), isItalic(isItalic_), isUnderline(isUnderline_), isOutline(false), @@ -65,7 +65,7 @@ namespace pdfi FontAttributes() : familyName(), - isBold(false), + fontWeight(u"normal"_ustr), isItalic(false), isUnderline(false), isOutline(false), @@ -74,7 +74,7 @@ namespace pdfi {} OUString familyName; - bool isBold; + OUString fontWeight; bool isItalic; bool isUnderline; bool isOutline; @@ -84,7 +84,7 @@ namespace pdfi bool operator==(const FontAttributes& rFont) const { return familyName == rFont.familyName && - !isBold == !rFont.isBold && + fontWeight == rFont.fontWeight && !isItalic == !rFont.isItalic && !isUnderline == !rFont.isUnderline && !isOutline == !rFont.isOutline && @@ -171,6 +171,11 @@ namespace pdfi css::beans::PropertyValue>& xImage, const css::uno::Sequence< css::beans::PropertyValue>& xMask) = 0; + virtual void tilingPatternFill(int nX0, int nY0, int nX1, int nY1, + double nxStep, double nyStep, + int nPaintType, + css::geometry::AffineMatrix2D& rMat, + const css::uno::Sequence<css::beans::PropertyValue>& xTile) = 0; }; typedef std::shared_ptr<ContentSink> ContentSinkSharedPtr; diff --git a/sdext/source/pdfimport/inc/genericelements.hxx b/sdext/source/pdfimport/inc/genericelements.hxx index ff0ba6f52d84..705773b9893a 100644 --- a/sdext/source/pdfimport/inc/genericelements.hxx +++ b/sdext/source/pdfimport/inc/genericelements.hxx @@ -25,6 +25,7 @@ #include <com/sun/star/task/XStatusIndicator.hpp> #include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/i18n/BreakIterator.hpp> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <rtl/ustring.hxx> #include <rtl/ustrbuf.hxx> @@ -92,6 +93,10 @@ namespace pdfi /// Union element geometry with given element void updateGeometryWith( const Element* pMergeFrom ); + /// To avoid some dynamic_cast cost + virtual const TextElement* dynCastAsTextElement() const { return nullptr; } + virtual TextElement* dynCastAsTextElement() { return nullptr; } + #if OSL_DEBUG_LEVEL > 0 // xxx refact TODO: move code to visitor virtual void emitStructure( int nLevel ); @@ -107,16 +112,15 @@ namespace pdfi std::list<std::unique_ptr<Element>> Children; }; - struct ListElement : public Element + struct ListElement final : public Element { ListElement() : Element( nullptr ) {} virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; }; - struct HyperlinkElement : public Element + struct HyperlinkElement final : public Element { friend class ElementFactory; - protected: HyperlinkElement( Element* pParent, const OUString& rURI ) : Element( pParent ), URI( rURI ) {} public: @@ -157,10 +161,9 @@ namespace pdfi sal_Int32 ZOrder; }; - struct FrameElement : public DrawElement + struct FrameElement final : public DrawElement { friend class ElementFactory; - protected: FrameElement( Element* pParent, sal_Int32 nGCId ) : DrawElement( pParent, nGCId ) {} @@ -168,24 +171,25 @@ namespace pdfi virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; }; - struct TextElement : public GraphicalElement + struct TextElement final : public GraphicalElement { friend class ElementFactory; - protected: TextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId ) : GraphicalElement( pParent, nGCId ), FontId( nFontId ) {} public: virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; + virtual const TextElement* dynCastAsTextElement() const override { return this; } + virtual TextElement* dynCastAsTextElement() override { return this; } + OUStringBuffer Text; sal_Int32 FontId; }; - struct ParagraphElement : public Element + struct ParagraphElement final : public Element { friend class ElementFactory; - protected: explicit ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ), bRtl( false ) {} public: @@ -204,13 +208,13 @@ namespace pdfi bool bRtl; }; - struct PolyPolyElement : public DrawElement + struct PolyPolyElement final : public DrawElement { friend class ElementFactory; - protected: PolyPolyElement( Element* pParent, sal_Int32 nGCId, const basegfx::B2DPolyPolygon& rPolyPoly, - sal_Int8 nAction ); + sal_Int8 nAction, ImageId nFillImage, + double nTileWidth, double nTileHeight ); public: virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override; @@ -222,12 +226,14 @@ namespace pdfi basegfx::B2DPolyPolygon PolyPoly; sal_Int8 Action; + ImageId FillImage; + double TileWidth; + double TileHeight; }; - struct ImageElement : public DrawElement + struct ImageElement final : public DrawElement { friend class ElementFactory; - protected: ImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage ) : DrawElement( pParent, nGCId ), Image( nImage ) {} @@ -237,10 +243,9 @@ namespace pdfi ImageId Image; }; - struct PageElement : public Element + struct PageElement final : public Element { friend class ElementFactory; - protected: PageElement( Element* pParent, sal_Int32 nPageNr ) : Element( pParent ), PageNumber( nPageNr ), Hyperlinks(), TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 ) @@ -267,7 +272,7 @@ namespace pdfi std::unique_ptr<Element> FooterElement; }; - struct DocumentElement : public Element + struct DocumentElement final : public Element { friend class ElementFactory; public: @@ -298,8 +303,10 @@ namespace pdfi createPolyPolyElement( Element* pParent, sal_Int32 nGCId, const basegfx::B2DPolyPolygon& rPolyPoly, - sal_Int8 nAction) - { return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction ); } + sal_Int8 nAction, ImageId nFillImage, + double nTileWidth, double nTileHeight ) + { return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction, + nFillImage, nTileWidth, nTileHeight ); } static ImageElement* createImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage ) { return new ImageElement( pParent, nGCId, nImage ); } @@ -309,6 +316,8 @@ namespace pdfi static std::shared_ptr<DocumentElement> createDocumentElement() { return std::make_shared<DocumentElement>(); } }; + + bool isComplex(const css::uno::Reference<css::i18n::XBreakIterator>& rBreakIterator, TextElement* const pTextElem); } #endif diff --git a/sdext/source/pdfimport/inc/imagecontainer.hxx b/sdext/source/pdfimport/inc/imagecontainer.hxx index d21ed7504f63..03672e8ca8b2 100644 --- a/sdext/source/pdfimport/inc/imagecontainer.hxx +++ b/sdext/source/pdfimport/inc/imagecontainer.hxx @@ -42,6 +42,7 @@ namespace pdfi ImageId addImage( const css::uno::Sequence< css::beans::PropertyValue>& xBitmap ); void writeBase64EncodedStream( ImageId nImageId, EmitContext& rContext ); + OUString asBase64EncodedString( ImageId nId ) const; }; } diff --git a/sdext/source/pdfimport/inc/pdfihelper.hxx b/sdext/source/pdfimport/inc/pdfihelper.hxx index aa3a22bd2b67..c6be1a6ba73e 100644 --- a/sdext/source/pdfimport/inc/pdfihelper.hxx +++ b/sdext/source/pdfimport/inc/pdfihelper.hxx @@ -64,9 +64,12 @@ namespace pdfi return fMM; } + /// round to 2 decimal places inline double convPx2mmPrec2( double fPix ) { - return rtl_math_round( convPx2mm( fPix ), 2, rtl_math_RoundingMode_Floor ); + constexpr double px2mm = 25.4/PDFI_OUTDEV_RESOLUTION; + double mm = fPix * ( px2mm * 100); + return std::floor(mm) / 100; } /// Convert color to "#FEFEFE" color notation @@ -82,7 +85,7 @@ namespace pdfi { std::size_t seed = 0; o3tl::hash_combine(seed, rFont.familyName.hashCode()); - o3tl::hash_combine(seed, rFont.isBold); + o3tl::hash_combine(seed, rFont.fontWeight); o3tl::hash_combine(seed, rFont.isItalic); o3tl::hash_combine(seed, rFont.isUnderline); o3tl::hash_combine(seed, rFont.isOutline); diff --git a/sdext/source/pdfimport/inc/pdfiprocessor.hxx b/sdext/source/pdfimport/inc/pdfiprocessor.hxx index 3305f0bf715e..11b7761d1738 100644 --- a/sdext/source/pdfimport/inc/pdfiprocessor.hxx +++ b/sdext/source/pdfimport/inc/pdfiprocessor.hxx @@ -20,6 +20,7 @@ #ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_PDFIPROCESSOR_HXX #define INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_PDFIPROCESSOR_HXX +#include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/task/XStatusIndicator.hpp> #include <com/sun/star/geometry/RealSize2D.hpp> #include <com/sun/star/geometry/RealRectangle2D.hpp> @@ -52,7 +53,7 @@ namespace pdfi Creates the internal DOM tree from the render calls */ - class PDFIProcessor : public ContentSink + class PDFIProcessor final : public ContentSink { public: css::uno::Reference< @@ -70,6 +71,7 @@ namespace pdfi const GraphicsContext& getGraphicsContext( sal_Int32 nGCId ) const; GraphicsContext& getCurrentContext() { return m_aGCStack.back(); } const GraphicsContext& getCurrentContext() const { return m_aGCStack.back(); } + const ImageContainer& getImages() const { return m_aImages; }; const css::uno::Reference< css::task::XStatusIndicator >& getStatusIndicator() const { return m_xStatusIndicator; } @@ -79,7 +81,7 @@ namespace pdfi static void sortElements( Element* pElement ); - static OUString mirrorString( const OUString& i_rInString ); + static OUString SubstituteBidiMirrored(std::u16string_view rString); private: void processGlyphLine(); @@ -149,6 +151,12 @@ namespace pdfi const css::uno::Sequence< css::beans::PropertyValue>& xMask) override; + virtual void tilingPatternFill(int nX0, int nY0, int nX1, int nY1, + double nxStep, double nyStep, + int nPaintType, + css::geometry::AffineMatrix2D& rMat, + const css::uno::Sequence<css::beans::PropertyValue>& xTile) override; + void startIndicator( const OUString& rText ); void endIndicator(); diff --git a/sdext/source/pdfimport/inc/pdfparse.hxx b/sdext/source/pdfimport/inc/pdfparse.hxx index abb674a48d22..542a9ed4b1a5 100644 --- a/sdext/source/pdfimport/inc/pdfparse.hxx +++ b/sdext/source/pdfimport/inc/pdfparse.hxx @@ -26,6 +26,7 @@ #include <string_view> #include <unordered_map> +#include <utility> #include <vector> #include <memory> @@ -68,12 +69,12 @@ protected: static void setEmitData( EmitContext& rContext, EmitImplData* pNewEmitData ); }; -struct PDFComment : public PDFEntry +struct PDFComment final : public PDFEntry { OString m_aComment; - explicit PDFComment( const OString& rComment ) - : PDFEntry(), m_aComment( rComment ) {} + explicit PDFComment( OString aComment ) + : PDFEntry(), m_aComment(std::move( aComment )) {} virtual ~PDFComment() override; virtual bool emit( EmitContext& rWriteContext ) const override; virtual PDFEntry* clone() const override; @@ -86,12 +87,12 @@ struct PDFValue : public PDFEntry virtual ~PDFValue() override; }; -struct PDFName : public PDFValue +struct PDFName final : public PDFValue { OString m_aName; - explicit PDFName( const OString& rName ) - : PDFValue(), m_aName( rName ) {} + explicit PDFName( OString aName ) + : PDFValue(), m_aName(std::move( aName )) {} virtual ~PDFName() override; virtual bool emit( EmitContext& rWriteContext ) const override; virtual PDFEntry* clone() const override; @@ -99,12 +100,12 @@ struct PDFName : public PDFValue OUString getFilteredName() const; }; -struct PDFString : public PDFValue +struct PDFString final : public PDFValue { OString m_aString; - explicit PDFString( const OString& rString ) - : PDFValue(), m_aString( rString ) {} + explicit PDFString( OString aString ) + : PDFValue(), m_aString(std::move( aString )) {} virtual ~PDFString() override; virtual bool emit( EmitContext& rWriteContext ) const override; virtual PDFEntry* clone() const override; @@ -112,7 +113,7 @@ struct PDFString : public PDFValue OString getFilteredString() const; }; -struct PDFNumber : public PDFValue +struct PDFNumber final : public PDFValue { double m_fValue; @@ -123,7 +124,7 @@ struct PDFNumber : public PDFValue virtual PDFEntry* clone() const override; }; -struct PDFBool : public PDFValue +struct PDFBool final : public PDFValue { bool m_bValue; @@ -134,7 +135,7 @@ struct PDFBool : public PDFValue virtual PDFEntry* clone() const override; }; -struct PDFObjectRef : public PDFValue +struct PDFObjectRef final : public PDFValue { unsigned int m_nNumber; unsigned int m_nGeneration; @@ -146,7 +147,7 @@ struct PDFObjectRef : public PDFValue virtual PDFEntry* clone() const override; }; -struct PDFNull : public PDFValue +struct PDFNull final : public PDFValue { PDFNull() {} virtual ~PDFNull() override; @@ -172,7 +173,7 @@ struct PDFContainer : public PDFEntry { return findObject( pRef->m_nNumber, pRef->m_nGeneration ); } }; -struct PDFArray : public PDFContainer +struct PDFArray final : public PDFContainer { PDFArray() {} virtual ~PDFArray() override; @@ -180,7 +181,7 @@ struct PDFArray : public PDFContainer virtual PDFEntry* clone() const override; }; -struct PDFDict : public PDFContainer +struct PDFDict final : public PDFContainer { typedef std::unordered_map<OString,PDFEntry*> Map; Map m_aMap; @@ -200,7 +201,7 @@ struct PDFDict : public PDFContainer PDFEntry* buildMap(); }; -struct PDFStream : public PDFEntry +struct PDFStream final : public PDFEntry { unsigned int m_nBeginOffset; unsigned int m_nEndOffset; // offset of the byte after the stream @@ -215,7 +216,7 @@ struct PDFStream : public PDFEntry unsigned int getDictLength( const PDFContainer* pObjectContainer ) const; // get contents of the "Length" entry of the dict }; -struct PDFTrailer : public PDFContainer +struct PDFTrailer final : public PDFContainer { PDFDict* m_pDict; @@ -226,7 +227,7 @@ struct PDFTrailer : public PDFContainer }; struct PDFFileImplData; -struct PDFFile : public PDFContainer +struct PDFFile final : public PDFContainer { private: mutable std::unique_ptr<PDFFileImplData> m_pData; @@ -255,7 +256,7 @@ public: unsigned int nObject, unsigned int nGeneration ) const; }; -struct PDFObject : public PDFContainer +struct PDFObject final : public PDFContainer { PDFEntry* m_pObject; PDFStream* m_pStream; @@ -279,7 +280,7 @@ private: bool getDeflatedStream( std::unique_ptr<char[]>& rpStream, unsigned int* pBytes, const PDFContainer* pObjectContainer, EmitContext& rContext ) const; }; -struct PDFPart : public PDFContainer +struct PDFPart final : public PDFContainer { PDFPart() : PDFContainer() {} virtual ~PDFPart() override; @@ -291,10 +292,7 @@ struct PDFReader { PDFReader() = delete; - static std::unique_ptr<PDFEntry> read( const char* pFileName ); -#ifdef _WIN32 - static std::unique_ptr<PDFEntry> read( const char* pBuffer, unsigned int nLen ); -#endif + static std::unique_ptr<PDFEntry> read(std::u16string_view aFileName); }; } // namespace diff --git a/sdext/source/pdfimport/inc/wrapper.hxx b/sdext/source/pdfimport/inc/wrapper.hxx index 68e383de6a1a..a27e92e28931 100644 --- a/sdext/source/pdfimport/inc/wrapper.hxx +++ b/sdext/source/pdfimport/inc/wrapper.hxx @@ -52,6 +52,41 @@ namespace pdfi const css::uno::Reference< css::uno::XComponentContext >& xContext, const OUString& rFilterOptions ); + + constexpr OUString fontAttributesSuffixes[] = { + // Note: for performance consideration, each one listed here is evaluated once, + // and they are checked from the suffix, thus the order matters. + // e.g. for "TimesNewRomanPS-BoldItalic", to get "TimesNewRoman", you should + // first have "Italic", and then "Bold", then "-", and then "PS". + u"-VKana"_ustr, + u"MT"_ustr, + u"PS"_ustr, + u"PSMT"_ustr, + u"Regular"_ustr, + u"Normal"_ustr, + u"Book"_ustr, + u"Medium"_ustr, + u"ExtraBold"_ustr, + u"UltraBold"_ustr, + u"ExtraLight"_ustr, + u"UltraLight"_ustr, + u"Bold"_ustr, + u"Heavy"_ustr, + u"Black"_ustr, + u"Italic"_ustr, + u"Oblique"_ustr, + u"Bold"_ustr, //BoldItalic, BoldOblique + u"Light"_ustr, + u"Thin"_ustr, + u"Semibold"_ustr, + u"-Roman"_ustr, + u"Reg"_ustr, + u"VKana"_ustr, + u"-"_ustr, + u","_ustr, + u";"_ustr, + u"PS"_ustr, // e.g. TimesNewRomanPS-BoldMT + }; } #endif // INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_WRAPPER_HXX diff --git a/sdext/source/pdfimport/misc/pwdinteract.cxx b/sdext/source/pdfimport/misc/pwdinteract.cxx index 9885a6606a54..dcd3f8566d1f 100644 --- a/sdext/source/pdfimport/misc/pwdinteract.cxx +++ b/sdext/source/pdfimport/misc/pwdinteract.cxx @@ -31,9 +31,8 @@ #include <com/sun/star/task/DocumentPasswordRequest.hpp> #include <cppuhelper/implbase.hxx> -#include <osl/mutex.hxx> #include <rtl/ref.hxx> -#include <vcl/errcode.hxx> +#include <comphelper/errcode.hxx> using namespace com::sun::star; @@ -74,7 +73,7 @@ private: PDFPasswordRequest::PDFPasswordRequest( bool bFirstTry, const OUString& rName ) : m_aRequest( - uno::makeAny( + uno::Any( task::DocumentPasswordRequest( OUString(), uno::Reference< uno::XInterface >(), task::InteractionClassification_QUERY, @@ -92,9 +91,7 @@ uno::Any PDFPasswordRequest::getRequest() uno::Sequence< uno::Reference< task::XInteractionContinuation > > PDFPasswordRequest::getContinuations() { - uno::Sequence< uno::Reference< task::XInteractionContinuation > > aRet( 1 ); - aRet[0] = this; - return aRet; + return { this }; } void PDFPasswordRequest::setPassword( const OUString& rPwd ) @@ -130,7 +127,7 @@ private: virtual ~UnsupportedEncryptionFormatRequest() override {} virtual uno::Any SAL_CALL getRequest() override { - return uno::makeAny( + return uno::Any( task::ErrorCodeRequest( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_IO_WRONGVERSION))); diff --git a/sdext/source/pdfimport/odf/odfemitter.cxx b/sdext/source/pdfimport/odf/odfemitter.cxx index af5476de9d92..1ff92deb73a4 100644 --- a/sdext/source/pdfimport/odf/odfemitter.cxx +++ b/sdext/source/pdfimport/odf/odfemitter.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/io/XOutputStream.hpp> #include <comphelper/stl_types.hxx> +#include <utility> using namespace com::sun::star; @@ -41,7 +42,7 @@ private: uno::Sequence<sal_Int8> m_aBuf; public: - explicit OdfEmitter( const uno::Reference<io::XOutputStream>& xOutput ); + explicit OdfEmitter( uno::Reference<io::XOutputStream> xOutput ); virtual void beginTag( const char* pTag, const PropertyMap& rProperties ) override; virtual void write( const OUString& rString ) override; @@ -50,13 +51,11 @@ public: } -OdfEmitter::OdfEmitter( const uno::Reference<io::XOutputStream>& xOutput ) : - m_xOutput( xOutput ), - m_aLineFeed(1), - m_aBuf() +OdfEmitter::OdfEmitter( uno::Reference<io::XOutputStream> xOutput ) : + m_xOutput(std::move( xOutput )), + m_aLineFeed{ '\n' } { OSL_PRECOND(m_xOutput.is(), "OdfEmitter(): invalid output stream"); - m_aLineFeed[0] = '\n'; write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); } @@ -65,8 +64,7 @@ void OdfEmitter::beginTag( const char* pTag, const PropertyMap& rProperties ) { OSL_PRECOND(pTag,"Invalid tag string"); - OUStringBuffer aElement; - aElement.append("<"); + OUStringBuffer aElement("<"); aElement.appendAscii(pTag); aElement.append(" "); @@ -106,8 +104,7 @@ void OdfEmitter::write( const OUString& rText ) void OdfEmitter::endTag( const char* pTag ) { - OUStringBuffer aElement; - aElement.append("</"); + OUStringBuffer aElement("</"); aElement.appendAscii(pTag); aElement.append(">"); write(aElement.makeStringAndClear()); diff --git a/sdext/source/pdfimport/pdfiadaptor.cxx b/sdext/source/pdfimport/pdfiadaptor.cxx index 0291ac95d925..0d5bad2d6373 100644 --- a/sdext/source/pdfimport/pdfiadaptor.cxx +++ b/sdext/source/pdfimport/pdfiadaptor.cxx @@ -33,7 +33,7 @@ #include <com/sun/star/lang/IllegalArgumentException.hpp> #include <com/sun/star/lang/XMultiComponentFactory.hpp> #include <com/sun/star/io/XSeekable.hpp> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <memory> @@ -44,9 +44,7 @@ namespace pdfi { PDFIHybridAdaptor::PDFIHybridAdaptor( const uno::Reference< uno::XComponentContext >& xContext ) : - PDFIHybridAdaptorBase( m_aMutex ), - m_xContext( xContext ), - m_xModel() + m_xContext( xContext ) { } @@ -130,9 +128,7 @@ sal_Bool SAL_CALL PDFIHybridAdaptor::filter( const uno::Sequence< beans::Propert } if( xSubStream.is() ) { - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= m_xModel; - aArgs[1] <<= xSubStream; + uno::Sequence< uno::Any > aArgs{ uno::Any(m_xModel), uno::Any(xSubStream) }; SAL_INFO("sdext.pdfimport", "try to instantiate subfilter" ); uno::Reference< document::XFilter > xSubFilter; @@ -159,9 +155,9 @@ sal_Bool SAL_CALL PDFIHybridAdaptor::filter( const uno::Sequence< beans::Propert { nPwPos = aFilterData.getLength(); aFilterData.realloc( nPwPos+1 ); - aFilterData[nPwPos].Name = "Password"; + aFilterData.getArray()[nPwPos].Name = "Password"; } - aFilterData[nPwPos].Value <<= aPwd; + aFilterData.getArray()[nPwPos].Value <<= aPwd; bRet = xSubFilter->filter( aFilterData ); } else @@ -206,11 +202,8 @@ css::uno::Sequence<OUString> PDFIHybridAdaptor::getSupportedServiceNames() } PDFIRawAdaptor::PDFIRawAdaptor( OUString const & implementationName, const uno::Reference< uno::XComponentContext >& xContext ) : - PDFIAdaptorBase( m_aMutex ), m_implementationName(implementationName), - m_xContext( xContext ), - m_xModel(), - m_pVisitorFactory() + m_xContext( xContext ) { } @@ -336,7 +329,7 @@ sdext_PDFIRawAdaptor_Writer_get_implementation( rtl::Reference<pdfi::PDFIRawAdaptor> pAdaptor = new pdfi::PDFIRawAdaptor( "org.libreoffice.comp.documents.WriterPDFImport", context ); pAdaptor->setTreeVisitorFactory(pdfi::createWriterTreeVisitorFactory()); pAdaptor->acquire(); - return static_cast<cppu::OWeakObject*>(pAdaptor.get()); + return getXWeak(pAdaptor.get()); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* @@ -346,7 +339,7 @@ sdext_PDFIRawAdaptor_Draw_get_implementation( rtl::Reference<pdfi::PDFIRawAdaptor> pAdaptor = new pdfi::PDFIRawAdaptor( "org.libreoffice.comp.documents.DrawPDFImport", context ); pAdaptor->setTreeVisitorFactory(pdfi::createDrawTreeVisitorFactory()); pAdaptor->acquire(); - return static_cast<cppu::OWeakObject*>(pAdaptor.get()); + return getXWeak(pAdaptor.get()); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* @@ -356,7 +349,7 @@ sdext_PDFIRawAdaptor_Impress_get_implementation( rtl::Reference<pdfi::PDFIRawAdaptor> pAdaptor = new pdfi::PDFIRawAdaptor( "org.libreoffice.comp.documents.ImpressPDFImport", context ); pAdaptor->setTreeVisitorFactory(pdfi::createImpressTreeVisitorFactory()); pAdaptor->acquire(); - return static_cast<cppu::OWeakObject*>(pAdaptor.get()); + return getXWeak(pAdaptor.get()); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* diff --git a/sdext/source/pdfimport/pdfiadaptor.hxx b/sdext/source/pdfimport/pdfiadaptor.hxx index 0a184f3cf8e0..8cf225b74332 100644 --- a/sdext/source/pdfimport/pdfiadaptor.hxx +++ b/sdext/source/pdfimport/pdfiadaptor.hxx @@ -34,19 +34,17 @@ #include <com/sun/star/document/XImporter.hpp> #include <com/sun/star/frame/XModel.hpp> -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> namespace pdfi { - typedef ::cppu::WeakComponentImplHelper< + typedef ::comphelper::WeakComponentImplHelper< css::document::XFilter, css::document::XImporter, css::lang::XServiceInfo> PDFIHybridAdaptorBase; - class PDFIHybridAdaptor : private cppu::BaseMutex, - public PDFIHybridAdaptorBase + class PDFIHybridAdaptor : public PDFIHybridAdaptorBase { private: css::uno::Reference< @@ -72,15 +70,14 @@ namespace pdfi css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; }; - typedef ::cppu::WeakComponentImplHelper< + typedef ::comphelper::WeakComponentImplHelper< css::xml::XImportFilter, css::document::XImporter, css::lang::XServiceInfo> PDFIAdaptorBase; /** Adapts raw pdf import to XImportFilter interface */ - class PDFIRawAdaptor : private cppu::BaseMutex, - public PDFIAdaptorBase + class PDFIRawAdaptor : public PDFIAdaptorBase { private: OUString const m_implementationName; diff --git a/sdext/source/pdfimport/pdfparse/pdfentries.cxx b/sdext/source/pdfimport/pdfparse/pdfentries.cxx index bc379e5e2508..03f4537080d7 100644 --- a/sdext/source/pdfimport/pdfparse/pdfentries.cxx +++ b/sdext/source/pdfimport/pdfparse/pdfentries.cxx @@ -183,7 +183,7 @@ OUString PDFName::getFilteredName() const else aFilter.append( pStr[i] ); } - return OStringToOUString( aFilter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); + return OStringToOUString( aFilter, RTL_TEXTENCODING_UTF8 ); } PDFString::~PDFString() @@ -624,7 +624,7 @@ unsigned int PDFStream::getDictLength( const PDFContainer* pContainer ) const return 0; // find /Length entry, can either be a direct or indirect number object std::unordered_map<OString,PDFEntry*>::const_iterator it = - m_pDict->m_aMap.find( "Length" ); + m_pDict->m_aMap.find( "Length"_ostr ); if( it == m_pDict->m_aMap.end() ) return 0; PDFNumber* pNum = dynamic_cast<PDFNumber*>(it->second); @@ -673,7 +673,7 @@ bool PDFObject::getDeflatedStream( std::unique_ptr<char[]>& rpStream, unsigned i } // is there a filter entry ? std::unordered_map<OString,PDFEntry*>::const_iterator it = - m_pStream->m_pDict->m_aMap.find( "Filter" ); + m_pStream->m_pDict->m_aMap.find( "Filter"_ostr ); if( it != m_pStream->m_pDict->m_aMap.end() ) { PDFName* pFilter = dynamic_cast<PDFName*>(it->second); @@ -842,13 +842,13 @@ bool PDFObject::emit( EmitContext& rWriteContext ) const std::unique_ptr<PDFObject> pClone(static_cast<PDFObject*>(clone())); // set length in the dictionary to new stream length std::unique_ptr<PDFNumber> pNewLen(new PDFNumber( double(nOutBytes) )); - pClone->m_pStream->m_pDict->insertValue( "Length", std::move(pNewLen) ); + pClone->m_pStream->m_pDict->insertValue( "Length"_ostr, std::move(pNewLen) ); if( bDeflate && rWriteContext.m_bDeflate ) { // delete flatedecode filter std::unordered_map<OString,PDFEntry*>::const_iterator it = - pClone->m_pStream->m_pDict->m_aMap.find( "Filter" ); + pClone->m_pStream->m_pDict->m_aMap.find( "Filter"_ostr ); if( it != pClone->m_pStream->m_pDict->m_aMap.end() ) { PDFName* pFilter = dynamic_cast<PDFName*>(it->second); @@ -950,11 +950,11 @@ bool PDFTrailer::emit( EmitContext& rWriteContext ) const section_end->first == nLast+1 ) nLast = section_end->first; // write first object number and number of following entries - OStringBuffer aBuf( 21 ); - aBuf.append( sal_Int32( section_begin->first ) ); - aBuf.append( ' ' ); - aBuf.append( sal_Int32(nLast - section_begin->first + 1) ); - aBuf.append( "\r\n" ); + OStringBuffer aBuf = + OString::number(sal_Int32( section_begin->first ) ) + + " " + + OString::number(sal_Int32(nLast - section_begin->first + 1)) + + "\r\n"; if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) ) return false; while( section_begin != section_end ) @@ -966,14 +966,12 @@ bool PDFTrailer::emit( EmitContext& rWriteContext ) const int nPad = 10 - aOffset.getLength(); for( int i = 0; i < nPad; i++ ) aBuf.append( '0' ); - aBuf.append( aOffset ); - aBuf.append( ' ' ); + aBuf.append( aOffset + " " ); OString aGeneration( OString::number( section_begin->second.first ) ); nPad = 5 - aGeneration.getLength(); for( int i = 0; i < nPad; i++ ) aBuf.append( '0' ); - aBuf.append( aGeneration ); - aBuf.append( " n\r\n" ); + aBuf.append( aGeneration + " n\r\n" ); if( ! rWriteContext.write( aBuf.getStr(), 20 ) ) return false; ++section_begin; @@ -1047,7 +1045,7 @@ struct PDFFileImplData } PDFFile::PDFFile() - : PDFContainer(), m_nMajor( 0 ), m_nMinor( 0 ) + : m_nMajor( 0 ), m_nMinor( 0 ) { } @@ -1290,7 +1288,7 @@ PDFFileImplData* PDFFile::impl_getData() const if( pTrailer && pTrailer->m_pDict ) { // search doc id - PDFDict::Map::iterator doc_id = pTrailer->m_pDict->m_aMap.find( "ID" ); + PDFDict::Map::iterator doc_id = pTrailer->m_pDict->m_aMap.find( "ID"_ostr ); if( doc_id != pTrailer->m_pDict->m_aMap.end() ) { PDFArray* pArr = dynamic_cast<PDFArray*>(doc_id->second); @@ -1309,7 +1307,7 @@ PDFFileImplData* PDFFile::impl_getData() const } // search Encrypt entry PDFDict::Map::iterator enc = - pTrailer->m_pDict->m_aMap.find( "Encrypt" ); + pTrailer->m_pDict->m_aMap.find( "Encrypt"_ostr ); if( enc != pTrailer->m_pDict->m_aMap.end() ) { PDFDict* pDict = dynamic_cast<PDFDict*>(enc->second); @@ -1325,13 +1323,13 @@ PDFFileImplData* PDFFile::impl_getData() const } if( pDict ) { - PDFDict::Map::iterator filter = pDict->m_aMap.find( "Filter" ); - PDFDict::Map::iterator version = pDict->m_aMap.find( "V" ); - PDFDict::Map::iterator len = pDict->m_aMap.find( "Length" ); - PDFDict::Map::iterator o_ent = pDict->m_aMap.find( "O" ); - PDFDict::Map::iterator u_ent = pDict->m_aMap.find( "U" ); - PDFDict::Map::iterator r_ent = pDict->m_aMap.find( "R" ); - PDFDict::Map::iterator p_ent = pDict->m_aMap.find( "P" ); + PDFDict::Map::iterator filter = pDict->m_aMap.find( "Filter"_ostr ); + PDFDict::Map::iterator version = pDict->m_aMap.find( "V"_ostr ); + PDFDict::Map::iterator len = pDict->m_aMap.find( "Length"_ostr ); + PDFDict::Map::iterator o_ent = pDict->m_aMap.find( "O"_ostr ); + PDFDict::Map::iterator u_ent = pDict->m_aMap.find( "U"_ostr ); + PDFDict::Map::iterator r_ent = pDict->m_aMap.find( "R"_ostr ); + PDFDict::Map::iterator p_ent = pDict->m_aMap.find( "P"_ostr ); if( filter != pDict->m_aMap.end() ) { m_pData->m_bIsEncrypted = true; diff --git a/sdext/source/pdfimport/pdfparse/pdfparse.cxx b/sdext/source/pdfimport/pdfparse/pdfparse.cxx index 3a032af5878c..34424b9ec320 100644 --- a/sdext/source/pdfimport/pdfparse/pdfparse.cxx +++ b/sdext/source/pdfimport/pdfparse/pdfparse.cxx @@ -20,34 +20,18 @@ #include <pdfparse.hxx> -// boost using obsolete stuff -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4996) -#pragma warning(disable:4503) -#endif - -// workaround windows compiler: do not include multi_pass.hpp -#include <boost/spirit/include/classic_core.hpp> -#include <boost/spirit/include/classic_utility.hpp> -#include <boost/spirit/include/classic_error_handling.hpp> -#include <boost/spirit/include/classic_file_iterator.hpp> +#include <boost/spirit/include/classic.hpp> #include <boost/bind/bind.hpp> #include <string.h> +#include <o3tl/char16_t2wchar_t.hxx> #include <o3tl/safeint.hxx> +#include <osl/thread.h> #include <rtl/strbuf.hxx> #include <rtl/ustrbuf.hxx> #include <sal/log.hxx> - -// disable warnings again because someone along the line has enabled them -// (we have included boost headers, what did you expect?) -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4996) -#pragma warning(disable:4503) -#endif +#include <utility> using namespace boost::spirit::classic; @@ -59,7 +43,7 @@ class StringEmitContext : public EmitContext { OStringBuffer m_aBuf; public: - StringEmitContext() : EmitContext(), m_aBuf(256) {} + StringEmitContext() : m_aBuf(256) {} virtual bool write( const void* pBuf, unsigned int nLen ) noexcept override { @@ -88,8 +72,8 @@ class PDFGrammar : public grammar< PDFGrammar<iteratorT> > { public: - explicit PDFGrammar( const iteratorT& first ) - : m_fDouble( 0.0 ), m_aGlobalBegin( first ) {} + explicit PDFGrammar( iteratorT first ) + : m_fDouble( 0.0 ), m_aGlobalBegin(std::move( first )) {} ~PDFGrammar() { if( !m_aObjectStack.empty() ) @@ -281,12 +265,12 @@ public: } #endif - static void parseError( const char* pMessage, iteratorT pLocation ) + static void parseError( const char* pMessage, const iteratorT& pLocation ) { throw_( pLocation, pMessage ); } - OString iteratorToString( iteratorT first, iteratorT last ) const + OString iteratorToString( iteratorT first, const iteratorT& last ) const { OStringBuffer aStr( 32 ); while( first != last ) @@ -297,7 +281,7 @@ public: return aStr.makeStringAndClear(); } - void haveFile( iteratorT pBegin, SAL_UNUSED_PARAMETER iteratorT /*pEnd*/ ) + void haveFile( const iteratorT& pBegin, SAL_UNUSED_PARAMETER iteratorT /*pEnd*/ ) { if( m_aObjectStack.empty() ) { @@ -312,7 +296,7 @@ public: parseError( "found file header in unusual place", pBegin ); } - void pushComment( iteratorT first, iteratorT last ) + void pushComment(const iteratorT& first, const iteratorT& last) { // add a comment to the current stack element PDFComment* pComment = @@ -325,7 +309,7 @@ public: pContainer->m_aSubElements.emplace_back( pComment ); } - void insertNewValue( std::unique_ptr<PDFEntry> pNewValue, iteratorT pPos ) + void insertNewValue( std::unique_ptr<PDFEntry> pNewValue, const iteratorT& pPos ) { PDFContainer* pContainer = nullptr; const char* pMsg = nullptr; @@ -381,33 +365,32 @@ public: } } - void pushName( iteratorT first, iteratorT last ) + void pushName(const iteratorT& first, const iteratorT& last ) { insertNewValue( std::make_unique<PDFName>(iteratorToString(first,last)), first ); } - void pushDouble( iteratorT first, SAL_UNUSED_PARAMETER iteratorT /*last*/ ) + void pushDouble( const iteratorT& first, SAL_UNUSED_PARAMETER const iteratorT& /*last*/ ) { insertNewValue( std::make_unique<PDFNumber>(m_fDouble), first ); } - void pushString( iteratorT first, iteratorT last ) + void pushString( const iteratorT& first, const iteratorT& last ) { insertNewValue( std::make_unique<PDFString>(iteratorToString(first,last)), first ); } - void pushBool( iteratorT first, iteratorT last ) + void pushBool( const iteratorT& first, const iteratorT& last ) { insertNewValue( std::make_unique<PDFBool>( last-first == 4 ), first ); } - void pushNull( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void pushNull( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { insertNewValue( std::make_unique<PDFNull>(), first ); } - - void beginObject( iteratorT first, SAL_UNUSED_PARAMETER iteratorT /*last*/ ) + void beginObject( const iteratorT& first, SAL_UNUSED_PARAMETER const iteratorT& /*last*/ ) { if( m_aObjectStack.empty() ) m_aObjectStack.push_back( new PDFPart() ); @@ -432,7 +415,7 @@ public: parseError( "object in wrong place", first ); } - void endObject( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void endObject( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { if( m_aObjectStack.empty() ) parseError( "endobj without obj", first ); @@ -442,7 +425,7 @@ public: m_aObjectStack.pop_back(); } - void pushObjectRef( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void pushObjectRef( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { unsigned int nGeneration = m_aUIntStack.back(); m_aUIntStack.pop_back(); @@ -451,7 +434,7 @@ public: insertNewValue( std::make_unique<PDFObjectRef>(nObject,nGeneration), first ); } - void beginDict( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void beginDict( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { PDFDict* pDict = new PDFDict(); pDict->m_nOffset = first - m_aGlobalBegin; @@ -460,7 +443,8 @@ public: // will not come here if insertion fails (exception) m_aObjectStack.push_back( pDict ); } - void endDict( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + + void endDict( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { PDFDict* pDict = nullptr; if( m_aObjectStack.empty() ) @@ -481,7 +465,7 @@ public: } } - void beginArray( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void beginArray( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { PDFArray* pArray = new PDFArray(); pArray->m_nOffset = first - m_aGlobalBegin; @@ -491,7 +475,7 @@ public: m_aObjectStack.push_back( pArray ); } - void endArray( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void endArray( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { if( m_aObjectStack.empty() ) parseError( "array end without begin", first ); @@ -501,7 +485,7 @@ public: m_aObjectStack.pop_back(); } - void emitStream( iteratorT first, iteratorT last ) + void emitStream(const iteratorT& first, const iteratorT& last) { if( m_aObjectStack.empty() ) parseError( "stream without object", first ); @@ -524,7 +508,7 @@ public: parseError( "stream without object", first ); } - void beginTrailer( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void beginTrailer( const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { if( m_aObjectStack.empty() ) m_aObjectStack.push_back( new PDFPart() ); @@ -544,7 +528,7 @@ public: parseError( "trailer in wrong place", first ); } - void endTrailer( iteratorT first, SAL_UNUSED_PARAMETER iteratorT ) + void endTrailer(const iteratorT& first, SAL_UNUSED_PARAMETER iteratorT ) { if( m_aObjectStack.empty() ) parseError( "%%EOF without trailer", first ); @@ -557,84 +541,14 @@ public: } -#ifdef _WIN32 -std::unique_ptr<PDFEntry> PDFReader::read( const char* pBuffer, unsigned int nLen ) -{ - PDFGrammar<const char*> aGrammar( pBuffer ); - - try - { -#if OSL_DEBUG_LEVEL > 0 - boost::spirit::classic::parse_info<const char*> aInfo = -#endif - boost::spirit::classic::parse( pBuffer, - pBuffer+nLen, - aGrammar, - boost::spirit::classic::space_p ); -#if OSL_DEBUG_LEVEL > 0 - SAL_INFO("sdext.pdfimport.pdfparse", "parseinfo: stop = " << aInfo.stop << " (buff=" << pBuffer << ", offset = " << aInfo.stop - pBuffer << "), hit = " << (aInfo.hit ? OUString("true") : OUString("false")) << ", full = " << (aInfo.full ? OUString("true") : OUString("false")) << ", length = " << static_cast<int>(aInfo.length) ); -#endif - } - catch( const parser_error<const char*, const char*>& rError ) - { -#if OSL_DEBUG_LEVEL > 0 - OString aTmp; - unsigned int nElem = aGrammar.m_aObjectStack.size(); - for( unsigned int i = 0; i < nElem; i++ ) - aTmp += OString::Concat(" ") + typeid( *(aGrammar.m_aObjectStack[i]) ).name(); - - SAL_WARN("sdext.pdfimport.pdfparse", "parse error: " << rError.descriptor << " at buffer pos " << rError.where - pBuffer << ", object stack: " << aTmp); -#else - (void)rError; -#endif - } - - std::unique_ptr<PDFEntry> pRet; - unsigned int nEntries = aGrammar.m_aObjectStack.size(); - if( nEntries == 1 ) - { - pRet.reset(aGrammar.m_aObjectStack.back()); - aGrammar.m_aObjectStack.pop_back(); - } -#if OSL_DEBUG_LEVEL > 0 - else if( nEntries > 1 ) - SAL_WARN("sdext.pdfimport.pdfparse", "error got " << nEntries << " stack objects in parse" ); -#endif - - return pRet; -} -#endif - -std::unique_ptr<PDFEntry> PDFReader::read( const char* pFileName ) +std::unique_ptr<PDFEntry> PDFReader::read(std::u16string_view aFileName) { #ifdef _WIN32 - /* #i106583# - since converting to boost 1.39 file_iterator does not work anymore on all Windows systems - C++ stdlib istream_iterator does not allow "-" apparently - using spirit 2.0 doesn't work in our environment with the MSC - - So for the time being bite the bullet and read the whole file. - FIXME: give Spirit 2.x another try when we upgrade boost again. - */ - std::unique_ptr<PDFEntry> pRet; - FILE* fp = fopen( pFileName, "rb" ); - if( fp ) - { - fseek( fp, 0, SEEK_END ); - unsigned int nLen = static_cast<unsigned int>(ftell( fp )); - fseek( fp, 0, SEEK_SET ); - char* pBuf = static_cast<char*>(std::malloc( nLen )); - if( pBuf ) - { - fread( pBuf, 1, nLen, fp ); - pRet = read( pBuf, nLen ); - std::free( pBuf ); - } - fclose( fp ); - } - return pRet; + file_iterator<> file_start(std::wstring(o3tl::toW(aFileName))); #else - file_iterator<> file_start( pFileName ); + file_iterator<> file_start( + std::string(OUStringToOString(aFileName, osl_getThreadTextEncoding()))); +#endif if( ! file_start ) return nullptr; file_iterator<> file_end = file_start.make_end(); @@ -675,27 +589,27 @@ std::unique_ptr<PDFEntry> PDFReader::read( const char* pFileName ) pRet.reset(aGrammar.m_aObjectStack.back()); aGrammar.m_aObjectStack.pop_back(); } -#if OSL_DEBUG_LEVEL > 0 else if( nEntries > 1 ) { + // It is possible that there are multiple trailers, which is OK. + // But still keep the warnings, just in case. SAL_WARN("sdext.pdfimport.pdfparse", "error got " << nEntries << " stack objects in parse"); - for( unsigned int i = 0; i < nEntries; i++ ) + for (;;) { - SAL_WARN("sdext.pdfimport.pdfparse", typeid(*aGrammar.m_aObjectStack[i]).name()); - PDFObject* pObj = dynamic_cast<PDFObject*>(aGrammar.m_aObjectStack[i]); + PDFEntry* pEntry = aGrammar.m_aObjectStack.back(); + aGrammar.m_aObjectStack.pop_back(); + SAL_WARN("sdext.pdfimport.pdfparse", typeid(*pEntry).name()); + PDFObject* pObj = dynamic_cast<PDFObject*>(pEntry); if( pObj ) SAL_WARN("sdext.pdfimport.pdfparse", " -> object " << pObj->m_nNumber << " generation " << pObj->m_nGeneration); - else - SAL_WARN("sdext.pdfimport.pdfparse", "(type " << typeid(*aGrammar.m_aObjectStack[i]).name() << ")"); + if (aGrammar.m_aObjectStack.empty()) + { + pRet.reset(pEntry); // The first entry references all others - see PDFGrammar dtor + break; + } } } -#endif return pRet; -#endif // WIN32 } -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/sax/emitcontext.cxx b/sdext/source/pdfimport/sax/emitcontext.cxx index a923488d688d..c32e327c4c4f 100644 --- a/sdext/source/pdfimport/sax/emitcontext.cxx +++ b/sdext/source/pdfimport/sax/emitcontext.cxx @@ -110,15 +110,14 @@ void SaxEmitter::beginTag( const char* pTag, const PropertyMap& rProperties ) pStream->write( " ", 4, nWritten ); OStringBuffer aBuf( 1024 ); - aBuf.append( '<' ); - aBuf.append( pTag ); + aBuf.append( OString::Concat("<") + pTag ); for( const auto& rProperty : rProperties ) { - aBuf.append( ' ' ); - aBuf.append( OUStringToOString( rProperty.first, RTL_TEXTENCODING_UTF8 ) ); - aBuf.append( "=\"" ); - aBuf.append( OUStringToOString( rProperty.second, RTL_TEXTENCODING_UTF8 ) ); - aBuf.append( "\"" ); + aBuf.append( " " + + OUStringToOString( rProperty.first, RTL_TEXTENCODING_UTF8 ) + + "=\"" + + OUStringToOString( rProperty.second, RTL_TEXTENCODING_UTF8 ) + + "\"" ); } aBuf.append( ">\n" ); pStream->write( aBuf.getStr(), aBuf.getLength(), nWritten ); diff --git a/sdext/source/pdfimport/sax/saxattrlist.cxx b/sdext/source/pdfimport/sax/saxattrlist.cxx index 538f6f4479b5..d9ae07b12317 100644 --- a/sdext/source/pdfimport/sax/saxattrlist.cxx +++ b/sdext/source/pdfimport/sax/saxattrlist.cxx @@ -34,10 +34,7 @@ SaxAttrList::SaxAttrList( const std::unordered_map< OUString, OUString >& rMap ) } namespace { - OUString getCDATAString() - { - return "CDATA"; - } + constexpr OUString CDATA = u"CDATA"_ustr; } sal_Int16 SAL_CALL SaxAttrList::getLength() @@ -51,12 +48,12 @@ OUString SAL_CALL SaxAttrList::getNameByIndex( sal_Int16 i_nIndex ) OUString SAL_CALL SaxAttrList::getTypeByIndex( sal_Int16 i_nIndex) { - return (i_nIndex < sal_Int16(m_aAttributes.size())) ? getCDATAString() : OUString(); + return (i_nIndex < sal_Int16(m_aAttributes.size())) ? CDATA : OUString(); } OUString SAL_CALL SaxAttrList::getTypeByName( const OUString& i_rName ) { - return (m_aIndexMap.find( i_rName ) != m_aIndexMap.end()) ? getCDATAString() : OUString(); + return (m_aIndexMap.find( i_rName ) != m_aIndexMap.end()) ? CDATA : OUString(); } OUString SAL_CALL SaxAttrList::getValueByIndex( sal_Int16 i_nIndex ) diff --git a/sdext/source/pdfimport/sax/saxattrlist.hxx b/sdext/source/pdfimport/sax/saxattrlist.hxx index e26afcbc5237..19c86793d4ee 100644 --- a/sdext/source/pdfimport/sax/saxattrlist.hxx +++ b/sdext/source/pdfimport/sax/saxattrlist.hxx @@ -22,6 +22,7 @@ #include <rtl/ustring.hxx> #include <unordered_map> +#include <utility> #include <vector> #include <cppuhelper/implbase.hxx> @@ -40,8 +41,8 @@ namespace pdfi OUString m_aName; OUString m_aValue; - AttrEntry( const OUString& i_rName, const OUString& i_rValue ) - : m_aName( i_rName ), m_aValue( i_rValue ) {} + AttrEntry( OUString i_aName, OUString i_aValue ) + : m_aName(std::move( i_aName )), m_aValue(std::move( i_aValue )) {} }; std::vector< AttrEntry > m_aAttributes; std::unordered_map< OUString, size_t > m_aIndexMap; diff --git a/sdext/source/pdfimport/test/pdf2xml.cxx b/sdext/source/pdfimport/test/pdf2xml.cxx index 04b5ee8d19c0..3592baef2e57 100644 --- a/sdext/source/pdfimport/test/pdf2xml.cxx +++ b/sdext/source/pdfimport/test/pdf2xml.cxx @@ -32,7 +32,7 @@ #include <unotest/bootstrapfixturebase.hxx> #include <comphelper/processfactory.hxx> #include <cppuhelper/bootstrap.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> using namespace ::pdfi; using namespace ::com::sun::star; diff --git a/sdext/source/pdfimport/test/pdfunzip.cxx b/sdext/source/pdfimport/test/pdfunzip.cxx index 3e2e614a9327..6db3b740d668 100644 --- a/sdext/source/pdfimport/test/pdfunzip.cxx +++ b/sdext/source/pdfimport/test/pdfunzip.cxx @@ -27,6 +27,7 @@ #include <rtl/alloc.h> #include <rtl/ustring.hxx> #include <rtl/strbuf.hxx> +#include <o3tl/string_view.hxx> #include <pdfparse.hxx> @@ -223,7 +224,8 @@ typedef int(*PDFFileHdl)(const char*, const char*, PDFFile*); static int handleFile( const char* pInFile, const char* pOutFile, const char* pPassword, PDFFileHdl pHdl ) { int nRet = 0; - std::unique_ptr<PDFEntry> pEntry = pdfparse::PDFReader::read( pInFile ); + std::unique_ptr<PDFEntry> pEntry + = pdfparse::PDFReader::read(OStringToOUString(pInFile, osl_getThreadTextEncoding())); if( pEntry ) { PDFFile* pPDFFile = dynamic_cast<PDFFile*>(pEntry.get()); @@ -301,7 +303,7 @@ static int write_addStreams( const char* pInFile, const char* pOutFile, PDFFile* if( pTrailer && pTrailer->m_pDict ) { // search for AdditionalStreams entry - auto add_stream = pTrailer->m_pDict->m_aMap.find( "AdditionalStreams" ); + auto add_stream = pTrailer->m_pDict->m_aMap.find( "AdditionalStreams"_ostr ); if( add_stream != pTrailer->m_pDict->m_aMap.end() ) { PDFArray* pStreams = dynamic_cast<PDFArray*>(add_stream->second); @@ -327,7 +329,7 @@ static int write_fonts( const char* i_pInFile, const char* i_pOutFile, PDFFile* continue; std::unordered_map<OString,PDFEntry*>::iterator map_it = - pDict->m_aMap.find( "Type" ); + pDict->m_aMap.find( "Type"_ostr ); if( map_it == pDict->m_aMap.end() ) continue; @@ -339,7 +341,7 @@ static int write_fonts( const char* i_pInFile, const char* i_pOutFile, PDFFile* // the font name will be helpful, also there must be one in // a font descriptor - map_it = pDict->m_aMap.find( "FontName" ); + map_it = pDict->m_aMap.find( "FontName"_ostr ); if( map_it == pDict->m_aMap.end() ) continue; pName = dynamic_cast<PDFName*>(map_it->second); @@ -350,7 +352,7 @@ static int write_fonts( const char* i_pInFile, const char* i_pOutFile, PDFFile* PDFObjectRef* pStreamRef = nullptr; const char* pFileType = nullptr; // we have a font descriptor, try for a type 1 font - map_it = pDict->m_aMap.find( "FontFile" ); + map_it = pDict->m_aMap.find( "FontFile"_ostr ); if( map_it != pDict->m_aMap.end() ) { pStreamRef = dynamic_cast<PDFObjectRef*>(map_it->second); @@ -361,7 +363,7 @@ static int write_fonts( const char* i_pInFile, const char* i_pOutFile, PDFFile* // perhaps it's a truetype file ? if( ! pStreamRef ) { - map_it = pDict->m_aMap.find( "FontFile2" ); + map_it = pDict->m_aMap.find( "FontFile2"_ostr ); if( map_it != pDict->m_aMap.end() ) { pStreamRef = dynamic_cast<PDFObjectRef*>(map_it->second); @@ -377,17 +379,16 @@ static int write_fonts( const char* i_pInFile, const char* i_pOutFile, PDFFile* if( ! pStream ) continue; - OStringBuffer aOutStream( i_pOutFile ); - aOutStream.append( "_font_" ); - aOutStream.append( sal_Int32(pStreamRef->m_nNumber) ); - aOutStream.append( "_" ); - aOutStream.append( sal_Int32(pStreamRef->m_nGeneration) ); - aOutStream.append( "_" ); - aOutStream.append( aFontName ); + OStringBuffer aOutStream( OString::Concat(i_pOutFile) + + "_font_" + + OString::number( sal_Int32(pStreamRef->m_nNumber) ) + + "_" + + OString::number( sal_Int32(pStreamRef->m_nGeneration) ) + + "_" + + aFontName ); if( pFileType ) { - aOutStream.append( "." ); - aOutStream.append( pFileType ); + aOutStream.append( OString::Concat(".") + pFileType ); } FileEmitContext aContext( aOutStream.getStr(), i_pInFile, i_pPDFFile ); aContext.m_bDecrypt = i_pPDFFile->isEncrypted(); @@ -478,9 +479,9 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv ) sal_Int32 nObject = 0; sal_Int32 nGeneration = 0; sal_Int32 nGenIndex = 0; - nObject = aToken.getToken( 0, ':', nGenIndex ).toInt32(); + nObject = o3tl::toInt32( o3tl::getToken( aToken, 0, ':', nGenIndex ) ); if( nGenIndex != -1 ) - nGeneration = aToken.getToken( 0, ':', nGenIndex ).toInt32(); + nGeneration = o3tl::toInt32( o3tl::getToken(aToken, 0, ':', nGenIndex )); s_aEmitObjects.push_back( std::pair<sal_Int32,sal_Int32>(nObject,nGeneration) ); } } diff --git a/sdext/source/pdfimport/test/tests.cxx b/sdext/source/pdfimport/test/tests.cxx deleted file mode 100644 index 6caa07cb2354..000000000000 --- a/sdext/source/pdfimport/test/tests.cxx +++ /dev/null @@ -1,568 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <config_features.h> - -#include "outputwrap.hxx" -#include <contentsink.hxx> -#include <pdfihelper.hxx> -#include <wrapper.hxx> -#include <pdfparse.hxx> -#include "../pdfiadaptor.hxx" - -#include <rtl/math.hxx> -#include <osl/file.hxx> -#include <comphelper/sequence.hxx> - -#include <cppunit/TestAssert.h> -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/plugin/TestPlugIn.h> -#include <test/bootstrapfixture.hxx> - -#include <com/sun/star/geometry/RealRectangle2D.hpp> -#include <com/sun/star/geometry/RealSize2D.hpp> -#include <com/sun/star/rendering/PathJoinType.hpp> -#include <com/sun/star/rendering/PathCapType.hpp> -#include <com/sun/star/rendering/BlendMode.hpp> - -#include <basegfx/utils/canvastools.hxx> -#include <basegfx/polygon/b2dpolypolygon.hxx> -#include <basegfx/polygon/b2dpolypolygontools.hxx> -#include <basegfx/polygon/b2dpolygonclipper.hxx> - -#include <unordered_map> -#include <vector> - -#include <rtl/ustring.hxx> -#include <rtl/ref.hxx> - -using namespace ::pdfparse; -using namespace ::pdfi; -using namespace ::com::sun::star; - -namespace -{ - - class TestSink : public ContentSink - { - public: - TestSink() : - m_nNextFontId( 1 ), - m_aIdToFont(), - m_aFontToId(), - m_aGCStack(1), - m_aPageSize(), - m_aHyperlinkBounds(), - m_aURI(), - m_aTextOut(), - m_nNumPages(0), - m_bPageEnded(false), - m_bRedCircleSeen(false), - m_bGreenStrokeSeen(false), - m_bDashedLineSeen(false), - m_bImageSeen(false) - {} - - void check() - { - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Width", 79400, m_aPageSize.Width, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Height", 59500, m_aPageSize.Height, 0.0000001 ); - CPPUNIT_ASSERT_MESSAGE( "endPage() called", m_bPageEnded ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Num pages equal one", sal_Int32(1), m_nNumPages ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.X1,34.7 ) ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.Y1,386.0) ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.X2,166.7) ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.Y2,406.2) ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Correct hyperlink URI", OUString("http://download.openoffice.org/"), m_aURI ); - - const char* const sText = " \n \nThis is a testtext\nNew paragraph,\nnew line\n" - "Hyperlink, this is\n?\nThis is more text\noutline mode\n?\nNew paragraph\n"; - OString aTmp; - m_aTextOut.makeStringAndClear().convertToString( &aTmp, - RTL_TEXTENCODING_ASCII_US, - OUSTRING_TO_OSTRING_CVTFLAGS ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Imported text is \"This is a testtext New paragraph, new line" - " Hyperlink, this is * This is more text outline mode * New paragraph\"", - aTmp, OString(sText) ); - - CPPUNIT_ASSERT_MESSAGE( "red circle seen in input", m_bRedCircleSeen ); - CPPUNIT_ASSERT_MESSAGE( "green stroke seen in input", m_bGreenStrokeSeen ); - CPPUNIT_ASSERT_MESSAGE( "dashed line seen in input", m_bDashedLineSeen ); - CPPUNIT_ASSERT_MESSAGE( "image seen in input", m_bImageSeen ); - } - - private: - GraphicsContext& getCurrentContext() { return m_aGCStack.back(); } - - // ContentSink interface implementation - virtual void setPageNum( sal_Int32 nNumPages ) override - { - m_nNumPages = nNumPages; - } - - virtual void startPage( const geometry::RealSize2D& rSize ) override - { - m_aPageSize = rSize; - } - - virtual void endPage() override - { - m_bPageEnded = true; - } - - virtual void hyperLink( const geometry::RealRectangle2D& rBounds, - const OUString& rURI ) override - { - m_aHyperlinkBounds = rBounds; - m_aURI = rURI; - } - - virtual void pushState() override - { - GraphicsContextStack::value_type const a(m_aGCStack.back()); - m_aGCStack.push_back(a); - } - - virtual void popState() override - { - m_aGCStack.pop_back(); - } - - virtual void setTransformation( const geometry::AffineMatrix2D& rMatrix ) override - { - basegfx::unotools::homMatrixFromAffineMatrix( - getCurrentContext().Transformation, - rMatrix ); - } - - virtual void setLineDash( const uno::Sequence<double>& dashes, - double start ) override - { - GraphicsContext& rContext( getCurrentContext() ); - if( dashes.hasElements() ) - comphelper::sequenceToContainer(rContext.DashArray,dashes); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "line dashing start offset", 0.0, start, 0.000000001 ); - } - - virtual void setFlatness( double nFlatness ) override - { - getCurrentContext().Flatness = nFlatness; - } - - virtual void setLineJoin(sal_Int8 nJoin) override - { - getCurrentContext().LineJoin = nJoin; - } - - virtual void setLineCap(sal_Int8 nCap) override - { - getCurrentContext().LineCap = nCap; - } - - virtual void setMiterLimit(double nVal) override - { - getCurrentContext().MiterLimit = nVal; - } - - virtual void setLineWidth(double nVal) override - { - getCurrentContext().LineWidth = nVal; - } - - virtual void setFillColor( const rendering::ARGBColor& rColor ) override - { - getCurrentContext().FillColor = rColor; - } - - virtual void setStrokeColor( const rendering::ARGBColor& rColor ) override - { - getCurrentContext().LineColor = rColor; - } - - virtual void setFont( const FontAttributes& rFont ) override - { - FontToIdMap::const_iterator it = m_aFontToId.find( rFont ); - if( it != m_aFontToId.end() ) - getCurrentContext().FontId = it->second; - else - { - m_aFontToId[ rFont ] = m_nNextFontId; - m_aIdToFont[ m_nNextFontId ] = rFont; - getCurrentContext().FontId = m_nNextFontId; - m_nNextFontId++; - } - } - - virtual void strokePath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) override - { - GraphicsContext& rContext( getCurrentContext() ); - basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aPath.transform( rContext.Transformation ); - - if( rContext.DashArray.empty() ) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_MESSAGE( "Line width is 0", - rtl::math::approxEqual(rContext.LineWidth, 28.3) ); - - static constexpr OUStringLiteral sExportString = u"m53570 7650-35430 24100"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is m535.7 518.5-354.3-241", - OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); - - m_bGreenStrokeSeen = true; - } - else - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Dash array consists of four entries", std::vector<double>::size_type(4), rContext.DashArray.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 14.3764, rContext.DashArray[0], 1E-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[0], rContext.DashArray[1], 1E-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[1], rContext.DashArray[2], 1E-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[2], rContext.DashArray[3], 1E-12 ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line width is 0", - 0, rContext.LineWidth, 0.0000001 ); - - static constexpr OUStringLiteral sExportString = u"m49890 5670.00000000001-35430 24090"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is m49890 5670.00000000001-35430 24090", - OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); - - m_bDashedLineSeen = true; - } - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", - rendering::BlendMode::NORMAL, rContext.BlendMode ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Join type is round", - rendering::PathJoinType::ROUND, rContext.LineJoin ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Cap type is butt", - rendering::PathCapType::BUTT, rContext.LineCap ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line miter limit is 10", - 10, rContext.MiterLimit, 0.0000001 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0", - 1, rContext.Flatness, 0.00000001 ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", - sal_Int32(0), rContext.FontId ); - } - - virtual void fillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) override - { - GraphicsContext& rContext( getCurrentContext() ); - basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aPath.transform( rContext.Transformation ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", - rendering::BlendMode::NORMAL, rContext.BlendMode ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 10", - 10, rContext.Flatness, 0.00000001 ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", - sal_Int32(0), rContext.FontId ); - } - - virtual void eoFillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) override - { - GraphicsContext& rContext( getCurrentContext() ); - basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aPath.transform( rContext.Transformation ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", - rendering::BlendMode::NORMAL, rContext.BlendMode ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0", - 1, rContext.Flatness, 0.00000001 ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", - sal_Int32(0), rContext.FontId ); - - static constexpr OUStringLiteral sExportString - = u"m12050 49610c-4310 0-7800-3490-7800-7800 0-4300 " - "3490-7790 7800-7790 4300 0 7790 3490 7790 7790 0 4310-3490 7800-7790 7800z"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is a 4-bezier circle", - OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); - - m_bRedCircleSeen = true; - } - - virtual void intersectClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath) override - { - basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; - - if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) - aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); - - getCurrentContext().Clip = aNewClip; - } - - virtual void intersectEoClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath) override - { - basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; - - if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) - aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); - - getCurrentContext().Clip = aNewClip; - } - - virtual void drawGlyphs( const OUString& rGlyphs, - const geometry::RealRectangle2D& /*rRect*/, - const geometry::Matrix2D& /*rFontMatrix*/, - double /*fontSize*/) override - { - m_aTextOut.append(rGlyphs); - } - - virtual void endText() override - { - m_aTextOut.append( "\n" ); - } - - virtual void drawMask(const uno::Sequence<beans::PropertyValue>& xBitmap, - bool /*bInvert*/ ) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask received two properties", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask got URL param", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask got InputStream param", - OUString("InputStream"), xBitmap[1].Name ); - } - - virtual void drawImage(const uno::Sequence<beans::PropertyValue>& xBitmap ) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage received two properties", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage got URL param", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage got InputStream param", - OUString("InputStream"), xBitmap[1].Name ); - m_bImageSeen = true; - } - - virtual void drawColorMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap, - const uno::Sequence<uno::Any>& /*xMaskColors*/ ) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage received two properties", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage got URL param", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage got InputStream param", - OUString("InputStream"), xBitmap[1].Name ); - } - - virtual void drawMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap, - const uno::Sequence<beans::PropertyValue>& xMask, - bool /*bInvertMask*/) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #1", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got URL param #1", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got InputStream param #1", - OUString("InputStream"), xBitmap[1].Name ); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #2", - sal_Int32(3), xMask.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got URL param #2", - OUString("URL"), xMask[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got InputStream param #2", - OUString("InputStream"), xMask[1].Name ); - } - - virtual void drawAlphaMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap, - const uno::Sequence<beans::PropertyValue>& xMask) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #1", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got URL param #1", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got InputStream param #1", - OUString("InputStream"), xBitmap[1].Name ); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #2", - sal_Int32(3), xMask.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got URL param #2", - OUString("URL"), xMask[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got InputStream param #2", - OUString("InputStream"), xMask[1].Name ); - } - - virtual void setTextRenderMode( sal_Int32 ) override - { - } - - typedef std::unordered_map<sal_Int32,FontAttributes> IdToFontMap; - typedef std::unordered_map<FontAttributes,sal_Int32,FontAttrHash> FontToIdMap; - - typedef std::vector<GraphicsContext> GraphicsContextStack; - - sal_Int32 m_nNextFontId; - IdToFontMap m_aIdToFont; - FontToIdMap m_aFontToId; - - GraphicsContextStack m_aGCStack; - geometry::RealSize2D m_aPageSize; - geometry::RealRectangle2D m_aHyperlinkBounds; - OUString m_aURI; - OUStringBuffer m_aTextOut; - sal_Int32 m_nNumPages; - bool m_bPageEnded; - bool m_bRedCircleSeen; - bool m_bGreenStrokeSeen; - bool m_bDashedLineSeen; - bool m_bImageSeen; - }; - - class PDFITest : public test::BootstrapFixture - { - public: - void testXPDFParser() - { -#if HAVE_FEATURE_POPPLER - auto pSink = std::make_shared<TestSink>(); - CPPUNIT_ASSERT( - pdfi::xpdf_ImportFromFile( - m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), - pSink, - uno::Reference< task::XInteractionHandler >(), - OUString(), - getComponentContext(), "" ) ); - pSink->check(); -#endif - } - - void testOdfDrawExport() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference<pdfi::PDFIRawAdaptor> xAdaptor( new pdfi::PDFIRawAdaptor(OUString(), getComponentContext()) ); - xAdaptor->setTreeVisitorFactory( createDrawTreeVisitorFactory() ); - - OUString tempFileURL; - CPPUNIT_ASSERT_EQUAL( osl::File::E_None, osl::File::createTempFile( nullptr, nullptr, &tempFileURL ) ); - osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), - new OutputWrap(tempFileURL), - nullptr )); - osl::File::remove( tempFileURL ); -#endif - } - - void testOdfWriterExport() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference<pdfi::PDFIRawAdaptor> xAdaptor( new pdfi::PDFIRawAdaptor(OUString(), getComponentContext()) ); - xAdaptor->setTreeVisitorFactory( createWriterTreeVisitorFactory() ); - - OUString tempFileURL; - CPPUNIT_ASSERT_EQUAL( osl::File::E_None, osl::File::createTempFile( nullptr, nullptr, &tempFileURL ) ); - osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), - new OutputWrap(tempFileURL), - nullptr )); - osl::File::remove( tempFileURL ); -#endif - } - - void testTdf96993() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference<pdfi::PDFIRawAdaptor> xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf96993.pdf"), - new OutputWrapString(aOutput), - nullptr)); - // This ensures that the imported image arrives properly flipped - CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"matrix(18520.8333333333 0 0 26281.9444444444 0 0)\"") != -1); -#endif - } - - void testTdf98421() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference<pdfi::PDFIRawAdaptor> xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf96993.pdf"), - new OutputWrapString(aOutput), - nullptr)); - // This ensures that the imported image arrives properly flipped - CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"scale( 1.0 -1.0 ) translate( 0mm 0mm )\"") != -1); - CPPUNIT_ASSERT(aOutput.indexOf("svg:height=\"-262.82mm\"") != -1); -#endif - } - - void testTdf105536() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference<pdfi::PDFIRawAdaptor> xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf105536.pdf"), - new OutputWrapString(aOutput), - nullptr)); - // This ensures that the imported image arrives properly flipped - CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"matrix(-21488.4 0 0 -27978.1 21488.4 27978.1)\"") != -1); -#endif - } - - CPPUNIT_TEST_SUITE(PDFITest); - CPPUNIT_TEST(testXPDFParser); - CPPUNIT_TEST(testOdfWriterExport); - CPPUNIT_TEST(testOdfDrawExport); - CPPUNIT_TEST(testTdf96993); - CPPUNIT_TEST(testTdf98421); - CPPUNIT_TEST(testTdf105536); - CPPUNIT_TEST_SUITE_END(); - }; - -} - -CPPUNIT_TEST_SUITE_REGISTRATION(PDFITest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx index ebce9efc896b..7897dbae9d08 100644 --- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx +++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx @@ -16,8 +16,7 @@ * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - - +#include <sal/log.hxx> #include <pdfiprocessor.hxx> #include <xmlemitter.hxx> #include <pdfihelper.hxx> @@ -33,6 +32,7 @@ #include <com/sun/star/i18n/CharacterClassification.hpp> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/i18n/DirectionProperty.hpp> +#include <comphelper/string.hxx> #include <string.h> #include <string_view> @@ -123,10 +123,16 @@ void DrawXmlEmitter::visit( TextElement& elem, const std::list< std::unique_ptr< } if (isRTL) // If so, reverse string - str = PDFIProcessor::mirrorString( str ); + { + // First, produce mirrored-image for each code point which has the Bidi_Mirrored property. + str = PDFIProcessor::SubstituteBidiMirrored(str); + // Then, reverse the code points in the string, in backward order. + str = ::comphelper::string::reverseCodePoints(str); + } m_rEmitContext.rEmitter.beginTag( "text:span", aProps ); + aProps = {}; for(int i=0; i< elem.Text.getLength(); i++) { OUString strToken= str.copy(i,1) ; @@ -188,26 +194,33 @@ void DrawXmlEmitter::fillFrameProps( DrawElement& rElem, bool bWasTransformed ) { - rProps[ "draw:z-index" ] = OUString::number( rElem.ZOrder ); - rProps[ "draw:style-name"] = rEmitContext.rStyles.getStyleName( rElem.StyleId ); + static constexpr OUStringLiteral sDrawZIndex = u"draw:z-index"; + static constexpr OUStringLiteral sDrawStyleName = u"draw:style-name"; + static constexpr OUStringLiteral sDrawTextStyleName = u"draw:text-style-name"; + static constexpr OUStringLiteral sSvgX = u"svg:x"; + static constexpr OUStringLiteral sSvgY = u"svg:y"; + static constexpr OUStringLiteral sSvgWidth = u"svg:width"; + static constexpr OUStringLiteral sSvgHeight = u"svg:height"; + static constexpr OUStringLiteral sDrawTransform = u"draw:transform"; + + rProps[ sDrawZIndex ] = OUString::number( rElem.ZOrder ); + rProps[ sDrawStyleName ] = rEmitContext.rStyles.getStyleName( rElem.StyleId ); if (rElem.IsForText) - rProps["draw:text-style-name"] = rEmitContext.rStyles.getStyleName(rElem.TextStyleId); + rProps[ sDrawTextStyleName ] = rEmitContext.rStyles.getStyleName(rElem.TextStyleId); const GraphicsContext& rGC = rEmitContext.rProcessor.getGraphicsContext( rElem.GCId ); if (bWasTransformed) { - rProps[ "svg:x" ] = convertPixelToUnitString(rElem.x); - rProps[ "svg:y" ] = convertPixelToUnitString(rElem.y); - rProps[ "svg:width" ] = convertPixelToUnitString(rElem.w); - rProps[ "svg:height" ] = convertPixelToUnitString(rElem.h); + rProps[ sSvgX ] = convertPixelToUnitString(rElem.x); + rProps[ sSvgY ] = convertPixelToUnitString(rElem.y); + rProps[ sSvgWidth ] = convertPixelToUnitString(rElem.w); + rProps[ sSvgHeight ] = convertPixelToUnitString(rElem.h); } else { - OUStringBuffer aBuf(256); - basegfx::B2DHomMatrix mat(rGC.Transformation); if (rElem.MirrorVertical) @@ -222,21 +235,21 @@ void DrawXmlEmitter::fillFrameProps( DrawElement& rElem, double scale = convPx2mm(100); mat.scale(scale, scale); - aBuf.append("matrix("); - aBuf.append(mat.get(0, 0)); - aBuf.append(' '); - aBuf.append(mat.get(1, 0)); - aBuf.append(' '); - aBuf.append(mat.get(0, 1)); - aBuf.append(' '); - aBuf.append(mat.get(1, 1)); - aBuf.append(' '); - aBuf.append(mat.get(0, 2)); - aBuf.append(' '); - aBuf.append(mat.get(1, 2)); - aBuf.append(")"); - - rProps["draw:transform"] = aBuf.makeStringAndClear(); + rProps[ sDrawTransform ] = + OUString::Concat("matrix(") + + OUString::number(mat.get(0, 0)) + + " " + + OUString::number(mat.get(1, 0)) + + " " + + OUString::number(mat.get(0, 1)) + + " " + + OUString::number(mat.get(1, 1)) + + " " + + OUString::number(mat.get(0, 2)) + + " " + + OUString::number(mat.get(1, 2)) + + ")"; + } } @@ -319,12 +332,11 @@ void DrawXmlEmitter::visit( PolyPolyElement& elem, const std::list< std::unique_ // so we need to tell fillFrameProps here that the transformation for // a PolyPolyElement was already applied (aside from translation) fillFrameProps( elem, aProps, m_rEmitContext, true ); - OUStringBuffer aBuf( 64 ); - aBuf.append( "0 0 " ); - aBuf.append( convPx2mmPrec2(elem.w)*100.0 ); - aBuf.append( ' ' ); - aBuf.append( convPx2mmPrec2(elem.h)*100.0 ); - aProps[ "svg:viewBox" ] = aBuf.makeStringAndClear(); + aProps[ "svg:viewBox" ] = + "0 0 " + + OUString::number( convPx2mmPrec2(elem.w)*100.0 ) + + " " + + OUString::number( convPx2mmPrec2(elem.h)*100.0 ); aProps[ "svg:d" ] = basegfx::utils::exportToSvgD( elem.PolyPoly, false, true, false ); m_rEmitContext.rEmitter.beginTag( "draw:path", aProps ); @@ -492,7 +504,7 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_pt nCurLineElements = 0; for( const auto& rxChild : pCurPara->Children ) { - TextElement* pTestText = dynamic_cast<TextElement*>(rxChild.get()); + TextElement* pTestText = rxChild->dynCastAsTextElement(); if( pTestText ) { fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->h)/double(nCurLineElements+1); @@ -526,12 +538,12 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_pt // or perhaps the draw element begins a new paragraph else if( next_page_element != elem.Children.end() ) { - TextElement* pText = dynamic_cast<TextElement*>(next_page_element->get()); + TextElement* pText = (*next_page_element)->dynCastAsTextElement(); if( ! pText ) { ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(next_page_element->get()); if( pPara && ! pPara->Children.empty() ) - pText = dynamic_cast<TextElement*>(pPara->Children.front().get()); + pText = pPara->Children.front()->dynCastAsTextElement(); } if( pText && // check there is a text pDraw->h < pText->h*1.5 && // and it is approx the same height @@ -560,9 +572,9 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_pt } } - TextElement* pText = dynamic_cast<TextElement*>(page_element->get()); + TextElement* pText = (*page_element)->dynCastAsTextElement(); if( ! pText && pLink && ! pLink->Children.empty() ) - pText = dynamic_cast<TextElement*>(pLink->Children.front().get()); + pText = pLink->Children.front()->dynCastAsTextElement(); if( pText ) { Element* pGeo = pLink ? static_cast<Element*>(pLink) : @@ -647,15 +659,6 @@ static bool isSpaces(TextElement* pTextElem) return true; } -static bool notTransformed(const GraphicsContext& GC) -{ - return - rtl::math::approxEqual(GC.Transformation.get(0,0), 100.00) && - GC.Transformation.get(1,0) == 0.00 && - GC.Transformation.get(0,1) == 0.00 && - rtl::math::approxEqual(GC.Transformation.get(1,1), -100.00); -} - void DrawXmlOptimizer::optimizeTextElements(Element& rParent) { if( rParent.Children.empty() ) // this should not happen @@ -671,22 +674,15 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) while( next != rParent.Children.end() ) { bool bConcat = false; - TextElement* pCur = dynamic_cast<TextElement*>(it->get()); + TextElement* pCur = (*it)->dynCastAsTextElement(); if( pCur ) { - TextElement* pNext = dynamic_cast<TextElement*>(next->get()); - bool isComplex = false; - OUString str(pCur->Text.toString()); - for(int i=0; i< str.getLength(); i++) - { - sal_Int16 nType = GetBreakIterator()->getScriptType( str, i ); - if (nType == css::i18n::ScriptType::COMPLEX) - isComplex = true; - } + TextElement* pNext = (*next)->dynCastAsTextElement(); + OUString str; bool bPara = strspn("ParagraphElement", typeid(rParent).name()); ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(&rParent); - if (bPara && pPara && isComplex) + if (bPara && pPara && isComplex(GetBreakIterator(), pCur)) pPara->bRtl = true; if( pNext ) { @@ -696,27 +692,61 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) // line and space optimization; works only in strictly horizontal mode // concatenate consecutive text elements unless there is a - // font or text color or matrix change, leave a new span in that case + // font or text color change, leave a new span in that case if( (pCur->FontId == pNext->FontId || isSpaces(pNext)) && rCurGC.FillColor.Red == rNextGC.FillColor.Red && rCurGC.FillColor.Green == rNextGC.FillColor.Green && rCurGC.FillColor.Blue == rNextGC.FillColor.Blue && - rCurGC.FillColor.Alpha == rNextGC.FillColor.Alpha && - (rCurGC.Transformation == rNextGC.Transformation || notTransformed(rNextGC)) + rCurGC.FillColor.Alpha == rNextGC.FillColor.Alpha ) { pCur->updateGeometryWith( pNext ); - // append text to current element - pCur->Text.append( pNext->Text ); - - str = pCur->Text.toString(); - for(int i=0; i< str.getLength(); i++) + if (pPara && pPara->bRtl) { - sal_Int16 nType = GetBreakIterator()->getScriptType( str, i ); - if (nType == css::i18n::ScriptType::COMPLEX) - isComplex = true; + // Tdf#152083: If RTL, reverse the text in pNext so that its correct order is + // restored when the combined text is reversed in DrawXmlEmitter::visit. + OUString tempStr; + bool bNeedReverse=false; + str = pNext->Text.toString(); + for (sal_Int32 i=0; i < str.getLength(); i++) + { + if (str[i] == u' ') + { // Space char (e.g. the space as in " Ù…") needs special treatment. + // First, append the space char to pCur. + pCur->Text.append(OUStringChar(str[i])); + // Then, check whether the tmpStr needs reverse, if so then reverse and append. + if (bNeedReverse) + { + tempStr = ::comphelper::string::reverseCodePoints(tempStr); + pCur->Text.append(tempStr); + tempStr = u""_ustr; + } + bNeedReverse = false; + } + else + { + tempStr += OUStringChar(str[i]); + bNeedReverse = true; + } + } + // Do the last append + if (bNeedReverse) + { + tempStr = ::comphelper::string::reverseCodePoints(tempStr); + pCur->Text.append(tempStr); + } + else + { + pCur->Text.append(tempStr); + } } - if (bPara && pPara && isComplex) + else + { + // append text to current element directly without reverse + pCur->Text.append( pNext->Text ); + } + + if (bPara && pPara && isComplex(GetBreakIterator(), pCur)) pPara->bRtl = true; // append eventual children to current element // and clear children (else the children just @@ -767,7 +797,7 @@ void DrawXmlFinalizer::visit( PolyPolyElement& elem, const std::list< std::uniqu { PropertyMap props; FillDashStyleProps(props, rGC.DashArray, scale); - StyleContainer::Style style("draw:stroke-dash", props); + StyleContainer::Style style("draw:stroke-dash"_ostr, std::move(props)); aGCProps[ "draw:stroke" ] = "dash"; aGCProps[ "draw:stroke-dash" ] = @@ -787,10 +817,31 @@ void DrawXmlFinalizer::visit( PolyPolyElement& elem, const std::list< std::uniqu aGCProps[ "draw:stroke" ] = "none"; } + if (elem.FillImage != -1) + { + PropertyMap props; + // The image isn't actually in a prop, it's in an extra chunk inside. + StyleContainer::Style style("draw:fill-image"_ostr, std::move(props)); + style.Contents = m_rProcessor.getImages().asBase64EncodedString(elem.FillImage); + aGCProps[ "draw:fill-image-name" ] = + m_rStyleContainer.getStyleName( + m_rStyleContainer.getStyleId(style)); + aGCProps[ "draw:fill-image-width" ] = unitMMString(convPx2mm(elem.TileWidth)); + aGCProps[ "draw:fill-image-height" ] = unitMMString(convPx2mm(elem.TileHeight)); + + } + // TODO(F1): check whether stuff could be emulated by gradient/bitmap/hatch if( elem.Action & (PATH_FILL | PATH_EOFILL) ) { - aGCProps[ "draw:fill" ] = "solid"; + if (elem.FillImage == -1) + { + aGCProps[ "draw:fill" ] = "solid"; + } + else + { + aGCProps[ "draw:fill" ] = "bitmap"; + } aGCProps[ "draw:fill-color" ] = getColorString(rGC.FillColor); if (rGC.FillColor.Alpha != 1.0) aGCProps["draw:opacity"] = getPercentString(rGC.FillColor.Alpha * 100.0); @@ -800,8 +851,8 @@ void DrawXmlFinalizer::visit( PolyPolyElement& elem, const std::list< std::uniqu aGCProps[ "draw:fill" ] = "none"; } - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:graphic-properties", aGCProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:graphic-properties"_ostr, std::move(aGCProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); @@ -828,23 +879,25 @@ void DrawXmlFinalizer::visit( TextElement& elem, const std::list< std::unique_pt PropertyMap aFontProps; // family name + // TODO: tdf#143095: use system font name rather than PSName + SAL_INFO("sdext.pdfimport", "The font used in xml is: " << rFont.familyName); aFontProps[ "fo:font-family" ] = rFont.familyName; + aFontProps[ "style:font-family-asian" ] = rFont.familyName; aFontProps[ "style:font-family-complex" ] = rFont.familyName; // bold - if( rFont.isBold ) - { - aFontProps[ "fo:font-weight" ] = "bold"; - aFontProps[ "fo:font-weight-asian" ] = "bold"; - aFontProps[ "style:font-weight-complex" ] = "bold"; - } + aFontProps[ "fo:font-weight" ] = rFont.fontWeight; + aFontProps[ "style:font-weight-asian" ] = rFont.fontWeight; + aFontProps[ "style:font-weight-complex" ] = rFont.fontWeight; + // italic if( rFont.isItalic ) { aFontProps[ "fo:font-style" ] = "italic"; - aFontProps[ "fo:font-style-asian" ] = "italic"; + aFontProps[ "style:font-style-asian" ] = "italic"; aFontProps[ "style:font-style-complex" ] = "italic"; } + // underline if( rFont.isUnderline ) { @@ -852,11 +905,10 @@ void DrawXmlFinalizer::visit( TextElement& elem, const std::list< std::unique_pt aFontProps[ "style:text-underline-width" ] = "auto"; aFontProps[ "style:text-underline-color" ] = "font-color"; } + // outline if( rFont.isOutline ) - { aFontProps[ "style:text-outline" ] = "true"; - } // size SetFontsizeProperties(aFontProps, rFont.size); @@ -876,8 +928,8 @@ void DrawXmlFinalizer::visit( TextElement& elem, const std::list< std::unique_pt aFontProps[ "style:text-scale" ] = getPercentString(textScale); } - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:text-properties", aFontProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:text-properties"_ostr, std::move(aFontProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); } @@ -898,8 +950,8 @@ void DrawXmlFinalizer::visit( ParagraphElement& elem, const std::list< std::uniq else aParProps[ "style:writing-mode"] = "lr-tb"; - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:paragraph-properties", aParProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:paragraph-properties"_ostr, std::move(aParProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); @@ -930,8 +982,8 @@ void DrawXmlFinalizer::visit( FrameElement& elem, const std::list< std::unique_p aGCProps[ "fo:padding-right" ] = "0cm"; aGCProps[ "fo:padding-bottom" ] = "0cm"; - StyleContainer::Style style1( "style:style", props1 ); - StyleContainer::Style subStyle1( "style:graphic-properties", aGCProps ); + StyleContainer::Style style1( "style:style"_ostr, std::move(props1) ); + StyleContainer::Style subStyle1( "style:graphic-properties"_ostr, std::move(aGCProps) ); style1.SubStyles.push_back(&subStyle1); elem.StyleId = m_rStyleContainer.getStyleId(style1); @@ -944,8 +996,8 @@ void DrawXmlFinalizer::visit( FrameElement& elem, const std::list< std::unique_p PropertyMap textProps; SetFontsizeProperties(textProps, elem.FontSize); - StyleContainer::Style style2("style:style", props2); - StyleContainer::Style subStyle2("style:text-properties", textProps); + StyleContainer::Style style2("style:style"_ostr, std::move(props2)); + StyleContainer::Style subStyle2("style:text-properties"_ostr, std::move(textProps)); style2.SubStyles.push_back(&subStyle2); elem.TextStyleId = m_rStyleContainer.getStyleId(style2); } @@ -1038,8 +1090,8 @@ void DrawXmlFinalizer::visit( PageElement& elem, const std::list< std::unique_pt aPageLayoutProps[ "style:print-orientation" ]= elem.w < elem.h ? std::u16string_view(u"portrait") : std::u16string_view(u"landscape"); aPageLayoutProps[ "style:writing-mode" ]= "lr-tb"; - StyleContainer::Style aStyle( "style:page-layout", aPageProps); - StyleContainer::Style aSubStyle( "style:page-layout-properties", aPageLayoutProps); + StyleContainer::Style aStyle( "style:page-layout"_ostr, std::move(aPageProps)); + StyleContainer::Style aSubStyle( "style:page-layout-properties"_ostr, std::move(aPageLayoutProps)); aStyle.SubStyles.push_back(&aSubStyle); sal_Int32 nPageStyle = m_rStyleContainer.impl_getStyleId( aStyle, false ); @@ -1047,7 +1099,7 @@ void DrawXmlFinalizer::visit( PageElement& elem, const std::list< std::unique_pt OUString aMasterPageLayoutName = m_rStyleContainer.getStyleName( nPageStyle ); aPageProps[ "style:page-layout-name" ] = aMasterPageLayoutName; - StyleContainer::Style aMPStyle( "style:master-page", aPageProps); + StyleContainer::Style aMPStyle( "style:master-page"_ostr, std::move(aPageProps)); elem.StyleId = m_rStyleContainer.impl_getStyleId( aMPStyle,false ); diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.hxx b/sdext/source/pdfimport/tree/drawtreevisiting.hxx index 81bfd927354b..e3ea8e537ff5 100644 --- a/sdext/source/pdfimport/tree/drawtreevisiting.hxx +++ b/sdext/source/pdfimport/tree/drawtreevisiting.hxx @@ -24,8 +24,6 @@ #include <com/sun/star/i18n/XBreakIterator.hpp> #include <com/sun/star/i18n/XCharacterClassification.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> namespace pdfi { diff --git a/sdext/source/pdfimport/tree/genericelements.cxx b/sdext/source/pdfimport/tree/genericelements.cxx index b02e2c0a727d..aec9c999fcf6 100644 --- a/sdext/source/pdfimport/tree/genericelements.cxx +++ b/sdext/source/pdfimport/tree/genericelements.cxx @@ -22,7 +22,8 @@ #include <pdfiprocessor.hxx> #include <pdfihelper.hxx> - +#include <com/sun/star/i18n/BreakIterator.hpp> +#include <com/sun/star/i18n/ScriptType.hpp> #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/range/b2drange.hxx> #include <sal/log.hxx> @@ -123,10 +124,16 @@ void ImageElement::visitedBy( ElementTreeVisitor& rVisi PolyPolyElement::PolyPolyElement( Element* pParent, sal_Int32 nGCId, const basegfx::B2DPolyPolygon& rPolyPoly, - sal_Int8 nAction ) + sal_Int8 nAction, + ImageId nFillImage, + double nTileWidth, + double nTileHeight ) : DrawElement( pParent, nGCId ), PolyPoly( rPolyPoly ), - Action( nAction ) + Action( nAction ), + FillImage( nFillImage ), + TileWidth( nTileWidth ), + TileHeight( nTileHeight ) { } @@ -156,8 +163,8 @@ void PolyPolyElement::visitedBy( ElementTreeVisitor& rV #if OSL_DEBUG_LEVEL > 0 void PolyPolyElement::emitStructure( int nLevel) { - SAL_WARN( "sdext", std::string(nLevel, ' ') << "<" << typeid( *this ).name() << " " << this << ">" ); - SAL_WARN( "sdext", "path=" ); + SAL_INFO( "sdext", std::string(nLevel, ' ') << "<" << typeid( *this ).name() << " " << this << ">" ); + SAL_INFO( "sdext", "path=" ); int nPoly = PolyPoly.count(); for( int i = 0; i < nPoly; i++ ) { @@ -169,11 +176,11 @@ void PolyPolyElement::emitStructure( int nLevel) basegfx::B2DPoint aPoint = aPoly.getB2DPoint( n ); buff.append( " (" + OUString::number(aPoint.getX()) + "," + OUString::number(aPoint.getY()) + ")"); } - SAL_WARN( "sdext", " " << buff.makeStringAndClear() ); + SAL_INFO( "sdext", " " << buff.makeStringAndClear() ); } for (auto const& child : Children) child->emitStructure( nLevel+1 ); - SAL_WARN( "sdext", std::string(nLevel, ' ') << "</" << typeid( *this ).name() << ">"); + SAL_INFO( "sdext", std::string(nLevel, ' ') << "</" << typeid( *this ).name() << ">"); } #endif @@ -192,7 +199,7 @@ bool ParagraphElement::isSingleLined( PDFIProcessor const & rProc ) const if( dynamic_cast< ParagraphElement* >(rxChild.get()) != nullptr ) return false; - pText = dynamic_cast< TextElement* >(rxChild.get()); + pText = rxChild->dynCastAsTextElement(); if( pText ) { const FontAttributes& rFont = rProc.getFont( pText->FontId ); @@ -226,7 +233,7 @@ double ParagraphElement::getLineHeight( PDFIProcessor& rProc ) const if( lh > line_h ) line_h = lh; } - else if( (pText = dynamic_cast< TextElement* >( rxChild.get() )) != nullptr ) + else if( (pText = rxChild->dynCastAsTextElement()) != nullptr ) { const FontAttributes& rFont = rProc.getFont( pText->FontId ); double lh = pText->h; @@ -243,9 +250,9 @@ TextElement* ParagraphElement::getFirstTextChild() const { TextElement* pText = nullptr; auto it = std::find_if(Children.begin(), Children.end(), - [](const std::unique_ptr<Element>& rxElem) { return dynamic_cast<TextElement*>(rxElem.get()) != nullptr; }); + [](const std::unique_ptr<Element>& rxElem) { return rxElem->dynCastAsTextElement() != nullptr; }); if (it != Children.end()) - pText = dynamic_cast<TextElement*>(it->get()); + pText = (*it)->dynCastAsTextElement(); return pText; } @@ -270,7 +277,7 @@ bool PageElement::resolveHyperlink( const std::list<std::unique_ptr<Element>>::i if( (*it)->x >= pLink->x && (*it)->x + (*it)->w <= pLink->x + pLink->w && (*it)->y >= pLink->y && (*it)->y + (*it)->h <= pLink->y + pLink->h ) { - TextElement* pText = dynamic_cast<TextElement*>(it->get()); + TextElement* pText = (*it)->dynCastAsTextElement(); if( pText ) { if( pLink->Children.empty() ) @@ -332,6 +339,14 @@ void PageElement::resolveUnderlines( PDFIProcessor const & rProc ) // FIXME: currently the algorithm used is quadratic // this could be solved by some sorting beforehand + std::vector<Element*> textAndHypers; + textAndHypers.reserve(Children.size()); + for (auto const & p : Children) + { + if (p->dynCastAsTextElement() || dynamic_cast<HyperlinkElement*>(p.get())) + textAndHypers.push_back(p.get()); + } + auto poly_it = Children.begin(); while( poly_it != Children.end() ) { @@ -372,16 +387,15 @@ void PageElement::resolveUnderlines( PDFIProcessor const & rProc ) u_y = r_x; r_x = l_x; l_x = u_y; } u_y = aPoly.getB2DPoint(0).getY(); - for( const auto& rxChild : Children ) + for( Element* pEle : textAndHypers ) { - Element* pEle = rxChild.get(); if( pEle->y <= u_y && pEle->y + pEle->h*1.1 >= u_y ) { // first: is the element underlined completely ? if( pEle->x + pEle->w*0.1 >= l_x && pEle->x + pEle->w*0.9 <= r_x ) { - TextElement* pText = dynamic_cast< TextElement* >(pEle); + TextElement* pText = pEle->dynCastAsTextElement(); if( pText ) { const GraphicsContext& rTextGC = rProc.getGraphicsContext( pText->GCId ); @@ -394,25 +408,20 @@ void PageElement::resolveUnderlines( PDFIProcessor const & rProc ) pText->FontId = rProc.getFontId( aAttr ); } } - else if( dynamic_cast< HyperlinkElement* >(pEle) ) + else // must be HyperlinkElement bRemovePoly = true; } // second: hyperlinks may be larger than their underline // since they are just arbitrary rectangles in the action definition - else if( dynamic_cast< HyperlinkElement* >(pEle) != nullptr && - l_x >= pEle->x && r_x <= pEle->x+pEle->w ) + else if( l_x >= pEle->x && r_x <= pEle->x+pEle->w && + dynamic_cast< HyperlinkElement* >(pEle) != nullptr ) { bRemovePoly = true; } } } if( bRemovePoly ) - { - auto next_it = poly_it; - ++next_it; - Children.erase( poly_it ); - poly_it = next_it; - } + poly_it = Children.erase( poly_it ); else ++poly_it; } @@ -428,6 +437,18 @@ void DocumentElement::visitedBy( ElementTreeVisitor& rV rVisitor.visit(*this, rParentIt); } +bool isComplex(const css::uno::Reference<css::i18n::XBreakIterator>& rBreakIterator, TextElement* const pTextElem) { + OUString str(pTextElem->Text.toString()); + for(int i=0; i< str.getLength(); i++) + { + sal_Int16 nType = rBreakIterator->getScriptType(str, i); + if (nType == css::i18n::ScriptType::COMPLEX) + { + return true; + } + } + return false; +} } diff --git a/sdext/source/pdfimport/tree/imagecontainer.cxx b/sdext/source/pdfimport/tree/imagecontainer.cxx index 087849d6b5dc..b9f7ef52e061 100644 --- a/sdext/source/pdfimport/tree/imagecontainer.cxx +++ b/sdext/source/pdfimport/tree/imagecontainer.cxx @@ -24,6 +24,7 @@ #include <rtl/ustrbuf.hxx> #include <sal/log.hxx> +#include <o3tl/safeint.hxx> #include <osl/diagnose.h> #include <com/sun/star/beans/PropertyValue.hpp> @@ -43,7 +44,7 @@ const char aBase64EncodeTable[] = 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; -OUString encodeBase64( const sal_Int8* i_pBuffer, const sal_uInt32 i_nBufferLength ) +OUString encodeBase64( const sal_Int8* i_pBuffer, const sal_Int32 i_nBufferLength ) { OUStringBuffer aBuf( (i_nBufferLength+1) * 4 / 3 ); const sal_Int32 nRemain(i_nBufferLength%3); @@ -100,8 +101,7 @@ OUString encodeBase64( const sal_Int8* i_pBuffer, const sal_uInt32 i_nBufferLeng } // namespace -ImageContainer::ImageContainer() : - m_aImages() +ImageContainer::ImageContainer() {} ImageId ImageContainer::addImage( const uno::Sequence<beans::PropertyValue>& xBitmap ) @@ -112,7 +112,7 @@ ImageId ImageContainer::addImage( const uno::Sequence<beans::PropertyValue>& xBi void ImageContainer::writeBase64EncodedStream( ImageId nId, EmitContext& rContext ) { - OSL_ASSERT( nId >= 0 && nId < ImageId( m_aImages.size()) ); + OSL_ASSERT( nId >= 0 && o3tl::make_unsigned(nId) < m_aImages.size() ); const uno::Sequence<beans::PropertyValue>& rEntry( m_aImages[nId] ); @@ -141,6 +141,37 @@ void ImageContainer::writeBase64EncodedStream( ImageId nId, EmitContext& rContex rContext.rEmitter.write( encodeBase64( aData.getConstArray(), aData.getLength() )); } +OUString ImageContainer::asBase64EncodedString( ImageId nId ) const +{ + OSL_ASSERT( nId >= 0 && o3tl::make_unsigned(nId) < m_aImages.size() ); + + const uno::Sequence<beans::PropertyValue>& rEntry( m_aImages[nId] ); + + // find "InputSequence" property + const beans::PropertyValue* pAry(rEntry.getConstArray()); + const sal_Int32 nLen(rEntry.getLength()); + const beans::PropertyValue* pValue( + std::find_if(pAry, pAry+nLen, + [] (beans::PropertyValue const& v) -> bool { + return v.Name == "InputSequence"; + })); + + if (pValue == pAry + nLen ) + { + SAL_WARN("sdext.pdfimport", "InputSequence not found"); + return ""; + } + + uno::Sequence<sal_Int8> aData; + if( !(pValue->Value >>= aData) ) + { + SAL_WARN("sdext.pdfimport", "Wrong data type"); + return ""; + } + + return encodeBase64( aData.getConstArray(), aData.getLength() ); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx index ed2eaf6510b9..d60431dbce09 100644 --- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx +++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx @@ -28,12 +28,15 @@ #include <sal/log.hxx> +#include <com/sun/star/geometry/AffineMatrix2D.hpp> + #include <comphelper/sequence.hxx> #include <basegfx/polygon/b2dpolygonclipper.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/utils/canvastools.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> -#include <vcl/svapp.hxx> +#include <i18nutil/unicode.hxx> +#include <o3tl/string_view.hxx> using namespace com::sun::star; @@ -50,20 +53,14 @@ namespace pdfi m_pCurPage(nullptr), m_pCurElement(nullptr), m_nNextFontId( 1 ), - m_aIdToFont(), - m_aFontToId(), - m_aGCStack(), m_nNextGCId( 1 ), - m_aIdToGC(), - m_aGCToId(), - m_aImages(), m_nPages(0), m_nNextZOrder( 1 ), m_xStatusIndicator( xStat ) { FontAttributes aDefFont; aDefFont.familyName = "Helvetica"; - aDefFont.isBold = false; + aDefFont.fontWeight = u"normal"_ustr; aDefFont.isItalic = false; aDefFont.size = 10*PDFI_OUTDEV_RESOLUTION/72; m_aIdToFont.insert({0, aDefFont}); @@ -147,7 +144,20 @@ void PDFIProcessor::setFont( const FontAttributes& i_rFont ) FontAttributes aChangedFont( i_rFont ); GraphicsContext& rGC=getCurrentContext(); // for text render modes, please see PDF reference manual - aChangedFont.isOutline = ( (rGC.TextRenderMode == 1) || (rGC. TextRenderMode == 2) ); + if (rGC.TextRenderMode == 1) + { + aChangedFont.isOutline = true; + } + else if (rGC.TextRenderMode == 2) + { + // tdf#81484: faux bold is represented as "stroke+fill" (while using the same color for both stroke and fill) in pdf. + // Convert to bold instead if the stroke color is the same as the fill color, + // otherwise it should be outline. + if (getCurrentContext().LineColor == getCurrentContext().FillColor) + aChangedFont.fontWeight = u"bold"_ustr; + else + aChangedFont.isOutline = true; + } FontToIdMap::const_iterator it = m_aFontToId.find( aChangedFont ); if( it != m_aFontToId.end() ) rGC.FontId = it->second; @@ -310,7 +320,7 @@ void PDFIProcessor::drawGlyphs( const OUString& rGlyphs, void PDFIProcessor::endText() { - TextElement* pText = dynamic_cast<TextElement*>(m_pCurElement); + TextElement* pText = m_pCurElement->dynCastAsTextElement(); if( pText ) m_pCurElement = pText->Parent; } @@ -376,6 +386,64 @@ void PDFIProcessor::drawAlphaMaskedImage(const uno::Sequence<beans::PropertyValu } +void PDFIProcessor::tilingPatternFill(int nX0, int nY0, int nX1, int nY1, + double nxStep, double nyStep, + int /* nPaintType */, + css::geometry::AffineMatrix2D& rMat, + const css::uno::Sequence<css::beans::PropertyValue>& xTile) +{ + const GraphicsContext& rGC(getCurrentContext()); + auto nTile = m_aImages.addImage(xTile); + + basegfx::B2DTuple aScale, aTranslation; + double fRotate, fShearX; + auto rTfm = rGC.Transformation; + rTfm.decompose(aScale, aTranslation, fRotate, fShearX); + + // Build a poly covering the whole fill area + double np0x = nX0 * nxStep; + double np0y = nY0 * nyStep; + double np1x = nX1 * nxStep; + double np1y = nY1 * nyStep; + + // Transform with the rMat passed in + double tmpx, tmpy; + tmpx = np0x * rMat.m00 + np0y * rMat.m01 + rMat.m02; + tmpy = np0x * rMat.m10 + np0y * rMat.m11 + rMat.m12; + np0x = tmpx; + np0y = tmpy; + tmpx = np1x * rMat.m00 + np1y * rMat.m01 + rMat.m02; + tmpy = np1x * rMat.m10 + np1y * rMat.m11 + rMat.m12; + np1x = tmpx; + np1y = tmpy; + + auto aB2DPoly = basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(basegfx::B2DRange(np0x, np0y, np1x, np1y))); + aB2DPoly.transform(getCurrentContext().Transformation); + + // Clip against current clip path, if any + basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; + if( aCurClip.count() ) { + aB2DPoly = basegfx::utils::clipPolyPolygonOnPolyPolygon( aB2DPoly, aCurClip, + true, /* bInside, keep parts inside the clip */ + false /* bStroke, filled not stroked */ ); + } + // TODO: That clipping might shift the fill pattern offsets + + double transformedxStep = nxStep * rMat.m00 + nyStep * rMat.m01; + double transformedyStep = nxStep * rMat.m10 + nyStep * rMat.m11; + + auto pPolyElement = ElementFactory::createPolyPolyElement( + m_pCurElement, + getGCId(getCurrentContext()), + aB2DPoly, + PATH_EOFILL, // Hmm how do I know if this should be EO or not? + nTile, + transformedxStep * aScale.getX(), + transformedyStep * -aScale.getY()); + pPolyElement->updateGeometry(); + pPolyElement->ZOrder = m_nNextZOrder++; +} + void PDFIProcessor::strokePath( const uno::Reference< rendering::XPolyPolygon2D >& rPath ) { basegfx::B2DPolyPolygon aPoly=basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); @@ -385,7 +453,8 @@ void PDFIProcessor::strokePath( const uno::Reference< rendering::XPolyPolygon2D m_pCurElement, getGCId(getCurrentContext()), aPoly, - PATH_STROKE ); + PATH_STROKE, + -1, 0, 0 ); pPoly->updateGeometry(); pPoly->ZOrder = m_nNextZOrder++; } @@ -399,7 +468,8 @@ void PDFIProcessor::fillPath( const uno::Reference< rendering::XPolyPolygon2D >& m_pCurElement, getGCId(getCurrentContext()), aPoly, - PATH_FILL ); + PATH_FILL, + -1, 0, 0 ); pPoly->updateGeometry(); pPoly->ZOrder = m_nNextZOrder++; } @@ -413,7 +483,8 @@ void PDFIProcessor::eoFillPath( const uno::Reference< rendering::XPolyPolygon2D m_pCurElement, getGCId(getCurrentContext()), aPoly, - PATH_EOFILL ); + PATH_EOFILL, + -1, 0, 0 ); pPoly->updateGeometry(); pPoly->ZOrder = m_nNextZOrder++; } @@ -464,6 +535,7 @@ const FontAttributes& PDFIProcessor::getFont( sal_Int32 nFontId ) const IdToFontMap::const_iterator it = m_aIdToFont.find( nFontId ); if( it == m_aIdToFont.end() ) it = m_aIdToFont.find( 0 ); + assert(it != m_aIdToFont.end()); return it->second; } @@ -489,6 +561,7 @@ const GraphicsContext& PDFIProcessor::getGraphicsContext( sal_Int32 nGCId ) cons auto it = m_aIdToGC.find( nGCId ); if( it == m_aIdToGC.end() ) it = m_aIdToGC.find( 0 ); + assert(it != m_aIdToGC.end()); return it->second; } @@ -630,9 +703,9 @@ static bool lr_tb_sort( std::unique_ptr<Element> const & pLeft, std::unique_ptr< // of the same order as font height whereas the real paint area // of text is usually smaller double fudge_factor_left = 0.0, fudge_factor_right = 0.0; - if( dynamic_cast< TextElement* >(pLeft.get()) ) + if( pLeft->dynCastAsTextElement() ) fudge_factor_left = 0.1; - if (dynamic_cast< TextElement* >(pRight.get())) + if( pRight->dynCastAsTextElement() ) fudge_factor_right = 0.1; // Allow negative height @@ -688,20 +761,17 @@ void PDFIProcessor::sortElements(Element* pEle) pEle->Children.sort(lr_tb_sort); } -// helper method: get a mirrored string -OUString PDFIProcessor::mirrorString( const OUString& i_rString ) +/* Produce mirrored-image for each code point which has the Bidi_Mirrored property, within a string. + This need to be done in forward order. +*/ +OUString PDFIProcessor::SubstituteBidiMirrored(std::u16string_view rString) { - const sal_Int32 nLen = i_rString.getLength(); - OUStringBuffer aMirror( nLen ); - - sal_Int32 i = 0; - while(i < nLen) - { - // read one code point - const sal_uInt32 nCodePoint = i_rString.iterateCodePoints( &i ); + const sal_Int32 nLen = rString.size(); + OUStringBuffer aMirror(nLen); - // and append it mirrored - aMirror.appendUtf32( GetMirroredChar(nCodePoint) ); + for (sal_Int32 i = 0; i < nLen;) { + const sal_uInt32 nCodePoint = o3tl::iterateCodePoints(rString, &i); + aMirror.appendUtf32(unicode::GetMirroredChar(nCodePoint)); } return aMirror.makeStringAndClear(); } diff --git a/sdext/source/pdfimport/tree/style.cxx b/sdext/source/pdfimport/tree/style.cxx index 73a9bd936663..969fdc0e9648 100644 --- a/sdext/source/pdfimport/tree/style.cxx +++ b/sdext/source/pdfimport/tree/style.cxx @@ -79,7 +79,7 @@ sal_Int32 StyleContainer::getStandardStyleId( std::string_view rName ) aProps[ "style:family" ] = OStringToOUString( rName, RTL_TEXTENCODING_UTF8 ); aProps[ "style:name" ] = "standard"; - Style aStyle( "style:style", aProps ); + Style aStyle( "style:style"_ostr, std::move(aProps) ); return getStyleId( aStyle ); } @@ -90,7 +90,7 @@ const PropertyMap* StyleContainer::getProperties( sal_Int32 nStyleId ) const return it != m_aIdToStyle.end() ? &(it->second.style.Properties) : nullptr; } -sal_Int32 StyleContainer::setProperties( sal_Int32 nStyleId, const PropertyMap& rNewProps ) +sal_Int32 StyleContainer::setProperties( sal_Int32 nStyleId, PropertyMap&& rNewProps ) { sal_Int32 nRet = -1; std::unordered_map< sal_Int32, RefCountedHashedStyle >::iterator it = @@ -103,7 +103,7 @@ sal_Int32 StyleContainer::setProperties( sal_Int32 nStyleId, const PropertyMap& // erase old hash to id mapping m_aStyleToId.erase( it->second.style ); // change properties - it->second.style.Properties = rNewProps; + it->second.style.Properties = std::move(rNewProps); // fill in new hash to id mapping m_aStyleToId[ it->second.style ] = nRet; } @@ -114,7 +114,7 @@ sal_Int32 StyleContainer::setProperties( sal_Int32 nStyleId, const PropertyMap& // acquire new HashedStyle HashedStyle aSearchStyle; aSearchStyle.Name = it->second.style.Name; - aSearchStyle.Properties = rNewProps; + aSearchStyle.Properties = std::move(rNewProps); aSearchStyle.Contents = it->second.style.Contents; aSearchStyle.ContainedElement = it->second.style.ContainedElement; aSearchStyle.SubStyles = it->second.style.SubStyles; @@ -167,14 +167,12 @@ OUString StyleContainer::getStyleName( sal_Int32 nStyle ) const else aStyleName = OStringToOUString( rStyle.Name, RTL_TEXTENCODING_ASCII_US ); sal_Int32 nIndex = aStyleName.lastIndexOf( ':' ); - aRet.append( aStyleName.subView(nIndex+1) ); - aRet.append( nStyle ); + aRet.append( aStyleName.subView(nIndex+1) + OUString::number( nStyle ) ); } } else { - aRet.append( "invalid style id " ); - aRet.append( nStyle ); + aRet.append( "invalid style id " + OUString::number(nStyle) ); } return aRet.makeStringAndClear(); @@ -192,14 +190,18 @@ void StyleContainer::impl_emitStyle( sal_Int32 nStyleId, PropertyMap aProps( rStyle.Properties ); if( !rStyle.IsSubStyle ) aProps[ "style:name" ] = getStyleName( nStyleId ); - if (rStyle.Name == "draw:stroke-dash") + if (rStyle.Name == "draw:stroke-dash" || rStyle.Name == "draw:fill-image") aProps[ "draw:name" ] = aProps[ "style:name" ]; rContext.rEmitter.beginTag( rStyle.Name.getStr(), aProps ); for(sal_Int32 nSubStyle : rStyle.SubStyles) impl_emitStyle( nSubStyle, rContext, rContainedElemVisitor ); if( !rStyle.Contents.isEmpty() ) + { + rContext.rEmitter.beginTag( "office:binary-data", PropertyMap() ); rContext.rEmitter.write( rStyle.Contents ); + rContext.rEmitter.endTag( "office:binary-data" ); + } if( rStyle.ContainedElement ) rStyle.ContainedElement->visitedBy( rContainedElemVisitor, std::list<std::unique_ptr<Element>>::iterator() ); diff --git a/sdext/source/pdfimport/tree/style.hxx b/sdext/source/pdfimport/tree/style.hxx index 784249a114c4..572be241e9e8 100644 --- a/sdext/source/pdfimport/tree/style.hxx +++ b/sdext/source/pdfimport/tree/style.hxx @@ -45,9 +45,9 @@ namespace pdfi Element* ContainedElement; std::vector< Style* > SubStyles; - Style( const OString& rName, const PropertyMap& rProps ) : + Style( const OString& rName, PropertyMap&& rProps ) : Name( rName ), - Properties( rProps ), + Properties( std::move(rProps) ), ContainedElement( nullptr ) {} }; @@ -156,7 +156,7 @@ namespace pdfi // returns NULL for an invalid style id const PropertyMap* getProperties( sal_Int32 nStyleId ) const; - sal_Int32 setProperties( sal_Int32 nStyleId, const PropertyMap &rNewProps ); + sal_Int32 setProperties( sal_Int32 nStyleId, PropertyMap&& rNewProps ); OUString getStyleName( sal_Int32 nStyle ) const; }; } diff --git a/sdext/source/pdfimport/tree/writertreevisiting.cxx b/sdext/source/pdfimport/tree/writertreevisiting.cxx index 79b799f7c9a3..9012aaa21038 100644 --- a/sdext/source/pdfimport/tree/writertreevisiting.cxx +++ b/sdext/source/pdfimport/tree/writertreevisiting.cxx @@ -18,7 +18,7 @@ */ #include <sal/config.h> - +#include <sal/log.hxx> #include <string_view> #include <pdfiprocessor.hxx> @@ -31,12 +31,37 @@ #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <osl/diagnose.h> +#include <com/sun/star/i18n/CharacterClassification.hpp> +#include <com/sun/star/i18n/DirectionProperty.hpp> +#include <comphelper/string.hxx> using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; namespace pdfi { +const Reference<XBreakIterator>& WriterXmlOptimizer::GetBreakIterator() +{ + if (!mxBreakIter.is()) + { + mxBreakIter = BreakIterator::create(m_rProcessor.m_xContext); + } + return mxBreakIter; +} + +const Reference< XCharacterClassification >& WriterXmlEmitter::GetCharacterClassification() +{ + if ( !mxCharClass.is() ) + { + Reference< XComponentContext > xContext( m_rEmitContext.m_xContext, uno::UNO_SET_THROW ); + mxCharClass = CharacterClassification::create(xContext); + } + return mxCharClass; +} + void WriterXmlEmitter::visit( HyperlinkElement& elem, const std::list< std::unique_ptr<Element> >::const_iterator& ) { if( elem.Children.empty() ) @@ -65,15 +90,65 @@ void WriterXmlEmitter::visit( TextElement& elem, const std::list< std::unique_pt if( elem.Text.isEmpty() ) return; - PropertyMap aProps; + PropertyMap aProps = {}; + const sal_Unicode strSpace = 0x0020; + const sal_Unicode strNbSpace = 0x00A0; + const sal_Unicode tabSpace = 0x0009; + if( elem.StyleId != -1 ) { aProps[ OUString( "text:style-name" ) ] = m_rEmitContext.rStyles.getStyleName( elem.StyleId ); } + OUString str(elem.Text.toString()); + + // Check for RTL + bool isRTL = false; + Reference< i18n::XCharacterClassification > xCC( GetCharacterClassification() ); + if( xCC.is() ) + { + for(int i=1; i< elem.Text.getLength(); i++) + { + i18n::DirectionProperty nType = static_cast<i18n::DirectionProperty>(xCC->getCharacterDirection( str, i )); + if ( nType == i18n::DirectionProperty_RIGHT_TO_LEFT || + nType == i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC || + nType == i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING || + nType == i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE + ) + isRTL = true; + } + } + + if (isRTL) // If so, reverse string + { + // First, produce mirrored-image for each code point which has the Bidi_Mirrored property. + str = PDFIProcessor::SubstituteBidiMirrored(str); + // Then, reverse the code points in the string, in backward order. + str = ::comphelper::string::reverseCodePoints(str); + } + m_rEmitContext.rEmitter.beginTag( "text:span", aProps ); - m_rEmitContext.rEmitter.write( elem.Text.makeStringAndClear() ); + + sal_Unicode strToken; + for (int i = 0; i < elem.Text.getLength(); i++) + { + strToken = str[i]; + if (strToken == strSpace || strToken == strNbSpace) + { + aProps["text:c"] = "1"; + m_rEmitContext.rEmitter.beginTag("text:s", aProps); + m_rEmitContext.rEmitter.endTag("text:s"); + } + else if (strToken == tabSpace) + { + m_rEmitContext.rEmitter.beginTag("text:tab", aProps); + m_rEmitContext.rEmitter.endTag("text:tab"); + } + else + m_rEmitContext.rEmitter.write(OUString(strToken)); + } + auto this_it = elem.Children.begin(); while( this_it != elem.Children.end() && this_it->get() != &elem ) { @@ -128,7 +203,7 @@ void WriterXmlEmitter::fillFrameProps( DrawElement& rElem, if (pParaElt) { rProps[ "text:anchor-type" ] = rElem.isCharacter - ? OUStringLiteral(u"character") : OUStringLiteral(u"paragraph"); + ? std::u16string_view(u"character") : std::u16string_view(u"paragraph"); } else { @@ -179,29 +254,25 @@ void WriterXmlEmitter::fillFrameProps( DrawElement& rElem, } if( fShearX != 0.0 ) { - aBuf.append( "skewX( " ); - aBuf.append( fShearX ); - aBuf.append( " )" ); + aBuf.append( "skewX( " + OUString::number(fShearX) + " )" ); } if( fRotate != 0.0 ) { if( !aBuf.isEmpty() ) aBuf.append( ' ' ); - aBuf.append( "rotate( " ); - aBuf.append( -fRotate ); - aBuf.append( " )" ); + aBuf.append( "rotate( " + OUString::number(-fRotate) + " )" ); } if( ! rElem.isCharacter ) { if( !aBuf.isEmpty() ) aBuf.append( ' ' ); - aBuf.append( "translate( " ); - aBuf.append( convertPixelToUnitString( rel_x ) ); - aBuf.append( ' ' ); - aBuf.append( convertPixelToUnitString( rel_y ) ); - aBuf.append( " )" ); - } + aBuf.append( "translate( " + + convertPixelToUnitString( rel_x ) + + " " + + convertPixelToUnitString( rel_y ) + + " )" ); + } rProps[ "draw:transform" ] = aBuf.makeStringAndClear(); } @@ -283,12 +354,11 @@ void WriterXmlEmitter::visit( PolyPolyElement& elem, const std::list< std::uniqu PropertyMap aProps; fillFrameProps( elem, aProps, m_rEmitContext ); - OUStringBuffer aBuf( 64 ); - aBuf.append( "0 0 " ); - aBuf.append( convPx2mmPrec2(elem.w)*100.0 ); - aBuf.append( ' ' ); - aBuf.append( convPx2mmPrec2(elem.h)*100.0 ); - aProps[ "svg:viewBox" ] = aBuf.makeStringAndClear(); + aProps[ "svg:viewBox" ] = + "0 0 " + + OUString::number(convPx2mmPrec2(elem.w)*100.0) + + " " + + OUString::number( convPx2mmPrec2(elem.h)*100.0 ); aProps[ "svg:d" ] = basegfx::utils::exportToSvgD( elem.PolyPoly, true, true, false ); m_rEmitContext.rEmitter.beginTag( "draw:path", aProps ); @@ -463,8 +533,17 @@ void WriterXmlOptimizer::visit( ParagraphElement& elem, const std::list< std::un { const FontAttributes& rPrevFont = m_rProcessor.getFont( pPrevText->FontId ); const FontAttributes& rThisFont = m_rProcessor.getFont( pThisText->FontId ); - if( rPrevFont.isBold && ! rThisFont.isBold ) + if ( (rPrevFont.fontWeight == u"600" || + rPrevFont.fontWeight == u"bold" || + rPrevFont.fontWeight == u"800" || + rPrevFont.fontWeight == u"900" ) && + (rThisFont.fontWeight == u"600" || + rThisFont.fontWeight == u"bold" || + rThisFont.fontWeight == u"800" || + rThisFont.fontWeight == u"900" ) ) + { pPrevPara->Type = ParagraphElement::Headline; + } } } } @@ -509,7 +588,7 @@ void WriterXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_ nCurLineElements = 0; for( const auto& rxChild : pCurPara->Children ) { - TextElement* pTestText = dynamic_cast<TextElement*>(rxChild.get()); + TextElement* pTestText = rxChild->dynCastAsTextElement(); if( pTestText ) { fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->h)/double(nCurLineElements+1); @@ -543,12 +622,12 @@ void WriterXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_ // or perhaps the draw element begins a new paragraph else if( next_page_element != elem.Children.end() ) { - TextElement* pText = dynamic_cast<TextElement*>(next_page_element->get()); + TextElement* pText = (*next_page_element)->dynCastAsTextElement(); if( ! pText ) { ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(next_page_element->get()); if( pPara && ! pPara->Children.empty() ) - pText = dynamic_cast<TextElement*>(pPara->Children.front().get()); + pText = pPara->Children.front()->dynCastAsTextElement(); } if( pText && // check there is a text pDraw->h < pText->h*1.5 && // and it is approx the same height @@ -577,9 +656,9 @@ void WriterXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_ } } - TextElement* pText = dynamic_cast<TextElement*>(page_element->get()); + TextElement* pText = (*page_element)->dynCastAsTextElement(); if( ! pText && pLink && ! pLink->Children.empty() ) - pText = dynamic_cast<TextElement*>(pLink->Children.front().get()); + pText = pLink->Children.front()->dynCastAsTextElement(); if( pText ) { Element* pGeo = pLink ? static_cast<Element*>(pLink) : @@ -736,10 +815,15 @@ void WriterXmlOptimizer::optimizeTextElements(Element& rParent) while( next != rParent.Children.end() ) { bool bConcat = false; - TextElement* pCur = dynamic_cast<TextElement*>(it->get()); + TextElement* pCur = (*it)->dynCastAsTextElement(); if( pCur ) { TextElement* pNext = dynamic_cast<TextElement*>(next->get()); + OUString str; + bool bPara = strspn("ParagraphElement", typeid(rParent).name()); + ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(&rParent); + if (bPara && pPara && isComplex(GetBreakIterator(), pCur)) + pPara->bRtl = true; if( pNext ) { const GraphicsContext& rCurGC = m_rProcessor.getGraphicsContext( pCur->GCId ); @@ -788,18 +872,61 @@ void WriterXmlOptimizer::optimizeTextElements(Element& rParent) } } // concatenate consecutive text elements unless there is a - // font or text color or matrix change, leave a new span in that case + // font or text color change, leave a new span in that case if( pCur->FontId == pNext->FontId && rCurGC.FillColor.Red == rNextGC.FillColor.Red && rCurGC.FillColor.Green == rNextGC.FillColor.Green && rCurGC.FillColor.Blue == rNextGC.FillColor.Blue && - rCurGC.FillColor.Alpha == rNextGC.FillColor.Alpha && - rCurGC.Transformation == rNextGC.Transformation + rCurGC.FillColor.Alpha == rNextGC.FillColor.Alpha ) { pCur->updateGeometryWith( pNext ); - // append text to current element - pCur->Text.append( pNext->Text ); + if (pPara && pPara->bRtl) + { + // Tdf#152083: If RTL, reverse the text in pNext so that its correct order is + // restored when the combined text is reversed in WriterXmlEmitter::visit. + OUString tempStr; + bool bNeedReverse=false; + str = pNext->Text.toString(); + for (sal_Int32 i=0; i < str.getLength(); i++) + { + if (str[i] == u' ') + { // Space char (e.g. the space as in " Ù…") needs special treatment. + // First, append the space char to pCur. + pCur->Text.append(OUStringChar(str[i])); + // Then, check whether the tmpStr needs reverse, if so then reverse and append. + if (bNeedReverse) + { + tempStr = ::comphelper::string::reverseCodePoints(tempStr); + pCur->Text.append(tempStr); + tempStr = u""_ustr; + } + bNeedReverse = false; + } + else + { + tempStr += OUStringChar(str[i]); + bNeedReverse = true; + } + } + // Do the last append + if (bNeedReverse) + { + tempStr = ::comphelper::string::reverseCodePoints(tempStr); + pCur->Text.append(tempStr); + } + else + { + pCur->Text.append(tempStr); + } + } + else + { + // append text to current element directly without reverse + pCur->Text.append(pNext->Text); + } + if (bPara && pPara && isComplex(GetBreakIterator(), pCur)) + pPara->bRtl = true; // append eventual children to current element // and clear children (else the children just // appended to pCur would be destroyed) @@ -850,7 +977,7 @@ void WriterXmlFinalizer::visit( PolyPolyElement& elem, const std::list< std::uni { PropertyMap props; FillDashStyleProps(props, rGC.DashArray, scale); - StyleContainer::Style style("draw:stroke-dash", props); + StyleContainer::Style style("draw:stroke-dash"_ostr, std::move(props)); aGCProps[ "draw:stroke" ] = "dash"; aGCProps[ "draw:stroke-dash" ] = @@ -868,10 +995,30 @@ void WriterXmlFinalizer::visit( PolyPolyElement& elem, const std::list< std::uni aGCProps[ "draw:stroke" ] = "none"; } + if (elem.FillImage != -1) + { + PropertyMap props; + // The image isn't actually in a prop, it's in an extra chunk inside. + StyleContainer::Style style("draw:fill-image"_ostr, std::move(props)); + style.Contents = m_rProcessor.getImages().asBase64EncodedString(elem.FillImage); + aGCProps[ "draw:fill-image-name" ] = + m_rStyleContainer.getStyleName( + m_rStyleContainer.getStyleId(style)); + aGCProps[ "draw:fill-image-width" ] = unitMMString(convPx2mm(elem.TileWidth)); + aGCProps[ "draw:fill-image-height" ] = unitMMString(convPx2mm(elem.TileHeight)); + } + // TODO(F1): check whether stuff could be emulated by gradient/bitmap/hatch if( elem.Action & (PATH_FILL | PATH_EOFILL) ) { - aGCProps[ "draw:fill" ] = "solid"; + if (elem.FillImage == -1) + { + aGCProps[ "draw:fill" ] = "solid"; + } + else + { + aGCProps[ "draw:fill" ] = "bitmap"; + } aGCProps[ "draw:fill-color" ] = getColorString( rGC.FillColor ); } else @@ -879,8 +1026,8 @@ void WriterXmlFinalizer::visit( PolyPolyElement& elem, const std::list< std::uni aGCProps[ "draw:fill" ] = "none"; } - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:graphic-properties", aGCProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:graphic-properties"_ostr, std::move(aGCProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); @@ -899,21 +1046,25 @@ void WriterXmlFinalizer::visit( TextElement& elem, const std::list< std::unique_ PropertyMap aFontProps; // family name + // TODO: tdf#143095: use system font name rather than PSName + SAL_INFO("sdext.pdfimport", "The font used in xml is: " << rFont.familyName); aFontProps[ "fo:font-family" ] = rFont.familyName; + aFontProps[ "style:font-family-asian" ] = rFont.familyName; + aFontProps[ "style:font-family-complex" ] = rFont.familyName; + // bold - if( rFont.isBold ) - { - aFontProps[ "fo:font-weight" ] = "bold"; - aFontProps[ "fo:font-weight-asian" ] = "bold"; - aFontProps[ "fo:font-weight-complex" ] = "bold"; - } + aFontProps[ "fo:font-weight" ] = rFont.fontWeight; + aFontProps[ "style:font-weight-asian" ] = rFont.fontWeight; + aFontProps[ "style:font-weight-complex" ] = rFont.fontWeight; + // italic if( rFont.isItalic ) { - aFontProps[ "fo:font-style" ] = "italic"; - aFontProps[ "fo:font-style-asian" ] = "italic"; - aFontProps[ "fo:font-style-complex" ] = "italic"; + aFontProps[ "fo:font-style" ] = "italic"; + aFontProps[ "style:font-style-asian" ] = "italic"; + aFontProps[ "style:font-style-complex" ] = "italic"; } + // underline if( rFont.isUnderline ) { @@ -921,22 +1072,23 @@ void WriterXmlFinalizer::visit( TextElement& elem, const std::list< std::unique_ aFontProps[ "style:text-underline-width" ] = "auto"; aFontProps[ "style:text-underline-color" ] = "font-color"; } + // outline if( rFont.isOutline ) - { aFontProps[ "style:text-outline" ] = "true"; - } + // size OUString aFSize = OUString::number( rFont.size*72/PDFI_OUTDEV_RESOLUTION ) + "pt"; aFontProps[ "fo:font-size" ] = aFSize; aFontProps[ "style:font-size-asian" ] = aFSize; aFontProps[ "style:font-size-complex" ] = aFSize; + // color const GraphicsContext& rGC = m_rProcessor.getGraphicsContext( elem.GCId ); - aFontProps[ "fo:color" ] = getColorString( rFont.isOutline ? rGC.LineColor : rGC.FillColor ); + aFontProps[ "fo:color" ] = getColorString( rFont.isOutline ? rGC.LineColor : rGC.FillColor ); - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:text-properties", aFontProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:text-properties"_ostr, std::move(aFontProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); } @@ -976,10 +1128,7 @@ void WriterXmlFinalizer::visit( ParagraphElement& elem, const std::list< std::un if( ! bIsCenter && elem.x > p_x + p_w/10 ) { // indent - OUStringBuffer aBuf( 32 ); - aBuf.append( convPx2mm( elem.x - p_x ) ); - aBuf.append( "mm" ); - aParaProps[ "fo:margin-left" ] = aBuf.makeStringAndClear(); + aParaProps[ "fo:margin-left" ] = OUString::number(convPx2mm( elem.x - p_x )) + "mm"; } // check whether to leave some space to next paragraph @@ -992,10 +1141,8 @@ void WriterXmlFinalizer::visit( ParagraphElement& elem, const std::list< std::un { if( pNextPara->y - (elem.y+elem.h) > convmm2Px( 10 ) ) { - OUStringBuffer aBuf( 32 ); - aBuf.append( convPx2mm( pNextPara->y - (elem.y+elem.h) ) ); - aBuf.append( "mm" ); - aParaProps[ "fo:margin-bottom" ] = aBuf.makeStringAndClear(); + aParaProps[ "fo:margin-bottom" ] = + OUString::number( convPx2mm( pNextPara->y - (elem.y+elem.h) ) ) + "mm"; } } } @@ -1004,8 +1151,8 @@ void WriterXmlFinalizer::visit( ParagraphElement& elem, const std::list< std::un { PropertyMap aProps; aProps[ "style:family" ] = "paragraph"; - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:paragraph-properties", aParaProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:paragraph-properties"_ostr, std::move(aParaProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); } @@ -1033,8 +1180,8 @@ void WriterXmlFinalizer::visit( FrameElement& elem, const std::list< std::unique aGCProps[ "fo:padding-right" ] = "0cm"; aGCProps[ "fo:padding-bottom" ] = "0cm"; - StyleContainer::Style aStyle( "style:style", aProps ); - StyleContainer::Style aSubStyle( "style:graphic-properties", aGCProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); + StyleContainer::Style aSubStyle( "style:graphic-properties"_ostr, std::move(aGCProps) ); aStyle.SubStyles.push_back( &aSubStyle ); elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); @@ -1061,10 +1208,10 @@ void WriterXmlFinalizer::setFirstOnPage( ParagraphElement& rElem, aProps[ "style:master-page-name" ] = rMasterPageName; if( rElem.StyleId != -1 ) - rElem.StyleId = rStyles.setProperties( rElem.StyleId, aProps ); + rElem.StyleId = rStyles.setProperties( rElem.StyleId, std::move(aProps) ); else { - StyleContainer::Style aStyle( "style:style", aProps ); + StyleContainer::Style aStyle( "style:style"_ostr, std::move(aProps) ); rElem.StyleId = rStyles.getStyleId( aStyle ); } } @@ -1169,17 +1316,17 @@ void WriterXmlFinalizer::visit( PageElement& elem, const std::list< std::unique_ aPageLayoutProps[ "fo:margin-right" ] = unitMMString( right_margin ); aPageLayoutProps[ "style:writing-mode" ]= "lr-tb"; - StyleContainer::Style aStyle( "style:page-layout", aPageProps); - StyleContainer::Style aSubStyle( "style:page-layout-properties", aPageLayoutProps); + StyleContainer::Style aStyle( "style:page-layout"_ostr, std::move(aPageProps)); + StyleContainer::Style aSubStyle( "style:page-layout-properties"_ostr, std::move(aPageLayoutProps)); aStyle.SubStyles.push_back(&aSubStyle); sal_Int32 nPageStyle = m_rStyleContainer.impl_getStyleId( aStyle, false ); // create master page OUString aMasterPageLayoutName = m_rStyleContainer.getStyleName( nPageStyle ); aPageProps[ "style:page-layout-name" ] = aMasterPageLayoutName; - StyleContainer::Style aMPStyle( "style:master-page", aPageProps ); - StyleContainer::Style aHeaderStyle( "style:header", PropertyMap() ); - StyleContainer::Style aFooterStyle( "style:footer", PropertyMap() ); + StyleContainer::Style aMPStyle( "style:master-page"_ostr, std::move(aPageProps) ); + StyleContainer::Style aHeaderStyle( "style:header"_ostr, PropertyMap() ); + StyleContainer::Style aFooterStyle( "style:footer"_ostr, PropertyMap() ); if( elem.HeaderElement ) { elem.HeaderElement->visitedBy( *this, std::list<std::unique_ptr<Element>>::iterator() ); diff --git a/sdext/source/pdfimport/tree/writertreevisiting.hxx b/sdext/source/pdfimport/tree/writertreevisiting.hxx index 1c1507f13349..b0644dd48154 100644 --- a/sdext/source/pdfimport/tree/writertreevisiting.hxx +++ b/sdext/source/pdfimport/tree/writertreevisiting.hxx @@ -24,6 +24,9 @@ #include <pdfihelper.hxx> +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/i18n/XCharacterClassification.hpp> + namespace pdfi { struct DrawElement; @@ -32,10 +35,12 @@ namespace pdfi { private: PDFIProcessor& m_rProcessor; + css::uno::Reference<css::i18n::XBreakIterator> mxBreakIter; void optimizeTextElements(Element& rParent); void checkHeaderAndFooter( PageElement& rElem ); public: + const css::uno::Reference<css::i18n::XBreakIterator>& GetBreakIterator(); explicit WriterXmlOptimizer(PDFIProcessor& rProcessor) : m_rProcessor(rProcessor) {} @@ -80,12 +85,14 @@ namespace pdfi class WriterXmlEmitter : public ElementTreeVisitor { private: + css::uno::Reference< css::i18n::XCharacterClassification > mxCharClass; EmitContext& m_rEmitContext ; static void fillFrameProps( DrawElement& rElem, PropertyMap& rProps, const EmitContext& rEmitContext ); public: + const css::uno::Reference<css::i18n::XCharacterClassification >& GetCharacterClassification(); explicit WriterXmlEmitter(EmitContext& rEmitContext) : m_rEmitContext(rEmitContext) {} diff --git a/sdext/source/pdfimport/wrapper/keyword_list b/sdext/source/pdfimport/wrapper/keyword_list index bf15ddb2460f..4d1e6d2d4013 100644 --- a/sdext/source/pdfimport/wrapper/keyword_list +++ b/sdext/source/pdfimport/wrapper/keyword_list @@ -38,6 +38,7 @@ setTextRenderMode,SETTEXTRENDERMODE setTransformation,SETTRANSFORMATION startPage,STARTPAGE strokePath,STROKEPATH +tilingPatternFill,TILINGPATTERNFILL updateBlendMode,UPDATEBLENDMODE updateCtm,UPDATECTM updateFillColor,UPDATEFILLCOLOR diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx index 2221f1ebe33f..86c0d3cf806f 100644 --- a/sdext/source/pdfimport/wrapper/wrapper.cxx +++ b/sdext/source/pdfimport/wrapper/wrapper.cxx @@ -32,15 +32,13 @@ #include <osl/diagnose.h> #include <rtl/bootstrap.hxx> #include <rtl/ustring.hxx> -#include <rtl/ustrbuf.hxx> #include <rtl/strbuf.hxx> #include <sal/log.hxx> #include <comphelper/propertysequence.hxx> +#include <comphelper/string.hxx> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/awt/FontDescriptor.hpp> -#include <com/sun/star/beans/XMaterialHolder.hpp> #include <com/sun/star/rendering/PathCapType.hpp> #include <com/sun/star/rendering/PathJoinType.hpp> #include <com/sun/star/rendering/XPolyPolygon2D.hpp> @@ -63,10 +61,8 @@ #include <memory> #include <string_view> #include <unordered_map> +#include <vector> #include <string.h> -#include <stdlib.h> - -#include <rtl/character.hxx> using namespace com::sun::star; @@ -112,6 +108,7 @@ enum parseKey { SETTRANSFORMATION, STARTPAGE, STROKEPATH, + TILINGPATTERNFILL, UPDATEBLENDMODE, UPDATECTM, UPDATEFILLCOLOR, @@ -161,31 +158,25 @@ public: m_aFontMap(101) {} - void parseLine( const OString& rLine ); + void parseLine( std::string_view aLine ); }; class LineParser { - Parser & m_parser; - OString m_aLine; - - static sal_Int32 parseFontCheckForString(const sal_Unicode* pCopy, sal_Int32 nCopyLen, - const char* pAttrib, sal_Int32 nAttribLen, - FontAttributes& rResult, bool bItalic, bool bBold); - static sal_Int32 parseFontRemoveSuffix(const sal_Unicode* pCopy, sal_Int32 nCopyLen, - const char* pAttrib, sal_Int32 nAttribLen); - static void parseFontFamilyName( FontAttributes& aResult ); + Parser & m_parser; + std::string_view m_aLine; - void readInt32( sal_Int32& o_Value ); - void readInt64( sal_Int64& o_Value ); - void readDouble( double& o_Value ); - void readBinaryData( uno::Sequence<sal_Int8>& rBuf ); + static void parseFontFamilyName( FontAttributes& aResult ); + void readInt32( sal_Int32& o_Value ); + void readInt64( sal_Int64& o_Value ); + void readDouble( double& o_Value ); + void readBinaryData( uno::Sequence<sal_Int8>& rBuf ); uno::Sequence<beans::PropertyValue> readImageImpl(); public: std::size_t m_nCharIndex = 0; - LineParser(Parser & parser, OString const & line): m_parser(parser), m_aLine(line) {} + LineParser(Parser & parser, std::string_view line): m_parser(parser), m_aLine(line) {} std::string_view readNextToken(); sal_Int32 readInt32(); @@ -206,6 +197,7 @@ public: void readLink(); void readMaskedImage(); void readSoftMaskedImage(); + void readTilingPatternFill(); }; /** Unescapes line-ending characters in input string. These @@ -266,25 +258,19 @@ std::string_view LineParser::readNextToken() void LineParser::readInt32( sal_Int32& o_Value ) { std::string_view tok = readNextToken(); - sal_Int64 n = rtl_str_toInt64_WithLength(tok.data(), 10, tok.size()); - if (n < SAL_MIN_INT32 || n > SAL_MAX_INT32) - n = 0; - o_Value = n; + o_Value = o3tl::toInt32(tok); } sal_Int32 LineParser::readInt32() { std::string_view tok = readNextToken(); - sal_Int64 n =rtl_str_toInt64_WithLength(tok.data(), 10, tok.size()); - if (n < SAL_MIN_INT32 || n > SAL_MAX_INT32) - n = 0; - return n; + return o3tl::toInt32(tok); } void LineParser::readInt64( sal_Int64& o_Value ) { std::string_view tok = readNextToken(); - o_Value = rtl_str_toInt64_WithLength(tok.data(), 10, tok.size()); + o_Value = o3tl::toInt64(tok); } void LineParser::readDouble( double& o_Value ) @@ -379,7 +365,7 @@ uno::Reference<rendering::XPolyPolygon2D> LineParser::readPath() } return static_cast<rendering::XLinePolyPolygon2D*>( - new basegfx::unotools::UnoPolyPolygon(aResult)); + new basegfx::unotools::UnoPolyPolygon(std::move(aResult))); } void LineParser::readChar() @@ -401,7 +387,7 @@ void LineParser::readChar() OString aChars; if (m_nCharIndex != std::string_view::npos) - aChars = lcl_unescapeLineFeeds( m_aLine.subView( m_nCharIndex ) ); + aChars = lcl_unescapeLineFeeds( m_aLine.substr( m_nCharIndex ) ); // chars gobble up rest of line m_nCharIndex = std::string_view::npos; @@ -477,148 +463,105 @@ rendering::ARGBColor LineParser::readColor() return aRes; } -sal_Int32 LineParser::parseFontCheckForString( - const sal_Unicode* pCopy, sal_Int32 nCopyLen, - const char* pAttrib, sal_Int32 nAttribLen, - FontAttributes& rResult, bool bItalic, bool bBold) -{ - if (nCopyLen < nAttribLen) - return 0; - for (sal_Int32 i = 0; i < nAttribLen; ++i) - { - sal_uInt32 nCode = pAttrib[i]; - if (rtl::toAsciiLowerCase(pCopy[i]) != nCode - && rtl::toAsciiUpperCase(pCopy[i]) != nCode) - return 0; - } - rResult.isItalic |= bItalic; - rResult.isBold |= bBold; - return nAttribLen; -} - -sal_Int32 LineParser::parseFontRemoveSuffix( - const sal_Unicode* pCopy, sal_Int32 nCopyLen, - const char* pAttrib, sal_Int32 nAttribLen) -{ - if (nCopyLen < nAttribLen) - return 0; - for (sal_Int32 i = 0; i < nAttribLen; ++i) - if ( pCopy[nCopyLen - nAttribLen + i] != pAttrib[i] ) - return 0; - return nAttribLen; -} +/* Parse and convert the font family name (passed from xpdfimport) to correct font names +e.g. TimesNewRomanPSMT -> TimesNewRoman + TimesNewRomanPS-BoldMT -> TimesNewRoman + TimesNewRomanPS-BoldItalicMT -> TimesNewRoman +During the conversion, also apply the font features (bold italic etc) to the result. +TODO: Further convert the font names to real font names in the system rather than the PS names. +e.g., TimesNewRoman -> Times New Roman +*/ void LineParser::parseFontFamilyName( FontAttributes& rResult ) { - OUStringBuffer aNewFamilyName( rResult.familyName.getLength() ); - - const sal_Unicode* pCopy = rResult.familyName.getStr(); - sal_Int32 nLen = rResult.familyName.getLength(); - // parse out truetype subsets (e.g. BAAAAA+Thorndale) - if( nLen > 8 && pCopy[6] == '+' ) - { - pCopy += 7; - nLen -= 7; - } - - // TODO: Looks like this block needs to be refactored - while( nLen ) + SAL_INFO("sdext.pdfimport", "Processing " << rResult.familyName << " ---"); + rResult.familyName = rResult.familyName.trim(); + for (const OUString& fontAttributesSuffix: fontAttributesSuffixes) { - if (parseFontRemoveSuffix(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("PSMT"))) - { - nLen -= RTL_CONSTASCII_LENGTH("PSMT"); - } - else if (parseFontRemoveSuffix(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("MT"))) + if ( rResult.familyName.endsWith(fontAttributesSuffix) ) { - nLen -= RTL_CONSTASCII_LENGTH("MT"); - } + rResult.familyName = rResult.familyName.replaceAll(fontAttributesSuffix, ""); + SAL_INFO("sdext.pdfimport", rResult.familyName); + if (fontAttributesSuffix == u"Heavy" || fontAttributesSuffix == u"Black") + { + rResult.fontWeight = u"900"_ustr; + } + else if (fontAttributesSuffix == u"ExtraBold" || fontAttributesSuffix == u"UltraBold") + { + rResult.fontWeight = u"800"_ustr; + } + else if (fontAttributesSuffix == u"Bold") + { + rResult.fontWeight = u"bold"_ustr; + } + else if (fontAttributesSuffix == u"Semibold") + { + rResult.fontWeight = u"600"_ustr; + } + else if (fontAttributesSuffix == u"Medium") + { + rResult.fontWeight = u"500"_ustr; + } + else if (fontAttributesSuffix == u"Normal" || fontAttributesSuffix == u"Regular" || fontAttributesSuffix == u"Book") + { + rResult.fontWeight = u"400"_ustr; + } + else if (fontAttributesSuffix == u"Light") + { + rResult.fontWeight = u"300"_ustr; + } + else if (fontAttributesSuffix == u"ExtraLight" || fontAttributesSuffix == u"UltraLight") + { + rResult.fontWeight = u"200"_ustr; + } + else if (fontAttributesSuffix == u"Thin") + { + rResult.fontWeight = u"100"_ustr; + } - if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("Italic"), rResult, true, false)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("Italic"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-LightOblique"), rResult, true, false)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-LightOblique"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-Light"), rResult, false, false)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-Light"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-BoldOblique"), rResult, true, true)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-BoldOblique"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-Bold"), rResult, false, true)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-Bold"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("Bold"), rResult, false, true)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("Bold"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-Roman"), rResult, false, false)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-Roman"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-Oblique"), rResult, true, false)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-Oblique"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if (parseFontCheckForString(pCopy, nLen, RTL_CONSTASCII_STRINGPARAM("-Reg"), rResult, false, false)) - { - sal_Int32 nAttribLen = RTL_CONSTASCII_LENGTH("-Reg"); - nLen -= nAttribLen; - pCopy += nAttribLen; - } - else if(nLen > 0) - { - if( *pCopy != '-' ) - aNewFamilyName.append( *pCopy ); - pCopy++; - nLen--; + if ( (fontAttributesSuffix == "Italic") or (fontAttributesSuffix == "Oblique") ) + { + rResult.isItalic = true; + } } } - rResult.familyName = aNewFamilyName.makeStringAndClear(); } void LineParser::readFont() { - OString aFontName; + /* + xpdf line is like (separated by space): + updateFont <FontID> <isEmbedded> <maFontWeight> <isItalic> <isUnderline> <TransformedFontSize> <nEmbedSize> <FontName> + updateFont 14 1 4 0 0 1200.000000 23068 TimesNewRomanPSMT + + If nEmbedSize > 0, then a fontFile is followed as a stream. + */ sal_Int64 nFontID; - sal_Int32 nIsEmbedded, nIsBold, nIsItalic, nIsUnderline, nFileLen; + sal_Int32 nIsEmbedded; + sal_Int32 nFontWeight; + sal_Int32 nIsItalic; + sal_Int32 nIsUnderline; double nSize; + sal_Int32 nFileLen; + OString aFontName; - readInt64(nFontID); - readInt32(nIsEmbedded); - readInt32(nIsBold); - readInt32(nIsItalic); - readInt32(nIsUnderline); - readDouble(nSize); - readInt32(nFileLen); + readInt64(nFontID); // read FontID + readInt32(nIsEmbedded); // read isEmbedded + readInt32(nFontWeight); // read maFontWeight, see GfxFont enum Weight + readInt32(nIsItalic); // read isItalic + readInt32(nIsUnderline);// read isUnderline + readDouble(nSize); // read TransformedFontSize + readInt32(nFileLen); // read nEmbedSize nSize = nSize < 0.0 ? -nSize : nSize; - aFontName = lcl_unescapeLineFeeds( m_aLine.subView( m_nCharIndex ) ); + // Read FontName. From the current position to the end (any white spaces will be included). + aFontName = lcl_unescapeLineFeeds(m_aLine.substr(m_nCharIndex)); // name gobbles up rest of line m_nCharIndex = std::string_view::npos; + // Check if this font is already in our font map list. + // If yes, update the font size and skip. Parser::FontMapType::const_iterator pFont( m_parser.m_aFontMap.find(nFontID) ); if( pFont != m_parser.m_aFontMap.end() ) { @@ -630,62 +573,111 @@ void LineParser::readFont() return; } - // yet unknown font - get info and add to map - FontAttributes aResult( OStringToOUString( aFontName, - RTL_TEXTENCODING_UTF8 ), - nIsBold != 0, + // The font is not yet in the map list - get info and add to map + OUString sFontWeight; // font weight name per ODF specifications + if (nFontWeight == 0 or nFontWeight == 4) // WeightNotDefined or W400, map to normal font + sFontWeight = u"normal"_ustr; + else if (nFontWeight == 1) // W100, Thin + sFontWeight = u"100"_ustr; + else if (nFontWeight == 2) // W200, Extra-Light + sFontWeight = u"200"_ustr; + else if (nFontWeight == 3) // W300, Light + sFontWeight = u"300"_ustr; + else if (nFontWeight == 5) // W500, Medium. Is this supported by ODF? + sFontWeight = u"500"_ustr; + else if (nFontWeight == 6) // W600, Semi-Bold + sFontWeight = u"600"_ustr; + else if (nFontWeight == 7) // W700, Bold + sFontWeight = u"bold"_ustr; + else if (nFontWeight == 8) // W800, Extra-Bold + sFontWeight = u"800"_ustr; + else if (nFontWeight == 9) // W900, Black + sFontWeight = u"900"_ustr; + SAL_INFO("sdext.pdfimport", "Font weight passed from xpdfimport is: " << sFontWeight); + + FontAttributes aResult( OStringToOUString( aFontName, RTL_TEXTENCODING_UTF8 ), + sFontWeight, nIsItalic != 0, nIsUnderline != 0, nSize, 1.0); - // extract textual attributes (bold, italic in the name, etc.) - parseFontFamilyName(aResult); - // need to read font file? - if( nFileLen ) + /* The above font attributes (fontName, fontWeight, italic) are based on + xpdf line output and may not be reliable. To get correct attributes, + we do the following: + 1. Read the embedded font file and determine the attributes based on the + font file. + 2. If we failed to read the font file, or empty result is returned, then + determine the font attributes from the font name. + 3. If all these attempts have failed, then use a fallback font. + */ + if (nFileLen > 0) { uno::Sequence<sal_Int8> aFontFile(nFileLen); - readBinaryData( aFontFile ); + readBinaryData(aFontFile); // Read fontFile. - awt::FontDescriptor aFD; - uno::Sequence< uno::Any > aArgs(1); - aArgs[0] <<= aFontFile; + vcl::Font aFontReadResult = vcl::Font::identifyFont(aFontFile.getArray(), nFileLen); + SAL_INFO("sdext.pdfimport", "familyName: " << aFontReadResult.GetFamilyName()); - try + if (!aFontReadResult.GetFamilyName().isEmpty()) // font detection successful { - uno::Reference< beans::XMaterialHolder > xMat( - m_parser.m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( - "com.sun.star.awt.FontIdentificator", aArgs, m_parser.m_xContext ), - uno::UNO_QUERY ); - if( xMat.is() ) + // Family name + aResult.familyName = aFontReadResult.GetFamilyName(); + SAL_INFO("sdext.pdfimport", aResult.familyName); + // tdf#143959: there are cases when the family name returned by font descriptor + // is like "AAAAAA+TimesNewRoman,Bold". In this case, use the font name + // determined by parseFontFamilyName instead, but still determine the font + // attributes (bold italic etc) from the font descriptor. + if (aResult.familyName.getLength() > 7 and aResult.familyName.indexOf(u"+", 6) == 6) { - uno::Any aRes( xMat->getMaterial() ); - if( aRes >>= aFD ) - { - if (!aFD.Name.isEmpty()) - { - aResult.familyName = aFD.Name; - parseFontFamilyName(aResult); - } - aResult.isBold = (aFD.Weight > 100.0); - aResult.isItalic = (aFD.Slant == awt::FontSlant_OBLIQUE || - aFD.Slant == awt::FontSlant_ITALIC ); - aResult.isUnderline = false; - aResult.size = 0; - } + aResult.familyName = aResult.familyName.copy(7, aResult.familyName.getLength() - 7); + parseFontFamilyName(aResult); + } + if (aResult.familyName.endsWithIgnoreAsciiCase("-VKana")) + { + parseFontFamilyName(aResult); } - } - catch( uno::Exception& ) - { - } - if( aResult.familyName.isEmpty() ) + // Font weight + if (aFontReadResult.GetWeight() == WEIGHT_THIN) + aResult.fontWeight = u"100"_ustr; + else if (aFontReadResult.GetWeight() == WEIGHT_ULTRALIGHT) + aResult.fontWeight = u"200"_ustr; + else if (aFontReadResult.GetWeight() == WEIGHT_LIGHT) + aResult.fontWeight = u"300"_ustr; + else if (aFontReadResult.GetWeight() == WEIGHT_SEMILIGHT) + aResult.fontWeight = u"350"_ustr; + // no need to check "normal" here as this is default in nFontWeight above + else if (aFontReadResult.GetWeight() == WEIGHT_SEMIBOLD) + aResult.fontWeight = u"600"_ustr; + else if (aFontReadResult.GetWeight() == WEIGHT_BOLD) + aResult.fontWeight = u"bold"_ustr; + else if (aFontReadResult.GetWeight() == WEIGHT_ULTRABOLD) + aResult.fontWeight = u"800"_ustr; + else if (aFontReadResult.GetWeight() == WEIGHT_BLACK) + aResult.fontWeight = u"900"_ustr; + SAL_INFO("sdext.pdfimport", aResult.fontWeight); + + // Italic + aResult.isItalic = (aFontReadResult.GetItalic() == ITALIC_OBLIQUE || + aFontReadResult.GetItalic() == ITALIC_NORMAL); + } else // font detection failed { - // last fallback - aResult.familyName = "Arial"; - aResult.isUnderline = false; + SAL_WARN("sdext.pdfimport", + "Font detection from fontFile returned empty result. Guessing font info from font name."); + parseFontFamilyName(aResult); } + } else // no embedded font file - guess font attributes from font name + { + parseFontFamilyName(aResult); + } + + // last fallback + if (aResult.familyName.isEmpty()) + { + SAL_WARN("sdext.pdfimport", "Failed to determine the font, using a fallback font Arial."); + aResult.familyName = "Arial"; } if (!m_parser.m_xDev) @@ -723,8 +715,7 @@ uno::Sequence<beans::PropertyValue> LineParser::readImageImpl() uno::Sequence<sal_Int8> aDataSequence(nImageSize); readBinaryData( aDataSequence ); - uno::Sequence< uno::Any > aStreamCreationArgs(1); - aStreamCreationArgs[0] <<= aDataSequence; + uno::Sequence< uno::Any > aStreamCreationArgs{ uno::Any(aDataSequence) }; uno::Reference< uno::XComponentContext > xContext( m_parser.m_xContext, uno::UNO_SET_THROW ); uno::Reference< lang::XMultiComponentFactory > xFactory( xContext->getServiceManager(), uno::UNO_SET_THROW ); @@ -733,9 +724,9 @@ uno::Sequence<beans::PropertyValue> LineParser::readImageImpl() uno::UNO_QUERY_THROW ); uno::Sequence<beans::PropertyValue> aSequence( comphelper::InitPropertySequence({ - { "URL", uno::makeAny(aFileName) }, - { "InputStream", uno::makeAny( xDataStream ) }, - { "InputSequence", uno::makeAny(aDataSequence) } + { "URL", uno::Any(aFileName) }, + { "InputStream", uno::Any( xDataStream ) }, + { "InputSequence", uno::Any(aDataSequence) } })); return aSequence; @@ -755,19 +746,17 @@ void LineParser::readImage() uno::Sequence<sal_Int8> aDataSequence(nMaskColors); readBinaryData( aDataSequence ); - uno::Sequence<uno::Any> aMaskRanges(2); - uno::Sequence<double> aMinRange(nMaskColors/2); + auto pMinRange = aMinRange.getArray(); uno::Sequence<double> aMaxRange(nMaskColors/2); + auto pMaxRange = aMaxRange.getArray(); for( sal_Int32 i=0; i<nMaskColors/2; ++i ) { - aMinRange[i] = aDataSequence[i] / 255.0; - aMaxRange[i] = aDataSequence[i+nMaskColors/2] / 255.0; + pMinRange[i] = aDataSequence[i] / 255.0; + pMaxRange[i] = aDataSequence[i+nMaskColors/2] / 255.0; } - aMaskRanges[0] <<= aMinRange; - aMaskRanges[1] <<= aMaxRange; - + uno::Sequence<uno::Any> aMaskRanges{ uno::Any(aMinRange), uno::Any(aMaxRange) }; m_parser.m_pSink->drawColorMaskedImage( aImg, aMaskRanges ); } else @@ -794,7 +783,7 @@ void LineParser::readLink() m_parser.m_pSink->hyperLink( aBounds, OStringToOUString( lcl_unescapeLineFeeds( - m_aLine.subView(m_nCharIndex) ), + m_aLine.substr(m_nCharIndex) ), RTL_TEXTENCODING_UTF8 ) ); // name gobbles up rest of line m_nCharIndex = std::string_view::npos; @@ -827,13 +816,45 @@ void LineParser::readSoftMaskedImage() m_parser.m_pSink->drawAlphaMaskedImage( aImage, aMask ); } -void Parser::parseLine( const OString& rLine ) +void LineParser::readTilingPatternFill() +{ + sal_Int32 nX0, nY0, nX1, nY1, nPaintType; + double nXStep, nYStep; + geometry::AffineMatrix2D aMat; + readInt32(nX0); + readInt32(nY0); + readInt32(nX1); + readInt32(nY1); + + readDouble(nXStep); + readDouble(nYStep); + + readInt32(nPaintType); + + readDouble(aMat.m00); + readDouble(aMat.m10); + readDouble(aMat.m01); + readDouble(aMat.m11); + readDouble(aMat.m02); + readDouble(aMat.m12); + + // The tile is an image with alpha + const uno::Sequence<beans::PropertyValue> aTile ( readImageImpl() ); + + m_parser.m_pSink->tilingPatternFill( nX0, nY0, nX1, nY1, + nXStep, nYStep, + nPaintType, + aMat, + aTile ); +} + +void Parser::parseLine( std::string_view aLine ) { OSL_PRECOND( m_pSink, "Invalid sink" ); OSL_PRECOND( m_pErr, "Invalid filehandle" ); OSL_PRECOND( m_xContext.is(), "Invalid service factory" ); - LineParser lp(*this, rLine); + LineParser lp(*this, aLine); const std::string_view rCmd = lp.readNextToken(); const hash_entry* pEntry = PdfKeywordHash::in_word_set( rCmd.data(), rCmd.size() ); @@ -879,6 +900,8 @@ void Parser::parseLine( const OString& rLine ) } case STROKEPATH: m_pSink->strokePath(lp.readPath()); break; + case TILINGPATTERNFILL: + lp.readTilingPatternFill(); break; case UPDATECTM: lp.readTransformation(); break; case UPDATEFILLCOLOR: @@ -925,9 +948,8 @@ static bool checkEncryption( std::u16string_view i_rPa ) { bool bSuccess = false; - OString aPDFFile = OUStringToOString( i_rPath, osl_getThreadTextEncoding() ); - std::unique_ptr<pdfparse::PDFEntry> pEntry( pdfparse::PDFReader::read( aPDFFile.getStr() )); + std::unique_ptr<pdfparse::PDFEntry> pEntry(pdfparse::PDFReader::read(i_rPath)); if( pEntry ) { pdfparse::PDFFile* pPDFFile = dynamic_cast<pdfparse::PDFFile*>(pEntry.get()); @@ -943,7 +965,7 @@ static bool checkEncryption( std::u16string_view i_rPa { OString aIsoPwd = OUStringToOString( io_rPwd, RTL_TEXTENCODING_ISO_8859_1 ); - bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() ); + bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd ); } if( bAuthenticated ) bSuccess = true; @@ -957,7 +979,7 @@ static bool checkEncryption( std::u16string_view i_rPa bEntered = getPassword( i_xIHdl, io_rPwd, ! bEntered, i_rDocName ); OString aIsoPwd = OUStringToOString( io_rPwd, RTL_TEXTENCODING_ISO_8859_1 ); - bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() ); + bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd ); } while( bEntered && ! bAuthenticated ); } @@ -1058,24 +1080,15 @@ bool xpdf_ImportFromFile(const OUString& rURL, OUString converterURL("$BRAND_BASE_DIR/" LIBO_BIN_FOLDER "/xpdfimport"); rtl::Bootstrap::expandMacros(converterURL); //TODO: detect failure - // Determine pathname of xpdfimport_err.pdf: - OUString errPathname("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/xpdfimport/xpdfimport_err.pdf"); - rtl::Bootstrap::expandMacros(errPathname); //TODO: detect failure - if (osl::FileBase::getSystemPathFromFileURL(errPathname, errPathname) - != osl::FileBase::E_None) - { - SAL_WARN( - "sdext.pdfimport", - "getSystemPathFromFileURL(" << errPathname << ") failed"); - return false; - } - // spawn separate process to keep LGPL/GPL code apart. - OUString aOptFlag("-o"); - rtl_uString* args[] = { aSysUPath.pData, errPathname.pData, - aOptFlag.pData, rFilterOptions.pData }; - sal_Int32 nArgs = rFilterOptions.isEmpty() ? 2 : 4; + constexpr OUString aOptFlag(u"-o"_ustr); + std::vector<rtl_uString*> args({ aSysUPath.pData }); + if (!rFilterOptions.isEmpty()) + { + args.push_back(aOptFlag.pData); + args.push_back(rFilterOptions.pData); + } oslProcess aProcess; oslFileHandle pIn = nullptr; @@ -1084,8 +1097,8 @@ bool xpdf_ImportFromFile(const OUString& rURL, oslSecurity pSecurity = osl_getCurrentSecurity (); oslProcessError eErr = osl_executeProcess_WithRedirectedIO(converterURL.pData, - args, - nArgs, + args.data(), + args.size(), osl_Process_SEARCHPATH|osl_Process_HIDDEN, pSecurity, nullptr, nullptr, 0, @@ -1154,7 +1167,8 @@ bool xpdf_ImportFromFile(const OUString& rURL, if ( line.isEmpty() ) break; - aParser.parseLine(line.makeStringAndClear()); + aParser.parseLine(line); + line.setLength(0); } } } @@ -1184,6 +1198,7 @@ bool xpdf_ImportFromFile(const OUString& rURL, "sdext.pdfimport", "getProcessInfo of " << converterURL << " failed with exit code " << info.Code); + // TODO: use xIHdl and/or exceptions to inform the user; see poppler/ErrorCodes.h bRet = false; } } diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx index 16ad04bf660a..57164f27cb42 100644 --- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx +++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx @@ -20,6 +20,25 @@ #include "pdfioutdev_gpl.hxx" #include "pnghelper.hxx" +#if defined __GNUC__ || defined __clang__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-parameter" +#elif defined _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4100) // unreferenced formal parameter +#pragma warning(disable : 4121) // alignment of a member was sensitive to packing in Gfx.h/Operator +#endif + +#include <Gfx.h> +#include <splash/SplashBitmap.h> +#include <SplashOutputDev.h> +#if defined __GNUC__ || defined __clang__ +# pragma GCC diagnostic pop +#elif defined _MSC_VER +#pragma warning(pop) +#endif + + #include <stdlib.h> #include <stdio.h> #include <assert.h> @@ -413,8 +432,6 @@ static void writeImage_( OutputBuffer& o_rOutputBuf, } // forwarders - - static void writeImageLF( OutputBuffer& o_rOutputBuf, Stream* str, int width, @@ -426,20 +443,70 @@ static void writeMaskLF( OutputBuffer& o_rOutputBuf, int height, bool bInvert ) { writeMask_(o_rOutputBuf,str,width,height,bInvert); } +// Vertically flip the bitmap +static void flipSplashBitmap(SplashBitmap *pBitmap) +{ + if (pBitmap->getRowSize() <= 0) + return; + + auto nBitmapHeight = static_cast<size_t>(pBitmap->getHeight()); + auto nRowSize = static_cast<size_t>(pBitmap->getRowSize()); + auto nAlphaRowSize = static_cast<size_t>(pBitmap->getAlphaRowSize()); + + std::unique_ptr<unsigned char[]> aTmpRow(new unsigned char[nRowSize]); + std::unique_ptr<unsigned char[]> aTmpAlphaRow(new unsigned char[nAlphaRowSize]); -int PDFOutDev::parseFont( long long nNewId, GfxFont* gfxFont, GfxState* state ) const + auto pBitmapData = pBitmap->getDataPtr(); + auto pAlphaData = pBitmap->getAlphaPtr(); + + // Set up pairs of pointers working from each end of the bitmap + auto pCurRowA = pBitmapData; + auto pCurAlphaA = pAlphaData; + auto pCurRowB = pBitmapData+nRowSize*(nBitmapHeight-1); + auto pCurAlphaB = pAlphaData+nAlphaRowSize*(nBitmapHeight-1); + + for (size_t nCur = 0; + nCur < nBitmapHeight/2; + nCur++, pCurRowA+=nRowSize, pCurRowB-=nRowSize, + pCurAlphaA+=nAlphaRowSize, pCurAlphaB-=nAlphaRowSize) + { + memcpy(aTmpRow.get(), pCurRowA, nRowSize); + memcpy(pCurRowA, pCurRowB, nRowSize); + memcpy(pCurRowB, aTmpRow.get(), nRowSize); + + memcpy(aTmpAlphaRow.get(), pCurAlphaA, nAlphaRowSize); + memcpy(pCurAlphaA, pCurAlphaB, nAlphaRowSize); + memcpy(pCurAlphaB, aTmpAlphaRow.get(), nAlphaRowSize); + } +} + +int PDFOutDev::parseFont( long long nNewId, GfxFont* gfxFont, const GfxState* state ) const { FontAttributes aNewFont; int nSize = 0; -#if POPPLER_CHECK_VERSION(0, 64, 0) - const +#if POPPLER_CHECK_VERSION(20, 12, 0) + std::string familyName = gfxFont->getNameWithoutSubsetTag(); +#else +#if POPPLER_CHECK_VERSION(0, 71, 0) // GooString::toStr() + std::string familyName = gfxFont->getName()->toStr(); +#else + const GooString* gooString = gfxFont->getName(); + std::string familyName = std::string(gooString->getCString(), gooString->getLength()); #endif - GooString* pFamily = gfxFont->getName(); - if( pFamily ) + if (familyName.length() > 7 && familyName.at(6) == '+') + { + familyName = familyName.substr(7); + } +#endif + if( familyName != "" ) { aNewFont.familyName.clear(); - aNewFont.familyName.append( gfxFont->getName() ); +#if POPPLER_CHECK_VERSION(0, 83, 0) // GooString::append(const std::string&) + aNewFont.familyName.append( familyName ); +#else + aNewFont.familyName.append( familyName.c_str() ); +#endif } else { @@ -447,21 +514,34 @@ int PDFOutDev::parseFont( long long nNewId, GfxFont* gfxFont, GfxState* state ) aNewFont.familyName.append( "Arial" ); } - aNewFont.isBold = gfxFont->isBold(); + aNewFont.maFontWeight = gfxFont->getWeight(); aNewFont.isItalic = gfxFont->isItalic(); +#if POPPLER_CHECK_VERSION(0, 83, 0) // const added to getTransformedFontSize aNewFont.size = state->getTransformedFontSize(); +#else + aNewFont.size = const_cast<GfxState*>(state)->getTransformedFontSize(); +#endif aNewFont.isUnderline = false; if( gfxFont->getType() == fontTrueType || gfxFont->getType() == fontType1 ) { // TODO(P3): Unfortunately, need to read stream twice, since // we must write byte count to stdout before +#if POPPLER_CHECK_VERSION(22, 6, 0) + std::optional<std::vector<unsigned char>> pBuf = gfxFont->readEmbFontFile( m_pDoc->getXRef() ); + if ( pBuf ) + { + aNewFont.isEmbedded = true; + nSize = pBuf->size(); + } +#else char* pBuf = gfxFont->readEmbFontFile( m_pDoc->getXRef(), &nSize ); if( pBuf ) { aNewFont.isEmbedded = true; gfree(pBuf); } +#endif } m_aFontMap[ nNewId ] = aNewFont; @@ -474,13 +554,29 @@ void PDFOutDev::writeFontFile( GfxFont* gfxFont ) const return; int nSize = 0; +#if POPPLER_CHECK_VERSION(22, 6, 0) + std::optional<std::vector<unsigned char>> pBuf = gfxFont->readEmbFontFile( m_pDoc->getXRef() ); + if ( pBuf ) + nSize = pBuf->size(); + if ( nSize == 0 ) + return; +#else char* pBuf = gfxFont->readEmbFontFile( m_pDoc->getXRef(), &nSize ); if( !pBuf ) return; +#endif // ---sync point--- see SYNC STREAMS above fflush(stdout); +#if POPPLER_CHECK_VERSION(22, 6, 0) + if( fwrite(pBuf->data(), sizeof(*pBuf->data()), nSize, g_binary_out) != static_cast<size_t>(nSize) ) + { + exit(1); // error + } + // ---sync point--- see SYNC STREAMS above + fflush(g_binary_out); +#else if( fwrite(pBuf, sizeof(char), nSize, g_binary_out) != static_cast<size_t>(nSize) ) { gfree(pBuf); @@ -489,6 +585,7 @@ void PDFOutDev::writeFontFile( GfxFont* gfxFont ) const // ---sync point--- see SYNC STREAMS above fflush(g_binary_out); gfree(pBuf); +#endif } #if POPPLER_CHECK_VERSION(0, 83, 0) @@ -520,7 +617,6 @@ void PDFOutDev::printPath( GfxPath* pPath ) PDFOutDev::PDFOutDev( PDFDoc* pDoc ) : m_pDoc( pDoc ), - m_aFontMap(), m_pUtf8Map( new UnicodeMap("UTF-8", true, &mapUTF8) ), m_bSkipImages(false) { @@ -530,7 +626,7 @@ PDFOutDev::~PDFOutDev() } void PDFOutDev::startPage(int /*pageNum*/, GfxState* state -#if POPPLER_CHECK_VERSION(0, 23, 0) || POPPLER_CHECK_VERSION(0, 24, 0) +#if POPPLER_CHECK_VERSION(0, 23, 0) , XRef* /*xref*/ #endif ) @@ -635,8 +731,15 @@ void PDFOutDev::updateLineDash(GfxState *state) return; assert(state); - double* dashArray; int arrayLen; double startOffset; + int arrayLen; double startOffset; +#if POPPLER_CHECK_VERSION(22, 9, 0) + const std::vector<double> &dash = state->getLineDash(&startOffset); + const double* dashArray = dash.data(); + arrayLen = dash.size(); +#else + double* dashArray; state->getLineDash(&dashArray, &arrayLen, &startOffset); +#endif printf( "updateLineDash" ); if( arrayLen && dashArray ) @@ -742,7 +845,11 @@ void PDFOutDev::updateFont(GfxState *state) { assert(state); +#if POPPLER_CHECK_VERSION(22, 6, 0) + GfxFont *gfxFont = state->getFont().get(); +#else GfxFont *gfxFont = state->getFont(); +#endif if( !gfxFont ) return; @@ -778,7 +885,7 @@ void PDFOutDev::updateFont(GfxState *state) #endif printf( " %d %d %d %d %f %d %s", aFont.isEmbedded, - aFont.isBold, + aFont.maFontWeight, aFont.isItalic, aFont.isUnderline, normalize(state->getTransformedFontSize()), @@ -787,8 +894,10 @@ void PDFOutDev::updateFont(GfxState *state) } printf( "\n" ); - if( nEmbedSize ) + if (nEmbedSize) + { writeFontFile(gfxFont); + } } void PDFOutDev::updateRender(GfxState *state) @@ -900,18 +1009,18 @@ void PDFOutDev::drawChar(GfxState *state, double x, double y, double csdx = 0.0; double csdy = 0.0; - if (state->getFont()->getWMode()) + if (!state->getFont() || !state->getFont()->getWMode()) { - csdy = state->getCharSpace(); + csdx = state->getCharSpace(); if (*u == ' ') - csdy += state->getWordSpace(); + csdx += state->getWordSpace(); + csdx *= state->getHorizScaling(); } else { - csdx = state->getCharSpace(); + csdy = state->getCharSpace(); if (*u == ' ') - csdx += state->getWordSpace(); - csdx *= state->getHorizScaling(); + csdy += state->getWordSpace(); } double cstdx = 0.0; @@ -1107,6 +1216,113 @@ void PDFOutDev::setSkipImages( bool bSkipImages ) m_bSkipImages = bSkipImages; } +#if POPPLER_CHECK_VERSION(21, 3, 0) +poppler_bool PDFOutDev::tilingPatternFill(GfxState *state, Gfx *, Catalog *, + GfxTilingPattern *tPat, const double *mat, + int x0, int y0, int x1, int y1, + double xStep, double yStep) +{ + const double *pBbox = tPat->getBBox(); + const int nPaintType = tPat->getPaintType(); + Dict *pResDict = tPat->getResDict(); + Object *aStr = tPat->getContentStream(); + double nWidth = pBbox[2] - pBbox[0]; + double nHeight = pBbox[3] - pBbox[1]; + + // If our wrapper is skipping images then we don't need to do anything + // but return 'true' so that Poppler doesn't do the slow method + if (m_bSkipImages) + return true; + + // Copied from the Cairo output dev; I think this is patterns + // with gaps, let poppler do the slow method for now. + if (xStep != nWidth || yStep != nHeight) + return false; + + printf( "tilingPatternFill %d %d %d %d %f %f " + "%d " + "%f %f %f %f %f %f", // No ending space! + + x0, y0, x1, y1, normalize(xStep), normalize(yStep), + + nPaintType, + + normalize(mat[0]), normalize(mat[1]), + normalize(mat[2]), normalize(mat[3]), + normalize(mat[4]), normalize(mat[5]) + ); + + PDFRectangle aBox; + aBox.x1 = pBbox[0]; + aBox.y1 = pBbox[1]; + aBox.x2 = pBbox[2]; + aBox.y2 = pBbox[3]; + + const int nDPI = 72; // GfxState seems to have 72.0 as magic for some reason + auto pSplashGfxState = new GfxState(nDPI, nDPI, &aBox, 0, false); + auto pSplashOut = new SplashOutputDev(splashModeRGB8, 1, false, nullptr); + pSplashOut->setEnableFreeType(false); + pSplashOut->startPage(0 /* pageNum */, pSplashGfxState, nullptr /* xref */); + + auto pSplashGfx = new Gfx(m_pDoc, pSplashOut, pResDict, &aBox, nullptr); + pSplashGfx->display(aStr); + std::unique_ptr<SplashBitmap> pSplashBitmap(pSplashOut->takeBitmap()); + // Poppler tells us to free the splash device immediately after taking the + // bitmap + delete pSplashGfxState; + delete pSplashGfx; + delete pSplashOut; + + // Add a vertical flip, we can't do this in LO for an image filled poly + flipSplashBitmap(pSplashBitmap.get()); + + auto nBitmapWidth = static_cast<size_t>(pSplashBitmap->getWidth()); + auto nBitmapHeight = static_cast<size_t>(pSplashBitmap->getHeight()); + + char *pBitmapData = reinterpret_cast<char *>(pSplashBitmap->getDataPtr()); + if (nPaintType == 2) + { + // My understanding is Type 2 fills are just bitmaps of *what* to fill + // in the current fill colour. + // sending it to LO as a flat colour image with the alpha map is easiest + GfxRGB aCurFill; + unsigned char r,g,b; + state->getFillColorSpace()->getRGB(state->getFillColor(), &aCurFill); + r = colToByte(aCurFill.r); + g = colToByte(aCurFill.g); + b = colToByte(aCurFill.b); + + for(size_t i=0; i < (nBitmapWidth * nBitmapHeight * 3); i+=3) + { + pBitmapData[i ] = r; + pBitmapData[i+1] = g; + pBitmapData[i+2] = b; + } + } + + std::unique_ptr<MemStream> pRgbStr(new MemStream(pBitmapData, 0, + nBitmapWidth * nBitmapHeight * 3, Object(objNull))); + std::unique_ptr<MemStream> pAlphaStr(new MemStream(reinterpret_cast<char *>(pSplashBitmap->getAlphaPtr()), + 0, nBitmapWidth * nBitmapHeight, Object(objNull))); + auto aDecode = Object(objNull); + std::unique_ptr<GfxImageColorMap> pRgbIdentityColorMap(new GfxImageColorMap(8, &aDecode, + new GfxDeviceRGBColorSpace())); + std::unique_ptr<GfxImageColorMap> pGrayIdentityColorMap(new GfxImageColorMap(8, &aDecode, + new GfxDeviceGrayColorSpace())); + + OutputBuffer aBuf; initBuf(aBuf); + writePng_(aBuf, pRgbStr.get(), nBitmapWidth, nBitmapHeight, pRgbIdentityColorMap.get(), + pAlphaStr.get(), nBitmapWidth, nBitmapHeight, pGrayIdentityColorMap.get()); + writeBinaryBuffer(aBuf); + + // If we return false here we can fall back to the slow path + return true; +} + +// This could be implemented for earlier versions, but the interface keeps +// changing a little; not having it is only a problem for inputs with +// large patterns. +#endif } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx index 2e7d2186f9a1..6a35d119314b 100644 --- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx +++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx @@ -55,14 +55,7 @@ class GfxPath; class GfxFont; class PDFDoc; -#if HAVE_POPPLER_VERSION_H #include <cpp/poppler-version.h> -#else -#define POPPLER_VERSION "0.12.3" -#define POPPLER_VERSION_MAJOR 0 -#define POPPLER_VERSION_MINOR 12 -#define POPPLER_VERSION_MICRO 3 -#endif #define POPPLER_CHECK_VERSION(major,minor,micro) \ (POPPLER_VERSION_MAJOR > (major) || \ (POPPLER_VERSION_MAJOR == (major) && POPPLER_VERSION_MINOR > (minor)) || \ @@ -75,7 +68,7 @@ namespace pdfi FontAttributes() : familyName(), isEmbedded(false), - isBold(false), + maFontWeight(GfxFont::W400), isItalic(false), isUnderline(false), size(0.0) @@ -86,7 +79,7 @@ namespace pdfi FontAttributes( const FontAttributes& rSrc ) : familyName(), isEmbedded(rSrc.isEmbedded), - isBold(rSrc.isBold), + maFontWeight(rSrc.maFontWeight), isItalic(rSrc.isItalic), isUnderline(rSrc.isUnderline), size(rSrc.size) @@ -100,7 +93,7 @@ namespace pdfi familyName.append(&rSrc.getFamilyName()); isEmbedded = rSrc.isEmbedded; - isBold = rSrc.isBold; + maFontWeight= rSrc.maFontWeight; isItalic = rSrc.isItalic; isUnderline = rSrc.isUnderline; size = rSrc.size; @@ -112,15 +105,15 @@ namespace pdfi { return getFamilyName().cmp(&rFont.getFamilyName())==0 && isEmbedded == rFont.isEmbedded && - isBold == rFont.isBold && + maFontWeight == rFont.maFontWeight && isItalic == rFont.isItalic && isUnderline == rFont.isUnderline && size == rFont.size; } - GooString familyName; + GooString familyName; bool isEmbedded; - bool isBold; + GfxFont::Weight maFontWeight; bool isItalic; bool isUnderline; double size; @@ -147,7 +140,7 @@ namespace pdfi std::unique_ptr<UnicodeMap> m_pUtf8Map; bool m_bSkipImages; - int parseFont( long long nNewId, GfxFont* pFont, GfxState* state ) const; + int parseFont( long long nNewId, GfxFont* pFont, const GfxState* state ) const; void writeFontFile( GfxFont* gfxFont ) const; #if POPPLER_CHECK_VERSION(0, 83, 0) static void printPath( const GfxPath* pPath ); @@ -186,7 +179,7 @@ namespace pdfi // Start a page. virtual void startPage(int pageNum, GfxState *state -#if POPPLER_CHECK_VERSION(0, 23, 0) || POPPLER_CHECK_VERSION(0, 24, 0) +#if POPPLER_CHECK_VERSION(0, 23, 0) , XRef *xref #endif ) override; @@ -290,6 +283,13 @@ namespace pdfi static void setPageNum( int nNumPages ); void setSkipImages ( bool bSkipImages ); +#if POPPLER_CHECK_VERSION(21, 3, 0) + poppler_bool useTilingPatternFill() override { return true; }; + poppler_bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, + GfxTilingPattern *tPat, const double *mat, + int x0, int y0, int x1, int y1, + double xStep, double yStep) override; +#endif }; } diff --git a/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx b/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx index a6390f0157e9..798555fe2f54 100644 --- a/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx +++ b/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx @@ -86,7 +86,7 @@ sal_uInt32 PngHelper::deflateBuffer( const Output_t* i_pBuf, size_t i_nLen, Outp if (Z_OK != deflateInit(&aStream, Z_BEST_COMPRESSION)) return 0; aStream.avail_in = uInt(i_nLen); - aStream.next_in = const_cast<Bytef*>(i_pBuf); + aStream.next_in = i_pBuf; sal_uInt8 aOutBuf[ 32768 ]; do diff --git a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx index b1a54bd09c5f..ebed120708cc 100644 --- a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx +++ b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx @@ -21,28 +21,69 @@ #ifdef _WIN32 # include <io.h> # include <fcntl.h> /*_O_BINARY*/ +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#endif +#ifndef SYSTEM_POPPLER +#include <string> // std::string +#include <cstddef> // std::size_t +#include <config_folders.h> //LIBO_SHARE_FOLDER #endif FILE* g_binary_out=stderr; -static const char *ownerPassword = "\001"; -static const char *userPassword = "\001"; -static const char *outputFile = "\001"; -static const char *options = "\001"; +#ifdef _WIN32 + +// Use Unicode API + +static const wchar_t *ownerPassword = nullptr; +static const wchar_t *userPassword = nullptr; +static const wchar_t *outputFile = nullptr; +static const wchar_t *options = L""; + +#define TO_STRING_VIEW(s) std::wstring_view(L##s) +using my_string = std::wstring; + +// Poppler expects UTF-8 strings on Windows - see its openFile in poppler/goo/gfile.cc. +static std::string myStringToStdString(std::wstring_view s) +{ + int len = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), nullptr, 0, nullptr, nullptr); + char* buff = static_cast<char*>(_alloca(len * sizeof(char))); + len = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), buff, len, nullptr, nullptr); + return std::string(buff, len); +} + +#else // ! _WIN32 + +static const char *ownerPassword = nullptr; +static const char *userPassword = nullptr; +static const char *outputFile = nullptr; +static const char *options = ""; + +#define TO_STRING_VIEW(s) std::string_view(s) +using my_string = std::string; + +static std::string myStringToStdString(std::string&& s) { return std::move(s); } + +#endif +#ifdef _WIN32 +int wmain(int argc, wchar_t **argv) +#else int main(int argc, char **argv) +#endif { - int k = 0; + int k = 1; while (k < argc) { - if (!strcmp(argv[k], "-f")) + if (argv[k] == TO_STRING_VIEW("-f")) { outputFile = argv[k+1]; argc -= 2; for (int j = k; j < argc; ++j) argv[j] = argv[j+2]; } - else if (!strcmp(argv[k], "-o")) + else if (argv[k] == TO_STRING_VIEW("-o")) { options = argv[k+1]; argc -= 2; @@ -50,14 +91,14 @@ int main(int argc, char **argv) argv[j] = argv[j+2]; } - else if (!strcmp(argv[k], "-opw")) + else if (argv[k] == TO_STRING_VIEW("-opw")) { ownerPassword = argv[k+1]; argc -= 2; for (int j = k; j < argc; ++j) argv[j] = argv[j+2]; } - else if (!strcmp(argv[k], "-upw")) + else if (argv[k] == TO_STRING_VIEW("-upw")) { userPassword = argv[k+1]; argc -= 2; @@ -67,11 +108,25 @@ int main(int argc, char **argv) ++k; } + /* Get data directory location */ +#ifdef SYSTEM_POPPLER + const char* datadir = nullptr; +#else + /* Creates an absolute path to the poppler_data directory, by taking the path + * to the xpdfimport executable (provided in argv[0], and concatenating a + * relative path to the poppler_data directory from the program directory. */ + const my_string execPath = argv[0]; + const std::size_t filenameStartPos = execPath.find_last_of(TO_STRING_VIEW("/\\")) + 1; + const my_string programPath = execPath.substr(0, filenameStartPos); + const std::string popplerDataPath = myStringToStdString(programPath + my_string(TO_STRING_VIEW("../" LIBO_SHARE_FOLDER "/xpdfimport/poppler_data"))); + const char* datadir = popplerDataPath.c_str(); +#endif + // read config file #if POPPLER_CHECK_VERSION(0, 83, 0) - globalParams = std::make_unique<GlobalParams>(); + globalParams = std::make_unique<GlobalParams>(datadir); #else - globalParams = new GlobalParams(); + globalParams = new GlobalParams(datadir); #endif globalParams->setErrQuiet(true); #if defined(_MSC_VER) @@ -96,22 +151,25 @@ int main(int argc, char **argv) } // PDFDoc takes over ownership for all strings below - GooString* pFileName = new GooString(argv[1]); - GooString* pErrFileName = new GooString(argv[2]); + GooString* pFileName = new GooString(myStringToStdString(argv[1])); // check for password string(s) GooString* pOwnerPasswordStr( aPwBuf[0] != 0 ? new GooString( aPwBuf ) - : (ownerPassword[0] != '\001' - ? new GooString(ownerPassword) + : (ownerPassword + ? new GooString(myStringToStdString(ownerPassword)) : nullptr ) ); GooString* pUserPasswordStr( aPwBuf[0] != 0 ? new GooString( aPwBuf ) - : (userPassword[0] != '\001' - ? new GooString(userPassword) + : (userPassword + ? new GooString(myStringToStdString(userPassword)) : nullptr ) ); - if( outputFile[0] != '\001' ) + if (outputFile) +#if defined _WIN32 + g_binary_out = _wfopen(outputFile, L"wb"); +#else g_binary_out = fopen(outputFile,"wb"); +#endif #ifdef _WIN32 // Win actually modifies output for O_TEXT file mode, so need to @@ -119,24 +177,26 @@ int main(int argc, char **argv) _setmode( _fileno( g_binary_out ), _O_BINARY ); #endif +#if POPPLER_CHECK_VERSION(22, 6, 0) + PDFDoc aDoc( std::make_unique<GooString>(pFileName), + std::optional<GooString>(pOwnerPasswordStr), + std::optional<GooString>(pUserPasswordStr) ); +#else PDFDoc aDoc( pFileName, pOwnerPasswordStr, pUserPasswordStr ); +#endif - PDFDoc aErrDoc( pErrFileName, - pOwnerPasswordStr, - pUserPasswordStr ); - - // Check various permissions for aDoc. - PDFDoc &rDoc = aDoc.isOk()? aDoc: aErrDoc; + if (!aDoc.isOk()) + return aDoc.getErrorCode(); - pdfi::PDFOutDev aOutDev(&rDoc); - if (!strcmp(options, "SkipImages")) { + pdfi::PDFOutDev aOutDev(&aDoc); + if (options == TO_STRING_VIEW("SkipImages")) { aOutDev.setSkipImages(true); } // tell the receiver early - needed for proper progress calculation - const int nPages = rDoc.isOk()? rDoc.getNumPages(): 0; + const int nPages = aDoc.getNumPages(); pdfi::PDFOutDev::setPageNum(nPages); // virtual resolution of the PDF OutputDev in dpi @@ -145,12 +205,12 @@ int main(int argc, char **argv) // do the conversion for (int i = 1; i <= nPages; ++i) { - rDoc.displayPage(&aOutDev, + aDoc.displayPage(&aOutDev, i, PDFI_OUTDEV_RESOLUTION, PDFI_OUTDEV_RESOLUTION, 0, true, true, true); - rDoc.processLinks(&aOutDev, i); + aDoc.processLinks(&aOutDev, i); } return 0; diff --git a/sdext/source/presenter/PresenterAccessibility.cxx b/sdext/source/presenter/PresenterAccessibility.cxx deleted file mode 100644 index c57cf61c946c..000000000000 --- a/sdext/source/presenter/PresenterAccessibility.cxx +++ /dev/null @@ -1,1866 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterAccessibility.hxx" -#include "PresenterTextView.hxx" -#include "PresenterConfigurationAccess.hxx" -#include "PresenterNotesView.hxx" -#include "PresenterPaneBase.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterPaneFactory.hxx" - -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleRelationType.hpp> -#include <com/sun/star/accessibility/AccessibleRole.hpp> -#include <com/sun/star/accessibility/AccessibleScrollType.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> -#include <com/sun/star/accessibility/XAccessibleContext.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/awt/XWindow2.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/implbase.hxx> -#include <o3tl/safeint.hxx> -#include <sal/log.hxx> - -#include <algorithm> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -//===== PresenterAccessibleObject ============================================= - -namespace sdext::presenter { - -namespace { - typedef ::cppu::WeakComponentImplHelper < - css::accessibility::XAccessible, - css::accessibility::XAccessibleContext, - css::accessibility::XAccessibleComponent, - css::accessibility::XAccessibleEventBroadcaster, - css::awt::XWindowListener - > PresenterAccessibleObjectInterfaceBase; -} - -class PresenterAccessible::AccessibleObject - : public ::cppu::BaseMutex, - public PresenterAccessibleObjectInterfaceBase -{ -public: - AccessibleObject ( - const css::lang::Locale& rLocale, - const sal_Int16 nRole, - const OUString& rsName); - void LateInitialization(); - - virtual void SetWindow ( - const css::uno::Reference<css::awt::XWindow>& rxContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow); - void SetAccessibleParent (const css::uno::Reference<css::accessibility::XAccessible>& rxAccessibleParent); - - virtual void SAL_CALL disposing() override; - - void AddChild (const ::rtl::Reference<AccessibleObject>& rpChild); - void RemoveChild (const ::rtl::Reference<AccessibleObject>& rpChild); - - void SetIsFocused (const bool bIsFocused); - void SetAccessibleName (const OUString& rsName); - - void FireAccessibleEvent ( - const sal_Int16 nEventId, - const css::uno::Any& rOldValue, - const css::uno::Any& rNewValue); - - void UpdateStateSet(); - - //----- XAccessible ------------------------------------------------------- - - virtual css::uno::Reference<css::accessibility::XAccessibleContext> SAL_CALL - getAccessibleContext() override; - - //----- XAccessibleContext ---------------------------------------------- - - virtual sal_Int32 SAL_CALL getAccessibleChildCount() override; - - virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL - getAccessibleChild (sal_Int32 nIndex) override; - - virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL getAccessibleParent() override; - - virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() override; - - virtual sal_Int16 SAL_CALL getAccessibleRole() override; - - virtual OUString SAL_CALL getAccessibleDescription() override; - - virtual OUString SAL_CALL getAccessibleName() override; - - virtual css::uno::Reference<css::accessibility::XAccessibleRelationSet> SAL_CALL - getAccessibleRelationSet() override; - - virtual css::uno::Reference<css::accessibility::XAccessibleStateSet> SAL_CALL - getAccessibleStateSet() override; - - virtual css::lang::Locale SAL_CALL getLocale() override; - - //----- XAccessibleComponent -------------------------------------------- - - virtual sal_Bool SAL_CALL containsPoint ( - const css::awt::Point& aPoint) override; - - virtual css::uno::Reference<css::accessibility::XAccessible> SAL_CALL - getAccessibleAtPoint ( - const css::awt::Point& aPoint) override; - - virtual css::awt::Rectangle SAL_CALL getBounds() override; - - virtual css::awt::Point SAL_CALL getLocation() override; - - virtual css::awt::Point SAL_CALL getLocationOnScreen() override; - - virtual css::awt::Size SAL_CALL getSize() override; - - virtual void SAL_CALL grabFocus() override; - - virtual sal_Int32 SAL_CALL getForeground() override; - - virtual sal_Int32 SAL_CALL getBackground() override; - - //----- XAccessibleEventBroadcaster -------------------------------------- - - virtual void SAL_CALL addAccessibleEventListener ( - const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rxListener) override; - - virtual void SAL_CALL removeAccessibleEventListener ( - const css::uno::Reference<css::accessibility::XAccessibleEventListener>& rxListener) override; - - //----- XWindowListener --------------------------------------------------- - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - //----- XEventListener ---------------------------------------------------- - - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - -protected: - OUString msName; - css::uno::Reference<css::awt::XWindow2> mxContentWindow; - css::uno::Reference<css::awt::XWindow2> mxBorderWindow; - const css::lang::Locale maLocale; - const sal_Int16 mnRole; - sal_uInt32 mnStateSet; - bool mbIsFocused; - css::uno::Reference<css::accessibility::XAccessible> mxParentAccessible; - ::std::vector<rtl::Reference<AccessibleObject> > maChildren; - ::std::vector<Reference<XAccessibleEventListener> > maListeners; - - virtual awt::Point GetRelativeLocation(); - virtual awt::Size GetSize(); - virtual awt::Point GetAbsoluteParentLocation(); - - virtual bool GetWindowState (const sal_Int16 nType) const; - - void UpdateState (const sal_Int16 aState, const bool bValue); - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -//===== AccessibleStateSet ==================================================== - -namespace { -typedef ::cppu::WeakComponentImplHelper < - css::accessibility::XAccessibleStateSet - > AccessibleStateSetInterfaceBase; - -class AccessibleStateSet - : public ::cppu::BaseMutex, - public AccessibleStateSetInterfaceBase -{ -public: - explicit AccessibleStateSet (const sal_Int32 nStateSet); - - static sal_uInt32 GetStateMask (const sal_Int16 nType); - - //----- XAccessibleStateSet ----------------------------------------------- - - virtual sal_Bool SAL_CALL isEmpty() override; - - virtual sal_Bool SAL_CALL contains (sal_Int16 nState) override; - - virtual sal_Bool SAL_CALL containsAll (const css::uno::Sequence<sal_Int16>& rStateSet) override; - - virtual css::uno::Sequence<sal_Int16> SAL_CALL getStates() override; - -private: - const sal_Int32 mnStateSet; -}; - -//===== AccessibleRelationSet ================================================= - -typedef ::cppu::WeakComponentImplHelper < - css::accessibility::XAccessibleRelationSet - > AccessibleRelationSetInterfaceBase; - -class AccessibleRelationSet - : public ::cppu::BaseMutex, - public AccessibleRelationSetInterfaceBase -{ -public: - AccessibleRelationSet(); - - void AddRelation ( - const sal_Int16 nRelationType, - const Reference<XInterface>& rxObject); - - //----- XAccessibleRelationSet -------------------------------------------- - - virtual sal_Int32 SAL_CALL getRelationCount() override; - - virtual AccessibleRelation SAL_CALL getRelation (sal_Int32 nIndex) override; - - virtual sal_Bool SAL_CALL containsRelation (sal_Int16 nRelationType) override; - - virtual AccessibleRelation SAL_CALL getRelationByType (sal_Int16 nRelationType) override; - -private: - ::std::vector<AccessibleRelation> maRelations; -}; - -//===== PresenterAccessibleParagraph ========================================== - -typedef ::cppu::ImplInheritanceHelper < - PresenterAccessible::AccessibleObject, - css::accessibility::XAccessibleText - > PresenterAccessibleParagraphInterfaceBase; -} - -class PresenterAccessible::AccessibleParagraph - : public PresenterAccessibleParagraphInterfaceBase -{ -public: - AccessibleParagraph ( - const css::lang::Locale& rLocale, - const OUString& rsName, - const SharedPresenterTextParagraph& rpParagraph, - const sal_Int32 nParagraphIndex); - - //----- XAccessibleContext ------------------------------------------------ - - virtual css::uno::Reference<css::accessibility::XAccessibleRelationSet> SAL_CALL - getAccessibleRelationSet() override; - - //----- XAccessibleText --------------------------------------------------- - - virtual sal_Int32 SAL_CALL getCaretPosition() override; - - virtual sal_Bool SAL_CALL setCaretPosition (sal_Int32 nIndex) override; - - virtual sal_Unicode SAL_CALL getCharacter (sal_Int32 nIndex) override; - - virtual css::uno::Sequence<css::beans::PropertyValue> SAL_CALL - getCharacterAttributes ( - ::sal_Int32 nIndex, - const css::uno::Sequence<OUString>& rRequestedAttributes) override; - - virtual css::awt::Rectangle SAL_CALL getCharacterBounds (sal_Int32 nIndex) override; - - virtual sal_Int32 SAL_CALL getCharacterCount() override; - - virtual sal_Int32 SAL_CALL getIndexAtPoint (const css::awt::Point& rPoint) override; - - virtual OUString SAL_CALL getSelectedText() override; - - virtual sal_Int32 SAL_CALL getSelectionStart() override; - - virtual sal_Int32 SAL_CALL getSelectionEnd() override; - - virtual sal_Bool SAL_CALL setSelection (sal_Int32 nStartIndex, sal_Int32 nEndIndex) override; - - virtual OUString SAL_CALL getText() override; - - virtual OUString SAL_CALL getTextRange ( - sal_Int32 nStartIndex, - sal_Int32 nEndIndex) override; - - virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex ( - sal_Int32 nIndex, - sal_Int16 nTextType) override; - - virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex ( - sal_Int32 nIndex, - sal_Int16 nTextType) override; - - virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex ( - sal_Int32 nIndex, - sal_Int16 nTextType) override; - - virtual sal_Bool SAL_CALL copyText (sal_Int32 nStartIndex, sal_Int32 nEndIndex) override; - - virtual sal_Bool SAL_CALL scrollSubstringTo( - sal_Int32 nStartIndex, - sal_Int32 nEndIndex, - css::accessibility::AccessibleScrollType aScrollType) override; - -protected: - virtual awt::Point GetRelativeLocation() override; - virtual awt::Size GetSize() override; - virtual awt::Point GetAbsoluteParentLocation() override; - virtual bool GetWindowState (const sal_Int16 nType) const override; - -private: - SharedPresenterTextParagraph mpParagraph; - const sal_Int32 mnParagraphIndex; -}; - -//===== AccessibleConsole ===================================================== - -namespace { - -class AccessibleConsole -{ -public: - static rtl::Reference<PresenterAccessible::AccessibleObject> Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const lang::Locale& rLocale) - { - OUString sName ("Presenter Console"); - PresenterConfigurationAccess aConfiguration ( - rxContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - aConfiguration.GetConfigurationNode("Presenter/Accessibility/Console/String") - >>= sName; - - rtl::Reference<PresenterAccessible::AccessibleObject> pObject ( - new PresenterAccessible::AccessibleObject( - rLocale, AccessibleRole::PANEL, sName)); - pObject->LateInitialization(); - pObject->UpdateStateSet(); - - return pObject; - } -}; - -//===== AccessiblePreview ===================================================== - -class AccessiblePreview -{ -public: - static rtl::Reference<PresenterAccessible::AccessibleObject> Create ( - const Reference<css::uno::XComponentContext>& rxContext, - const lang::Locale& rLocale, - const Reference<awt::XWindow>& rxContentWindow, - const Reference<awt::XWindow>& rxBorderWindow) - { - OUString sName ("Presenter Notes Window"); - { - PresenterConfigurationAccess aConfiguration ( - rxContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - aConfiguration.GetConfigurationNode("Presenter/Accessibility/Preview/String") - >>= sName; - } - - rtl::Reference<PresenterAccessible::AccessibleObject> pObject ( - new PresenterAccessible::AccessibleObject( - rLocale, - AccessibleRole::LABEL, - sName)); - pObject->LateInitialization(); - pObject->UpdateStateSet(); - pObject->SetWindow(rxContentWindow, rxBorderWindow); - - return pObject; - } -}; - -//===== AccessibleNotes ======================================================= - -class AccessibleNotes : public PresenterAccessible::AccessibleObject -{ -public: - AccessibleNotes ( - const css::lang::Locale& rLocale, - const OUString& rsName); - - static rtl::Reference<PresenterAccessible::AccessibleObject> Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const lang::Locale& rLocale, - const Reference<awt::XWindow>& rxContentWindow, - const Reference<awt::XWindow>& rxBorderWindow, - const std::shared_ptr<PresenterTextView>& rpTextView); - - void SetTextView (const std::shared_ptr<PresenterTextView>& rpTextView); - - virtual void SetWindow ( - const css::uno::Reference<css::awt::XWindow>& rxContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) override; - -private: - std::shared_ptr<PresenterTextView> mpTextView; - - void NotifyCaretChange ( - const sal_Int32 nOldParagraphIndex, - const sal_Int32 nOldCharacterIndex, - const sal_Int32 nNewParagraphIndex, - const sal_Int32 nNewCharacterIndex); -}; - -//===== AccessibleFocusManager ================================================ - -/** A singleton class that makes sure that only one accessibility object in - the PresenterConsole hierarchy has the focus. -*/ -class AccessibleFocusManager -{ -public: - static std::shared_ptr<AccessibleFocusManager> const & Instance(); - - void AddFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject); - void RemoveFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject); - - void FocusObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject); - - ~AccessibleFocusManager(); - -private: - static std::shared_ptr<AccessibleFocusManager> mpInstance; - ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > maFocusableObjects; - bool m_isInDtor = false; - - AccessibleFocusManager(); -}; - -} - -//===== PresenterAccessible =================================================== - -PresenterAccessible::PresenterAccessible ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const Reference<drawing::framework::XPane>& rxMainPane) - : PresenterAccessibleInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - mpPresenterController(rpPresenterController), - mxMainPane(rxMainPane, UNO_QUERY), - mxMainWindow(), - mxPreviewContentWindow(), - mxPreviewBorderWindow(), - mxNotesContentWindow(), - mxNotesBorderWindow(), - mpAccessibleConsole(), - mpAccessiblePreview(), - mpAccessibleNotes(), - mxAccessibleParent() -{ - if (mxMainPane.is()) - mxMainPane->setAccessible(this); -} - -PresenterAccessible::~PresenterAccessible() -{ -} - -PresenterPaneContainer::SharedPaneDescriptor PresenterAccessible::GetPreviewPane() const -{ - PresenterPaneContainer::SharedPaneDescriptor pPreviewPane; - - if ( ! mpPresenterController.is()) - return pPreviewPane; - - rtl::Reference<PresenterPaneContainer> pContainer (mpPresenterController->GetPaneContainer()); - if ( ! pContainer.is()) - return pPreviewPane; - - pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL); - Reference<drawing::framework::XPane> xPreviewPane; - if (pPreviewPane) - xPreviewPane = pPreviewPane->mxPane.get(); - if ( ! xPreviewPane.is()) - { - pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msSlideSorterPaneURL); - } - return pPreviewPane; -} - -void PresenterAccessible::UpdateAccessibilityHierarchy() -{ - if ( ! mpPresenterController.is()) - return; - - Reference<drawing::framework::XConfigurationController> xConfigurationController( - mpPresenterController->GetConfigurationController()); - if ( ! xConfigurationController.is()) - return; - - rtl::Reference<PresenterPaneContainer> pPaneContainer ( - mpPresenterController->GetPaneContainer()); - if ( ! pPaneContainer.is()) - return; - - if ( ! mpAccessibleConsole.is()) - return; - - // Get the preview pane (standard or notes view) or the slide overview - // pane. - PresenterPaneContainer::SharedPaneDescriptor pPreviewPane(GetPreviewPane()); - Reference<drawing::framework::XPane> xPreviewPane; - if (pPreviewPane) - xPreviewPane = pPreviewPane->mxPane.get(); - - // Get the notes pane. - PresenterPaneContainer::SharedPaneDescriptor pNotesPane( - pPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL)); - Reference<drawing::framework::XPane> xNotesPane; - if (pNotesPane) - xNotesPane = pNotesPane->mxPane.get(); - - // Get the notes view. - Reference<drawing::framework::XView> xNotesView; - if (pNotesPane) - xNotesView = pNotesPane->mxView; - rtl::Reference<PresenterNotesView> pNotesView ( - dynamic_cast<PresenterNotesView*>(xNotesView.get())); - - UpdateAccessibilityHierarchy( - pPreviewPane ? pPreviewPane->mxContentWindow : Reference<awt::XWindow>(), - pPreviewPane ? pPreviewPane->mxBorderWindow : Reference<awt::XWindow>(), - (pPreviewPane&&pPreviewPane->mxPane.is()) ? pPreviewPane->mxPane->GetTitle() : OUString(), - pNotesPane ? pNotesPane->mxContentWindow : Reference<awt::XWindow>(), - pNotesPane ? pNotesPane->mxBorderWindow : Reference<awt::XWindow>(), - pNotesView.is() - ? pNotesView->GetTextView() - : std::shared_ptr<PresenterTextView>()); -} - -void PresenterAccessible::UpdateAccessibilityHierarchy ( - const Reference<awt::XWindow>& rxPreviewContentWindow, - const Reference<awt::XWindow>& rxPreviewBorderWindow, - const OUString& rsTitle, - const Reference<awt::XWindow>& rxNotesContentWindow, - const Reference<awt::XWindow>& rxNotesBorderWindow, - const std::shared_ptr<PresenterTextView>& rpNotesTextView) -{ - if ( ! mpAccessibleConsole.is()) - return; - - if (mxPreviewContentWindow != rxPreviewContentWindow) - { - if (mpAccessiblePreview.is()) - { - mpAccessibleConsole->RemoveChild(mpAccessiblePreview); - mpAccessiblePreview = nullptr; - } - - mxPreviewContentWindow = rxPreviewContentWindow; - mxPreviewBorderWindow = rxPreviewBorderWindow; - - if (mxPreviewContentWindow.is()) - { - mpAccessiblePreview = AccessiblePreview::Create( - mxComponentContext, - lang::Locale(), - mxPreviewContentWindow, - mxPreviewBorderWindow); - mpAccessibleConsole->AddChild(mpAccessiblePreview); - mpAccessiblePreview->SetAccessibleName(rsTitle); - } - } - - if (mxNotesContentWindow == rxNotesContentWindow) - return; - - if (mpAccessibleNotes.is()) - { - mpAccessibleConsole->RemoveChild(mpAccessibleNotes); - mpAccessibleNotes = nullptr; - } - - mxNotesContentWindow = rxNotesContentWindow; - mxNotesBorderWindow = rxNotesBorderWindow; - - if (mxNotesContentWindow.is()) - { - mpAccessibleNotes = AccessibleNotes::Create( - mxComponentContext, - lang::Locale(), - mxNotesContentWindow, - mxNotesBorderWindow, - rpNotesTextView); - mpAccessibleConsole->AddChild(mpAccessibleNotes); - } -} - -void PresenterAccessible::NotifyCurrentSlideChange () -{ - if (mpAccessiblePreview.is()) - { - PresenterPaneContainer::SharedPaneDescriptor pPreviewPane (GetPreviewPane()); - mpAccessiblePreview->SetAccessibleName( - pPreviewPane&&pPreviewPane->mxPane.is() - ? pPreviewPane->mxPane->GetTitle() - : OUString()); - } - - // Play some focus ping-pong to trigger AT tools. - //AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole); - AccessibleFocusManager::Instance()->FocusObject(mpAccessiblePreview); -} - -void SAL_CALL PresenterAccessible::disposing() -{ - UpdateAccessibilityHierarchy( - nullptr, - nullptr, - OUString(), - nullptr, - nullptr, - std::shared_ptr<PresenterTextView>()); - - if (mxMainWindow.is()) - { - mxMainWindow->removeFocusListener(this); - - if (mxMainPane.is()) - mxMainPane->setAccessible(nullptr); - } - - mpAccessiblePreview = nullptr; - mpAccessibleNotes = nullptr; - mpAccessibleConsole = nullptr; -} - -//----- XAccessible ----------------------------------------------------------- - -Reference<XAccessibleContext> SAL_CALL PresenterAccessible::getAccessibleContext() -{ - if ( ! mpAccessibleConsole.is()) - { - Reference<XPane> xMainPane (mxMainPane, UNO_QUERY); - if (xMainPane.is()) - { - mxMainWindow = xMainPane->getWindow(); - mxMainWindow->addFocusListener(this); - } - mpAccessibleConsole = AccessibleConsole::Create( - mxComponentContext, css::lang::Locale()); - mpAccessibleConsole->SetWindow(mxMainWindow, nullptr); - mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent); - UpdateAccessibilityHierarchy(); - if (mpPresenterController.is()) - mpPresenterController->SetAccessibilityActiveState(true); - } - return mpAccessibleConsole->getAccessibleContext(); -} - -//----- XFocusListener ---------------------------------------------------- - -void SAL_CALL PresenterAccessible::focusGained (const css::awt::FocusEvent&) -{ - SAL_INFO("sdext.presenter", __func__ << ": PresenterAccessible::focusGained at " << this - << " and window " << mxMainWindow.get()); - AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole); -} - -void SAL_CALL PresenterAccessible::focusLost (const css::awt::FocusEvent&) -{ - SAL_INFO("sdext.presenter", __func__ << ": PresenterAccessible::focusLost at " << this); - AccessibleFocusManager::Instance()->FocusObject(nullptr); -} - -//----- XEventListener ---------------------------------------------------- - -void SAL_CALL PresenterAccessible::disposing (const css::lang::EventObject& rEvent) -{ - if (rEvent.Source == mxMainWindow) - mxMainWindow = nullptr; -} - -//----- XInitialize ----------------------------------------------------------- - -void SAL_CALL PresenterAccessible::initialize (const css::uno::Sequence<css::uno::Any>& rArguments) -{ - if (rArguments.hasElements()) - { - mxAccessibleParent.set(rArguments[0], UNO_QUERY); - if (mpAccessibleConsole.is()) - mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent); - } -} - -//===== PresenterAccessible::AccessibleObject ========================================= - -PresenterAccessible::AccessibleObject::AccessibleObject ( - const lang::Locale& rLocale, - const sal_Int16 nRole, - const OUString& rsName) - : PresenterAccessibleObjectInterfaceBase(m_aMutex), - msName(rsName), - mxContentWindow(), - mxBorderWindow(), - maLocale(rLocale), - mnRole(nRole), - mnStateSet(0), - mbIsFocused(false), - mxParentAccessible(), - maChildren(), - maListeners() -{ -} - -void PresenterAccessible::AccessibleObject::LateInitialization() -{ - AccessibleFocusManager::Instance()->AddFocusableObject(this); -} - -void PresenterAccessible::AccessibleObject::SetWindow ( - const Reference<awt::XWindow>& rxContentWindow, - const Reference<awt::XWindow>& rxBorderWindow) -{ - Reference<awt::XWindow2> xContentWindow (rxContentWindow, UNO_QUERY); - - if (mxContentWindow.get() == xContentWindow.get()) - return; - - if (mxContentWindow.is()) - { - mxContentWindow->removeWindowListener(this); - } - - mxContentWindow = xContentWindow; - mxBorderWindow.set(rxBorderWindow, UNO_QUERY); - - if (mxContentWindow.is()) - { - mxContentWindow->addWindowListener(this); - } - - UpdateStateSet(); -} - -void PresenterAccessible::AccessibleObject::SetAccessibleParent ( - const Reference<XAccessible>& rxAccessibleParent) -{ - mxParentAccessible = rxAccessibleParent; -} - -void SAL_CALL PresenterAccessible::AccessibleObject::disposing() -{ - AccessibleFocusManager::Instance()->RemoveFocusableObject(this); - SetWindow(nullptr, nullptr); -} - -//----- XAccessible ------------------------------------------------------- - -Reference<XAccessibleContext> SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleContext() -{ - ThrowIfDisposed(); - - return this; -} - -//----- XAccessibleContext ---------------------------------------------- - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getAccessibleChildCount() -{ - ThrowIfDisposed(); - - const sal_Int32 nChildCount (maChildren.size()); - - return nChildCount; -} - -Reference<XAccessible> SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleChild (sal_Int32 nIndex) -{ - ThrowIfDisposed(); - - if (nIndex<0 || nIndex>=sal_Int32(maChildren.size())) - throw lang::IndexOutOfBoundsException("invalid child index", static_cast<uno::XWeak*>(this)); - - return maChildren[nIndex]; -} - -Reference<XAccessible> SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleParent() -{ - ThrowIfDisposed(); - - return mxParentAccessible; -} - -sal_Int32 SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleIndexInParent() -{ - ThrowIfDisposed(); - - const Reference<XAccessible> xThis (this); - if (mxParentAccessible.is()) - { - const Reference<XAccessibleContext> xContext (mxParentAccessible->getAccessibleContext()); - for (sal_Int32 nIndex=0,nCount=xContext->getAccessibleChildCount(); - nIndex<nCount; - ++nIndex) - { - if (xContext->getAccessibleChild(nIndex) == xThis) - return nIndex; - } - } - - return 0; -} - -sal_Int16 SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleRole() -{ - ThrowIfDisposed(); - - return mnRole; -} - -OUString SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleDescription() -{ - ThrowIfDisposed(); - - return msName; -} - -OUString SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleName() -{ - ThrowIfDisposed(); - - return msName; -} - -Reference<XAccessibleRelationSet> SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleRelationSet() -{ - ThrowIfDisposed(); - - return nullptr; -} - -Reference<XAccessibleStateSet> SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleStateSet() -{ - ThrowIfDisposed(); - - return Reference<XAccessibleStateSet>(new AccessibleStateSet(mnStateSet)); -} - -lang::Locale SAL_CALL - PresenterAccessible::AccessibleObject::getLocale() -{ - ThrowIfDisposed(); - - if (mxParentAccessible.is()) - { - Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext()); - if (xParentContext.is()) - return xParentContext->getLocale(); - } - return maLocale; -} - -//----- XAccessibleComponent ------------------------------------------------ - -sal_Bool SAL_CALL PresenterAccessible::AccessibleObject::containsPoint ( - const awt::Point& rPoint) -{ - ThrowIfDisposed(); - - if (mxContentWindow.is()) - { - const awt::Rectangle aBox (getBounds()); - return rPoint.X>=aBox.X - && rPoint.Y>=aBox.Y - && rPoint.X<aBox.X+aBox.Width - && rPoint.Y<aBox.Y+aBox.Height; - } - else - return false; -} - -Reference<XAccessible> SAL_CALL - PresenterAccessible::AccessibleObject::getAccessibleAtPoint (const awt::Point&) -{ - ThrowIfDisposed(); - - return Reference<XAccessible>(); -} - -awt::Rectangle SAL_CALL PresenterAccessible::AccessibleObject::getBounds() -{ - ThrowIfDisposed(); - - const awt::Point aLocation (GetRelativeLocation()); - const awt::Size aSize (GetSize()); - - return awt::Rectangle (aLocation.X, aLocation.Y, aSize.Width, aSize.Height); -} - -awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocation() -{ - ThrowIfDisposed(); - - const awt::Point aLocation (GetRelativeLocation()); - - return aLocation; -} - -awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocationOnScreen() -{ - ThrowIfDisposed(); - - awt::Point aRelativeLocation (GetRelativeLocation()); - awt::Point aParentLocationOnScreen (GetAbsoluteParentLocation()); - - return awt::Point( - aRelativeLocation.X + aParentLocationOnScreen.X, - aRelativeLocation.Y + aParentLocationOnScreen.Y); -} - -awt::Size SAL_CALL PresenterAccessible::AccessibleObject::getSize() -{ - ThrowIfDisposed(); - - const awt::Size aSize (GetSize()); - - return aSize; -} - -void SAL_CALL PresenterAccessible::AccessibleObject::grabFocus() -{ - ThrowIfDisposed(); - if (mxBorderWindow.is()) - mxBorderWindow->setFocus(); - else if (mxContentWindow.is()) - mxContentWindow->setFocus(); -} - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getForeground() -{ - ThrowIfDisposed(); - - return 0x00ffffff; -} - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getBackground() -{ - ThrowIfDisposed(); - - return 0x00000000; -} - -//----- XAccessibleEventBroadcaster ------------------------------------------- - -void SAL_CALL PresenterAccessible::AccessibleObject::addAccessibleEventListener ( - const Reference<XAccessibleEventListener>& rxListener) -{ - if (!rxListener.is()) - return; - - const osl::MutexGuard aGuard(m_aMutex); - - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - uno::Reference<uno::XInterface> xThis (static_cast<XWeak*>(this), UNO_QUERY); - rxListener->disposing (lang::EventObject(xThis)); - } - else - { - maListeners.push_back(rxListener); - } -} - -void SAL_CALL PresenterAccessible::AccessibleObject::removeAccessibleEventListener ( - const Reference<XAccessibleEventListener>& rxListener) -{ - ThrowIfDisposed(); - if (rxListener.is()) - { - const osl::MutexGuard aGuard(m_aMutex); - - auto const it(std::remove(maListeners.begin(), maListeners.end(), rxListener)); - if (it != maListeners.end()) - { - maListeners.erase(it); - } - } -} - -//----- XWindowListener --------------------------------------------------- - -void SAL_CALL PresenterAccessible::AccessibleObject::windowResized ( - const css::awt::WindowEvent&) -{ - FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any()); -} - -void SAL_CALL PresenterAccessible::AccessibleObject::windowMoved ( - const css::awt::WindowEvent&) -{ - FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any()); -} - -void SAL_CALL PresenterAccessible::AccessibleObject::windowShown ( - const css::lang::EventObject&) -{ - UpdateStateSet(); -} - -void SAL_CALL PresenterAccessible::AccessibleObject::windowHidden ( - const css::lang::EventObject&) -{ - UpdateStateSet(); -} - -//----- XEventListener -------------------------------------------------------- - -void SAL_CALL PresenterAccessible::AccessibleObject::disposing (const css::lang::EventObject& rEvent) -{ - if (rEvent.Source == mxContentWindow) - { - mxContentWindow = nullptr; - mxBorderWindow = nullptr; - } - else - { - SetWindow(nullptr, nullptr); - } -} - -//----- private --------------------------------------------------------------- - -bool PresenterAccessible::AccessibleObject::GetWindowState (const sal_Int16 nType) const -{ - switch (nType) - { - case AccessibleStateType::ENABLED: - return mxContentWindow.is() && mxContentWindow->isEnabled(); - - case AccessibleStateType::FOCUSABLE: - return true; - - case AccessibleStateType::FOCUSED: - return mbIsFocused; - - case AccessibleStateType::SHOWING: - return mxContentWindow.is() && mxContentWindow->isVisible(); - - default: - return false; - } -} - -void PresenterAccessible::AccessibleObject::UpdateStateSet() -{ - UpdateState(AccessibleStateType::FOCUSABLE, true); - UpdateState(AccessibleStateType::VISIBLE, true); - UpdateState(AccessibleStateType::ENABLED, true); - UpdateState(AccessibleStateType::MULTI_LINE, true); - UpdateState(AccessibleStateType::SENSITIVE, true); - - UpdateState(AccessibleStateType::ENABLED, GetWindowState(AccessibleStateType::ENABLED)); - UpdateState(AccessibleStateType::FOCUSED, GetWindowState(AccessibleStateType::FOCUSED)); - UpdateState(AccessibleStateType::SHOWING, GetWindowState(AccessibleStateType::SHOWING)); - // UpdateState(AccessibleStateType::ACTIVE, GetWindowState(AccessibleStateType::ACTIVE)); -} - -void PresenterAccessible::AccessibleObject::UpdateState( - const sal_Int16 nState, - const bool bValue) -{ - const sal_uInt32 nStateMask (AccessibleStateSet::GetStateMask(nState)); - if (((mnStateSet & nStateMask) != 0) == bValue) - return; - if (bValue) - { - mnStateSet |= nStateMask; - FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(), Any(nState)); - } - else - { - mnStateSet &= ~nStateMask; - FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(nState), Any()); - } -} - -void PresenterAccessible::AccessibleObject::AddChild ( - const ::rtl::Reference<AccessibleObject>& rpChild) -{ - maChildren.push_back(rpChild); - rpChild->SetAccessibleParent(this); - FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); -} - -void PresenterAccessible::AccessibleObject::RemoveChild ( - const ::rtl::Reference<AccessibleObject>& rpChild) -{ - rpChild->SetAccessibleParent(Reference<XAccessible>()); - maChildren.erase(::std::find(maChildren.begin(), maChildren.end(), rpChild)); - FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); -} - -void PresenterAccessible::AccessibleObject::SetIsFocused (const bool bIsFocused) -{ - if (mbIsFocused != bIsFocused) - { - mbIsFocused = bIsFocused; - UpdateStateSet(); - } -} - -void PresenterAccessible::AccessibleObject::SetAccessibleName (const OUString& rsName) -{ - if (msName != rsName) - { - const OUString sOldName(msName); - msName = rsName; - FireAccessibleEvent(AccessibleEventId::NAME_CHANGED, Any(sOldName), Any(msName)); - } -} - -void PresenterAccessible::AccessibleObject::FireAccessibleEvent ( - const sal_Int16 nEventId, - const uno::Any& rOldValue, - const uno::Any& rNewValue ) -{ - AccessibleEventObject aEventObject; - - aEventObject.Source = Reference<XWeak>(this); - aEventObject.EventId = nEventId; - aEventObject.NewValue = rNewValue; - aEventObject.OldValue = rOldValue; - - ::std::vector<Reference<XAccessibleEventListener> > aListenerCopy(maListeners); - for (const auto& rxListener : aListenerCopy) - { - try - { - rxListener->notifyEvent(aEventObject); - } - catch (const lang::DisposedException&) - { - // Listener has been disposed and should have been removed - // already. - removeAccessibleEventListener(rxListener); - } - catch (const Exception&) - { - // Ignore all other exceptions and assume that they are - // caused by a temporary problem. - } - } -} - -awt::Point PresenterAccessible::AccessibleObject::GetRelativeLocation() -{ - awt::Point aLocation; - if (mxContentWindow.is()) - { - const awt::Rectangle aContentBox (mxContentWindow->getPosSize()); - aLocation.X = aContentBox.X; - aLocation.Y = aContentBox.Y; - if (mxBorderWindow.is()) - { - const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); - aLocation.X += aBorderBox.X; - aLocation.Y += aBorderBox.Y; - } - } - return aLocation; -} - -awt::Size PresenterAccessible::AccessibleObject::GetSize() -{ - if (mxContentWindow.is()) - { - const awt::Rectangle aBox (mxContentWindow->getPosSize()); - return awt::Size(aBox.Width, aBox.Height); - } - else - return awt::Size(); -} - -awt::Point PresenterAccessible::AccessibleObject::GetAbsoluteParentLocation() -{ - Reference<XAccessibleComponent> xParentComponent; - if (mxParentAccessible.is()) - xParentComponent.set( mxParentAccessible->getAccessibleContext(), UNO_QUERY); - if (xParentComponent.is()) - return xParentComponent->getLocationOnScreen(); - else - return awt::Point(); -} - -void PresenterAccessible::AccessibleObject::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - throw lang::DisposedException("object has already been disposed", uno::Reference<uno::XInterface>(const_cast<uno::XWeak*>(static_cast<uno::XWeak const *>(this)))); -} - -//===== AccessibleStateSet ==================================================== - -AccessibleStateSet::AccessibleStateSet (const sal_Int32 nStateSet) - : AccessibleStateSetInterfaceBase(m_aMutex), - mnStateSet (nStateSet) -{ -} - -sal_uInt32 AccessibleStateSet::GetStateMask (const sal_Int16 nState) -{ - if (nState<0 || nState>=sal_Int16(sizeof(sal_uInt32)*8)) - { - throw RuntimeException("AccessibleStateSet::GetStateMask: invalid state"); - } - - return 1<<nState; -} - -//----- XAccessibleStateSet --------------------------------------------------- - -sal_Bool SAL_CALL AccessibleStateSet::isEmpty() -{ - return mnStateSet==0; -} - -sal_Bool SAL_CALL AccessibleStateSet::contains (sal_Int16 nState) -{ - return (mnStateSet & GetStateMask(nState)) != 0; -} - -sal_Bool SAL_CALL AccessibleStateSet::containsAll (const css::uno::Sequence<sal_Int16>& rStateSet) -{ - return std::none_of(rStateSet.begin(), rStateSet.end(), - [this](const sal_Int16 nState) { return (mnStateSet & GetStateMask(nState)) == 0; }); -} - -css::uno::Sequence<sal_Int16> SAL_CALL AccessibleStateSet::getStates() -{ - ::std::vector<sal_Int16> aStates; - aStates.reserve(sizeof(mnStateSet)*8); - for (sal_uInt16 nIndex=0; nIndex<sizeof(mnStateSet)*8; ++nIndex) - if ((mnStateSet & GetStateMask(nIndex)) != 0) - aStates.push_back(nIndex); - return Sequence<sal_Int16>(aStates.data(), aStates.size()); -} - -//===== AccessibleRelationSet ================================================= - -AccessibleRelationSet::AccessibleRelationSet() - : AccessibleRelationSetInterfaceBase(m_aMutex), - maRelations() -{ -} - -void AccessibleRelationSet::AddRelation ( - const sal_Int16 nRelationType, - const Reference<XInterface>& rxObject) -{ - maRelations.emplace_back(); - maRelations.back().RelationType = nRelationType; - maRelations.back().TargetSet.realloc(1); - maRelations.back().TargetSet[0] = rxObject; -} - -//----- XAccessibleRelationSet ------------------------------------------------ - -sal_Int32 SAL_CALL AccessibleRelationSet::getRelationCount() -{ - return maRelations.size(); -} - -AccessibleRelation SAL_CALL AccessibleRelationSet::getRelation (sal_Int32 nIndex) -{ - if (nIndex<0 && o3tl::make_unsigned(nIndex)>=maRelations.size()) - return AccessibleRelation(); - else - return maRelations[nIndex]; -} - -sal_Bool SAL_CALL AccessibleRelationSet::containsRelation (sal_Int16 nRelationType) -{ - return std::any_of(maRelations.begin(), maRelations.end(), - [nRelationType](const AccessibleRelation& rRelation) { return rRelation.RelationType == nRelationType; }); -} - -AccessibleRelation SAL_CALL AccessibleRelationSet::getRelationByType (sal_Int16 nRelationType) -{ - auto iRelation = std::find_if(maRelations.begin(), maRelations.end(), - [nRelationType](const AccessibleRelation& rRelation) { return rRelation.RelationType == nRelationType; }); - if (iRelation != maRelations.end()) - return *iRelation; - return AccessibleRelation(); -} - -//===== PresenterAccessible::AccessibleParagraph ============================== - -PresenterAccessible::AccessibleParagraph::AccessibleParagraph ( - const lang::Locale& rLocale, - const OUString& rsName, - const SharedPresenterTextParagraph& rpParagraph, - const sal_Int32 nParagraphIndex) - : PresenterAccessibleParagraphInterfaceBase(rLocale, AccessibleRole::PARAGRAPH, rsName), - mpParagraph(rpParagraph), - mnParagraphIndex(nParagraphIndex) -{ -} - -//----- XAccessibleContext ---------------------------------------------------- - -Reference<XAccessibleRelationSet> SAL_CALL - PresenterAccessible::AccessibleParagraph::getAccessibleRelationSet() -{ - ThrowIfDisposed(); - - rtl::Reference<AccessibleRelationSet> pSet (new AccessibleRelationSet); - - if (mxParentAccessible.is()) - { - Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext()); - if (xParentContext.is()) - { - if (mnParagraphIndex>0) - pSet->AddRelation( - AccessibleRelationType::CONTENT_FLOWS_FROM, - xParentContext->getAccessibleChild(mnParagraphIndex-1)); - - if (mnParagraphIndex<xParentContext->getAccessibleChildCount()-1) - pSet->AddRelation( - AccessibleRelationType::CONTENT_FLOWS_TO, - xParentContext->getAccessibleChild(mnParagraphIndex+1)); - } - } - - return pSet; -} - -//----- XAccessibleText ------------------------------------------------------- - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCaretPosition() -{ - ThrowIfDisposed(); - - sal_Int32 nPosition (-1); - if (mpParagraph) - nPosition = mpParagraph->GetCaretPosition(); - - return nPosition; -} - -sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setCaretPosition (sal_Int32 nIndex) -{ - ThrowIfDisposed(); - - if (mpParagraph) - { - mpParagraph->SetCaretPosition(nIndex); - return true; - } - else - return false; -} - -sal_Unicode SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacter (sal_Int32 nIndex) -{ - ThrowIfDisposed(); - - if (!mpParagraph) - throw lang::IndexOutOfBoundsException("no text support in current mode", static_cast<uno::XWeak*>(this)); - return mpParagraph->GetCharacter(nIndex); -} - -Sequence<css::beans::PropertyValue> SAL_CALL - PresenterAccessible::AccessibleParagraph::getCharacterAttributes ( - ::sal_Int32 nIndex, - const css::uno::Sequence<OUString>& rRequestedAttributes) -{ - ThrowIfDisposed(); - -#if OSL_DEBUG_LEVEL > 0 - SAL_INFO( "sdext.presenter", __func__ << " at " << this << ", " << nIndex << " returns empty set" ); - for (sal_Int32 nAttributeIndex(0), nAttributeCount(rRequestedAttributes.getLength()); - nAttributeIndex < nAttributeCount; - ++nAttributeIndex) - { - SAL_INFO( "sdext.presenter", - " requested attribute " << nAttributeIndex << " is " << rRequestedAttributes[nAttributeIndex] ); - } -#else - (void)nIndex; - (void)rRequestedAttributes; -#endif - - // Character properties are not supported. - return Sequence<css::beans::PropertyValue>(); -} - -awt::Rectangle SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterBounds ( - sal_Int32 nIndex) -{ - ThrowIfDisposed(); - - awt::Rectangle aCharacterBox; - if (nIndex < 0) - { - throw lang::IndexOutOfBoundsException("invalid text index", static_cast<uno::XWeak*>(this)); - } - else if (mpParagraph) - { - aCharacterBox = mpParagraph->GetCharacterBounds(nIndex, false); - // Convert coordinates relative to the window origin into absolute - // screen coordinates. - const awt::Point aWindowLocationOnScreen (getLocationOnScreen()); - aCharacterBox.X += aWindowLocationOnScreen.X; - aCharacterBox.Y += aWindowLocationOnScreen.Y; - } - else - { - throw lang::IndexOutOfBoundsException("no text support in current mode", static_cast<uno::XWeak*>(this)); - } - - return aCharacterBox; -} - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterCount() -{ - ThrowIfDisposed(); - - sal_Int32 nCount (0); - if (mpParagraph) - nCount = mpParagraph->GetCharacterCount(); - - return nCount; -} - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getIndexAtPoint ( - const css::awt::Point& ) -{ - ThrowIfDisposed(); - return -1; -} - -OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectedText() -{ - ThrowIfDisposed(); - - return getTextRange(getSelectionStart(), getSelectionEnd()); -} - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionStart() -{ - ThrowIfDisposed(); - - return getCaretPosition(); -} - -sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionEnd() -{ - ThrowIfDisposed(); - - return getCaretPosition(); -} - -sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setSelection ( - sal_Int32 nStartIndex, - sal_Int32) -{ - ThrowIfDisposed(); - - return setCaretPosition(nStartIndex); -} - -OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getText() -{ - ThrowIfDisposed(); - - OUString sText; - if (mpParagraph) - sText = mpParagraph->GetText(); - - return sText; -} - -OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getTextRange ( - sal_Int32 nLocalStartIndex, - sal_Int32 nLocalEndIndex) -{ - ThrowIfDisposed(); - - OUString sText; - if (mpParagraph) - { - const TextSegment aSegment ( - mpParagraph->CreateTextSegment(nLocalStartIndex, nLocalEndIndex)); - sText = aSegment.SegmentText; - } - - return sText; -} - -TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextAtIndex ( - sal_Int32 nLocalCharacterIndex, - sal_Int16 nTextType) -{ - ThrowIfDisposed(); - - TextSegment aSegment; - if (mpParagraph) - aSegment = mpParagraph->GetTextSegment(0, nLocalCharacterIndex, nTextType); - - return aSegment; -} - -TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBeforeIndex ( - sal_Int32 nLocalCharacterIndex, - sal_Int16 nTextType) -{ - ThrowIfDisposed(); - - TextSegment aSegment; - if (mpParagraph) - aSegment = mpParagraph->GetTextSegment(-1, nLocalCharacterIndex, nTextType); - - return aSegment; -} - -TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBehindIndex ( - sal_Int32 nLocalCharacterIndex, - sal_Int16 nTextType) -{ - ThrowIfDisposed(); - - TextSegment aSegment; - if (mpParagraph) - aSegment = mpParagraph->GetTextSegment(+1, nLocalCharacterIndex, nTextType); - - return aSegment; -} - -sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::copyText ( - sal_Int32, - sal_Int32) -{ - ThrowIfDisposed(); - - // Return false because copying to clipboard is not supported. - // It IS supported in the notes view. There is no need to duplicate - // this here. - return false; -} - -sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::scrollSubstringTo( - sal_Int32, - sal_Int32, - AccessibleScrollType) -{ - return false; -} - -//----- protected ------------------------------------------------------------- - -awt::Point PresenterAccessible::AccessibleParagraph::GetRelativeLocation() -{ - awt::Point aLocation (AccessibleObject::GetRelativeLocation()); - if (mpParagraph) - { - const awt::Point aParagraphLocation (mpParagraph->GetRelativeLocation()); - aLocation.X += aParagraphLocation.X; - aLocation.Y += aParagraphLocation.Y; - } - - return aLocation; -} - -awt::Size PresenterAccessible::AccessibleParagraph::GetSize() -{ - if (mpParagraph) - return mpParagraph->GetSize(); - else - return AccessibleObject::GetSize(); -} - -awt::Point PresenterAccessible::AccessibleParagraph::GetAbsoluteParentLocation() -{ - if (mxParentAccessible.is()) - { - Reference<XAccessibleContext> xParentContext = - mxParentAccessible->getAccessibleContext(); - if (xParentContext.is()) - { - Reference<XAccessibleComponent> xGrandParentComponent( - xParentContext->getAccessibleParent(), UNO_QUERY); - if (xGrandParentComponent.is()) - return xGrandParentComponent->getLocationOnScreen(); - } - } - - return awt::Point(); -} - -bool PresenterAccessible::AccessibleParagraph::GetWindowState (const sal_Int16 nType) const -{ - switch (nType) - { - case AccessibleStateType::EDITABLE: - return bool(mpParagraph); - - case AccessibleStateType::ACTIVE: - return true; - - default: - return AccessibleObject::GetWindowState(nType); - } -} - -//===== AccessibleNotes ======================================================= - -AccessibleNotes::AccessibleNotes ( - const css::lang::Locale& rLocale, - const OUString& rsName) - : AccessibleObject(rLocale,AccessibleRole::PANEL,rsName), - mpTextView() -{ -} - -rtl::Reference<PresenterAccessible::AccessibleObject> AccessibleNotes::Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const lang::Locale& rLocale, - const Reference<awt::XWindow>& rxContentWindow, - const Reference<awt::XWindow>& rxBorderWindow, - const std::shared_ptr<PresenterTextView>& rpTextView) -{ - OUString sName ("Presenter Notes Text"); - { - PresenterConfigurationAccess aConfiguration ( - rxContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - aConfiguration.GetConfigurationNode("Presenter/Accessibility/Notes/String") - >>= sName; - } - - rtl::Reference<AccessibleNotes> pObject ( - new AccessibleNotes( - rLocale, - sName)); - pObject->LateInitialization(); - pObject->SetTextView(rpTextView); - pObject->UpdateStateSet(); - pObject->SetWindow(rxContentWindow, rxBorderWindow); - - return pObject; -} - -void AccessibleNotes::SetTextView ( - const std::shared_ptr<PresenterTextView>& rpTextView) -{ - ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > aChildren; - - // Release any listeners to the current text view. - if (mpTextView) - { - mpTextView->GetCaret()->SetCaretMotionBroadcaster( - ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)>()); - mpTextView->SetTextChangeBroadcaster( - ::std::function<void ()>()); - } - - mpTextView = rpTextView; - - if (!mpTextView) - return; - - // Create a new set of children, one for each paragraph. - const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount()); - for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex) - { - rtl::Reference<PresenterAccessible::AccessibleParagraph> pParagraph ( - new PresenterAccessible::AccessibleParagraph( - css::lang::Locale(), - "Paragraph"+OUString::number(nIndex), - rpTextView->GetParagraph(nIndex), - nIndex)); - pParagraph->LateInitialization(); - pParagraph->SetWindow(mxContentWindow, mxBorderWindow); - pParagraph->SetAccessibleParent(this); - aChildren.emplace_back(pParagraph.get()); - } - maChildren.swap(aChildren); - FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); - - // Dispose the old children. (This will remove them from the focus - // manager). - for (const auto& rxChild : aChildren) - { - Reference<lang::XComponent> xComponent (static_cast<XWeak*>(rxChild.get()), UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - } - - // This class acts as a controller of who broadcasts caret motion - // events and handles text changes. Register the corresponding - // listeners here. - mpTextView->GetCaret()->SetCaretMotionBroadcaster( - [this](sal_Int32 a, sal_Int32 b, sal_Int32 c, sal_Int32 d) - { return this->NotifyCaretChange(a, b, c, d); }); - mpTextView->SetTextChangeBroadcaster( - [this]() { return SetTextView(mpTextView); }); -} - -void AccessibleNotes::SetWindow ( - const css::uno::Reference<css::awt::XWindow>& rxContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow) -{ - AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow); - - // Set the windows at the children as well, so that every paragraph can - // setup its geometry. - for (auto& rxChild : maChildren) - { - rxChild->SetWindow(rxContentWindow, rxBorderWindow); - } -} - -void AccessibleNotes::NotifyCaretChange ( - const sal_Int32 nOldParagraphIndex, - const sal_Int32 nOldCharacterIndex, - const sal_Int32 nNewParagraphIndex, - const sal_Int32 nNewCharacterIndex) -{ - AccessibleFocusManager::Instance()->FocusObject( - nNewParagraphIndex >= 0 - ? maChildren[nNewParagraphIndex] - : this); - - if (nOldParagraphIndex != nNewParagraphIndex) - { - // Moved caret from one paragraph to another (or showed or - // hid the caret). Move focus from one accessible - // paragraph to another. - if (nOldParagraphIndex >= 0) - { - maChildren[nOldParagraphIndex]->FireAccessibleEvent( - AccessibleEventId::CARET_CHANGED, - Any(nOldCharacterIndex), - Any(sal_Int32(-1))); - } - if (nNewParagraphIndex >= 0) - { - maChildren[nNewParagraphIndex]->FireAccessibleEvent( - AccessibleEventId::CARET_CHANGED, - Any(sal_Int32(-1)), - Any(nNewCharacterIndex)); - } - } - else if (nNewParagraphIndex >= 0) - { - // Caret moved inside one paragraph. - maChildren[nNewParagraphIndex]->FireAccessibleEvent( - AccessibleEventId::CARET_CHANGED, - Any(nOldCharacterIndex), - Any(nNewCharacterIndex)); - } -} - - -//===== AccessibleFocusManager ================================================ - -std::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::mpInstance; - -std::shared_ptr<AccessibleFocusManager> const & AccessibleFocusManager::Instance() -{ - if ( ! mpInstance) - { - mpInstance.reset(new AccessibleFocusManager()); - } - return mpInstance; -} - -AccessibleFocusManager::AccessibleFocusManager() -{ -} - -AccessibleFocusManager::~AccessibleFocusManager() -{ - // copy member to stack, then drop it - otherwise will get use-after-free - // from AccessibleObject::disposing(), it will call ~Reference *twice* - auto const temp(std::move(maFocusableObjects)); - (void) temp; - m_isInDtor = true; -} - -void AccessibleFocusManager::AddFocusableObject ( - const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject) -{ - OSL_ASSERT(rpObject.is()); - OSL_ASSERT(::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)==maFocusableObjects.end()); - - maFocusableObjects.push_back(rpObject); -} - -void AccessibleFocusManager::RemoveFocusableObject ( - const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject) -{ - ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::iterator iObject ( - ::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)); - - if (iObject != maFocusableObjects.end()) - maFocusableObjects.erase(iObject); - else - { - OSL_ASSERT(m_isInDtor); // in dtor, was removed already - } -} - -void AccessibleFocusManager::FocusObject ( - const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject) -{ - // Remove the focus of any of the other focusable objects. - for (auto& rxObject : maFocusableObjects) - { - if (rxObject!=rpObject) - rxObject->SetIsFocused(false); - } - - if (rpObject.is()) - rpObject->SetIsFocused(true); -} - -} // end of namespace ::sd::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterAccessibility.hxx b/sdext/source/presenter/PresenterAccessibility.hxx deleted file mode 100644 index 9789db5256ca..000000000000 --- a/sdext/source/presenter/PresenterAccessibility.hxx +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERACCESSIBILITY_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERACCESSIBILITY_HXX - -#include "PresenterPaneContainer.hxx" - -#include <com/sun/star/accessibility/XAccessible.hpp> -#include <com/sun/star/awt/XFocusListener.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/drawing/framework/XPane2.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <rtl/ref.hxx> -#include <memory> - - -namespace sdext::presenter { - -class PresenterController; -class PresenterTextView; - -typedef ::cppu::WeakComponentImplHelper < - css::accessibility::XAccessible, - css::lang::XInitialization, - css::awt::XFocusListener -> PresenterAccessibleInterfaceBase; - -class PresenterAccessible - : public ::cppu::BaseMutex, - public PresenterAccessibleInterfaceBase -{ -public: - PresenterAccessible ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const css::uno::Reference<css::drawing::framework::XPane>& rxMainPane); - virtual ~PresenterAccessible() override; - - void UpdateAccessibilityHierarchy(); - - void NotifyCurrentSlideChange (); - - virtual void SAL_CALL disposing() override; - - //----- XAccessible ------------------------------------------------------- - - virtual css::uno::Reference<css::accessibility::XAccessibleContext> SAL_CALL - getAccessibleContext() override; - - //----- XFocusListener ---------------------------------------------------- - - virtual void SAL_CALL focusGained (const css::awt::FocusEvent& rEvent) override; - - virtual void SAL_CALL focusLost (const css::awt::FocusEvent& rEvent) override; - - //----- XEventListener ---------------------------------------------------- - - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - - //----- XInitialization --------------------------------------------------- - - virtual void SAL_CALL initialize (const css::uno::Sequence<css::uno::Any>& rArguments) override; - - class AccessibleObject; - class AccessibleParagraph; - -private: - const css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::drawing::framework::XPane2> mxMainPane; - css::uno::Reference<css::awt::XWindow> mxMainWindow; - css::uno::Reference<css::awt::XWindow> mxPreviewContentWindow; - css::uno::Reference<css::awt::XWindow> mxPreviewBorderWindow; - css::uno::Reference<css::awt::XWindow> mxNotesContentWindow; - css::uno::Reference<css::awt::XWindow> mxNotesBorderWindow; - ::rtl::Reference<AccessibleObject> mpAccessibleConsole; - ::rtl::Reference<AccessibleObject> mpAccessiblePreview; - ::rtl::Reference<AccessibleObject> mpAccessibleNotes; - css::uno::Reference<css::accessibility::XAccessible> mxAccessibleParent; - - void UpdateAccessibilityHierarchy ( - const css::uno::Reference<css::awt::XWindow>& rxPreviewContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxPreviewBorderWindow, - const OUString& rsTitle, - const css::uno::Reference<css::awt::XWindow>& rxNotesContentWindow, - const css::uno::Reference<css::awt::XWindow>& rxNotesBorderWindow, - const std::shared_ptr<PresenterTextView>& rpNotesTextView); - PresenterPaneContainer::SharedPaneDescriptor GetPreviewPane() const; -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterBitmapContainer.cxx b/sdext/source/presenter/PresenterBitmapContainer.cxx deleted file mode 100644 index e094bae22ac0..000000000000 --- a/sdext/source/presenter/PresenterBitmapContainer.cxx +++ /dev/null @@ -1,411 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterBitmapContainer.hxx" -#include "PresenterConfigurationAccess.hxx" - -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/lang/XMultiComponentFactory.hpp> -#include <osl/diagnose.h> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::std; - -namespace sdext::presenter { - -//===== PresenterBitmapContainer ============================================== - -PresenterBitmapContainer::PresenterBitmapContainer ( - const OUString& rsConfigurationBase, - const std::shared_ptr<PresenterBitmapContainer>& rpParentContainer, - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper) - : mpParentContainer(rpParentContainer), - maIconContainer(), - mxCanvas(rxCanvas), - mxPresenterHelper(rxPresenterHelper) -{ - Initialize(rxComponentContext); - - // Get access to the configuration. - PresenterConfigurationAccess aConfiguration ( - rxComponentContext, - "org.openoffice.Office.PresenterScreen", - PresenterConfigurationAccess::READ_ONLY); - Reference<container::XNameAccess> xBitmapList ( - aConfiguration.GetConfigurationNode(rsConfigurationBase), - UNO_QUERY_THROW); - - LoadBitmaps(xBitmapList); -} - -PresenterBitmapContainer::PresenterBitmapContainer ( - const css::uno::Reference<css::container::XNameAccess>& rxRootNode, - const std::shared_ptr<PresenterBitmapContainer>& rpParentContainer, - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper) - : mpParentContainer(rpParentContainer), - maIconContainer(), - mxCanvas(rxCanvas), - mxPresenterHelper(rxPresenterHelper) -{ - Initialize(rxComponentContext); - - LoadBitmaps(rxRootNode); -} - -void PresenterBitmapContainer::Initialize ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext) -{ - if ( mxPresenterHelper.is()) - return; - - // Create an object that is able to load the bitmaps in a format that is - // supported by the canvas. - Reference<lang::XMultiComponentFactory> xFactory = - rxComponentContext->getServiceManager(); - if ( ! xFactory.is()) - return; - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.drawing.PresenterHelper", - rxComponentContext), - UNO_QUERY_THROW); -} - -PresenterBitmapContainer::~PresenterBitmapContainer() -{ - maIconContainer.clear(); -} - -std::shared_ptr<PresenterBitmapContainer::BitmapDescriptor> PresenterBitmapContainer::GetBitmap ( - const OUString& rsName) const -{ - BitmapContainer::const_iterator iSet (maIconContainer.find(rsName)); - if (iSet != maIconContainer.end()) - return iSet->second; - else if (mpParentContainer != nullptr) - return mpParentContainer->GetBitmap(rsName); - else - return SharedBitmapDescriptor(); -} - -void PresenterBitmapContainer::LoadBitmaps ( - const css::uno::Reference<css::container::XNameAccess>& rxBitmapList) -{ - if ( ! mxCanvas.is()) - return; - - if ( ! rxBitmapList.is()) - return; - - try - { - // Load all button bitmaps. - if (rxBitmapList.is()) - { - PresenterConfigurationAccess::ForAll( - rxBitmapList, - [this](OUString const& rKey, Reference<beans::XPropertySet> const& xProps) - { - this->ProcessBitmap(rKey, xProps); - }); - } - } - catch (Exception&) - { - OSL_ASSERT(false); - } -} - -std::shared_ptr<PresenterBitmapContainer::BitmapDescriptor> PresenterBitmapContainer::LoadBitmap ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const OUString& rsPath, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const std::shared_ptr<BitmapDescriptor>& rpDefault) -{ - SharedBitmapDescriptor pBitmap; - - if (rxNode.is()) - { - try - { - Reference<beans::XPropertySet> xBitmapProperties ( - PresenterConfigurationAccess::GetConfigurationNode(rxNode, rsPath), - UNO_QUERY); - if (xBitmapProperties.is()) - pBitmap = LoadBitmap( - xBitmapProperties, - rxPresenterHelper, - rxCanvas, - rpDefault); - } - catch (Exception&) - { - OSL_ASSERT(false); - } - } - - return pBitmap; -} - -void PresenterBitmapContainer::ProcessBitmap ( - const OUString& rsKey, - const Reference<beans::XPropertySet>& rxProperties) -{ - OUString sName; - if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, "Name") >>= sName)) - sName = rsKey; - - maIconContainer[sName] = LoadBitmap( - rxProperties, - mxPresenterHelper, - mxCanvas, - SharedBitmapDescriptor()); -} - -std::shared_ptr<PresenterBitmapContainer::BitmapDescriptor> PresenterBitmapContainer::LoadBitmap ( - const Reference<beans::XPropertySet>& rxProperties, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const std::shared_ptr<BitmapDescriptor>& rpDefault) -{ - OSL_ASSERT(rxCanvas.is()); - OSL_ASSERT(rxPresenterHelper.is()); - - SharedBitmapDescriptor pBitmap = std::make_shared<BitmapDescriptor>(rpDefault); - - if ( ! rxProperties.is()) - return pBitmap; - - OUString sFileName; - - // Load bitmaps. - if (PresenterConfigurationAccess::GetProperty(rxProperties, "NormalFileName") >>= sFileName) - try - { - pBitmap->SetBitmap( - BitmapDescriptor::Normal, - rxPresenterHelper->loadBitmap(sFileName, rxCanvas)); - } - catch (Exception&) - {} - if (PresenterConfigurationAccess::GetProperty(rxProperties, "MouseOverFileName") >>= sFileName) - try - { - pBitmap->SetBitmap( - BitmapDescriptor::MouseOver, - rxPresenterHelper->loadBitmap(sFileName, rxCanvas)); - } - catch (Exception&) - {} - if (PresenterConfigurationAccess::GetProperty(rxProperties, "ButtonDownFileName") >>= sFileName) - try - { - pBitmap->SetBitmap( - BitmapDescriptor::ButtonDown, - rxPresenterHelper->loadBitmap(sFileName, rxCanvas)); - } - catch (Exception&) - {} - if (PresenterConfigurationAccess::GetProperty(rxProperties, "DisabledFileName") >>= sFileName) - try - { - pBitmap->SetBitmap( - BitmapDescriptor::Disabled, - rxPresenterHelper->loadBitmap(sFileName, rxCanvas)); - } - catch (Exception&) - {} - if (PresenterConfigurationAccess::GetProperty(rxProperties, "MaskFileName") >>= sFileName) - try - { - pBitmap->SetBitmap( - BitmapDescriptor::Mask, - rxPresenterHelper->loadBitmap(sFileName, rxCanvas)); - } - catch (Exception&) - {} - - PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pBitmap->mnXOffset; - PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pBitmap->mnYOffset; - - PresenterConfigurationAccess::GetProperty(rxProperties, "XHotSpot") >>= pBitmap->mnXHotSpot; - PresenterConfigurationAccess::GetProperty(rxProperties, "YHotSpot") >>= pBitmap->mnYHotSpot; - - PresenterConfigurationAccess::GetProperty(rxProperties, "ReplacementColor") >>= pBitmap->maReplacementColor; - - OUString sTexturingMode; - if (PresenterConfigurationAccess::GetProperty(rxProperties, "HorizontalTexturingMode") >>= sTexturingMode) - pBitmap->meHorizontalTexturingMode = StringToTexturingMode(sTexturingMode); - if (PresenterConfigurationAccess::GetProperty(rxProperties, "VerticalTexturingMode") >>= sTexturingMode) - pBitmap->meVerticalTexturingMode = StringToTexturingMode(sTexturingMode); - - return pBitmap; -} - -PresenterBitmapContainer::BitmapDescriptor::TexturingMode - PresenterBitmapContainer::StringToTexturingMode (std::u16string_view rsTexturingMode) -{ - if (rsTexturingMode == u"Once") - return PresenterBitmapContainer::BitmapDescriptor::Once; - else if (rsTexturingMode == u"Repeat") - return PresenterBitmapContainer::BitmapDescriptor::Repeat; - else if (rsTexturingMode == u"Stretch") - return PresenterBitmapContainer::BitmapDescriptor::Stretch; - else - return PresenterBitmapContainer::BitmapDescriptor::Once; -} - -//===== PresenterBitmapContainer::BitmapSet =================================== - -PresenterBitmapContainer::BitmapDescriptor::BitmapDescriptor() - : mnWidth(0), - mnHeight(0), - mnXOffset(0), - mnYOffset(0), - mnXHotSpot(0), - mnYHotSpot(0), - maReplacementColor(0x00000000), - meHorizontalTexturingMode(Once), - meVerticalTexturingMode(Once), - mxNormalBitmap(), - mxMouseOverBitmap(), - mxButtonDownBitmap(), - mxDisabledBitmap(), - mxMaskBitmap() -{ -} - -PresenterBitmapContainer::BitmapDescriptor::BitmapDescriptor ( - const std::shared_ptr<PresenterBitmapContainer::BitmapDescriptor>& rpDefault) - : mnWidth(0), - mnHeight(0), - mnXOffset(0), - mnYOffset(0), - mnXHotSpot(0), - mnYHotSpot(0), - maReplacementColor(0x00000000), - meHorizontalTexturingMode(Once), - meVerticalTexturingMode(Once), - mxNormalBitmap(), - mxMouseOverBitmap(), - mxButtonDownBitmap(), - mxDisabledBitmap(), - mxMaskBitmap() -{ - if (rpDefault == nullptr) - return; - - mnWidth = rpDefault->mnWidth; - mnHeight = rpDefault->mnHeight; - mnXOffset = rpDefault->mnXOffset; - mnYOffset = rpDefault->mnYOffset; - mnXHotSpot = rpDefault->mnXHotSpot; - mnYHotSpot = rpDefault->mnYHotSpot; - maReplacementColor = rpDefault->maReplacementColor; - meHorizontalTexturingMode = rpDefault->meHorizontalTexturingMode; - meVerticalTexturingMode = rpDefault->meVerticalTexturingMode; - mxNormalBitmap = rpDefault->mxNormalBitmap; - mxMouseOverBitmap = rpDefault->mxMouseOverBitmap; - mxButtonDownBitmap = rpDefault->mxButtonDownBitmap; - mxDisabledBitmap = rpDefault->mxDisabledBitmap; - mxMaskBitmap = rpDefault->mxMaskBitmap; -} - -const css::uno::Reference<css::rendering::XBitmap>& - PresenterBitmapContainer::BitmapDescriptor::GetNormalBitmap() const -{ - return mxNormalBitmap; -} - -css::uno::Reference<css::rendering::XBitmap> const & - PresenterBitmapContainer::BitmapDescriptor::GetBitmap(const Mode eMode) const -{ - switch (eMode) - { - case Normal: - default: - return mxNormalBitmap; - - case MouseOver: - if (mxMouseOverBitmap.is()) - return mxMouseOverBitmap; - else - return mxNormalBitmap; - - case ButtonDown: - if (mxButtonDownBitmap.is()) - return mxButtonDownBitmap; - else - return mxNormalBitmap; - - case Disabled: - if (mxDisabledBitmap.is()) - return mxDisabledBitmap; - else - return mxNormalBitmap; - - case Mask: - return mxMaskBitmap; - } -} - -void PresenterBitmapContainer::BitmapDescriptor::SetBitmap ( - const Mode eMode, - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap) -{ - switch (eMode) - { - case Normal: - default: - mxNormalBitmap = rxBitmap; - if (mxNormalBitmap.is()) - { - const geometry::IntegerSize2D aSize (mxNormalBitmap->getSize()); - mnWidth = aSize.Width; - mnHeight = aSize.Height; - } - break; - - case MouseOver: - mxMouseOverBitmap = rxBitmap; - break; - - case ButtonDown: - mxButtonDownBitmap = rxBitmap; - break; - - case Disabled: - mxDisabledBitmap = rxBitmap; - break; - - case Mask: - mxMaskBitmap = rxBitmap; - break; - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterBitmapContainer.hxx b/sdext/source/presenter/PresenterBitmapContainer.hxx deleted file mode 100644 index 65f385b2b4e6..000000000000 --- a/sdext/source/presenter/PresenterBitmapContainer.hxx +++ /dev/null @@ -1,146 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERBITMAPCONTAINER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERBITMAPCONTAINER_HXX - -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/container/XHierarchicalNameAccess.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/rendering/XBitmap.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/util/Color.hpp> -#include <map> -#include <memory> - -namespace sdext::presenter { - -/** Manage a set of bitmap groups as they are used for buttons: three - bitmaps, one for the normal state, one for a mouse over effect and one - to show that the button has been pressed. - A bitmap group is defined by some entries in the configuration. -*/ -class PresenterBitmapContainer -{ -public: - /** There is one bitmap for the normal state, one for a mouse over effect and one - to show that a button has been pressed. - */ - class BitmapDescriptor - { - public: - BitmapDescriptor(); - explicit BitmapDescriptor (const std::shared_ptr<BitmapDescriptor>& rpDefault); - - enum Mode {Normal, MouseOver, ButtonDown, Disabled, Mask}; - const css::uno::Reference<css::rendering::XBitmap>& GetNormalBitmap() const; - css::uno::Reference<css::rendering::XBitmap> const & GetBitmap(const Mode eMode) const; - void SetBitmap ( - const Mode eMode, - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap); - - sal_Int32 mnWidth; - sal_Int32 mnHeight; - sal_Int32 mnXOffset; - sal_Int32 mnYOffset; - sal_Int32 mnXHotSpot; - sal_Int32 mnYHotSpot; - css::util::Color maReplacementColor; - enum TexturingMode { Once, Repeat, Stretch }; - TexturingMode meHorizontalTexturingMode; - TexturingMode meVerticalTexturingMode; - - private: - css::uno::Reference<css::rendering::XBitmap> mxNormalBitmap; - css::uno::Reference<css::rendering::XBitmap> mxMouseOverBitmap; - css::uno::Reference<css::rendering::XBitmap> mxButtonDownBitmap; - css::uno::Reference<css::rendering::XBitmap> mxDisabledBitmap; - css::uno::Reference<css::rendering::XBitmap> mxMaskBitmap; - }; - - /** Create a new bitmap container from a section of the configuration. - @param rxComponentContext - The component context is used to create new API objects. - @param rxCanvas - Bitmaps are created specifically for this canvas. - @param rsConfigurationBase - The name of a configuration node whose sub-tree defines the - bitmap sets. - */ - PresenterBitmapContainer ( - const OUString& rsConfigurationBase, - const std::shared_ptr<PresenterBitmapContainer>& rpParentContainer, - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper = nullptr); - PresenterBitmapContainer ( - const css::uno::Reference<css::container::XNameAccess>& rsRootNode, - const std::shared_ptr<PresenterBitmapContainer>& rpParentContainer, - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper = nullptr); - ~PresenterBitmapContainer(); - PresenterBitmapContainer(const PresenterBitmapContainer&) = delete; - PresenterBitmapContainer& operator=(const PresenterBitmapContainer&) = delete; - - void Initialize ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext); - - /** Return the bitmap set that is associated with the given name. - */ - std::shared_ptr<BitmapDescriptor> GetBitmap (const OUString& rsName) const; - - static std::shared_ptr<BitmapDescriptor> LoadBitmap ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const OUString& rsPathToBitmapNode, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const std::shared_ptr<BitmapDescriptor>& rpDefaultBitmap); - -private: - std::shared_ptr<PresenterBitmapContainer> mpParentContainer; - typedef ::std::map<OUString, std::shared_ptr<BitmapDescriptor> > BitmapContainer; - BitmapContainer maIconContainer; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - - void LoadBitmaps ( - const css::uno::Reference<css::container::XNameAccess>& rsRootNode); - void ProcessBitmap ( - const OUString& rsKey, - const css::uno::Reference<css::beans::XPropertySet>& rProperties); - static std::shared_ptr<BitmapDescriptor> LoadBitmap ( - const css::uno::Reference<css::beans::XPropertySet>& rxProperties, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const std::shared_ptr<PresenterBitmapContainer::BitmapDescriptor>& rpDefault); - static BitmapDescriptor::TexturingMode - StringToTexturingMode (std::u16string_view rsTexturingMode); -}; - -typedef PresenterBitmapContainer::BitmapDescriptor PresenterBitmapDescriptor; -typedef std::shared_ptr<PresenterBitmapContainer::BitmapDescriptor> SharedBitmapDescriptor; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterButton.cxx b/sdext/source/presenter/PresenterButton.cxx deleted file mode 100644 index 329ff8399064..000000000000 --- a/sdext/source/presenter/PresenterButton.cxx +++ /dev/null @@ -1,453 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterButton.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterController.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterUIPainter.hxx" -#include <com/sun/star/awt/PosSize.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -const double gnHorizontalBorder (15); -const double gnVerticalBorder (5); - -::rtl::Reference<PresenterButton> PresenterButton::Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const std::shared_ptr<PresenterTheme>& rpTheme, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas, - const OUString& rsConfigurationName) -{ - Reference<beans::XPropertySet> xProperties (GetConfigurationProperties( - rxComponentContext, - rsConfigurationName)); - if (xProperties.is()) - { - OUString sText; - OUString sAction; - PresenterConfigurationAccess::GetProperty(xProperties, "Text") >>= sText; - PresenterConfigurationAccess::GetProperty(xProperties, "Action") >>= sAction; - - PresenterTheme::SharedFontDescriptor pFont; - if (rpTheme != nullptr) - pFont = rpTheme->GetFont("ButtonFont"); - - PresenterTheme::SharedFontDescriptor pMouseOverFont; - if (rpTheme != nullptr) - pMouseOverFont = rpTheme->GetFont("ButtonMouseOverFont"); - - rtl::Reference<PresenterButton> pButton ( - new PresenterButton( - rxComponentContext, - rpPresenterController, - rpTheme, - rxParentWindow, - pFont, - pMouseOverFont, - sText, - sAction)); - pButton->SetCanvas(rxParentCanvas, rxParentWindow); - return pButton; - } - else - return nullptr; -} - -PresenterButton::PresenterButton ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const std::shared_ptr<PresenterTheme>& rpTheme, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const PresenterTheme::SharedFontDescriptor& rpFont, - const PresenterTheme::SharedFontDescriptor& rpMouseOverFont, - const OUString& rsText, - const OUString& rsAction) - : PresenterButtonInterfaceBase(m_aMutex), - mpPresenterController(rpPresenterController), - mpTheme(rpTheme), - mxWindow(), - mxCanvas(), - mxPresenterHelper(), - msText(rsText), - mpFont(rpFont), - mpMouseOverFont(rpMouseOverFont), - msAction(rsAction), - maCenter(), - maButtonSize(-1,-1), - meState(PresenterBitmapDescriptor::Normal), - mxNormalBitmap(), - mxMouseOverBitmap() -{ - try - { - Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager()); - if ( ! xFactory.is()) - throw RuntimeException(); - - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - rxComponentContext), - UNO_QUERY_THROW); - - if (mxPresenterHelper.is()) - mxWindow = mxPresenterHelper->createWindow(rxParentWindow, - false, - false, - false, - false); - - // Make the background transparent. - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW); - xPeer->setBackground(0xff000000); - - mxWindow->setVisible(true); - mxWindow->addPaintListener(this); - mxWindow->addMouseListener(this); - } - catch (RuntimeException&) - { - } -} - -PresenterButton::~PresenterButton() -{ -} - -void SAL_CALL PresenterButton::disposing() -{ - if (mxCanvas.is()) - { - Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY); - mxCanvas = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - if (mxWindow.is()) - { - mxWindow->removePaintListener(this); - mxWindow->removeMouseListener(this); - Reference<lang::XComponent> xComponent = mxWindow; - mxWindow = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } -} - -void PresenterButton::SetCenter (const css::geometry::RealPoint2D& rLocation) -{ - if (mxCanvas.is()) - { - Invalidate(); - - maCenter = rLocation; - mxWindow->setPosSize( - sal_Int32(0.5 + maCenter.X - maButtonSize.Width/2), - sal_Int32(0.5 + maCenter.Y - maButtonSize.Height/2), - maButtonSize.Width, - maButtonSize.Height, - awt::PosSize::POSSIZE); - - Invalidate(); - } - else - { - // The button can not be painted but we can at least store the new center. - maCenter = rLocation; - } -} - -void PresenterButton::SetCanvas ( - const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow) -{ - if (mxCanvas.is()) - { - Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY); - mxCanvas = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - if (!(mxPresenterHelper.is() && rxParentCanvas.is() && rxParentWindow.is())) - return; - - mxCanvas = mxPresenterHelper->createSharedCanvas ( - Reference<rendering::XSpriteCanvas>(rxParentCanvas, UNO_QUERY), - rxParentWindow, - rxParentCanvas, - rxParentWindow, - mxWindow); - if (mxCanvas.is()) - { - SetupButtonBitmaps(); - SetCenter(maCenter); - } -} - -css::geometry::IntegerSize2D const & PresenterButton::GetSize() -{ - if (maButtonSize.Width < 0) - CalculateButtonSize(); - return maButtonSize; -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterButton::windowPaint (const css::awt::PaintEvent& rEvent) -{ - ThrowIfDisposed(); - if (!(mxWindow.is() && mxCanvas.is())) - return; - - Reference<rendering::XBitmap> xBitmap; - if (meState == PresenterBitmapDescriptor::MouseOver) - xBitmap = mxMouseOverBitmap; - else - xBitmap = mxNormalBitmap; - if ( ! xBitmap.is()) - return; - - rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()), - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - mxCanvas->drawBitmap(xBitmap, aViewState, aRenderState); - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -//----- XMouseListener -------------------------------------------------------- - -void SAL_CALL PresenterButton::mousePressed (const css::awt::MouseEvent&) -{ - ThrowIfDisposed(); - meState = PresenterBitmapDescriptor::ButtonDown; -} - -void SAL_CALL PresenterButton::mouseReleased (const css::awt::MouseEvent&) -{ - ThrowIfDisposed(); - - if (meState == PresenterBitmapDescriptor::ButtonDown) - { - OSL_ASSERT(mpPresenterController); - mpPresenterController->DispatchUnoCommand(msAction); - - meState = PresenterBitmapDescriptor::Normal; - Invalidate(); - } -} - -void SAL_CALL PresenterButton::mouseEntered (const css::awt::MouseEvent&) -{ - ThrowIfDisposed(); - meState = PresenterBitmapDescriptor::MouseOver; - Invalidate(); -} - -void SAL_CALL PresenterButton::mouseExited (const css::awt::MouseEvent&) -{ - ThrowIfDisposed(); - meState = PresenterBitmapDescriptor::Normal; - Invalidate(); -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterButton::disposing (const css::lang::EventObject& rEvent) -{ - if (rEvent.Source == mxWindow) - mxWindow = nullptr; -} - - -css::geometry::IntegerSize2D PresenterButton::CalculateButtonSize() -{ - if (mpFont && !mpFont->mxFont.is() && mxCanvas.is()) - mpFont->PrepareFont(mxCanvas); - if (!mpFont || !mpFont->mxFont.is()) - return geometry::IntegerSize2D(-1,-1); - - geometry::RealSize2D aTextSize (PresenterCanvasHelper::GetTextSize(mpFont->mxFont,msText)); - - return geometry::IntegerSize2D ( - sal_Int32(0.5 + aTextSize.Width + 2*gnHorizontalBorder), - sal_Int32(0.5 + aTextSize.Height + 2*gnVerticalBorder)); -} - -void PresenterButton::RenderButton ( - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::IntegerSize2D& rSize, - const PresenterTheme::SharedFontDescriptor& rpFont, - const PresenterBitmapDescriptor::Mode eMode, - const SharedBitmapDescriptor& rpLeft, - const SharedBitmapDescriptor& rpCenter, - const SharedBitmapDescriptor& rpRight) -{ - if ( ! rxCanvas.is()) - return; - - const awt::Rectangle aBox(0,0, rSize.Width, rSize.Height); - - PresenterUIPainter::PaintHorizontalBitmapComposite ( - rxCanvas, - aBox, - aBox, - GetBitmap(rpLeft, eMode), - GetBitmap(rpCenter, eMode), - GetBitmap(rpRight, eMode)); - - if (!rpFont || ! rpFont->mxFont.is()) - return; - - const rendering::StringContext aContext (msText, 0, msText.getLength()); - const Reference<rendering::XTextLayout> xLayout ( - rpFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0)); - const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds()); - - rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0), nullptr, - Sequence<double>(4), rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, rpFont->mnColor); - - aRenderState.AffineTransform.m02 = (rSize.Width - aTextBBox.X2 + aTextBBox.X1)/2; - aRenderState.AffineTransform.m12 = (rSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y1; - - /// this is responsible of the close button - rxCanvas->drawTextLayout( - xLayout, - rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), nullptr), - aRenderState); -} - -void PresenterButton::Invalidate() -{ - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); -} - -Reference<rendering::XBitmap> PresenterButton::GetBitmap ( - const SharedBitmapDescriptor& mpIcon, - const PresenterBitmapDescriptor::Mode eMode) -{ - if (mpIcon) - return mpIcon->GetBitmap(eMode); - else - { - OSL_ASSERT(mpIcon); - return nullptr; - } -} - -void PresenterButton::SetupButtonBitmaps() -{ - if ( ! mxCanvas.is()) - return; - if ( ! mxCanvas->getDevice().is()) - return; - - // Get the bitmaps for the button border. - SharedBitmapDescriptor pLeftBitmap (mpTheme->GetBitmap("ButtonFrameLeft")); - SharedBitmapDescriptor pCenterBitmap(mpTheme->GetBitmap("ButtonFrameCenter")); - SharedBitmapDescriptor pRightBitmap(mpTheme->GetBitmap("ButtonFrameRight")); - - maButtonSize = CalculateButtonSize(); - - if (maButtonSize.Height<=0 && maButtonSize.Width<= 0) - return; - - mxNormalBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize); - Reference<rendering::XCanvas> xCanvas (mxNormalBitmap, UNO_QUERY); - if (xCanvas.is()) - RenderButton( - xCanvas, - maButtonSize, - mpFont, - PresenterBitmapDescriptor::Normal, - pLeftBitmap, - pCenterBitmap, - pRightBitmap); - - mxMouseOverBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize); - xCanvas.set(mxMouseOverBitmap, UNO_QUERY); - if (mpMouseOverFont && !mpMouseOverFont->mxFont.is() && mxCanvas.is()) - mpMouseOverFont->PrepareFont(mxCanvas); - if (xCanvas.is()) - RenderButton( - xCanvas, - maButtonSize, - mpMouseOverFont, - PresenterBitmapDescriptor::MouseOver, - pLeftBitmap, - pCenterBitmap, - pRightBitmap); -} - -Reference<beans::XPropertySet> PresenterButton::GetConfigurationProperties ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const OUString& rsConfigurationName) -{ - PresenterConfigurationAccess aConfiguration ( - rxComponentContext, - PresenterConfigurationAccess::msPresenterScreenRootName, - PresenterConfigurationAccess::READ_ONLY); - return Reference<beans::XPropertySet>( - PresenterConfigurationAccess::Find ( - Reference<container::XNameAccess>( - aConfiguration.GetConfigurationNode("PresenterScreenSettings/Buttons"), - UNO_QUERY), - [&rsConfigurationName](OUString const&, uno::Reference<beans::XPropertySet> const& xProps) -> bool - { - return PresenterConfigurationAccess::IsStringPropertyEqual( - rsConfigurationName, "Name", xProps); - }), - UNO_QUERY); -} - -void PresenterButton::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterButton object has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -} // end of namespace sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterButton.hxx b/sdext/source/presenter/PresenterButton.hxx deleted file mode 100644 index f722e7da1c52..000000000000 --- a/sdext/source/presenter/PresenterButton.hxx +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERBUTTON_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERBUTTON_HXX - -#include "PresenterBitmapContainer.hxx" -#include "PresenterTheme.hxx" -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XMouseListener.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/rendering/XBitmap.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <rtl/ref.hxx> - -namespace sdext::presenter { - -class PresenterController; - -typedef ::cppu::WeakComponentImplHelper < - css::awt::XPaintListener, - css::awt::XMouseListener -> PresenterButtonInterfaceBase; - -/** Button for the presenter screen. It displays a text surrounded by a - frame. -*/ -class PresenterButton - : private ::cppu::BaseMutex, - public PresenterButtonInterfaceBase -{ -public: - static ::rtl::Reference<PresenterButton> Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const std::shared_ptr<PresenterTheme>& rpTheme, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas, - const OUString& rsConfigurationName); - virtual ~PresenterButton() override; - PresenterButton(const PresenterButton&) = delete; - PresenterButton& operator=(const PresenterButton&) = delete; - - virtual void SAL_CALL disposing() override; - - void SetCenter (const css::geometry::RealPoint2D& rLocation); - void SetCanvas ( - const css::uno::Reference<css::rendering::XCanvas>& rxParentCanvas, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow); - css::geometry::IntegerSize2D const & GetSize(); - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XMouseListener - - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - - // lang::XEventListener - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - -private: - ::rtl::Reference<PresenterController> mpPresenterController; - std::shared_ptr<PresenterTheme> mpTheme; - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - const OUString msText; - const PresenterTheme::SharedFontDescriptor mpFont; - const PresenterTheme::SharedFontDescriptor mpMouseOverFont; - const OUString msAction; - css::geometry::RealPoint2D maCenter; - css::geometry::IntegerSize2D maButtonSize; - PresenterBitmapDescriptor::Mode meState; - css::uno::Reference<css::rendering::XBitmap> mxNormalBitmap; - css::uno::Reference<css::rendering::XBitmap> mxMouseOverBitmap; - - PresenterButton ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const std::shared_ptr<PresenterTheme>& rpTheme, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const PresenterTheme::SharedFontDescriptor& rFont, - const PresenterTheme::SharedFontDescriptor& rMouseOverFont, - const OUString& rxText, - const OUString& rxAction); - void RenderButton ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::geometry::IntegerSize2D& rSize, - const PresenterTheme::SharedFontDescriptor& rFont, - const PresenterBitmapDescriptor::Mode eMode, - const SharedBitmapDescriptor& rpLeft, - const SharedBitmapDescriptor& rpCenter, - const SharedBitmapDescriptor& rpRight); - css::geometry::IntegerSize2D CalculateButtonSize(); - void Invalidate(); - static css::uno::Reference<css::rendering::XBitmap> GetBitmap ( - const SharedBitmapDescriptor& mpIcon, - const PresenterBitmapDescriptor::Mode eMode); - void SetupButtonBitmaps(); - static css::uno::Reference<css::beans::XPropertySet> GetConfigurationProperties ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const OUString& rsConfigurationName); - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterCanvasHelper.cxx b/sdext/source/presenter/PresenterCanvasHelper.cxx deleted file mode 100644 index 8381f8d5aabd..000000000000 --- a/sdext/source/presenter/PresenterCanvasHelper.cxx +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterCanvasHelper.hxx" - -#include "PresenterGeometryHelper.hxx" -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <osl/diagnose.h> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -PresenterCanvasHelper::PresenterCanvasHelper() - : maDefaultViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr), - maDefaultRenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE) -{ -} - -PresenterCanvasHelper::~PresenterCanvasHelper() -{ -} - -void PresenterCanvasHelper::Paint ( - const SharedBitmapDescriptor& rpBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::awt::Rectangle& rOuterBoundingBox, - const css::awt::Rectangle& rContentBoundingBox) const -{ - PaintRectangle(rpBitmap,rxCanvas,rRepaintBox,rOuterBoundingBox,rContentBoundingBox, - maDefaultViewState, maDefaultRenderState); -} - -void PresenterCanvasHelper::PaintRectangle ( - const SharedBitmapDescriptor& rpBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::awt::Rectangle& rOuterBoundingBox, - const css::awt::Rectangle& rContentBoundingBox, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState) -{ - if (!rpBitmap) - return; - - if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) - return; - - // Create a clip polypolygon that has the content box as hole. - ::std::vector<awt::Rectangle> aRectangles; - aRectangles.reserve(2); - aRectangles.push_back( - PresenterGeometryHelper::Intersection(rRepaintBox, rOuterBoundingBox)); - if (rContentBoundingBox.Width > 0 && rContentBoundingBox.Height > 0) - aRectangles.push_back( - PresenterGeometryHelper::Intersection(rRepaintBox, rContentBoundingBox)); - Reference<rendering::XPolyPolygon2D> xPolyPolygon ( - PresenterGeometryHelper::CreatePolygon( - aRectangles, - rxCanvas->getDevice())); - if ( ! xPolyPolygon.is()) - return; - xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD); - - if (rpBitmap->GetNormalBitmap().is()) - { - if (rpBitmap->meHorizontalTexturingMode == PresenterBitmapDescriptor::Repeat - || rpBitmap->meVerticalTexturingMode == PresenterBitmapDescriptor::Repeat) - { - PaintTiledBitmap( - rpBitmap->GetNormalBitmap(), - rxCanvas, - rRepaintBox, - xPolyPolygon, - rContentBoundingBox, - rDefaultViewState, - rDefaultRenderState); - } - else - { - PaintBitmap( - rpBitmap->GetNormalBitmap(), - awt::Point(rOuterBoundingBox.X, rOuterBoundingBox.Y), - rxCanvas, - rRepaintBox, - xPolyPolygon, - rDefaultViewState, - rDefaultRenderState); - } - } - else - { - PaintColor( - rpBitmap->maReplacementColor, - rxCanvas, - rRepaintBox, - xPolyPolygon, - rDefaultViewState, - rDefaultRenderState); - } -} - -void PresenterCanvasHelper::PaintTiledBitmap ( - const css::uno::Reference<css::rendering::XBitmap>& rxTexture, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, - const css::awt::Rectangle& rHole, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState) -{ - if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) - return; - - if ( ! rxTexture.is()) - return; - - if ( ! rxPolygon.is()) - return; - - rendering::ViewState aViewState (rDefaultViewState); - aViewState.Clip = rxPolygon; - - // Create a local render state at which the location of the bitmap is - // set. - rendering::RenderState aRenderState (rDefaultRenderState); - - // Tile the bitmap over the repaint box. - const geometry::IntegerSize2D aBitmapSize (rxTexture->getSize()); - if( aBitmapSize.Width < 1 || aBitmapSize.Height < 1) - return; - - const sal_Int32 nLeft = (rRepaintBox.X / aBitmapSize.Width) * aBitmapSize.Width; - const sal_Int32 nTop = (rRepaintBox.Y / aBitmapSize.Height) * aBitmapSize.Height; - const sal_Int32 nRight = ((rRepaintBox.X + rRepaintBox.Width - 1 + aBitmapSize.Width - 1) - / aBitmapSize.Width) * aBitmapSize.Width; - const sal_Int32 nBottom = ((rRepaintBox.Y + rRepaintBox.Height - 1 + aBitmapSize.Height - 1) - / aBitmapSize.Height) * aBitmapSize.Height; - - for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height) - for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width) - { - if (PresenterGeometryHelper::IsInside( - awt::Rectangle(nX,nY,aBitmapSize.Width,aBitmapSize.Height), - rHole)) - { - continue; - } - aRenderState.AffineTransform.m02 = nX; - aRenderState.AffineTransform.m12 = nY; - rxCanvas->drawBitmap( - rxTexture, - aViewState, - aRenderState); - } -} - -void PresenterCanvasHelper::PaintBitmap ( - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, - const awt::Point& rLocation, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState) -{ - if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) - return; - - if ( ! rxBitmap.is()) - return; - - if ( ! rxPolygon.is()) - return; - - // Set the repaint box as clip rectangle at the view state. - rendering::ViewState aViewState (rDefaultViewState); - aViewState.Clip = PresenterGeometryHelper::CreatePolygon(rRepaintBox, rxCanvas->getDevice()); - - // Setup the rendering state so that the bitmap is painted top left in - // the polygon bounding box. - rendering::RenderState aRenderState (rDefaultRenderState); - aRenderState.AffineTransform = geometry::AffineMatrix2D(1,0, rLocation.X, 0,1,rLocation.Y); - aRenderState.Clip = rxPolygon; - - rxCanvas->drawBitmap( - rxBitmap, - aViewState, - aRenderState); -} - -void PresenterCanvasHelper::PaintColor ( - const css::util::Color nColor, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState) -{ - if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) - return; - - if ( ! rxPolygon.is()) - return; - - // Set the repaint box as clip rectangle at the view state. - rendering::ViewState aViewState (rDefaultViewState); - aViewState.Clip = PresenterGeometryHelper::CreatePolygon(rRepaintBox, rxCanvas->getDevice()); - - // Setup the rendering state to use the given color. - rendering::RenderState aRenderState (rDefaultRenderState); - SetDeviceColor(aRenderState, nColor); - - rxCanvas->fillPolyPolygon( - rxPolygon, - aViewState, - aRenderState); -} - -void PresenterCanvasHelper::SetDeviceColor( - rendering::RenderState& rRenderState, - const util::Color aColor) -{ - // Other component counts then 4 (RGBA) are not accepted (anymore). - - OSL_ASSERT(rRenderState.DeviceColor.getLength() == 4); - if (rRenderState.DeviceColor.getLength() == 4) - { - rRenderState.DeviceColor[0] = ((aColor >> 16) & 0x0ff) / 255.0; - rRenderState.DeviceColor[1] = ((aColor >> 8) & 0x0ff) / 255.0; - rRenderState.DeviceColor[2] = ((aColor >> 0) & 0x0ff) / 255.0; - rRenderState.DeviceColor[3] = 1.0 - ((aColor >> 24) & 0x0ff) / 255.0; - } -} - -css::geometry::RealRectangle2D PresenterCanvasHelper::GetTextBoundingBox ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const OUString& rsText, - const sal_Int8 nTextDirection) -{ - if (rxFont.is() && !rsText.isEmpty()) - { - rendering::StringContext aContext (rsText, 0, rsText.getLength()); - Reference<rendering::XTextLayout> xLayout ( - rxFont->createTextLayout(aContext, nTextDirection, 0)); - return xLayout->queryTextBounds(); - } - else - { - return geometry::RealRectangle2D(0,0,0,0); - } -} - -css::geometry::RealSize2D PresenterCanvasHelper::GetTextSize ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const OUString& rsText) -{ - const geometry::RealRectangle2D aTextBBox (GetTextBoundingBox(rxFont, rsText)); - return css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1); -} - -} // end of namespace sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterCanvasHelper.hxx b/sdext/source/presenter/PresenterCanvasHelper.hxx deleted file mode 100644 index 8902a9712bf6..000000000000 --- a/sdext/source/presenter/PresenterCanvasHelper.hxx +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCANVASHELPER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCANVASHELPER_HXX - -#include "PresenterBitmapContainer.hxx" -#include <com/sun/star/awt/Point.hpp> -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/rendering/XCanvasFont.hpp> -#include <com/sun/star/rendering/XPolyPolygon2D.hpp> - -namespace sdext::presenter { - -/** Collection of functions to ease the life of a canvas user. -*/ -class PresenterCanvasHelper -{ -public: - PresenterCanvasHelper(); - ~PresenterCanvasHelper(); - PresenterCanvasHelper(const PresenterCanvasHelper&) = delete; - PresenterCanvasHelper& operator=(const PresenterCanvasHelper&) = delete; - - void Paint ( - const SharedBitmapDescriptor& rpBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::awt::Rectangle& rBackgroundBoundingBox, - const css::awt::Rectangle& rContentBoundingBox) const; - - static void PaintRectangle ( - const SharedBitmapDescriptor& rpBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::awt::Rectangle& rBackgroundBoundingBox, - const css::awt::Rectangle& rContentBoundingBox, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState); - - static void SetDeviceColor( - css::rendering::RenderState& rRenderState, - const css::util::Color aColor); - - static css::geometry::RealRectangle2D GetTextBoundingBox ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const OUString& rsText, - const sal_Int8 = css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT); - - static css::geometry::RealSize2D GetTextSize ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const OUString& rsText ); - -private: - const css::rendering::ViewState maDefaultViewState; - const css::rendering::RenderState maDefaultRenderState; - - static void PaintTiledBitmap ( - const css::uno::Reference<css::rendering::XBitmap>& rxTexture, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, - const css::awt::Rectangle& rHole, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState); - - static void PaintBitmap ( - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, - const css::awt::Point& rLocation, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState); - - static void PaintColor ( - const css::util::Color nColor, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, - const css::rendering::ViewState& rDefaultViewState, - const css::rendering::RenderState& rDefaultRenderState); -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterConfigurationAccess.cxx b/sdext/source/presenter/PresenterConfigurationAccess.cxx deleted file mode 100644 index c4a08812a631..000000000000 --- a/sdext/source/presenter/PresenterConfigurationAccess.cxx +++ /dev/null @@ -1,276 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterConfigurationAccess.hxx" - -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/container/XHierarchicalNameAccess.hpp> -#include <com/sun/star/configuration/theDefaultProvider.hpp> -#include <com/sun/star/util/XChangesBatch.hpp> -#include <comphelper/propertysequence.hxx> -#include <osl/diagnose.h> -#include <tools/diagnose_ex.h> -#include <sal/log.hxx> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -PresenterConfigurationAccess::PresenterConfigurationAccess ( - const Reference<XComponentContext>& rxContext, - const OUString& rsRootName, - WriteMode eMode) - : mxRoot(), - maNode() -{ - try - { - if (rxContext.is()) - { - uno::Sequence<uno::Any> aCreationArguments(comphelper::InitAnyPropertySequence( - { - {"nodepath", uno::Any(rsRootName)}, - {"depth", uno::Any(sal_Int32(-1))} - })); - - OUString sAccessService; - if (eMode == READ_ONLY) - sAccessService = "com.sun.star.configuration.ConfigurationAccess"; - else - sAccessService = "com.sun.star.configuration.ConfigurationUpdateAccess"; - - Reference<lang::XMultiServiceFactory> xProvider = - configuration::theDefaultProvider::get( rxContext ); - mxRoot = xProvider->createInstanceWithArguments( - sAccessService, aCreationArguments); - maNode <<= mxRoot; - } - } - catch (const Exception&) - { - DBG_UNHANDLED_EXCEPTION("sdext.presenter", "caught exception while opening configuration"); - } -} - -PresenterConfigurationAccess::~PresenterConfigurationAccess() -{ -} - -bool PresenterConfigurationAccess::IsValid() const -{ - return mxRoot.is(); -} - -Any PresenterConfigurationAccess::GetConfigurationNode (const OUString& sPathToNode) -{ - return GetConfigurationNode( - Reference<container::XHierarchicalNameAccess>(mxRoot, UNO_QUERY), - sPathToNode); -} - -bool PresenterConfigurationAccess::GoToChild (const OUString& rsPathToNode) -{ - if ( ! IsValid()) - return false; - - Reference<container::XHierarchicalNameAccess> xNode (maNode, UNO_QUERY); - if (xNode.is()) - { - maNode = GetConfigurationNode( - Reference<container::XHierarchicalNameAccess>(maNode, UNO_QUERY), - rsPathToNode); - if (Reference<XInterface>(maNode, UNO_QUERY).is()) - return true; - } - - mxRoot = nullptr; - return false; -} - -bool PresenterConfigurationAccess::GoToChild (const Predicate& rPredicate) -{ - if ( ! IsValid()) - return false; - - maNode = Find(Reference<container::XNameAccess>(maNode,UNO_QUERY), rPredicate); - if (Reference<XInterface>(maNode, UNO_QUERY).is()) - return true; - - mxRoot = nullptr; - return false; -} - -bool PresenterConfigurationAccess::SetProperty ( - const OUString& rsPropertyName, - const Any& rValue) -{ - Reference<beans::XPropertySet> xProperties (maNode, UNO_QUERY); - if (xProperties.is()) - { - xProperties->setPropertyValue(rsPropertyName, rValue); - return true; - } - else - return false; -} - -Any PresenterConfigurationAccess::GetConfigurationNode ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const OUString& sPathToNode) -{ - if (sPathToNode.isEmpty()) - return Any(rxNode); - - try - { - if (rxNode.is()) - { - return rxNode->getByHierarchicalName(sPathToNode); - } - } - catch (const Exception&) - { - TOOLS_WARN_EXCEPTION("sdext.presenter", "caught exception while getting configuration node " << sPathToNode); - } - - return Any(); -} - -Reference<beans::XPropertySet> PresenterConfigurationAccess::GetNodeProperties ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const OUString& rsPathToNode) -{ - return Reference<beans::XPropertySet>(GetConfigurationNode(rxNode, rsPathToNode), UNO_QUERY); -} - -void PresenterConfigurationAccess::CommitChanges() -{ - Reference<util::XChangesBatch> xConfiguration (mxRoot, UNO_QUERY); - if (xConfiguration.is()) - xConfiguration->commitChanges(); -} - -void PresenterConfigurationAccess::ForAll ( - const Reference<container::XNameAccess>& rxContainer, - const ::std::vector<OUString>& rArguments, - const ItemProcessor& rProcessor) -{ - if (!rxContainer.is()) - return; - - ::std::vector<Any> aValues(rArguments.size()); - const Sequence<OUString> aKeys (rxContainer->getElementNames()); - for (const OUString& rsKey : aKeys) - { - bool bHasAllValues (true); - Reference<container::XNameAccess> xSetItem (rxContainer->getByName(rsKey), UNO_QUERY); - Reference<beans::XPropertySet> xSet (xSetItem, UNO_QUERY); - OSL_ASSERT(xSet.is()); - if (xSetItem.is()) - { - // Get from the current item of the container the children - // that match the names in the rArguments list. - for (size_t nValueIndex=0; nValueIndex<aValues.size(); ++nValueIndex) - { - if ( ! xSetItem->hasByName(rArguments[nValueIndex])) - bHasAllValues = false; - else - aValues[nValueIndex] = xSetItem->getByName(rArguments[nValueIndex]); - } - } - else - bHasAllValues = false; - if (bHasAllValues) - rProcessor(aValues); - } -} - -void PresenterConfigurationAccess::ForAll ( - const Reference<container::XNameAccess>& rxContainer, - const PropertySetProcessor& rProcessor) -{ - if (rxContainer.is()) - { - const Sequence<OUString> aKeys (rxContainer->getElementNames()); - for (const OUString& rsKey : aKeys) - { - Reference<beans::XPropertySet> xSet (rxContainer->getByName(rsKey), UNO_QUERY); - if (xSet.is()) - rProcessor(rsKey, xSet); - } - } -} - -Any PresenterConfigurationAccess::Find ( - const Reference<container::XNameAccess>& rxContainer, - const Predicate& rPredicate) -{ - if (rxContainer.is()) - { - const Sequence<OUString> aKeys (rxContainer->getElementNames()); - for (const auto& rKey : aKeys) - { - Reference<beans::XPropertySet> xProperties ( - rxContainer->getByName(rKey), - UNO_QUERY); - if (xProperties.is()) - if (rPredicate(rKey, xProperties)) - return Any(xProperties); - } - } - return Any(); -} - -bool PresenterConfigurationAccess::IsStringPropertyEqual ( - std::u16string_view rsValue, - const OUString& rsPropertyName, - const css::uno::Reference<css::beans::XPropertySet>& rxNode) -{ - OUString sValue; - if (GetProperty(rxNode, rsPropertyName) >>= sValue) - return sValue == rsValue; - else - return false; -} - -Any PresenterConfigurationAccess::GetProperty ( - const Reference<beans::XPropertySet>& rxProperties, - const OUString& rsKey) -{ - OSL_ASSERT(rxProperties.is()); - if ( ! rxProperties.is()) - return Any(); - try - { - Reference<beans::XPropertySetInfo> xInfo (rxProperties->getPropertySetInfo()); - if (xInfo.is()) - if ( ! xInfo->hasPropertyByName(rsKey)) - return Any(); - return rxProperties->getPropertyValue(rsKey); - } - catch (beans::UnknownPropertyException&) - { - } - return Any(); -} - -} // end of namespace sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterConfigurationAccess.hxx b/sdext/source/presenter/PresenterConfigurationAccess.hxx deleted file mode 100644 index afd1b9aa4e87..000000000000 --- a/sdext/source/presenter/PresenterConfigurationAccess.hxx +++ /dev/null @@ -1,178 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCONFIGURATIONACCESS_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCONFIGURATIONACCESS_HXX - -#include <rtl/ustring.hxx> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/container/XHierarchicalNameAccess.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> - -#include <vector> -#include <functional> - -namespace sdext::presenter { - -/** This class gives access to the configuration. Create an object of this - class for one node of the configuration. This will be the root node. - From this one you can use this class in two ways. - - <p>In a stateless mode (with exception of the root node) you can use static - methods for obtaining child nodes, get values from properties at leaf - nodes and iterate over children of inner nodes.</p> - - <p>In a stateful mode use non-static methods like GoToChild() to - navigate to children.</p> - - <p>Note to call CommitChanges() after making changes to - PresenterConfigurationAccess object that was opened in READ_WRITE mode.</p> -*/ -class PresenterConfigurationAccess -{ -public: - enum WriteMode { READ_WRITE, READ_ONLY }; - typedef ::std::function<bool ( - const OUString&, - const css::uno::Reference<css::beans::XPropertySet>&)> Predicate; - static constexpr OUStringLiteral msPresenterScreenRootName = - u"/org.openoffice.Office.PresenterScreen/"; - - /** Create a new object to access the configuration entries below the - given root. - @param rsRootName - Name of the root. You can use msPresenterScreenRootName to - access the configuration of the presenter screen. - @param eMode - This flag specifies whether to give read-write or read-only - access. - */ - PresenterConfigurationAccess( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const OUString& rsRootName, - WriteMode eMode); - - ~PresenterConfigurationAccess(); - - /** Return a configuration node below the root of the called object. - @param rsPathToNode - The relative path from the root (as given the constructor) to the node. - */ - css::uno::Any GetConfigurationNode ( - const OUString& rsPathToNode); - - /** Return <TRUE/> when opening the configuration (via creating a new - PresenterConfigurationAccess object) or previous calls to - GoToChild() left the called PresenterConfigurationAccess object in a - valid state. - */ - bool IsValid() const; - - /** Move the focused node to the (possibly indirect) child specified by the given path. - */ - bool GoToChild (const OUString& rsPathToNode); - - /** Move the focused node to the first direct child that fulfills the given predicate. - */ - bool GoToChild (const Predicate& rPredicate); - - /** Modify the property child of the currently focused node. Keep in - mind to call CommitChanges() to write the change back to the - configuration. - */ - bool SetProperty (const OUString& rsPropertyName, const css::uno::Any& rValue); - - /** Return a configuration node below the given node. - @param rxNode - The node that acts as root to the given relative path. - @param rsPathToNode - The relative path from the given node to the requested node. - When this string is empty then rxNode is returned. - @return - The type of the returned node varies with the requested node. - It is empty when the node was not found. - */ - static css::uno::Any GetConfigurationNode ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const OUString& rsPathToNode); - - static css::uno::Reference<css::beans::XPropertySet> GetNodeProperties ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const OUString& rsPathToNode); - - /** Write any changes that have been made back to the configuration. - This call is ignored when the called ConfigurationAccess object was - not create with read-write mode. - */ - void CommitChanges(); - - typedef ::std::function<void ( - const ::std::vector<css::uno::Any>&) > ItemProcessor; - typedef ::std::function<void ( - const OUString&, - const css::uno::Reference<css::beans::XPropertySet>&) > PropertySetProcessor; - - /** Execute a functor for all elements of the given container. - @param rxContainer - The container is a XNameAccess to a list of the configuration. - This can be a node returned by GetConfigurationNode(). - @param rArguments - The functor is called with arguments that are children of each - element of the container. The set of children is specified this - list. - @param rFunctor - The functor to be executed for some or all of the elements in - the given container. - */ - static void ForAll ( - const css::uno::Reference<css::container::XNameAccess>& rxContainer, - const ::std::vector<OUString>& rArguments, - const ItemProcessor& rProcessor); - static void ForAll ( - const css::uno::Reference<css::container::XNameAccess>& rxContainer, - const PropertySetProcessor& rProcessor); - - static css::uno::Any Find ( - const css::uno::Reference<css::container::XNameAccess>& rxContainer, - const Predicate& rPredicate); - - static bool IsStringPropertyEqual ( - std::u16string_view rsValue, - const OUString& rsPropertyName, - const css::uno::Reference<css::beans::XPropertySet>& rxNode); - - /** This method wraps a call to getPropertyValue() and returns an empty - Any instead of throwing an exception when the property does not - exist. - */ - static css::uno::Any GetProperty ( - const css::uno::Reference<css::beans::XPropertySet>& rxProperties, - const OUString& rsKey); - -private: - css::uno::Reference<css::uno::XInterface> mxRoot; - css::uno::Any maNode; -}; - -} // end of namespace sdext::tools - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterController.cxx b/sdext/source/presenter/PresenterController.cxx deleted file mode 100644 index 7d4ac91b710e..000000000000 --- a/sdext/source/presenter/PresenterController.cxx +++ /dev/null @@ -1,1188 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include <string_view> - -#include "PresenterController.hxx" - -#include "PresenterAccessibility.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterCurrentSlideObserver.hxx" -#include "PresenterScreen.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterPaneBase.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterPaneBorderPainter.hxx" -#include "PresenterTheme.hxx" -#include "PresenterViewFactory.hxx" -#include "PresenterWindowManager.hxx" - -#include <com/sun/star/awt/Key.hpp> -#include <com/sun/star/awt/KeyModifier.hpp> -#include <com/sun/star/awt/MouseButton.hpp> -#include <com/sun/star/container/XNamed.hpp> -#include <com/sun/star/drawing/XDrawView.hpp> -#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> -#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp> -#include <com/sun/star/drawing/framework/ResourceId.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/frame/FrameSearchFlag.hpp> -#include <com/sun/star/frame/XDispatchProvider.hpp> -#include <com/sun/star/presentation/AnimationEffect.hpp> -#include <com/sun/star/presentation/XPresentation.hpp> -#include <com/sun/star/presentation/XPresentationSupplier.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/util/URLTransformer.hpp> - -#include <rtl/ustrbuf.hxx> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::presentation; -using namespace ::com::sun::star::drawing::framework; - -namespace { - const sal_Int32 ResourceActivationEventType = 0; - const sal_Int32 ResourceDeactivationEventType = 1; - const sal_Int32 ConfigurationUpdateEndEventType = 2; -} - -namespace sdext::presenter { - -IPresentationTime::~IPresentationTime() -{ -} - -PresenterController::InstanceContainer PresenterController::maInstances; - -::rtl::Reference<PresenterController> PresenterController::Instance ( - const css::uno::Reference<css::frame::XFrame>& rxFrame) -{ - InstanceContainer::const_iterator iInstance (maInstances.find(rxFrame)); - if (iInstance != maInstances.end()) - return iInstance->second; - else - return ::rtl::Reference<PresenterController>(); -} - -PresenterController::PresenterController ( - const css::uno::WeakReference<css::lang::XEventListener> &rxScreen, - const Reference<XComponentContext>& rxContext, - const Reference<frame::XController>& rxController, - const Reference<presentation::XSlideShowController>& rxSlideShowController, - const rtl::Reference<PresenterPaneContainer>& rpPaneContainer, - const Reference<XResourceId>& rxMainPaneId) - : PresenterControllerInterfaceBase(m_aMutex), - mxScreen(rxScreen), - mxComponentContext(rxContext), - mxController(rxController), - mxConfigurationController(), - mxSlideShowController(rxSlideShowController), - mxMainPaneId(rxMainPaneId), - mpPaneContainer(rpPaneContainer), - mnCurrentSlideIndex(-1), - mxCurrentSlide(), - mxNextSlide(), - mpWindowManager(new PresenterWindowManager(rxContext,mpPaneContainer,this)), - mpTheme(), - mxMainWindow(), - mpPaneBorderPainter(), - mpCanvasHelper(std::make_shared<PresenterCanvasHelper>()), - mxPresenterHelper(), - mpPaintManager(), - mnPendingSlideNumber(-1), - mxUrlTransformer(), - mpAccessibleObject(), - mbIsAccessibilityActive(false) -{ - OSL_ASSERT(mxController.is()); - - if ( ! mxSlideShowController.is()) - throw lang::IllegalArgumentException( - "missing slide show controller", - static_cast<XWeak*>(this), - 2); - - new PresenterCurrentSlideObserver(this,rxSlideShowController); - - // Listen for configuration changes. - Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW); - mxConfigurationController = xCM->getConfigurationController(); - if (mxConfigurationController.is()) - { - mxConfigurationController->addConfigurationChangeListener( - this, - "ResourceActivation", - Any(ResourceActivationEventType)); - mxConfigurationController->addConfigurationChangeListener( - this, - "ResourceDeactivation", - Any(ResourceDeactivationEventType)); - mxConfigurationController->addConfigurationChangeListener( - this, - "ConfigurationUpdateEnd", - Any(ConfigurationUpdateEndEventType)); - } - - // Listen for the frame being activated. - Reference<frame::XFrame> xFrame (mxController->getFrame()); - if (xFrame.is()) - xFrame->addFrameActionListener(this); - - // Create the border painter. - mpPaneBorderPainter = new PresenterPaneBorderPainter(rxContext); - mpWindowManager->SetPaneBorderPainter(mpPaneBorderPainter); - - // Create an object that is able to load the bitmaps in a format that is - // supported by the canvas. - Reference<lang::XMultiComponentFactory> xFactory = - rxContext->getServiceManager(); - if ( ! xFactory.is()) - return; - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.drawing.PresenterHelper", - rxContext), - UNO_QUERY_THROW); - - if (mxSlideShowController.is()) - { - mxSlideShowController->activate(); - Reference<beans::XPropertySet> xProperties (mxSlideShowController, UNO_QUERY); - if (xProperties.is()) - { - Reference<awt::XWindow> xWindow ( - xProperties->getPropertyValue("ParentWindow"), UNO_QUERY); - if (xWindow.is()) - xWindow->addKeyListener(this); - } - } - - UpdateCurrentSlide(0); - - maInstances[mxController->getFrame()] = this; - - // Create a URLTransformer. - if (xFactory.is()) - { - mxUrlTransformer.set(util::URLTransformer::create(mxComponentContext)); - } -} - -PresenterController::~PresenterController() -{ -} - -void PresenterController::disposing() -{ - maInstances.erase(mxController->getFrame()); - - if (mxMainWindow.is()) - { - mxMainWindow->removeKeyListener(this); - mxMainWindow->removeMouseListener(this); - mxMainWindow = nullptr; - } - if (mxConfigurationController.is()) - mxConfigurationController->removeConfigurationChangeListener(this); - - if (mxController.is()) - { - Reference<frame::XFrame> xFrame (mxController->getFrame()); - if (xFrame.is()) - xFrame->removeFrameActionListener(this); - mxController = nullptr; - } - - Reference<XComponent> xWindowManagerComponent ( - static_cast<XWeak*>(mpWindowManager.get()), UNO_QUERY); - mpWindowManager = nullptr; - if (xWindowManagerComponent.is()) - xWindowManagerComponent->dispose(); - - mxComponentContext = nullptr; - mxConfigurationController = nullptr; - mxSlideShowController = nullptr; - mxMainPaneId = nullptr; - mpPaneContainer = nullptr; - mnCurrentSlideIndex = -1; - mxCurrentSlide = nullptr; - mxNextSlide = nullptr; - mpTheme.reset(); - { - Reference<lang::XComponent> xComponent ( - static_cast<XWeak*>(mpPaneBorderPainter.get()), UNO_QUERY); - mpPaneBorderPainter = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - mpCanvasHelper.reset(); - { - Reference<lang::XComponent> xComponent (mxPresenterHelper, UNO_QUERY); - mxPresenterHelper = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - mpPaintManager.reset(); - mnPendingSlideNumber = -1; - { - Reference<lang::XComponent> xComponent (mxUrlTransformer, UNO_QUERY); - mxUrlTransformer = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } -} - -void PresenterController::UpdateCurrentSlide (const sal_Int32 nOffset) -{ - // std::cerr << "Updating current Slide to " << nOffset << std::endl; - GetSlides(nOffset); - UpdatePaneTitles(); - UpdateViews(); - - // Update the accessibility object. - if (IsAccessibilityActive()) - { - mpAccessibleObject->NotifyCurrentSlideChange(); - } -} - -void PresenterController::GetSlides (const sal_Int32 nOffset) -{ - if ( ! mxSlideShowController.is()) - return; - - // Get the current slide from the slide show controller. - mxCurrentSlide = nullptr; - Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY); - try - { - sal_Int32 nSlideIndex = mxSlideShowController->getCurrentSlideIndex() + nOffset; - if (mxSlideShowController->isPaused()) - nSlideIndex = -1; - - if (xIndexAccess.is() && nSlideIndex>=0) - { - if (nSlideIndex < xIndexAccess->getCount()) - { - mnCurrentSlideIndex = nSlideIndex; - mxCurrentSlide.set( xIndexAccess->getByIndex(nSlideIndex), UNO_QUERY); - } - } - } - catch (RuntimeException&) - { - } - - // Get the next slide. - mxNextSlide = nullptr; - try - { - const sal_Int32 nNextSlideIndex (mxSlideShowController->getNextSlideIndex()+nOffset); - if (nNextSlideIndex >= 0) - { - if (xIndexAccess.is()) - { - if (nNextSlideIndex < xIndexAccess->getCount()) - mxNextSlide.set( xIndexAccess->getByIndex(nNextSlideIndex), UNO_QUERY); - } - } - } - catch (RuntimeException&) - { - } -} - -void PresenterController::UpdatePaneTitles() -{ - if ( ! mxSlideShowController.is()) - return; - - // Get placeholders and their values. - static const OUStringLiteral sCurrentSlideNumberPlaceholder (u"CURRENT_SLIDE_NUMBER"); - static const OUStringLiteral sCurrentSlideNamePlaceholder (u"CURRENT_SLIDE_NAME"); - static const OUStringLiteral sSlideCountPlaceholder (u"SLIDE_COUNT"); - - // Get string for slide count. - OUString sSlideCount ("---"); - Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY); - if (xIndexAccess.is()) - sSlideCount = OUString::number(xIndexAccess->getCount()); - - // Get string for current slide index. - OUString sCurrentSlideNumber (OUString::number(mnCurrentSlideIndex + 1)); - - // Get name of the current slide. - OUString sCurrentSlideName; - Reference<container::XNamed> xNamedSlide (mxCurrentSlide, UNO_QUERY); - if (xNamedSlide.is()) - sCurrentSlideName = xNamedSlide->getName(); - Reference<beans::XPropertySet> xSlideProperties (mxCurrentSlide, UNO_QUERY); - if (xSlideProperties.is()) - { - try - { - OUString sName; - if (xSlideProperties->getPropertyValue("LinkDisplayName") >>= sName) - { - // Find out whether the name of the current slide has been - // automatically created or has been set by the user. - if (sName != sCurrentSlideName) - sCurrentSlideName = sName; - } - } - catch (const beans::UnknownPropertyException&) - { - } - } - - // Replace the placeholders with their current values. - for (auto& rxPane : mpPaneContainer->maPanes) - { - OSL_ASSERT(rxPane != nullptr); - - OUString sTemplate (IsAccessibilityActive() - ? rxPane->msAccessibleTitleTemplate - : rxPane->msTitleTemplate); - if (sTemplate.isEmpty()) - continue; - - OUStringBuffer sResult; - sResult.ensureCapacity(sTemplate.getLength()); - - sal_Int32 nIndex (0); - while (true) - { - sal_Int32 nStartIndex = sTemplate.indexOf('%', nIndex); - if (nStartIndex < 0) - { - // Add the remaining part of the string. - sResult.append(sTemplate.subView(nIndex)); - break; - } - else - { - // Add the part preceding the next %. - sResult.append(sTemplate.subView(nIndex, nStartIndex-nIndex)); - - // Get the placeholder - ++nStartIndex; - const sal_Int32 nEndIndex (sTemplate.indexOf('%', nStartIndex+1)); - const OUString sPlaceholder (sTemplate.copy(nStartIndex, nEndIndex-nStartIndex)); - nIndex = nEndIndex+1; - - // Replace the placeholder with its current value. - if (sPlaceholder == sCurrentSlideNumberPlaceholder) - sResult.append(sCurrentSlideNumber); - else if (sPlaceholder == sCurrentSlideNamePlaceholder) - sResult.append(sCurrentSlideName); - else if (sPlaceholder == sSlideCountPlaceholder) - sResult.append(sSlideCount); - } - } - - rxPane->msTitle = sResult.makeStringAndClear(); - if (rxPane->mxPane.is()) - rxPane->mxPane->SetTitle(rxPane->msTitle); - } -} - -void PresenterController::UpdateViews() -{ - // Tell all views about the slides they should display. - for (const auto& rxPane : mpPaneContainer->maPanes) - { - Reference<drawing::XDrawView> xDrawView (rxPane->mxView, UNO_QUERY); - if (xDrawView.is()) - xDrawView->setCurrentPage(mxCurrentSlide); - } -} - -SharedBitmapDescriptor - PresenterController::GetViewBackground (const OUString& rsViewURL) const -{ - if (mpTheme != nullptr) - { - const OUString sStyleName (mpTheme->GetStyleName(rsViewURL)); - return mpTheme->GetBitmap(sStyleName, "Background"); - } - return SharedBitmapDescriptor(); -} - -PresenterTheme::SharedFontDescriptor - PresenterController::GetViewFont (const OUString& rsViewURL) const -{ - if (mpTheme != nullptr) - { - const OUString sStyleName (mpTheme->GetStyleName(rsViewURL)); - return mpTheme->GetFont(sStyleName); - } - return PresenterTheme::SharedFontDescriptor(); -} - -const std::shared_ptr<PresenterTheme>& PresenterController::GetTheme() const -{ - return mpTheme; -} - -const ::rtl::Reference<PresenterWindowManager>& PresenterController::GetWindowManager() const -{ - return mpWindowManager; -} - -const Reference<presentation::XSlideShowController>& - PresenterController::GetSlideShowController() const -{ - return mxSlideShowController; -} - -const rtl::Reference<PresenterPaneContainer>& PresenterController::GetPaneContainer() const -{ - return mpPaneContainer; -} - -const ::rtl::Reference<PresenterPaneBorderPainter>& PresenterController::GetPaneBorderPainter() const -{ - return mpPaneBorderPainter; -} - -const std::shared_ptr<PresenterCanvasHelper>& PresenterController::GetCanvasHelper() const -{ - return mpCanvasHelper; -} - -const Reference<drawing::XPresenterHelper>& PresenterController::GetPresenterHelper() const -{ - return mxPresenterHelper; -} - -const std::shared_ptr<PresenterPaintManager>& PresenterController::GetPaintManager() const -{ - return mpPaintManager; -} - -void PresenterController::ShowView (const OUString& rsViewURL) -{ - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPaneContainer->FindViewURL(rsViewURL)); - if (!pDescriptor) - return; - - pDescriptor->mbIsActive = true; - mxConfigurationController->requestResourceActivation( - pDescriptor->mxPaneId, - ResourceActivationMode_ADD); - mxConfigurationController->requestResourceActivation( - ResourceId::createWithAnchor( - mxComponentContext, - rsViewURL, - pDescriptor->mxPaneId), - ResourceActivationMode_REPLACE); -} - -void PresenterController::HideView (const OUString& rsViewURL) -{ - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPaneContainer->FindViewURL(rsViewURL)); - if (pDescriptor) - { - mxConfigurationController->requestResourceDeactivation( - ResourceId::createWithAnchor( - mxComponentContext, - rsViewURL, - pDescriptor->mxPaneId)); - } -} - -void PresenterController::DispatchUnoCommand (const OUString& rsCommand) const -{ - if ( ! mxUrlTransformer.is()) - return; - - util::URL aURL; - aURL.Complete = rsCommand; - mxUrlTransformer->parseStrict(aURL); - - Reference<frame::XDispatch> xDispatch (GetDispatch(aURL)); - if ( ! xDispatch.is()) - return; - - xDispatch->dispatch(aURL, Sequence<beans::PropertyValue>()); -} - -Reference<css::frame::XDispatch> PresenterController::GetDispatch (const util::URL& rURL) const -{ - if ( ! mxController.is()) - return nullptr; - - Reference<frame::XDispatchProvider> xDispatchProvider (mxController->getFrame(), UNO_QUERY); - if ( ! xDispatchProvider.is()) - return nullptr; - - return xDispatchProvider->queryDispatch( - rURL, - OUString(), - frame::FrameSearchFlag::SELF); -} - -util::URL PresenterController::CreateURLFromString (const OUString& rsURL) const -{ - util::URL aURL; - - if (mxUrlTransformer.is()) - { - aURL.Complete = rsURL; - mxUrlTransformer->parseStrict(aURL); - } - - return aURL; -} - -const Reference<drawing::framework::XConfigurationController>& - PresenterController::GetConfigurationController() const -{ - return mxConfigurationController; -} - -const Reference<drawing::XDrawPage>& PresenterController::GetCurrentSlide() const -{ - return mxCurrentSlide; -} - -bool PresenterController::HasTransition (Reference<drawing::XDrawPage> const & rxPage) -{ - bool bTransition = false; - if( rxPage.is() ) - { - Reference<beans::XPropertySet> xSlidePropertySet (rxPage, UNO_QUERY); - try - { - sal_uInt16 aTransitionType = 0; - xSlidePropertySet->getPropertyValue("TransitionType") >>= aTransitionType; - if (aTransitionType > 0) - { - bTransition = true; - } - } - catch (const beans::UnknownPropertyException&) - { - } - } - return bTransition; -} - -bool PresenterController::HasCustomAnimation (Reference<drawing::XDrawPage> const & rxPage) -{ - bool bCustomAnimation = false; - if( rxPage.is() ) - { - sal_uInt32 i, nCount = rxPage->getCount(); - for ( i = 0; i < nCount; i++ ) - { - Reference<drawing::XShape> xShape(rxPage->getByIndex(i), UNO_QUERY); - Reference<beans::XPropertySet> xShapePropertySet(xShape, UNO_QUERY); - presentation::AnimationEffect aEffect = presentation::AnimationEffect_NONE; - presentation::AnimationEffect aTextEffect = presentation::AnimationEffect_NONE; - try - { - xShapePropertySet->getPropertyValue("Effect") >>= aEffect; - xShapePropertySet->getPropertyValue("TextEffect") >>= aTextEffect; - } - catch (const beans::UnknownPropertyException&) - { - } - if( aEffect != presentation::AnimationEffect_NONE || - aTextEffect != presentation::AnimationEffect_NONE ) - { - bCustomAnimation = true; - break; - } - } - } - return bCustomAnimation; -} - -void PresenterController::SetAccessibilityActiveState (const bool bIsActive) -{ - if ( mbIsAccessibilityActive != bIsActive) - { - mbIsAccessibilityActive = bIsActive; - UpdatePaneTitles(); - } -} - - -void PresenterController::HandleMouseClick (const awt::MouseEvent& rEvent) -{ - if (!mxSlideShowController.is()) - return; - - switch (rEvent.Buttons) - { - case awt::MouseButton::LEFT: - if (rEvent.Modifiers == awt::KeyModifier::MOD2) - mxSlideShowController->gotoNextSlide(); - else - mxSlideShowController->gotoNextEffect(); - break; - - case awt::MouseButton::RIGHT: - mxSlideShowController->gotoPreviousSlide(); - break; - - default: - // Other or multiple buttons. - break; - } -} - -void PresenterController::RequestViews ( - const bool bIsSlideSorterActive, - const bool bIsNotesViewActive, - const bool bIsHelpViewActive) -{ - for (const auto& rxPane : mpPaneContainer->maPanes) - { - bool bActivate (true); - const OUString sViewURL (rxPane->msViewURL); - if (sViewURL == PresenterViewFactory::msNotesViewURL) - { - bActivate = bIsNotesViewActive && !bIsSlideSorterActive && !bIsHelpViewActive; - } - else if (sViewURL == PresenterViewFactory::msSlideSorterURL) - { - bActivate = bIsSlideSorterActive; - } - else if (sViewURL == PresenterViewFactory::msCurrentSlidePreviewViewURL - || sViewURL == PresenterViewFactory::msNextSlidePreviewViewURL) - { - bActivate = !bIsSlideSorterActive && ! bIsHelpViewActive; - } - else if (sViewURL == PresenterViewFactory::msToolBarViewURL) - { - bActivate = true; - } - else if (sViewURL == PresenterViewFactory::msHelpViewURL) - { - bActivate = bIsHelpViewActive; - } - - if (bActivate) - ShowView(sViewURL); - else - HideView(sViewURL); - } -} - -void PresenterController::SetPresentationTime(IPresentationTime* pPresentationTime) -{ - mpPresentationTime = pPresentationTime; -} - -IPresentationTime* PresenterController::GetPresentationTime() -{ - return mpPresentationTime; -} - -//----- XConfigurationChangeListener ------------------------------------------ - -void SAL_CALL PresenterController::notifyConfigurationChange ( - const ConfigurationChangeEvent& rEvent) -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterController object has already been disposed", - static_cast<uno::XWeak*>(this)); - } - - sal_Int32 nType (0); - if ( ! (rEvent.UserData >>= nType)) - return; - - switch (nType) - { - case ResourceActivationEventType: - if (rEvent.ResourceId->compareTo(mxMainPaneId) == 0) - { - InitializeMainPane(Reference<XPane>(rEvent.ResourceObject,UNO_QUERY)); - } - else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_DIRECT)) - { - // A pane bound to the main pane has been created and is - // stored in the pane container. - Reference<XPane> xPane (rEvent.ResourceObject,UNO_QUERY); - if (xPane.is()) - { - mpPaneContainer->FindPaneId(xPane->getResourceId()); - } - } - else if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT)) - { - // A view bound to one of the panes has been created and is - // stored in the pane container along with its pane. - Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY); - if (xView.is()) - { - mpPaneContainer->StoreView(xView); - UpdateViews(); - mpWindowManager->NotifyViewCreation(xView); - } - } - break; - - case ResourceDeactivationEventType: - if (rEvent.ResourceId->isBoundTo(mxMainPaneId,AnchorBindingMode_INDIRECT)) - { - // If this is a view then remove it from the pane container. - Reference<XView> xView (rEvent.ResourceObject,UNO_QUERY); - if (xView.is()) - { - PresenterPaneContainer::SharedPaneDescriptor pDescriptor( - mpPaneContainer->RemoveView(xView)); - - // A possibly opaque view has been removed. Update() - // updates the clip polygon. - mpWindowManager->Update(); - // Request the repainting of the area previously - // occupied by the view. - if (pDescriptor) - GetPaintManager()->Invalidate(pDescriptor->mxBorderWindow); - } - } - break; - - case ConfigurationUpdateEndEventType: - if (IsAccessibilityActive()) - { - mpAccessibleObject->UpdateAccessibilityHierarchy(); - UpdateCurrentSlide(0); - } - break; - } -} - -//----- XEventListener -------------------------------------------------------- - -void SAL_CALL PresenterController::disposing ( - const lang::EventObject& rEvent) -{ - if (rEvent.Source == mxController) - mxController = nullptr; - else if (rEvent.Source == mxConfigurationController) - mxConfigurationController = nullptr; - else if (rEvent.Source == mxSlideShowController) - mxSlideShowController = nullptr; - else if (rEvent.Source == mxMainWindow) - mxMainWindow = nullptr; -} - -//----- XFrameActionListener -------------------------------------------------- - -void SAL_CALL PresenterController::frameAction ( - const frame::FrameActionEvent& rEvent) -{ - if (rEvent.Action == frame::FrameAction_FRAME_ACTIVATED) - { - if (mxSlideShowController.is()) - mxSlideShowController->activate(); - } -} - -//----- XKeyListener ---------------------------------------------------------- - -void SAL_CALL PresenterController::keyPressed (const awt::KeyEvent& rEvent) -{ - // Tell all views about the unhandled key event. - for (const auto& rxPane : mpPaneContainer->maPanes) - { - if ( ! rxPane->mbIsActive) - continue; - - Reference<awt::XKeyListener> xKeyListener (rxPane->mxView, UNO_QUERY); - if (xKeyListener.is()) - xKeyListener->keyPressed(rEvent); - } -} - -void SAL_CALL PresenterController::keyReleased (const awt::KeyEvent& rEvent) -{ - if (rEvent.Source != mxMainWindow) - return; - - switch (rEvent.KeyCode) - { - case awt::Key::ESCAPE: - case awt::Key::SUBTRACT: - { - if( mxController.is() ) - { - Reference< XPresentationSupplier > xPS( mxController->getModel(), UNO_QUERY ); - if( xPS.is() ) - { - Reference< XPresentation > xP( xPS->getPresentation() ); - if( xP.is() ) - xP->end(); - } - } - } - break; - - case awt::Key::PAGEDOWN: - if (mxSlideShowController.is()) - { - if (rEvent.Modifiers == awt::KeyModifier::MOD2) - mxSlideShowController->gotoNextSlide(); - else - mxSlideShowController->gotoNextEffect(); - } - break; - - case awt::Key::RIGHT: - case awt::Key::SPACE: - case awt::Key::DOWN: - if (mxSlideShowController.is()) - { - mxSlideShowController->gotoNextEffect(); - } - break; - - case awt::Key::PAGEUP: - if (mxSlideShowController.is()) - { - if (rEvent.Modifiers == awt::KeyModifier::MOD2) - mxSlideShowController->gotoPreviousSlide(); - else - mxSlideShowController->gotoPreviousEffect(); - } - break; - - case awt::Key::LEFT: - case awt::Key::UP: - case awt::Key::BACKSPACE: - if (mxSlideShowController.is()) - { - mxSlideShowController->gotoPreviousEffect(); - } - break; - - case awt::Key::P: - if (mxSlideShowController.is()) - { - bool bPenEnabled = mxSlideShowController->getUsePen(); - mxSlideShowController->setUsePen( !bPenEnabled ); - } - break; - - case awt::Key::E: - if (mxSlideShowController.is()) - { - mxSlideShowController->setEraseAllInk( true ); - } - break; - - case awt::Key::HOME: - if (mxSlideShowController.is()) - { - mxSlideShowController->gotoFirstSlide(); - } - break; - - case awt::Key::END: - if (mxSlideShowController.is()) - { - mxSlideShowController->gotoLastSlide(); - } - break; - - case awt::Key::W: - case awt::Key::COMMA: - if (mxSlideShowController.is()) - { - if (mxSlideShowController->isPaused()) - mxSlideShowController->resume(); - else - mxSlideShowController->blankScreen(0x00ffffff); - } - break; - - case awt::Key::B: - case awt::Key::POINT: - if (mxSlideShowController.is()) - { - if (mxSlideShowController->isPaused()) - mxSlideShowController->resume(); - else - mxSlideShowController->blankScreen(0x00000000); - } - break; - - case awt::Key::NUM0: - case awt::Key::NUM1: - case awt::Key::NUM2: - case awt::Key::NUM3: - case awt::Key::NUM4: - case awt::Key::NUM5: - case awt::Key::NUM6: - case awt::Key::NUM7: - case awt::Key::NUM8: - case awt::Key::NUM9: - HandleNumericKeyPress(rEvent.KeyCode-awt::Key::NUM0, rEvent.Modifiers); - break; - - case awt::Key::RETURN: - if (mnPendingSlideNumber > 0) - { - if (mxSlideShowController.is()) - mxSlideShowController->gotoSlideIndex(mnPendingSlideNumber - 1); - mnPendingSlideNumber = -1; - } - else - { - if (mxSlideShowController.is()) - mxSlideShowController->gotoNextEffect(); - } - - break; - - case awt::Key::F1: - // Toggle the help view. - if (mpWindowManager) - { - if (mpWindowManager->GetViewMode() != PresenterWindowManager::VM_Help) - mpWindowManager->SetViewMode(PresenterWindowManager::VM_Help); - else - mpWindowManager->SetHelpViewState(false); - } - - break; - - default: - // Tell all views about the unhandled key event. - for (const auto& rxPane : mpPaneContainer->maPanes) - { - if ( ! rxPane->mbIsActive) - continue; - - Reference<awt::XKeyListener> xKeyListener (rxPane->mxView, UNO_QUERY); - if (xKeyListener.is()) - xKeyListener->keyReleased(rEvent); - } - break; - } -} - -void PresenterController::HandleNumericKeyPress ( - const sal_Int32 nKey, - const sal_Int32 nModifiers) -{ - switch (nModifiers) - { - case 0: - if (mnPendingSlideNumber == -1) - mnPendingSlideNumber = 0; - UpdatePendingSlideNumber(mnPendingSlideNumber * 10 + nKey); - break; - - case awt::KeyModifier::MOD1: - // Ctrl-1, Ctrl-2, and Ctrl-3 are used to switch between views - // (slide view, notes view, normal). Ctrl-4 switches monitors - mnPendingSlideNumber = -1; - if (!mpWindowManager) - return; - switch(nKey) - { - case 1: - mpWindowManager->SetViewMode(PresenterWindowManager::VM_Standard); - break; - case 2: - mpWindowManager->SetViewMode(PresenterWindowManager::VM_Notes); - break; - case 3: - mpWindowManager->SetViewMode(PresenterWindowManager::VM_SlideOverview); - break; - case 4: - SwitchMonitors(); - break; - default: - // Ignore unsupported key. - break; - } - break; - - default: - // Ignore unsupported modifiers. - break; - } -} - -//----- XMouseListener -------------------------------------------------------- - -void SAL_CALL PresenterController::mousePressed (const css::awt::MouseEvent&) -{ - if (mxMainWindow.is()) - mxMainWindow->setFocus(); -} - -void SAL_CALL PresenterController::mouseReleased (const css::awt::MouseEvent&) {} - -void SAL_CALL PresenterController::mouseEntered (const css::awt::MouseEvent&) {} - -void SAL_CALL PresenterController::mouseExited (const css::awt::MouseEvent&) {} - -void PresenterController::InitializeMainPane (const Reference<XPane>& rxPane) -{ - if ( ! rxPane.is()) - return; - - mpAccessibleObject = new PresenterAccessible( - mxComponentContext, - this, - rxPane); - - LoadTheme(rxPane); - - // Main pane has been created and is now observed by the window - // manager. - mpWindowManager->SetParentPane(rxPane); - mpWindowManager->SetTheme(mpTheme); - - if (mpPaneBorderPainter) - mpPaneBorderPainter->SetTheme(mpTheme); - - // Add key listener - mxMainWindow = rxPane->getWindow(); - if (mxMainWindow.is()) - { - mxMainWindow->addKeyListener(this); - mxMainWindow->addMouseListener(this); - } - Reference<XPane2> xPane2 (rxPane, UNO_QUERY); - if (xPane2.is()) - xPane2->setVisible(true); - - mpPaintManager = std::make_shared<PresenterPaintManager>(mxMainWindow, mxPresenterHelper, mpPaneContainer); - - mxCanvas.set(rxPane->getCanvas(), UNO_QUERY); - - if (mxSlideShowController.is()) - mxSlideShowController->activate(); - - UpdateCurrentSlide(0); -} - -void PresenterController::LoadTheme (const Reference<XPane>& rxPane) -{ - // Create (load) the current theme. - if (rxPane.is()) - mpTheme = std::make_shared<PresenterTheme>(mxComponentContext, rxPane->getCanvas()); -} - -double PresenterController::GetSlideAspectRatio() const -{ - double nSlideAspectRatio (28.0/21.0); - - try - { - if (mxController.is()) - { - Reference<drawing::XDrawPagesSupplier> xSlideSupplier ( - mxController->getModel(), UNO_QUERY_THROW); - Reference<drawing::XDrawPages> xSlides (xSlideSupplier->getDrawPages()); - if (xSlides.is() && xSlides->getCount()>0) - { - Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW); - sal_Int32 nWidth (28000); - sal_Int32 nHeight (21000); - if ((xProperties->getPropertyValue("Width") >>= nWidth) - && (xProperties->getPropertyValue("Height") >>= nHeight) - && nHeight > 0) - { - nSlideAspectRatio = double(nWidth) / double(nHeight); - } - } - } - } - catch (RuntimeException&) - { - OSL_ASSERT(false); - } - - return nSlideAspectRatio; -} - -void PresenterController::UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber) -{ - mnPendingSlideNumber = nPendingSlideNumber; - - if (mpTheme == nullptr) - return; - - if ( ! mxMainWindow.is()) - return; - - PresenterTheme::SharedFontDescriptor pFont ( - mpTheme->GetFont("PendingSlideNumberFont")); - if (!pFont) - return; - - pFont->PrepareFont(mxCanvas); - if ( ! pFont->mxFont.is()) - return; - - const OUString sText (OUString::number(mnPendingSlideNumber)); - rendering::StringContext aContext (sText, 0, sText.getLength()); - pFont->mxFont->createTextLayout( - aContext, - rendering::TextDirection::WEAK_LEFT_TO_RIGHT, - 0); -} - -void PresenterController::SwitchMonitors() -{ - Reference<lang::XEventListener> xScreen( mxScreen ); - if (!xScreen.is()) - return; - - PresenterScreen *pScreen = dynamic_cast<PresenterScreen *>(xScreen.get()); - if (!pScreen) - return; - - pScreen->SwitchMonitors(); -} - -void PresenterController::ExitPresenter() -{ - if( mxController.is() ) - { - Reference< XPresentationSupplier > xPS( mxController->getModel(), UNO_QUERY ); - if( xPS.is() ) - { - Reference< XPresentation > xP( xPS->getPresentation() ); - if( xP.is() ) - xP->end(); - } - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterController.hxx b/sdext/source/presenter/PresenterController.hxx deleted file mode 100644 index 1a9d8a1aaa04..000000000000 --- a/sdext/source/presenter/PresenterController.hxx +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCONTROLLER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCONTROLLER_HXX - -#include "PresenterAccessibility.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterTheme.hxx" -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <com/sun/star/awt/XKeyListener.hpp> -#include <com/sun/star/awt/XMouseListener.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/frame/XDispatch.hpp> -#include <com/sun/star/presentation/XSlideShowController.hpp> -#include <com/sun/star/frame/XFrameActionListener.hpp> -#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/util/XURLTransformer.hpp> -#include <rtl/ref.hxx> -#include <map> -#include <memory> - -namespace sdext::presenter { - -class PresenterCanvasHelper; -class PresenterPaintManager; -class PresenterPaneAnimator; -class PresenterPaneContainer; -class PresenterPaneBorderPainter; -class PresenterTheme; -class PresenterWindowManager; - -typedef ::cppu::WeakComponentImplHelper < - css::drawing::framework::XConfigurationChangeListener, - css::frame::XFrameActionListener, - css::awt::XKeyListener, - css::awt::XMouseListener -> PresenterControllerInterfaceBase; - -/// Represents an element in the toolbar that shows the time elapsed since the presentation started. -class IPresentationTime -{ -public: - virtual void restart() = 0; - virtual bool isPaused() = 0; - virtual void setPauseStatus(const bool pauseStatus) = 0; - virtual ~IPresentationTime(); -}; - -/** The controller of the presenter screen is responsible for telling the - individual views which slides to show. Additionally it provides access - to frequently used values of the current theme. -*/ -class PresenterController - : protected ::cppu::BaseMutex, - public PresenterControllerInterfaceBase -{ -public: - static ::rtl::Reference<PresenterController> Instance ( - const css::uno::Reference<css::frame::XFrame>& rxFrame); - - PresenterController ( - const css::uno::WeakReference<css::lang::XEventListener> &rxScreen, - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XController>& rxController, - const css::uno::Reference<css::presentation::XSlideShowController>& rxSlideShowController, - const rtl::Reference<PresenterPaneContainer>& rpPaneContainer, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxMainPaneId); - virtual ~PresenterController() override; - - virtual void SAL_CALL disposing() override; - - void UpdateCurrentSlide (const sal_Int32 nOffset); - - SharedBitmapDescriptor - GetViewBackground (const OUString& rsViewURL) const; - PresenterTheme::SharedFontDescriptor - GetViewFont (const OUString& rsViewURL) const; - const std::shared_ptr<PresenterTheme>& GetTheme() const; - const ::rtl::Reference<PresenterWindowManager>& GetWindowManager() const; - const css::uno::Reference<css::presentation::XSlideShowController>& - GetSlideShowController() const; - const rtl::Reference<PresenterPaneContainer>& GetPaneContainer() const; - const ::rtl::Reference<PresenterPaneBorderPainter>& GetPaneBorderPainter() const; - const std::shared_ptr<PresenterCanvasHelper>& GetCanvasHelper() const; - const css::uno::Reference<css::drawing::XPresenterHelper>& GetPresenterHelper() const; - const std::shared_ptr<PresenterPaintManager>& GetPaintManager() const; - double GetSlideAspectRatio() const; - void ShowView (const OUString& rsViewURL); - void HideView (const OUString& rsViewURL); - void SwitchMonitors(); - void ExitPresenter(); - void DispatchUnoCommand (const OUString& rsCommand) const; - css::uno::Reference<css::frame::XDispatch> GetDispatch ( - const css::util::URL& rURL) const; - css::util::URL CreateURLFromString (const OUString& rsURL) const; - const css::uno::Reference<css::drawing::framework::XConfigurationController>& - GetConfigurationController() const; - const css::uno::Reference<css::drawing::XDrawPage>& GetCurrentSlide() const; - static bool HasTransition (css::uno::Reference<css::drawing::XDrawPage> const & rxPage); - static bool HasCustomAnimation (css::uno::Reference<css::drawing::XDrawPage> const & rxPage); - void SetAccessibilityActiveState (const bool bIsActive); - bool IsAccessibilityActive() const { return mbIsAccessibilityActive;} - - void HandleMouseClick (const css::awt::MouseEvent& rEvent); - void UpdatePaneTitles(); - - /** Request activation or deactivation of (some of) the views according - to the given parameters. - */ - void RequestViews ( - const bool bIsSlideSorterActive, - const bool bIsNotesViewActive, - const bool bIsHelpViewActive); - - void SetPresentationTime(IPresentationTime* pPresentationTime); - IPresentationTime* GetPresentationTime(); - - // XConfigurationChangeListener - - virtual void SAL_CALL notifyConfigurationChange ( - const css::drawing::framework::ConfigurationChangeEvent& rEvent) override; - - // XEventListener - - virtual void SAL_CALL disposing ( - const css::lang::EventObject& rEvent) override; - - // XFrameActionListener - - virtual void SAL_CALL frameAction ( - const css::frame::FrameActionEvent& rEvent) override; - - // XKeyListener - - virtual void SAL_CALL keyPressed (const css::awt::KeyEvent& rEvent) override; - virtual void SAL_CALL keyReleased (const css::awt::KeyEvent& rEvent) override; - - // XMouseListener - - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - -private: - typedef ::std::map<css::uno::Reference<css::frame::XFrame>,rtl::Reference<PresenterController> > InstanceContainer; - static InstanceContainer maInstances; - - css::uno::WeakReference<css::lang::XEventListener> mxScreen; - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - css::uno::Reference<css::rendering::XSpriteCanvas> mxCanvas; - css::uno::Reference<css::frame::XController> mxController; - css::uno::Reference<css::drawing::framework::XConfigurationController> - mxConfigurationController; - css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController; - css::uno::Reference<css::drawing::framework::XResourceId> mxMainPaneId; - rtl::Reference<PresenterPaneContainer> mpPaneContainer; - sal_Int32 mnCurrentSlideIndex; - css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide; - css::uno::Reference<css::drawing::XDrawPage> mxNextSlide; - ::rtl::Reference<PresenterWindowManager> mpWindowManager; - std::shared_ptr<PresenterTheme> mpTheme; - css::uno::Reference<css::awt::XWindow> mxMainWindow; - ::rtl::Reference<PresenterPaneBorderPainter> mpPaneBorderPainter; - std::shared_ptr<PresenterCanvasHelper> mpCanvasHelper; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - std::shared_ptr<PresenterPaintManager> mpPaintManager; - sal_Int32 mnPendingSlideNumber; - css::uno::Reference<css::util::XURLTransformer> mxUrlTransformer; - ::rtl::Reference<PresenterAccessible> mpAccessibleObject; - bool mbIsAccessibilityActive; - IPresentationTime* mpPresentationTime; - - void GetSlides (const sal_Int32 nOffset); - void UpdateViews(); - void InitializeMainPane (const css::uno::Reference<css::drawing::framework::XPane>& rxPane); - void LoadTheme (const css::uno::Reference<css::drawing::framework::XPane>& rxPane); - void UpdatePendingSlideNumber (const sal_Int32 nPendingSlideNumber); - - /** This method is called when the user pressed one of the numerical - keys. Depending on the modifier, numeric keys switch to another - slide (no modifier), or change to another view (Ctrl modifier). - @param nKey - Numeric value that is printed on the pressed key. For example - pressing the key '4' will result in the value 4, not the ASCII - code (0x34?). - @param nModifiers - The modifier bit field as provided by the key up event. - */ - void HandleNumericKeyPress (const sal_Int32 nKey, const sal_Int32 nModifiers); -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterCurrentSlideObserver.cxx b/sdext/source/presenter/PresenterCurrentSlideObserver.cxx deleted file mode 100644 index 0cd33d9c0beb..000000000000 --- a/sdext/source/presenter/PresenterCurrentSlideObserver.cxx +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterCurrentSlideObserver.hxx" - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -//===== PresenterCurrentSlideObserver ========================================= - -PresenterCurrentSlideObserver::PresenterCurrentSlideObserver ( - const ::rtl::Reference<PresenterController>& rxPresenterController, - const Reference<presentation::XSlideShowController>& rxSlideShowController) - : PresenterCurrentSlideObserverInterfaceBase(m_aMutex), - mpPresenterController(rxPresenterController), - mxSlideShowController(rxSlideShowController) -{ - if( mpPresenterController.is() ) - { - mpPresenterController->addEventListener(this); - } - - if( mxSlideShowController.is() ) - { - // Listen for events from the slide show controller. - mxSlideShowController->addSlideShowListener(static_cast<XSlideShowListener*>(this)); - } -} - -PresenterCurrentSlideObserver::~PresenterCurrentSlideObserver() -{ -} - -void SAL_CALL PresenterCurrentSlideObserver::disposing() -{ - // Disconnect form the slide show controller. - if(mxSlideShowController.is()) - { - mxSlideShowController->removeSlideShowListener(static_cast<XSlideShowListener*>(this)); - mxSlideShowController = nullptr; - } - - if (mpPresenterController.is()) - mpPresenterController->removeEventListener(this); -} - -//----- XSlideShowListener ---------------------------------------------------- - -void SAL_CALL PresenterCurrentSlideObserver::beginEvent ( - const Reference<animations::XAnimationNode>&) -{} - -void SAL_CALL PresenterCurrentSlideObserver::endEvent ( - const Reference<animations::XAnimationNode>&) -{} - -void SAL_CALL PresenterCurrentSlideObserver::repeat ( - const css::uno::Reference<css::animations::XAnimationNode>&, - sal_Int32) -{} - -void SAL_CALL PresenterCurrentSlideObserver::paused() -{ -} - -void SAL_CALL PresenterCurrentSlideObserver::resumed() -{ -} - -void SAL_CALL PresenterCurrentSlideObserver::slideEnded (sal_Bool bReverse) -{ - // Determine whether the new current slide (the one after the one that - // just ended) is the slide past the last slide in the presentation, - // i.e. the one that says something like "click to end presentation...". - if (mxSlideShowController.is() && !bReverse) - if (mxSlideShowController->getNextSlideIndex() < 0) - if( mpPresenterController.is() ) - mpPresenterController->UpdateCurrentSlide(+1); -} - -void SAL_CALL PresenterCurrentSlideObserver::hyperLinkClicked (const OUString &) -{ -} - -void SAL_CALL PresenterCurrentSlideObserver::slideTransitionStarted() -{ - if( mpPresenterController.is() ) - mpPresenterController->UpdateCurrentSlide(0); -} - -void SAL_CALL PresenterCurrentSlideObserver::slideTransitionEnded() -{ -} - -void SAL_CALL PresenterCurrentSlideObserver::slideAnimationsEnded() -{ -} - -//----- XEventListener -------------------------------------------------------- - -void SAL_CALL PresenterCurrentSlideObserver::disposing ( - const lang::EventObject& rEvent) -{ - if (rEvent.Source == Reference<XInterface>(static_cast<XWeak*>(mpPresenterController.get()))) - dispose(); - else if (rEvent.Source == mxSlideShowController) - mxSlideShowController = nullptr; -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterCurrentSlideObserver.hxx b/sdext/source/presenter/PresenterCurrentSlideObserver.hxx deleted file mode 100644 index 786744bfb8b8..000000000000 --- a/sdext/source/presenter/PresenterCurrentSlideObserver.hxx +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCURRENTSLIDEOBSERVER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCURRENTSLIDEOBSERVER_HXX - -#include "PresenterController.hxx" -#include <com/sun/star/presentation/XSlideShowController.hpp> -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <rtl/ref.hxx> - -namespace sdext::presenter { - -typedef ::cppu::WeakComponentImplHelper < - css::presentation::XSlideShowListener -> PresenterCurrentSlideObserverInterfaceBase; - -/** Check periodically the slide show controller and the - frame::XController whether the current slide has changed. If so, - then inform the presenter controller about it. - - Objects of this class have their own lifetime control and destroy - themselves when the presenter controller is disposed. -*/ -class PresenterCurrentSlideObserver - : protected ::cppu::BaseMutex, - public PresenterCurrentSlideObserverInterfaceBase -{ -public: - PresenterCurrentSlideObserver ( - const ::rtl::Reference<PresenterController>& rxPresenterController, - const css::uno::Reference<css::presentation::XSlideShowController>& rxSlideShowController); - virtual ~PresenterCurrentSlideObserver() override; - - virtual void SAL_CALL disposing() override; - - // XSlideShowListener - virtual void SAL_CALL paused( ) override; - virtual void SAL_CALL resumed( ) override; - virtual void SAL_CALL slideTransitionStarted( ) override; - virtual void SAL_CALL slideTransitionEnded( ) override; - virtual void SAL_CALL slideAnimationsEnded( ) override; - virtual void SAL_CALL slideEnded(sal_Bool bReverse) override; - virtual void SAL_CALL hyperLinkClicked( const OUString& hyperLink ) override; - - // XAnimationListener - virtual void SAL_CALL beginEvent( const css::uno::Reference< css::animations::XAnimationNode >& Node ) override; - virtual void SAL_CALL endEvent( const css::uno::Reference< css::animations::XAnimationNode >& Node ) override; - virtual void SAL_CALL repeat( const css::uno::Reference< css::animations::XAnimationNode >& Node, ::sal_Int32 Repeat ) override; - - // XEventListener - virtual void SAL_CALL disposing ( - const css::lang::EventObject& rEvent) override; - -private: - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController; -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterFrameworkObserver.cxx b/sdext/source/presenter/PresenterFrameworkObserver.cxx deleted file mode 100644 index 0f56da0b0566..000000000000 --- a/sdext/source/presenter/PresenterFrameworkObserver.cxx +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterFrameworkObserver.hxx" -#include <com/sun/star/lang/IllegalArgumentException.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - - -namespace sdext::presenter { - -PresenterFrameworkObserver::PresenterFrameworkObserver ( - const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController, - const Action& rAction) - : PresenterFrameworkObserverInterfaceBase(m_aMutex), - mxConfigurationController(rxController), - maAction(rAction) -{ - if ( ! mxConfigurationController.is()) - throw lang::IllegalArgumentException(); - - if (mxConfigurationController->hasPendingRequests()) - { - mxConfigurationController->addConfigurationChangeListener( - this, - "ConfigurationUpdateEnd", - Any()); - } - else - { - rAction(true); - } -} - -PresenterFrameworkObserver::~PresenterFrameworkObserver() -{ -} - -void PresenterFrameworkObserver::RunOnUpdateEnd ( - const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController, - const Action& rAction) -{ - new PresenterFrameworkObserver( - rxController, - rAction); -} - -void SAL_CALL PresenterFrameworkObserver::disposing() -{ - if (maAction) - maAction(false); - Shutdown(); -} - -void PresenterFrameworkObserver::Shutdown() -{ - maAction = Action(); - if (mxConfigurationController != nullptr) - { - mxConfigurationController->removeConfigurationChangeListener(this); - mxConfigurationController = nullptr; - } -} - -void SAL_CALL PresenterFrameworkObserver::disposing (const lang::EventObject& rEvent) -{ - if ( ! rEvent.Source.is()) - return; - - if (rEvent.Source == mxConfigurationController) - { - mxConfigurationController = nullptr; - if (maAction) - maAction(false); - } -} - -void SAL_CALL PresenterFrameworkObserver::notifyConfigurationChange ( - const ConfigurationChangeEvent& /*rEvent*/) -{ - Action aAction(maAction); - Shutdown(); - aAction(true); - - maAction = nullptr; - dispose(); -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterFrameworkObserver.hxx b/sdext/source/presenter/PresenterFrameworkObserver.hxx deleted file mode 100644 index bc4b4bda11d3..000000000000 --- a/sdext/source/presenter/PresenterFrameworkObserver.hxx +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERFRAMEWORKOBSERVER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERFRAMEWORKOBSERVER_HXX - -#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> - -#include <functional> - -namespace sdext::presenter { - -typedef ::cppu::WeakComponentImplHelper < - css::drawing::framework::XConfigurationChangeListener - > PresenterFrameworkObserverInterfaceBase; - -/** Watch the drawing framework for changes and run callbacks when a certain - change takes place. -*/ -class PresenterFrameworkObserver - : private ::cppu::BaseMutex, - public PresenterFrameworkObserverInterfaceBase -{ -public: - typedef ::std::function<void (bool)> Action; - - PresenterFrameworkObserver(const PresenterFrameworkObserver&) = delete; - PresenterFrameworkObserver& operator=(const PresenterFrameworkObserver&) = delete; - - static void RunOnUpdateEnd ( - const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController, - const Action& rAction); - - virtual void SAL_CALL disposing() override; - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - virtual void SAL_CALL notifyConfigurationChange ( - const css::drawing::framework::ConfigurationChangeEvent& rEvent) override; - -private: - css::uno::Reference<css::drawing::framework::XConfigurationController> mxConfigurationController; - Action maAction; - - /** Create a new PresenterFrameworkObserver object. - @param rPredicate - This functor tests whether the action is to be executed or not. - @param rAction - The functor to execute when the predicate returns true, - e.g. when some resource has been created. - */ - PresenterFrameworkObserver ( - const css::uno::Reference<css::drawing::framework::XConfigurationController>&rxController, - const Action& rAction); - virtual ~PresenterFrameworkObserver() override; - - void Shutdown(); -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterGeometryHelper.cxx b/sdext/source/presenter/PresenterGeometryHelper.cxx deleted file mode 100644 index 67a81d63c766..000000000000 --- a/sdext/source/presenter/PresenterGeometryHelper.cxx +++ /dev/null @@ -1,261 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterGeometryHelper.hxx" - -#include <math.h> -#include <algorithm> -#include <o3tl/safeint.hxx> - - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace { - -sal_Int32 Right (const awt::Rectangle& rBox) -{ - return rBox.X + rBox.Width - 1; -} - -sal_Int32 Bottom (const awt::Rectangle& rBox) -{ - return rBox.Y + rBox.Height - 1; -} - -sal_Int32 Width (const sal_Int32 nLeft, const sal_Int32 nRight) -{ - return nRight - nLeft + 1; -} - -sal_Int32 Height (const sal_Int32 nTop, const sal_Int32 nBottom) -{ - return nBottom - nTop + 1; -} - -} // end of anonymous namespace - -namespace sdext::presenter { - -sal_Int32 PresenterGeometryHelper::Floor (const double nValue) -{ - return sal::static_int_cast<sal_Int32>(floor(nValue)); -} - -sal_Int32 PresenterGeometryHelper::Ceil (const double nValue) -{ - return sal::static_int_cast<sal_Int32>(ceil(nValue)); -} - -sal_Int32 PresenterGeometryHelper::Round (const double nValue) -{ - return sal::static_int_cast<sal_Int32>(floor(0.5 + nValue)); -} - -awt::Rectangle PresenterGeometryHelper::ConvertRectangle ( - const geometry::RealRectangle2D& rBox) -{ - const sal_Int32 nLeft (Floor(rBox.X1)); - const sal_Int32 nTop (Floor(rBox.Y1)); - const sal_Int32 nRight (Ceil(rBox.X2)); - const sal_Int32 nBottom (Ceil(rBox.Y2)); - return awt::Rectangle (nLeft,nTop,nRight-nLeft,nBottom-nTop); -} - -awt::Rectangle PresenterGeometryHelper::ConvertRectangleWithConstantSize ( - const geometry::RealRectangle2D& rBox) -{ - return awt::Rectangle ( - Round(rBox.X1), - Round(rBox.Y1), - Round(rBox.X2 - rBox.X1), - Round(rBox.Y2 - rBox.Y1)); -} - -geometry::RealRectangle2D PresenterGeometryHelper::ConvertRectangle ( - const css::awt::Rectangle& rBox) -{ - return geometry::RealRectangle2D( - rBox.X, - rBox.Y, - rBox.X + rBox.Width, - rBox.Y + rBox.Height); -} - -awt::Rectangle PresenterGeometryHelper::TranslateRectangle ( - const css::awt::Rectangle& rBox, - const sal_Int32 nXOffset, - const sal_Int32 nYOffset) -{ - return awt::Rectangle(rBox.X + nXOffset, rBox.Y + nYOffset, rBox.Width, rBox.Height); -} - -awt::Rectangle PresenterGeometryHelper::Intersection ( - const css::awt::Rectangle& rBox1, - const css::awt::Rectangle& rBox2) -{ - const sal_Int32 nLeft (::std::max(rBox1.X, rBox2.X)); - const sal_Int32 nTop (::std::max(rBox1.Y, rBox2.Y)); - const sal_Int32 nRight (::std::min(Right(rBox1), Right(rBox2))); - const sal_Int32 nBottom (::std::min(Bottom(rBox1), Bottom(rBox2))); - if (nLeft >= nRight || nTop >= nBottom) - return awt::Rectangle(); - else - return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom)); -} - -geometry::RealRectangle2D PresenterGeometryHelper::Intersection ( - const geometry::RealRectangle2D& rBox1, - const geometry::RealRectangle2D& rBox2) -{ - const double nLeft (::std::max(rBox1.X1, rBox2.X1)); - const double nTop (::std::max(rBox1.Y1, rBox2.Y1)); - const double nRight (::std::min(rBox1.X2, rBox2.X2)); - const double nBottom (::std::min(rBox1.Y2, rBox2.Y2)); - if (nLeft >= nRight || nTop >= nBottom) - return geometry::RealRectangle2D(0,0,0,0); - else - return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom); -} - -bool PresenterGeometryHelper::IsInside ( - const css::geometry::RealRectangle2D& rBox, - const css::geometry::RealPoint2D& rPoint) -{ - return rBox.X1 <= rPoint.X - && rBox.Y1 <= rPoint.Y - && rBox.X2 >= rPoint.X - && rBox.Y2 >= rPoint.Y; -} - -bool PresenterGeometryHelper::IsInside ( - const css::awt::Rectangle& rBox1, - const css::awt::Rectangle& rBox2) -{ - return rBox1.X >= rBox2.X - && rBox1.Y >= rBox2.Y - && rBox1.X+rBox1.Width <= rBox2.X+rBox2.Width - && rBox1.Y+rBox1.Height <= rBox2.Y+rBox2.Height; -} - -geometry::RealRectangle2D PresenterGeometryHelper::Union ( - const geometry::RealRectangle2D& rBox1, - const geometry::RealRectangle2D& rBox2) -{ - const double nLeft (::std::min(rBox1.X1, rBox2.X1)); - const double nTop (::std::min(rBox1.Y1, rBox2.Y1)); - const double nRight (::std::max(rBox1.X2, rBox2.X2)); - const double nBottom (::std::max(rBox1.Y2, rBox2.Y2)); - if (nLeft >= nRight || nTop >= nBottom) - return geometry::RealRectangle2D(0,0,0,0); - else - return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom); -} - -bool PresenterGeometryHelper::AreRectanglesDisjoint ( - const css::awt::Rectangle& rBox1, - const css::awt::Rectangle& rBox2) -{ - return rBox1.X+rBox1.Width <= rBox2.X - || rBox1.Y+rBox1.Height <= rBox2.Y - || rBox1.X >= rBox2.X+rBox2.Width - || rBox1.Y >= rBox2.Y+rBox2.Height; -} - -Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon( - const awt::Rectangle& rBox, - const Reference<rendering::XGraphicDevice>& rxDevice) -{ - if ( ! rxDevice.is()) - return nullptr; - - Sequence<Sequence<geometry::RealPoint2D> > aPoints - { - { - { o3tl::narrowing<double>(rBox.X), o3tl::narrowing<double>(rBox.Y) }, - { o3tl::narrowing<double>(rBox.X), o3tl::narrowing<double>(rBox.Y+rBox.Height) }, - { o3tl::narrowing<double>(rBox.X+rBox.Width), o3tl::narrowing<double>(rBox.Y+rBox.Height) }, - { o3tl::narrowing<double>(rBox.X+rBox.Width), o3tl::narrowing<double>(rBox.Y) } - } - }; - Reference<rendering::XLinePolyPolygon2D> xPolygon ( - rxDevice->createCompatibleLinePolyPolygon(aPoints)); - if (xPolygon.is()) - xPolygon->setClosed(0, true); - - return xPolygon; -} - -Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon( - const geometry::RealRectangle2D& rBox, - const Reference<rendering::XGraphicDevice>& rxDevice) -{ - if ( ! rxDevice.is()) - return nullptr; - - Sequence<Sequence<geometry::RealPoint2D> > aPoints - { - { - { rBox.X1, rBox.Y1 }, - { rBox.X1, rBox.Y2 }, - { rBox.X2, rBox.Y2 }, - { rBox.X2, rBox.Y1 } - } - }; - Reference<rendering::XLinePolyPolygon2D> xPolygon ( - rxDevice->createCompatibleLinePolyPolygon(aPoints)); - if (xPolygon.is()) - xPolygon->setClosed(0, true); - - return xPolygon; -} - -Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon( - const ::std::vector<css::awt::Rectangle>& rBoxes, - const Reference<rendering::XGraphicDevice>& rxDevice) -{ - if ( ! rxDevice.is()) - return nullptr; - - const sal_Int32 nCount (rBoxes.size()); - Sequence<Sequence<geometry::RealPoint2D> > aPoints(nCount); - for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) - { - const awt::Rectangle& rBox (rBoxes[nIndex]); - aPoints[nIndex] = Sequence<geometry::RealPoint2D> - { - { o3tl::narrowing<double>(rBox.X), o3tl::narrowing<double>(rBox.Y) }, - { o3tl::narrowing<double>(rBox.X), o3tl::narrowing<double>(rBox.Y+rBox.Height) }, - { o3tl::narrowing<double>(rBox.X+rBox.Width), o3tl::narrowing<double>(rBox.Y+rBox.Height) }, - { o3tl::narrowing<double>(rBox.X+rBox.Width), o3tl::narrowing<double>(rBox.Y) } - }; - } - - Reference<rendering::XLinePolyPolygon2D> xPolygon ( - rxDevice->createCompatibleLinePolyPolygon(aPoints)); - if (xPolygon.is()) - for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) - xPolygon->setClosed(nIndex, true); - - return xPolygon; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterGeometryHelper.hxx b/sdext/source/presenter/PresenterGeometryHelper.hxx deleted file mode 100644 index c2f55757e9da..000000000000 --- a/sdext/source/presenter/PresenterGeometryHelper.hxx +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERGEOMETRYHELPER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERGEOMETRYHELPER_HXX - -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/rendering/XGraphicDevice.hpp> -#include <com/sun/star/rendering/XPolyPolygon2D.hpp> -#include <com/sun/star/geometry/RealRectangle2D.hpp> -#include <vector> - -namespace sdext::presenter { - -/** Collection of geometry related convenience functions. -*/ -class PresenterGeometryHelper -{ -public: - static sal_Int32 Round (const double nValue); - static sal_Int32 Floor (const double nValue); - static sal_Int32 Ceil (const double nValue); - - /** Return the bounding box with integer coordinates of the given - rectangle. Note that due to different rounding of the left/top and - the right/bottom border the width of the resulting rectangle may - differ for different positions but constant width and height. - */ - static css::awt::Rectangle ConvertRectangle ( - const css::geometry::RealRectangle2D& rBox); - - /** Convert the given rectangle to integer coordinates so that width and - height remain constant when only the position changes. - */ - static css::awt::Rectangle ConvertRectangleWithConstantSize ( - const css::geometry::RealRectangle2D& rBox); - - static css::geometry::RealRectangle2D ConvertRectangle ( - const css::awt::Rectangle& rBox); - - // static css::awt::Size ConvertSize ( - // const css::geometry::RealSize2D& rSize); - - static css::awt::Rectangle TranslateRectangle ( - const css::awt::Rectangle& rBox, - const sal_Int32 nXOffset, - const sal_Int32 nYOffset); - - static css::awt::Rectangle Intersection ( - const css::awt::Rectangle& rBox1, - const css::awt::Rectangle& rBox2); - - static css::geometry::RealRectangle2D Intersection ( - const css::geometry::RealRectangle2D& rBox1, - const css::geometry::RealRectangle2D& rBox2); - - static bool IsInside ( - const css::geometry::RealRectangle2D& rBox, - const css::geometry::RealPoint2D& rPoint); - - /** Return whether rBox1 is completely inside rBox2. - */ - static bool IsInside ( - const css::awt::Rectangle& rBox1, - const css::awt::Rectangle& rBox2); - - static css::geometry::RealRectangle2D Union ( - const css::geometry::RealRectangle2D& rBox1, - const css::geometry::RealRectangle2D& rBox2); - - static bool AreRectanglesDisjoint ( - const css::awt::Rectangle& rBox1, - const css::awt::Rectangle& rBox2); - - static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon( - const css::awt::Rectangle& rBox, - const css::uno::Reference<css::rendering::XGraphicDevice>& rxDevice); - - static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon( - const css::geometry::RealRectangle2D& rBox, - const css::uno::Reference<css::rendering::XGraphicDevice>& rxDevice); - - static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon( - const ::std::vector<css::awt::Rectangle>& rBoxes, - const css::uno::Reference<css::rendering::XGraphicDevice>& rxDevice); - - /** Create a polygon for a rounded rectangle. - */ - /* static css::uno::Reference<css::rendering::XPolyPolygon2D> CreatePolygon( - const css::awt::Rectangle& rBox, - const double nRadius, - const css::uno::Reference<css::rendering::XGraphicDevice>& - rxDevice); - */ -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterHelpView.cxx b/sdext/source/presenter/PresenterHelpView.cxx deleted file mode 100644 index d6b625e53183..000000000000 --- a/sdext/source/presenter/PresenterHelpView.cxx +++ /dev/null @@ -1,755 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <vcl/settings.hxx> -#include "PresenterHelpView.hxx" -#include "PresenterButton.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/util/Color.hpp> -#include <algorithm> -#include <numeric> -#include <string_view> -#include <vector> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; -using ::std::vector; - -namespace sdext::presenter { - -namespace { - const sal_Int32 gnHorizontalGap (20); - const sal_Int32 gnVerticalBorder (30); - const sal_Int32 gnVerticalButtonPadding (12); - - class LineDescriptor - { - public: - LineDescriptor(); - void AddPart ( - std::u16string_view rsLine, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont); - bool IsEmpty() const; - - OUString msLine; - geometry::RealSize2D maSize; - double mnVerticalOffset; - - void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont); - }; - - class LineDescriptorList - { - public: - LineDescriptorList ( - const OUString& rsText, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth); - - void Update ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth); - - double Paint( - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::RealRectangle2D& rBBox, - const bool bFlushLeft, - const rendering::ViewState& rViewState, - rendering::RenderState& rRenderState, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const; - double GetHeight() const; - - private: - const OUString msText; - std::shared_ptr<vector<LineDescriptor> > mpLineDescriptors; - - static void SplitText (const OUString& rsText, vector<OUString>& rTextParts); - void FormatText ( - const vector<OUString>& rTextParts, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth); - }; - - class Block - { - public: - Block ( - const OUString& rsLeftText, - const OUString& rsRightText, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth); - Block(const Block&) = delete; - Block& operator=(const Block&) = delete; - void Update ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth); - - LineDescriptorList maLeft; - LineDescriptorList maRight; - }; -} // end of anonymous namespace - -class PresenterHelpView::TextContainer : public vector<std::shared_ptr<Block> > -{ -}; - -PresenterHelpView::PresenterHelpView ( - const Reference<uno::XComponentContext>& rxContext, - const Reference<XResourceId>& rxViewId, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterHelpViewInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - mxViewId(rxViewId), - mxPane(), - mxWindow(), - mxCanvas(), - mpPresenterController(rpPresenterController), - mpFont(), - mpTextContainer(), - mpCloseButton(), - mnSeparatorY(0), - mnMaximalWidth(0) -{ - try - { - // Get the content window via the pane anchor. - Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); - Reference<XConfigurationController> xCC ( - xCM->getConfigurationController(), UNO_SET_THROW); - mxPane.set(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW); - - mxWindow = mxPane->getWindow(); - ProvideCanvas(); - - mxWindow->addWindowListener(this); - mxWindow->addPaintListener(this); - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->setBackground(util::Color(0xff000000)); - mxWindow->setVisible(true); - - if (mpPresenterController.is()) - { - mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL()); - if (mpFont) - { - mpFont->PrepareFont(mxCanvas); - } - } - - // Create the close button. - mpCloseButton = PresenterButton::Create( - mxComponentContext, - mpPresenterController, - mpPresenterController->GetTheme(), - mxWindow, - mxCanvas, - "HelpViewCloser"); - - ReadHelpStrings(); - Resize(); - } - catch (RuntimeException&) - { - mxViewId = nullptr; - mxWindow = nullptr; - throw; - } -} - -PresenterHelpView::~PresenterHelpView() -{ -} - -void SAL_CALL PresenterHelpView::disposing() -{ - mxViewId = nullptr; - - if (mpCloseButton.is()) - { - Reference<lang::XComponent> xComponent ( - static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY); - mpCloseButton = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - if (mxWindow.is()) - { - mxWindow->removeWindowListener(this); - mxWindow->removePaintListener(this); - } -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterHelpView::disposing (const lang::EventObject& rEventObject) -{ - if (rEventObject.Source == mxCanvas) - { - mxCanvas = nullptr; - } - else if (rEventObject.Source == mxWindow) - { - mxWindow = nullptr; - dispose(); - } -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterHelpView::windowResized (const awt::WindowEvent&) -{ - ThrowIfDisposed(); - Resize(); -} - -void SAL_CALL PresenterHelpView::windowMoved (const awt::WindowEvent&) -{ - ThrowIfDisposed(); -} - -void SAL_CALL PresenterHelpView::windowShown (const lang::EventObject&) -{ - ThrowIfDisposed(); - Resize(); -} - -void SAL_CALL PresenterHelpView::windowHidden (const lang::EventObject&) -{ - ThrowIfDisposed(); -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent) -{ - Paint(rEvent.UpdateRect); -} - -void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox) -{ - ProvideCanvas(); - if ( ! mxCanvas.is()) - return; - - // Clear background. - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - mpPresenterController->GetCanvasHelper()->Paint( - mpPresenterController->GetViewBackground(mxViewId->getResourceURL()), - mxCanvas, - rUpdateBox, - awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height), - awt::Rectangle()); - - // Paint vertical divider. - - rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice())); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor); - - mxCanvas->drawLine( - geometry::RealPoint2D((aWindowBox.Width/2.0), gnVerticalBorder), - geometry::RealPoint2D((aWindowBox.Width/2.0), mnSeparatorY - gnVerticalBorder), - aViewState, - aRenderState); - - // Paint the horizontal separator. - mxCanvas->drawLine( - geometry::RealPoint2D(0, mnSeparatorY), - geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY), - aViewState, - aRenderState); - - // Paint text. - double nY (gnVerticalBorder); - for (const auto& rxBlock : *mpTextContainer) - { - sal_Int32 LeftX1 = gnHorizontalGap; - sal_Int32 LeftX2 = aWindowBox.Width/2 - gnHorizontalGap; - sal_Int32 RightX1 = aWindowBox.Width/2 + gnHorizontalGap; - sal_Int32 RightX2 = aWindowBox.Width - gnHorizontalGap; - /* check whether RTL interface or not - then replace the windowbox position */ - if(AllSettings::GetLayoutRTL()) - { - LeftX1 = aWindowBox.Width/2 + gnHorizontalGap; - LeftX2 = aWindowBox.Width - gnHorizontalGap; - RightX1 = gnHorizontalGap; - RightX2 = aWindowBox.Width/2 - gnHorizontalGap; - } - const double nLeftHeight ( - rxBlock->maLeft.Paint(mxCanvas, - geometry::RealRectangle2D( - LeftX1, - nY, - LeftX2, - aWindowBox.Height - gnVerticalBorder), - false, - aViewState, - aRenderState, - mpFont->mxFont)); - const double nRightHeight ( - rxBlock->maRight.Paint(mxCanvas, - geometry::RealRectangle2D( - RightX1, - nY, - RightX2, - aWindowBox.Height - gnVerticalBorder), - true, - aViewState, - aRenderState, - mpFont->mxFont)); - - nY += ::std::max(nLeftHeight,nRightHeight); - } - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -void PresenterHelpView::ReadHelpStrings() -{ - mpTextContainer.reset(new TextContainer); - PresenterConfigurationAccess aConfiguration ( - mxComponentContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - Reference<container::XNameAccess> xStrings ( - aConfiguration.GetConfigurationNode("PresenterScreenSettings/HelpView/HelpStrings"), - UNO_QUERY); - PresenterConfigurationAccess::ForAll( - xStrings, - [this](OUString const&, uno::Reference<beans::XPropertySet> const& xProps) - { - return this->ProcessString(xProps); - }); -} - -void PresenterHelpView::ProcessString ( - const Reference<beans::XPropertySet>& rsProperties) -{ - if ( ! rsProperties.is()) - return; - - OUString sLeftText; - PresenterConfigurationAccess::GetProperty(rsProperties, "Left") >>= sLeftText; - OUString sRightText; - PresenterConfigurationAccess::GetProperty(rsProperties, "Right") >>= sRightText; - mpTextContainer->push_back( - std::make_shared<Block>( - sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)); -} - -void PresenterHelpView::CheckFontSize() -{ - if (!mpFont) - return; - - sal_Int32 nBestSize (6); - - // Scaling down and then reformatting can cause the text to be too large - // still. So do this again and again until the text size is - // small enough. Restrict the number of loops. - for (int nLoopCount=0; nLoopCount<5; ++nLoopCount) - { - double nY = std::accumulate(mpTextContainer->begin(), mpTextContainer->end(), double(0), - [](const double& sum, const std::shared_ptr<Block>& rxBlock) { - return sum + std::max( - rxBlock->maLeft.GetHeight(), - rxBlock->maRight.GetHeight()); - }); - - const double nHeightDifference (nY - (mnSeparatorY-gnVerticalBorder)); - if (nHeightDifference <= 0 && nHeightDifference > -50) - { - // We have found a good font size that is large and leaves not - // too much space below the help text. - return; - } - - // Use a simple linear transformation to calculate initial guess of - // a size that lets all help text be shown inside the window. - const double nScale (double(mnSeparatorY-gnVerticalBorder) / nY); - if (nScale > 1.0 && nScale < 1.05) - break; - - sal_Int32 nFontSizeGuess (sal_Int32(mpFont->mnSize * nScale)); - if (nHeightDifference<=0 && mpFont->mnSize>nBestSize) - nBestSize = mpFont->mnSize; - mpFont->mnSize = nFontSizeGuess; - mpFont->mxFont = nullptr; - mpFont->PrepareFont(mxCanvas); - - // Reformat blocks. - for (auto& rxBlock : *mpTextContainer) - rxBlock->Update(mpFont->mxFont, mnMaximalWidth); - } - - if (nBestSize != mpFont->mnSize) - { - mpFont->mnSize = nBestSize; - mpFont->mxFont = nullptr; - mpFont->PrepareFont(mxCanvas); - - // Reformat blocks. - for (auto& rxBlock : *mpTextContainer) - { - rxBlock->Update(mpFont->mxFont, mnMaximalWidth); - } - } -} - -//----- XResourceId ----------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterHelpView::getResourceId() -{ - ThrowIfDisposed(); - return mxViewId; -} - -sal_Bool SAL_CALL PresenterHelpView::isAnchorOnly() -{ - return false; -} - - -void PresenterHelpView::ProvideCanvas() -{ - if ( ! mxCanvas.is() && mxPane.is()) - { - mxCanvas = mxPane->getCanvas(); - if ( ! mxCanvas.is()) - return; - Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY); - if (xComponent.is()) - xComponent->addEventListener(static_cast<awt::XPaintListener*>(this)); - - if (mpCloseButton.is()) - mpCloseButton->SetCanvas(mxCanvas, mxWindow); - } -} - -void PresenterHelpView::Resize() -{ - if (!(mpCloseButton && mxWindow.is())) - return; - - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2; - - // Place vertical separator. - mnSeparatorY = aWindowBox.Height - - mpCloseButton->GetSize().Height - gnVerticalButtonPadding; - - mpCloseButton->SetCenter(geometry::RealPoint2D( - aWindowBox.Width/2.0, - aWindowBox.Height - mpCloseButton->GetSize().Height/2.0)); - - CheckFontSize(); -} - -void PresenterHelpView::ThrowIfDisposed() -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterHelpView has been already disposed", - static_cast<uno::XWeak*>(this)); - } -} - -//===== LineDescriptor ========================================================= - -namespace { - -LineDescriptor::LineDescriptor() - : msLine(), - maSize(0,0), - mnVerticalOffset(0) -{ -} - -void LineDescriptor::AddPart ( - std::u16string_view rsLine, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) -{ - msLine += rsLine; - - CalculateSize(rxFont); -} - -bool LineDescriptor::IsEmpty() const -{ - return msLine.isEmpty(); -} - -void LineDescriptor::CalculateSize ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) -{ - OSL_ASSERT(rxFont.is()); - - rendering::StringContext aContext (msLine, 0, msLine.getLength()); - Reference<rendering::XTextLayout> xLayout ( - rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0)); - const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds()); - maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1); - mnVerticalOffset = aTextBBox.Y2; -} - -} // end of anonymous namespace - -//===== LineDescriptorList ==================================================== - -namespace { - -LineDescriptorList::LineDescriptorList ( - const OUString& rsText, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth) - : msText(rsText) -{ - Update(rxFont, nMaximalWidth); -} - -double LineDescriptorList::Paint( - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::RealRectangle2D& rBBox, - const bool bFlushLeft, - const rendering::ViewState& rViewState, - rendering::RenderState& rRenderState, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const -{ - if ( ! rxCanvas.is()) - return 0; - - double nY (rBBox.Y1); - for (const auto& rLine : *mpLineDescriptors) - { - double nX; - /// check whether RTL interface or not - if(!AllSettings::GetLayoutRTL()) - { - nX = rBBox.X1; - if ( ! bFlushLeft) - nX = rBBox.X2 - rLine.maSize.Width; - } - else - { - nX=rBBox.X2 - rLine.maSize.Width; - if ( ! bFlushLeft) - nX = rBBox.X1; - } - rRenderState.AffineTransform.m02 = nX; - rRenderState.AffineTransform.m12 = nY + rLine.maSize.Height - rLine.mnVerticalOffset; - - const rendering::StringContext aContext (rLine.msLine, 0, rLine.msLine.getLength()); - Reference<rendering::XTextLayout> xLayout ( - rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0)); - rxCanvas->drawTextLayout ( - xLayout, - rViewState, - rRenderState); - - nY += rLine.maSize.Height * 1.2; - } - - return nY - rBBox.Y1; -} - -double LineDescriptorList::GetHeight() const -{ - return std::accumulate(mpLineDescriptors->begin(), mpLineDescriptors->end(), double(0), - [](const double& nHeight, const LineDescriptor& rLine) { - return nHeight + rLine.maSize.Height * 1.2; - }); -} - -void LineDescriptorList::Update ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth) -{ - vector<OUString> aTextParts; - SplitText(msText, aTextParts); - FormatText(aTextParts, rxFont, nMaximalWidth); -} - -void LineDescriptorList::SplitText ( - const OUString& rsText, - vector<OUString>& rTextParts) -{ - const char cQuote ('\''); - const char cSeparator (','); - - sal_Int32 nIndex (0); - sal_Int32 nStart (0); - sal_Int32 nLength (rsText.getLength()); - bool bIsQuoted (false); - while (nIndex < nLength) - { - const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex)); - const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex)); - if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex)) - { - bIsQuoted = !bIsQuoted; - nIndex = nQuoteIndex+1; - continue; - } - - const sal_Int32 nNextIndex = nSeparatorIndex; - if (nNextIndex < 0) - { - break; - } - else if ( ! bIsQuoted) - { - rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart)); - nStart = nNextIndex + 1; - } - nIndex = nNextIndex+1; - } - if (nStart < nLength) - rTextParts.push_back(rsText.copy(nStart, nLength-nStart)); -} - -void LineDescriptorList::FormatText ( - const vector<OUString>& rTextParts, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth) -{ - LineDescriptor aLineDescriptor; - - mpLineDescriptors = std::make_shared<vector<LineDescriptor>>(); - - vector<OUString>::const_iterator iPart (rTextParts.begin()); - vector<OUString>::const_iterator iEnd (rTextParts.end()); - while (iPart!=iEnd) - { - if (aLineDescriptor.IsEmpty()) - { - // Avoid empty lines. - if (PresenterCanvasHelper::GetTextSize( - rxFont, *iPart).Width > nMaximalWidth) - { - const char cSpace (' '); - - sal_Int32 nIndex (0); - sal_Int32 nStart (0); - sal_Int32 nLength (iPart->getLength()); - while (nIndex < nLength) - { - sal_Int32 nSpaceIndex (iPart->indexOf(cSpace, nIndex)); - while (nSpaceIndex >= 0 && PresenterCanvasHelper::GetTextSize( - rxFont, iPart->copy(nStart, nSpaceIndex-nStart)).Width <= nMaximalWidth) - { - nIndex = nSpaceIndex; - nSpaceIndex = iPart->indexOf(cSpace, nIndex+1); - } - - if (nSpaceIndex < 0 && PresenterCanvasHelper::GetTextSize( - rxFont, iPart->copy(nStart, nLength-nStart)).Width <= nMaximalWidth) - { - nIndex = nLength; - } - - if (nIndex == nStart) - { - nIndex = nLength; - } - - aLineDescriptor.AddPart(iPart->subView(nStart, nIndex-nStart), rxFont); - if (nIndex != nLength) - { - mpLineDescriptors->push_back(aLineDescriptor); - aLineDescriptor = LineDescriptor(); - } - nStart = nIndex; - } - } - else - { - aLineDescriptor.AddPart(*iPart, rxFont); - } - } - else if (PresenterCanvasHelper::GetTextSize( - rxFont, aLineDescriptor.msLine+", "+*iPart).Width > nMaximalWidth) - { - aLineDescriptor.AddPart(u",", rxFont); - mpLineDescriptors->push_back(aLineDescriptor); - aLineDescriptor = LineDescriptor(); - continue; - } - else - { - aLineDescriptor.AddPart(OUString(", "+*iPart), rxFont); - } - ++iPart; - } - if ( ! aLineDescriptor.IsEmpty()) - { - mpLineDescriptors->push_back(aLineDescriptor); - } -} - -} // end of anonymous namespace - -//===== Block ================================================================= - -namespace { - -Block::Block ( - const OUString& rsLeftText, - const OUString& rsRightText, - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth) - : maLeft(rsLeftText, rxFont, nMaximalWidth), - maRight(rsRightText, rxFont, nMaximalWidth) -{ -} - -void Block::Update ( - const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, - const sal_Int32 nMaximalWidth) -{ - maLeft.Update(rxFont, nMaximalWidth); - maRight.Update(rxFont, nMaximalWidth); -} - -} // end of anonymous namespace - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterHelpView.hxx b/sdext/source/presenter/PresenterHelpView.hxx deleted file mode 100644 index 58f629a36cd2..000000000000 --- a/sdext/source/presenter/PresenterHelpView.hxx +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERHELPVIEW_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERHELPVIEW_HXX - -#include "PresenterController.hxx" -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/drawing/framework/XResourceId.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <memory> - -namespace sdext::presenter { - -class PresenterButton; - -typedef cppu::WeakComponentImplHelper< - css::drawing::framework::XView, - css::awt::XWindowListener, - css::awt::XPaintListener - > PresenterHelpViewInterfaceBase; - -/** Show help text that describes the defined keys. -*/ -class PresenterHelpView - : private ::cppu::BaseMutex, - public PresenterHelpViewInterfaceBase -{ -public: - explicit PresenterHelpView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterHelpView() override; - - virtual void SAL_CALL disposing() override; - - // lang::XEventListener - - virtual void SAL_CALL - disposing (const css::lang::EventObject& rEventObject) override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XResourceId - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - -private: - class TextContainer; - - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - css::uno::Reference<css::drawing::framework::XResourceId> mxViewId; - css::uno::Reference<css::drawing::framework::XPane> mxPane; - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - ::rtl::Reference<PresenterController> mpPresenterController; - PresenterTheme::SharedFontDescriptor mpFont; - std::unique_ptr<TextContainer> mpTextContainer; - ::rtl::Reference<PresenterButton> mpCloseButton; - sal_Int32 mnSeparatorY; - sal_Int32 mnMaximalWidth; - - void ProvideCanvas(); - void Resize(); - void Paint (const css::awt::Rectangle& rRedrawArea); - void ReadHelpStrings(); - void ProcessString ( - const css::uno::Reference<css::beans::XPropertySet>& rsProperties); - - /** Find a font size, so that all text can be displayed at the same - time. - */ - void CheckFontSize(); - - /** @throws css::lang::DisposedException when the object has already been - disposed. - */ - void ThrowIfDisposed(); -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterHelper.cxx b/sdext/source/presenter/PresenterHelper.cxx deleted file mode 100644 index 76bec0ecee7d..000000000000 --- a/sdext/source/presenter/PresenterHelper.cxx +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterHelper.hxx" - -#include <com/sun/star/presentation/XPresentationSupplier.hpp> -#include <com/sun/star/presentation/XPresentation2.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::presentation; - -namespace sdext::presenter { - -constexpr OUStringLiteral msPaneURLPrefix( u"private:resource/pane/"); -const OUString PresenterHelper::msFullScreenPaneURL( msPaneURLPrefix + "FullScreenPane"); - -Reference<presentation::XSlideShowController> PresenterHelper::GetSlideShowController ( - const Reference<frame::XController>& rxController) -{ - Reference<presentation::XSlideShowController> xSlideShowController; - - if( rxController.is() ) try - { - Reference<XPresentationSupplier> xPS ( rxController->getModel(), UNO_QUERY_THROW); - - Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW); - - xSlideShowController = xPresentation->getController(); - } - catch(RuntimeException&) - { - } - - return xSlideShowController; -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterHelper.hxx b/sdext/source/presenter/PresenterHelper.hxx deleted file mode 100644 index 69fc57333941..000000000000 --- a/sdext/source/presenter/PresenterHelper.hxx +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERHELPER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERHELPER_HXX - -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/presentation/XSlideShowController.hpp> - -namespace sdext::presenter -{ -/** Collection of helper functions that do not fit in anywhere else. - Provide access to frequently used strings of the drawing framework. -*/ -namespace PresenterHelper -{ -extern const OUString msFullScreenPaneURL; - -/** Return the slide show controller of a running presentation that has - the same document as the given framework controller. - @return - When no presentation is running this method returns an empty reference. -*/ -css::uno::Reference<css::presentation::XSlideShowController> -GetSlideShowController(const css::uno::Reference<css::frame::XController>& rxController); -} - -} // end of namespace presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterNotesView.cxx b/sdext/source/presenter/PresenterNotesView.cxx deleted file mode 100644 index 86258464471d..000000000000 --- a/sdext/source/presenter/PresenterNotesView.cxx +++ /dev/null @@ -1,661 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <vcl/settings.hxx> -#include "PresenterNotesView.hxx" -#include "PresenterButton.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterScrollBar.hxx" -#include "PresenterTextView.hxx" -#include <com/sun/star/accessibility/AccessibleTextType.hpp> -#include <com/sun/star/awt/Key.hpp> -#include <com/sun/star/awt/KeyModifier.hpp> -#include <com/sun/star/awt/PosSize.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/lang/XServiceName.hpp> -#include <com/sun/star/presentation/XPresentationPage.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/XSpriteCanvas.hpp> -#include <com/sun/star/text/XTextRange.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -const sal_Int32 gnSpaceBelowSeparator (10); -const sal_Int32 gnSpaceAboveSeparator (10); -const double gnLineScrollFactor (1.2); - -namespace sdext::presenter { - -//===== PresenterNotesView ==================================================== - -PresenterNotesView::PresenterNotesView ( - const Reference<XComponentContext>& rxComponentContext, - const Reference<XResourceId>& rxViewId, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterNotesViewInterfaceBase(m_aMutex), - mxViewId(rxViewId), - mpPresenterController(rpPresenterController), - mxCanvas(), - mxCurrentNotesPage(), - mpScrollBar(), - mxToolBarWindow(), - mxToolBarCanvas(), - mpToolBar(), - mpCloseButton(), - maSeparatorColor(0xffffff), - mnSeparatorYLocation(0), - maTextBoundingBox(), - mpBackground(), - mnTop(0), - mpFont(), - mpTextView() -{ - try - { - Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); - Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_SET_THROW); - Reference<XPane> xPane (xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW); - - mxParentWindow = xPane->getWindow(); - mxCanvas = xPane->getCanvas(); - mpTextView = std::make_shared<PresenterTextView>( - rxComponentContext, - mxCanvas, - mpPresenterController->GetPaintManager()->GetInvalidator(mxParentWindow)); - - const OUString sResourceURL (mxViewId->getResourceURL()); - mpFont = std::make_shared<PresenterTheme::FontDescriptor>( - rpPresenterController->GetViewFont(sResourceURL)); - maSeparatorColor = mpFont->mnColor; - mpTextView->SetFont(mpFont); - - CreateToolBar(rxComponentContext, rpPresenterController); - - mpCloseButton = PresenterButton::Create( - rxComponentContext, - mpPresenterController, - mpPresenterController->GetTheme(), - mxParentWindow, - mxCanvas, - "NotesViewCloser"); - - if (mxParentWindow.is()) - { - mxParentWindow->addWindowListener(this); - mxParentWindow->addPaintListener(this); - mxParentWindow->addKeyListener(this); - mxParentWindow->setVisible(true); - } - - mpScrollBar = new PresenterVerticalScrollBar( - rxComponentContext, - mxParentWindow, - mpPresenterController->GetPaintManager(), - [this](double f) { return this->SetTop(f); }); - mpScrollBar->SetBackground( - mpPresenterController->GetViewBackground(mxViewId->getResourceURL())); - - mpScrollBar->SetCanvas(mxCanvas); - - Layout(); - } - catch (RuntimeException&) - { - PresenterNotesView::disposing(); - throw; - } -} - -PresenterNotesView::~PresenterNotesView() -{ -} - -void SAL_CALL PresenterNotesView::disposing() -{ - if (mxParentWindow.is()) - { - mxParentWindow->removeWindowListener(this); - mxParentWindow->removePaintListener(this); - mxParentWindow->removeKeyListener(this); - mxParentWindow = nullptr; - } - - // Dispose tool bar. - { - Reference<XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY); - mpToolBar = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - { - Reference<XComponent> xComponent (mxToolBarCanvas, UNO_QUERY); - mxToolBarCanvas = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - { - Reference<XComponent> xComponent = mxToolBarWindow; - mxToolBarWindow = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - // Dispose close button - { - Reference<XComponent> xComponent (static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY); - mpCloseButton = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - // Create the tool bar. - - mpScrollBar = nullptr; - - mxViewId = nullptr; -} - -void PresenterNotesView::CreateToolBar ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController) -{ - if (!rpPresenterController) - return; - - Reference<drawing::XPresenterHelper> xPresenterHelper ( - rpPresenterController->GetPresenterHelper()); - if ( ! xPresenterHelper.is()) - return; - - // Create a new window as container of the tool bar. - mxToolBarWindow = xPresenterHelper->createWindow( - mxParentWindow, - false, - true, - false, - false); - mxToolBarCanvas = xPresenterHelper->createSharedCanvas ( - Reference<rendering::XSpriteCanvas>(mxCanvas, UNO_QUERY), - mxParentWindow, - mxCanvas, - mxParentWindow, - mxToolBarWindow); - - // Create the tool bar. - mpToolBar = new PresenterToolBar( - rxContext, - mxToolBarWindow, - mxToolBarCanvas, - rpPresenterController, - PresenterToolBar::Left); - mpToolBar->Initialize( - "PresenterScreenSettings/ToolBars/NotesToolBar"); -} - -void PresenterNotesView::SetSlide (const Reference<drawing::XDrawPage>& rxNotesPage) -{ - static constexpr OUStringLiteral sNotesShapeName ( - u"com.sun.star.presentation.NotesShape"); - static constexpr OUStringLiteral sTextShapeName ( - u"com.sun.star.drawing.TextShape"); - - if (!rxNotesPage.is()) - return; - - // Iterate over all shapes and find the one that holds the text. - sal_Int32 nCount (rxNotesPage->getCount()); - for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) - { - - Reference<lang::XServiceName> xServiceName ( - rxNotesPage->getByIndex(nIndex), UNO_QUERY); - if (xServiceName.is() - && xServiceName->getServiceName() == sNotesShapeName) - { - } - else - { - Reference<drawing::XShapeDescriptor> xShapeDescriptor ( - rxNotesPage->getByIndex(nIndex), UNO_QUERY); - if (xShapeDescriptor.is()) - { - OUString sType (xShapeDescriptor->getShapeType()); - if (sType == sNotesShapeName || sType == sTextShapeName) - { - Reference<text::XTextRange> xText ( - rxNotesPage->getByIndex(nIndex), UNO_QUERY); - if (xText.is()) - { - mpTextView->SetText(Reference<text::XText>(xText, UNO_QUERY)); - } - } - } - } - } - - Layout(); - - if (mpScrollBar) - { - mpScrollBar->SetThumbPosition(0, false); - UpdateScrollBar(); - } - - Invalidate(); -} - -//----- lang::XEventListener ------------------------------------------------- - -void SAL_CALL PresenterNotesView::disposing (const lang::EventObject& rEventObject) -{ - if (rEventObject.Source == mxParentWindow) - mxParentWindow = nullptr; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterNotesView::windowResized (const awt::WindowEvent&) -{ - Layout(); -} - -void SAL_CALL PresenterNotesView::windowMoved (const awt::WindowEvent&) {} - -void SAL_CALL PresenterNotesView::windowShown (const lang::EventObject&) {} - -void SAL_CALL PresenterNotesView::windowHidden (const lang::EventObject&) {} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterNotesView::windowPaint (const awt::PaintEvent& rEvent) -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterNotesView object has already been disposed", - static_cast<uno::XWeak*>(this)); - } - - if ( ! mbIsPresenterViewActive) - return; - - ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex()); - Paint(rEvent.UpdateRect); -} - -//----- XResourceId ----------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterNotesView::getResourceId() -{ - return mxViewId; -} - -sal_Bool SAL_CALL PresenterNotesView::isAnchorOnly() -{ - return false; -} - -//----- XDrawView ------------------------------------------------------------- - -void SAL_CALL PresenterNotesView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide) -{ - // Get the associated notes page. - mxCurrentNotesPage = nullptr; - try - { - Reference<presentation::XPresentationPage> xPresentationPage(rxSlide, UNO_QUERY); - if (xPresentationPage.is()) - mxCurrentNotesPage = xPresentationPage->getNotesPage(); - } - catch (RuntimeException&) - { - } - - SetSlide(mxCurrentNotesPage); -} - -Reference<drawing::XDrawPage> SAL_CALL PresenterNotesView::getCurrentPage() -{ - return nullptr; -} - -//----- XKeyListener ---------------------------------------------------------- - -void SAL_CALL PresenterNotesView::keyPressed (const awt::KeyEvent& rEvent) -{ - switch (rEvent.KeyCode) - { - case awt::Key::A: - Scroll(-gnLineScrollFactor * mpFont->mnSize); - break; - - case awt::Key::Y: - case awt::Key::Z: - Scroll(+gnLineScrollFactor * mpFont->mnSize); - break; - - case awt::Key::S: - ChangeFontSize(-1); - break; - - case awt::Key::G: - ChangeFontSize(+1); - break; - - case awt::Key::H: - if (mpTextView) - mpTextView->MoveCaret( - -1, - (rEvent.Modifiers == awt::KeyModifier::SHIFT) - ? css::accessibility::AccessibleTextType::CHARACTER - : css::accessibility::AccessibleTextType::WORD); - break; - - case awt::Key::L: - if (mpTextView) - mpTextView->MoveCaret( - +1, - (rEvent.Modifiers == awt::KeyModifier::SHIFT) - ? css::accessibility::AccessibleTextType::CHARACTER - : css::accessibility::AccessibleTextType::WORD); - break; - } -} - -void SAL_CALL PresenterNotesView::keyReleased (const awt::KeyEvent&) {} - - -void PresenterNotesView::Layout() -{ - if ( ! mxParentWindow.is()) - return; - awt::Rectangle aWindowBox (mxParentWindow->getPosSize()); - geometry::RealRectangle2D aNewTextBoundingBox (0,0,aWindowBox.Width, aWindowBox.Height); - // Size the tool bar and the horizontal separator above it. - if (mxToolBarWindow.is()) - { - const geometry::RealSize2D aToolBarSize (mpToolBar->GetMinimalSize()); - const sal_Int32 nToolBarHeight = sal_Int32(aToolBarSize.Height + 0.5); - mxToolBarWindow->setPosSize(0, aWindowBox.Height - nToolBarHeight, - sal_Int32(aToolBarSize.Width + 0.5), nToolBarHeight, - awt::PosSize::POSSIZE); - mnSeparatorYLocation = aWindowBox.Height - nToolBarHeight - gnSpaceBelowSeparator; - aNewTextBoundingBox.Y2 = mnSeparatorYLocation - gnSpaceAboveSeparator; - // Place the close button. - if (mpCloseButton) - mpCloseButton->SetCenter(geometry::RealPoint2D( - (aWindowBox.Width + aToolBarSize.Width) / 2, - aWindowBox.Height - aToolBarSize.Height/2)); - } - // Check whether the vertical scroll bar is necessary. - if (mpScrollBar) - { - bool bShowVerticalScrollbar (false); - try - { - const double nTextBoxHeight (aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1); - const double nHeight (mpTextView->GetTotalTextHeight()); - if (nHeight > nTextBoxHeight) - { - bShowVerticalScrollbar = true; - if(!AllSettings::GetLayoutRTL()) - aNewTextBoundingBox.X2 -= mpScrollBar->GetSize(); - else - aNewTextBoundingBox.X1 += mpScrollBar->GetSize(); - } - mpScrollBar->SetTotalSize(nHeight); - } - catch(beans::UnknownPropertyException&) - { - OSL_ASSERT(false); - } - if(AllSettings::GetLayoutRTL()) - { - mpScrollBar->SetVisible(bShowVerticalScrollbar); - mpScrollBar->SetPosSize( - geometry::RealRectangle2D( - aNewTextBoundingBox.X1 - mpScrollBar->GetSize(), - aNewTextBoundingBox.Y1, - aNewTextBoundingBox.X1, - aNewTextBoundingBox.Y2)); - if( ! bShowVerticalScrollbar) - mpScrollBar->SetThumbPosition(0, false); - UpdateScrollBar(); - } - else - { - mpScrollBar->SetVisible(bShowVerticalScrollbar); - mpScrollBar->SetPosSize( - geometry::RealRectangle2D( - aWindowBox.Width - mpScrollBar->GetSize(), - aNewTextBoundingBox.Y1, - aNewTextBoundingBox.X2 + mpScrollBar->GetSize(), - aNewTextBoundingBox.Y2)); - if( ! bShowVerticalScrollbar) - mpScrollBar->SetThumbPosition(0, false); - UpdateScrollBar(); - } - } - // Has the text area has changed it position or size? - if (aNewTextBoundingBox.X1 != maTextBoundingBox.X1 - || aNewTextBoundingBox.Y1 != maTextBoundingBox.Y1 - || aNewTextBoundingBox.X2 != maTextBoundingBox.X2 - || aNewTextBoundingBox.Y2 != maTextBoundingBox.Y2) - { - maTextBoundingBox = aNewTextBoundingBox; - mpTextView->SetLocation( - geometry::RealPoint2D( - aNewTextBoundingBox.X1, - aNewTextBoundingBox.Y1)); - mpTextView->SetSize( - geometry::RealSize2D( - aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1, - aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1)); - } -} - -void PresenterNotesView::Paint (const awt::Rectangle& rUpdateBox) -{ - if ( ! mxParentWindow.is()) - return; - if ( ! mxCanvas.is()) - return; - - if (!mpBackground) - mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL()); - - if (rUpdateBox.Y < maTextBoundingBox.Y2 - && rUpdateBox.X < maTextBoundingBox.X2) - { - PaintText(rUpdateBox); - } - - mpTextView->Paint(rUpdateBox); - - if (rUpdateBox.Y + rUpdateBox.Height > maTextBoundingBox.Y2) - { - PaintToolBar(rUpdateBox); - } -} - -void PresenterNotesView::PaintToolBar (const awt::Rectangle& rUpdateBox) -{ - awt::Rectangle aWindowBox (mxParentWindow->getPosSize()); - - rendering::ViewState aViewState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - if (mpBackground) - { - // Paint the background. - mpPresenterController->GetCanvasHelper()->Paint( - mpBackground, - mxCanvas, - rUpdateBox, - awt::Rectangle(0,sal_Int32(maTextBoundingBox.Y2),aWindowBox.Width,aWindowBox.Height), - awt::Rectangle()); - } - - // Paint the horizontal separator. - OSL_ASSERT(mxViewId.is()); - PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor); - - mxCanvas->drawLine( - geometry::RealPoint2D(0,mnSeparatorYLocation), - geometry::RealPoint2D(aWindowBox.Width,mnSeparatorYLocation), - aViewState, - aRenderState); -} - -void PresenterNotesView::PaintText (const awt::Rectangle& rUpdateBox) -{ - const awt::Rectangle aBox (PresenterGeometryHelper::Intersection(rUpdateBox, - PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox))); - - if (aBox.Width <= 0 || aBox.Height <= 0) - return; - - if (mpBackground) - { - // Paint the background. - mpPresenterController->GetCanvasHelper()->Paint( - mpBackground, - mxCanvas, - rUpdateBox, - aBox, - awt::Rectangle()); - } - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -void PresenterNotesView::Invalidate() -{ - mpPresenterController->GetPaintManager()->Invalidate( - mxParentWindow, - PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox)); -} - -void PresenterNotesView::Scroll (const double rnDistance) -{ - try - { - mnTop += rnDistance; - mpTextView->SetOffset(0, mnTop); - - UpdateScrollBar(); - Invalidate(); - } - catch (beans::UnknownPropertyException&) - {} -} - -void PresenterNotesView::SetTop (const double nTop) -{ - try - { - mnTop = nTop; - mpTextView->SetOffset(0, mnTop); - - UpdateScrollBar(); - Invalidate(); - } - catch (beans::UnknownPropertyException&) - {} -} - -void PresenterNotesView::ChangeFontSize (const sal_Int32 nSizeChange) -{ - const sal_Int32 nNewSize (mpFont->mnSize + nSizeChange); - if (nNewSize <= 5) - return; - - mpFont->mnSize = nNewSize; - mpFont->mxFont = nullptr; - mpTextView->SetFont(mpFont); - - Layout(); - UpdateScrollBar(); - Invalidate(); - - // Write the new font size to the configuration to make it persistent. - try - { - const OUString sStyleName (mpPresenterController->GetTheme()->GetStyleName( - mxViewId->getResourceURL())); - std::shared_ptr<PresenterConfigurationAccess> pConfiguration ( - mpPresenterController->GetTheme()->GetNodeForViewStyle( - sStyleName)); - if (pConfiguration == nullptr || !pConfiguration->IsValid()) - return; - - pConfiguration->GoToChild("Font"); - pConfiguration->SetProperty("Size", Any(static_cast<sal_Int32>(nNewSize+0.5))); - pConfiguration->CommitChanges(); - } - catch (Exception&) - { - OSL_ASSERT(false); - } -} - -const std::shared_ptr<PresenterTextView>& PresenterNotesView::GetTextView() const -{ - return mpTextView; -} - -void PresenterNotesView::UpdateScrollBar() -{ - if (!mpScrollBar) - return; - - try - { - mpScrollBar->SetTotalSize(mpTextView->GetTotalTextHeight()); - } - catch(beans::UnknownPropertyException&) - { - OSL_ASSERT(false); - } - - mpScrollBar->SetLineHeight(mpFont->mnSize*1.2); - mpScrollBar->SetThumbPosition(mnTop, false); - - mpScrollBar->SetThumbSize(maTextBoundingBox.Y2 - maTextBoundingBox.Y1); - mpScrollBar->CheckValues(); -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterNotesView.hxx b/sdext/source/presenter/PresenterNotesView.hxx deleted file mode 100644 index 1af3f241f004..000000000000 --- a/sdext/source/presenter/PresenterNotesView.hxx +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERNOTESVIEW_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERNOTESVIEW_HXX - -#include "PresenterController.hxx" -#include "PresenterToolBar.hxx" -#include "PresenterViewFactory.hxx" -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/drawing/XDrawPage.hpp> -#include <com/sun/star/drawing/XDrawView.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/drawing/framework/XResourceId.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <rtl/ref.hxx> -#include <memory> - -namespace sdext::presenter { - -class PresenterButton; -class PresenterScrollBar; -class PresenterTextView; - -typedef cppu::WeakComponentImplHelper< - css::awt::XWindowListener, - css::awt::XPaintListener, - css::drawing::framework::XView, - css::drawing::XDrawView, - css::awt::XKeyListener - > PresenterNotesViewInterfaceBase; - -/** A drawing framework view of the notes of a slide. At the moment this is - a simple text view that does not show the original formatting of the - notes text. -*/ -class PresenterNotesView - : private ::cppu::BaseMutex, - public PresenterNotesViewInterfaceBase, - public CachablePresenterView -{ -public: - explicit PresenterNotesView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterNotesView() override; - - virtual void SAL_CALL disposing() override; - - /** Typically called from setCurrentSlide() with the notes page that is - associated with the slide given to setCurrentSlide(). - - Iterates over all text shapes on the given notes page and displays - the concatenated text of these. - */ - void SetSlide ( - const css::uno::Reference<css::drawing::XDrawPage>& rxNotesPage); - - void ChangeFontSize (const sal_Int32 nSizeChange); - - const std::shared_ptr<PresenterTextView>& GetTextView() const; - - // lang::XEventListener - - virtual void SAL_CALL - disposing (const css::lang::EventObject& rEventObject) override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XResourceId - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - - // XDrawView - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override; - - virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage() override; - - // XKeyListener - - virtual void SAL_CALL keyPressed (const css::awt::KeyEvent& rEvent) override; - virtual void SAL_CALL keyReleased (const css::awt::KeyEvent& rEvent) override; - -private: - css::uno::Reference<css::drawing::framework::XResourceId> mxViewId; - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::awt::XWindow> mxParentWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::drawing::XDrawPage> mxCurrentNotesPage; - ::rtl::Reference<PresenterScrollBar> mpScrollBar; - css::uno::Reference<css::awt::XWindow> mxToolBarWindow; - css::uno::Reference<css::rendering::XCanvas> mxToolBarCanvas; - ::rtl::Reference<PresenterToolBar> mpToolBar; - ::rtl::Reference<PresenterButton> mpCloseButton; - css::util::Color maSeparatorColor; - sal_Int32 mnSeparatorYLocation; - css::geometry::RealRectangle2D maTextBoundingBox; - SharedBitmapDescriptor mpBackground; - double mnTop; - PresenterTheme::SharedFontDescriptor mpFont; - std::shared_ptr<PresenterTextView> mpTextView; - - void CreateToolBar ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController); - void Layout(); - void Paint (const css::awt::Rectangle& rUpdateBox); - void PaintToolBar (const css::awt::Rectangle& rUpdateBox); - void PaintText (const css::awt::Rectangle& rUpdateBox); - void Invalidate(); - void Scroll (const double nDistance); - void SetTop (const double nTop); - void UpdateScrollBar(); -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaintManager.cxx b/sdext/source/presenter/PresenterPaintManager.cxx deleted file mode 100644 index ba1bc48defb7..000000000000 --- a/sdext/source/presenter/PresenterPaintManager.cxx +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterPaintManager.hxx" - -#include "PresenterPaneContainer.hxx" -#include <com/sun/star/awt/InvalidateStyle.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -PresenterPaintManager::PresenterPaintManager ( - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper, - const rtl::Reference<PresenterPaneContainer>& rpPaneContainer) - : mxParentWindow(rxParentWindow), - mxParentWindowPeer(rxParentWindow, UNO_QUERY), - mxPresenterHelper(rxPresenterHelper), - mpPaneContainer(rpPaneContainer) -{ -} - -::std::function<void (const css::awt::Rectangle& rRepaintBox)> - PresenterPaintManager::GetInvalidator ( - const css::uno::Reference<css::awt::XWindow>& rxWindow) -{ - return [this, rxWindow] (css::awt::Rectangle const& rRepaintBox) - { - return this->Invalidate(rxWindow, rRepaintBox /* , bSynchronous=false */); - }; -} - -void PresenterPaintManager::Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow) -{ - sal_Int16 nInvalidateMode (awt::InvalidateStyle::CHILDREN); - - PresenterPaneContainer::SharedPaneDescriptor pDescriptor( - mpPaneContainer->FindContentWindow(rxWindow)); - if (!pDescriptor || ! pDescriptor->mbIsOpaque) - nInvalidateMode |= awt::InvalidateStyle::TRANSPARENT; - else - nInvalidateMode |= awt::InvalidateStyle::NOTRANSPARENT; - - Invalidate(rxWindow, nInvalidateMode); -} - -void PresenterPaintManager::Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const sal_Int16 nInvalidateFlags) -{ - if ((nInvalidateFlags & awt::InvalidateStyle::TRANSPARENT) != 0) - { - // Window is transparent and parent window(s) have to be painted as - // well. Invalidate the parent explicitly. - if (mxPresenterHelper.is() && mxParentWindowPeer.is()) - { - const awt::Rectangle aBBox ( - mxPresenterHelper->getWindowExtentsRelative(rxWindow, mxParentWindow)); - mxParentWindowPeer->invalidateRect(aBBox, nInvalidateFlags); - } - } - else - { - Reference<awt::XWindowPeer> xPeer (rxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->invalidate(nInvalidateFlags); - } -} - -void PresenterPaintManager::Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const css::awt::Rectangle& rRepaintBox, - const bool bSynchronous) -{ - sal_Int16 nInvalidateMode (awt::InvalidateStyle::CHILDREN); - if (bSynchronous) - nInvalidateMode |= awt::InvalidateStyle::UPDATE; - - PresenterPaneContainer::SharedPaneDescriptor pDescriptor( - mpPaneContainer->FindContentWindow(rxWindow)); - if (!pDescriptor || ! pDescriptor->mbIsOpaque) - nInvalidateMode |= awt::InvalidateStyle::TRANSPARENT; - else - nInvalidateMode |= awt::InvalidateStyle::NOTRANSPARENT; - - Invalidate(rxWindow, rRepaintBox, nInvalidateMode); -} - -void PresenterPaintManager::Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const css::awt::Rectangle& rRepaintBox, - const sal_Int16 nInvalidateFlags) -{ - if ((nInvalidateFlags & awt::InvalidateStyle::TRANSPARENT) != 0) - { - // Window is transparent and parent window(s) have to be painted as - // well. Invalidate the parent explicitly. - if (mxPresenterHelper.is() && mxParentWindowPeer.is()) - { - const awt::Rectangle aBBox ( - mxPresenterHelper->getWindowExtentsRelative(rxWindow, mxParentWindow)); - mxParentWindowPeer->invalidateRect( - awt::Rectangle( - rRepaintBox.X + aBBox.X, - rRepaintBox.Y + aBBox.Y, - rRepaintBox.Width, - rRepaintBox.Height), - nInvalidateFlags); - } - } - else - { - Reference<awt::XWindowPeer> xPeer (rxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->invalidateRect(rRepaintBox, nInvalidateFlags); - } -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaintManager.hxx b/sdext/source/presenter/PresenterPaintManager.hxx deleted file mode 100644 index d3013209aeed..000000000000 --- a/sdext/source/presenter/PresenterPaintManager.hxx +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPAINTMANAGER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPAINTMANAGER_HXX - -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <rtl/ref.hxx> - -#include <functional> - -#include "PresenterPaneContainer.hxx" - -namespace sdext::presenter { - -class PresenterPaneContainer; - -/** Synchronize painting of windows and canvases. At the moment there is - just some processing of invalidate calls. - This could be extended to process incoming windowPaint() calls. -*/ -class PresenterPaintManager -{ -public: - /** Create paint manager with the window that is the top node in the - local window hierarchy. - */ - PresenterPaintManager ( - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper, - const rtl::Reference<PresenterPaneContainer>& rpPaneContainer); - - ::std::function<void (const css::awt::Rectangle& rRepaintBox)> - GetInvalidator ( - const css::uno::Reference<css::awt::XWindow>& rxWindow); - - /** Request a repaint of the whole window. - @param rxWindow - May be the parent window or one of its descendents. - */ - void Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow); - void Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const sal_Int16 nInvalidateFlags); - - /** Request a repaint of a part of a window. - @param rxWindow - May be the parent window or one of its descendents. - */ - void Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const css::awt::Rectangle& rRepaintBox, - const bool bSynchronous = false); - void Invalidate ( - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const css::awt::Rectangle& rRepaintBox, - const sal_Int16 nInvalidateFlags); - -private: - css::uno::Reference<css::awt::XWindow> mxParentWindow; - css::uno::Reference<css::awt::XWindowPeer> mxParentWindowPeer; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - ::rtl::Reference<PresenterPaneContainer> mpPaneContainer; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPane.cxx b/sdext/source/presenter/PresenterPane.cxx deleted file mode 100644 index 88628e72cd5e..000000000000 --- a/sdext/source/presenter/PresenterPane.cxx +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterPane.hxx" -#include "PresenterController.hxx" -#include "PresenterPaintManager.hxx" -#include <com/sun/star/lang/XMultiComponentFactory.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -//===== PresenterPane ========================================================= - -PresenterPane::PresenterPane ( - const Reference<XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterPaneBase(rxContext, rpPresenterController), - maBoundingBox() -{ - Reference<lang::XMultiComponentFactory> xFactory ( - mxComponentContext->getServiceManager(), UNO_SET_THROW); - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - mxComponentContext), - UNO_QUERY_THROW); -} - -PresenterPane::~PresenterPane() -{ -} - -//----- XPane ----------------------------------------------------------------- - -Reference<awt::XWindow> SAL_CALL PresenterPane::getWindow() -{ - ThrowIfDisposed(); - return mxContentWindow; -} - -Reference<rendering::XCanvas> SAL_CALL PresenterPane::getCanvas() -{ - ThrowIfDisposed(); - return mxContentCanvas; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterPane::windowResized (const awt::WindowEvent& rEvent) -{ - PresenterPaneBase::windowResized(rEvent); - - Invalidate(maBoundingBox); - - LayoutContextWindow(); - ToTop(); - - UpdateBoundingBox(); - Invalidate(maBoundingBox); -} - -void SAL_CALL PresenterPane::windowMoved (const awt::WindowEvent& rEvent) -{ - PresenterPaneBase::windowMoved(rEvent); - - Invalidate(maBoundingBox); - - ToTop(); - - UpdateBoundingBox(); - Invalidate(maBoundingBox); -} - -void SAL_CALL PresenterPane::windowShown (const lang::EventObject& rEvent) -{ - PresenterPaneBase::windowShown(rEvent); - - ToTop(); - - if (mxContentWindow.is()) - { - LayoutContextWindow(); - mxContentWindow->setVisible(true); - } - - UpdateBoundingBox(); - Invalidate(maBoundingBox); -} - -void SAL_CALL PresenterPane::windowHidden (const lang::EventObject& rEvent) -{ - PresenterPaneBase::windowHidden(rEvent); - - if (mxContentWindow.is()) - mxContentWindow->setVisible(false); -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterPane::windowPaint (const awt::PaintEvent& rEvent) -{ - ThrowIfDisposed(); - - PaintBorder(rEvent.UpdateRect); -} - - -void PresenterPane::CreateCanvases ( - const Reference<rendering::XSpriteCanvas>& rxParentCanvas) -{ - if ( ! mxPresenterHelper.is()) - return; - if ( ! mxParentWindow.is()) - return; - if ( ! rxParentCanvas.is()) - return; - - mxBorderCanvas = mxPresenterHelper->createSharedCanvas( - rxParentCanvas, - mxParentWindow, - rxParentCanvas, - mxParentWindow, - mxBorderWindow); - mxContentCanvas = mxPresenterHelper->createSharedCanvas( - rxParentCanvas, - mxParentWindow, - rxParentCanvas, - mxParentWindow, - mxContentWindow); - - PaintBorder(mxBorderWindow->getPosSize()); -} - -void PresenterPane::Invalidate (const css::awt::Rectangle& rRepaintBox) -{ - // Invalidate the parent window to be able to invalidate an area outside - // the current window area. - mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow, rRepaintBox); -} - -void PresenterPane::UpdateBoundingBox() -{ - if (mxBorderWindow.is() && IsVisible()) - maBoundingBox = mxBorderWindow->getPosSize(); - else - maBoundingBox = awt::Rectangle(); -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPane.hxx b/sdext/source/presenter/PresenterPane.hxx deleted file mode 100644 index 2a057229f802..000000000000 --- a/sdext/source/presenter/PresenterPane.hxx +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANE_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANE_HXX - -#include "PresenterPaneBase.hxx" -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <rtl/ref.hxx> - -namespace sdext::presenter -{ -/** Pane used by the presenter screen. Pane objects are stored in the - PresenterPaneContainer. Sizes and positions are controlled - by the PresenterWindowManager. Interactive positioning and resizing is - managed by the PresenterPaneBorderManager. Borders around panes are - painted by the PresenterPaneBorderPainter. -*/ -class PresenterPane : public PresenterPaneBase -{ -public: - PresenterPane(const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterPane() override; - - // XPane - - css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow() override; - - css::uno::Reference<css::rendering::XCanvas> SAL_CALL getCanvas() override; - - // XWindowListener - - virtual void SAL_CALL windowResized(const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved(const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown(const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden(const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint(const css::awt::PaintEvent& rEvent) override; - -private: - /** Store the bounding box so that when the window is resized or moved - we still know the old position and size. - */ - css::awt::Rectangle maBoundingBox; - - virtual void CreateCanvases( - const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas) override; - - void Invalidate(const css::awt::Rectangle& rRepaintBox); - void UpdateBoundingBox(); -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneBase.cxx b/sdext/source/presenter/PresenterPaneBase.cxx deleted file mode 100644 index 6ec411b99c1b..000000000000 --- a/sdext/source/presenter/PresenterPaneBase.cxx +++ /dev/null @@ -1,351 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterPaneBase.hxx" -#include "PresenterController.hxx" -#include "PresenterPaintManager.hxx" -#include <com/sun/star/awt/PosSize.hpp> -#include <com/sun/star/awt/XWindow2.hpp> - -using namespace css; -using namespace css::uno; -using namespace css::drawing::framework; - -namespace sdext::presenter { - -//===== PresenterPaneBase ===================================================== - -PresenterPaneBase::PresenterPaneBase ( - const Reference<XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterPaneBaseInterfaceBase(m_aMutex), - mpPresenterController(rpPresenterController), - mxParentWindow(), - mxBorderWindow(), - mxBorderCanvas(), - mxContentWindow(), - mxContentCanvas(), - mxPaneId(), - mxBorderPainter(), - mxPresenterHelper(), - msTitle(), - mxComponentContext(rxContext) -{ - if (mpPresenterController) - mxPresenterHelper = mpPresenterController->GetPresenterHelper(); -} - -PresenterPaneBase::~PresenterPaneBase() -{ -} - -void PresenterPaneBase::disposing() -{ - if (mxBorderWindow.is()) - { - mxBorderWindow->removeWindowListener(this); - mxBorderWindow->removePaintListener(this); - } - - { - Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY); - mxContentCanvas = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - { - Reference<XComponent> xComponent = mxContentWindow; - mxContentWindow = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - { - Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY); - mxBorderCanvas = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - { - Reference<XComponent> xComponent = mxBorderWindow; - mxBorderWindow = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - mxComponentContext = nullptr; -} - -void PresenterPaneBase::SetTitle (const OUString& rsTitle) -{ - msTitle = rsTitle; - - OSL_ASSERT(mpPresenterController); - OSL_ASSERT(mpPresenterController->GetPaintManager() != nullptr); - - mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow); -} - -const OUString& PresenterPaneBase::GetTitle() const -{ - return msTitle; -} - -const Reference<drawing::framework::XPaneBorderPainter>& - PresenterPaneBase::GetPaneBorderPainter() const -{ - return mxBorderPainter; -} - -//----- XInitialization ------------------------------------------------------- - -void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments) -{ - ThrowIfDisposed(); - - if ( ! mxComponentContext.is()) - { - throw RuntimeException( - "PresenterSpritePane: missing component context", - static_cast<XWeak*>(this)); - } - - if (rArguments.getLength() != 5 && rArguments.getLength() != 6) - { - throw RuntimeException( - "PresenterSpritePane: invalid number of arguments", - static_cast<XWeak*>(this)); - } - - try - { - // Get the resource id from the first argument. - if ( ! (rArguments[0] >>= mxPaneId)) - { - throw lang::IllegalArgumentException( - "PresenterPane: invalid pane id", - static_cast<XWeak*>(this), - 0); - } - - if ( ! (rArguments[1] >>= mxParentWindow)) - { - throw lang::IllegalArgumentException( - "PresenterPane: invalid parent window", - static_cast<XWeak*>(this), - 1); - } - - Reference<rendering::XSpriteCanvas> xParentCanvas; - if ( ! (rArguments[2] >>= xParentCanvas)) - { - throw lang::IllegalArgumentException( - "PresenterPane: invalid parent canvas", - static_cast<XWeak*>(this), - 2); - } - - if ( ! (rArguments[3] >>= msTitle)) - { - throw lang::IllegalArgumentException( - "PresenterPane: invalid title", - static_cast<XWeak*>(this), - 3); - } - - if ( ! (rArguments[4] >>= mxBorderPainter)) - { - throw lang::IllegalArgumentException( - "PresenterPane: invalid border painter", - static_cast<XWeak*>(this), - 4); - } - - bool bIsWindowVisibleOnCreation (true); - if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation)) - { - throw lang::IllegalArgumentException( - "PresenterPane: invalid window visibility flag", - static_cast<XWeak*>(this), - 5); - } - - CreateWindows(bIsWindowVisibleOnCreation); - - if (mxBorderWindow.is()) - { - mxBorderWindow->addWindowListener(this); - mxBorderWindow->addPaintListener(this); - } - - CreateCanvases(xParentCanvas); - - // Raise new windows. - ToTop(); - } - catch (Exception&) - { - mxContentWindow = nullptr; - mxComponentContext = nullptr; - throw; - } -} - -//----- XResourceId ----------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId() -{ - ThrowIfDisposed(); - return mxPaneId; -} - -sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly() -{ - return true; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent&) -{ - ThrowIfDisposed(); -} - -void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent&) -{ - ThrowIfDisposed(); -} - -void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject&) -{ - ThrowIfDisposed(); -} - -void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject&) -{ - ThrowIfDisposed(); -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent) -{ - if (rEvent.Source == mxBorderWindow) - { - mxBorderWindow = nullptr; - } -} - - -void PresenterPaneBase::CreateWindows ( - const bool bIsWindowVisibleOnCreation) -{ - if (!(mxPresenterHelper.is() && mxParentWindow.is())) - return; - - mxBorderWindow = mxPresenterHelper->createWindow( - mxParentWindow, - false, - bIsWindowVisibleOnCreation, - false, - false); - mxContentWindow = mxPresenterHelper->createWindow( - mxBorderWindow, - false, - bIsWindowVisibleOnCreation, - false, - false); -} - -const Reference<awt::XWindow>& PresenterPaneBase::GetBorderWindow() const -{ - return mxBorderWindow; -} - -void PresenterPaneBase::ToTop() -{ - if (mxPresenterHelper.is()) - mxPresenterHelper->toTop(mxContentWindow); -} - -void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox) -{ - OSL_ASSERT(mxPaneId.is()); - - if (!(mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is())) - return; - - awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); - awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height); - - //TODO: paint border background? - - mxBorderPainter->paintBorder( - mxPaneId->getResourceURL(), - mxBorderCanvas, - aLocalBorderBox, - rUpdateBox, - msTitle); -} - -void PresenterPaneBase::LayoutContextWindow() -{ - OSL_ASSERT(mxPaneId.is()); - OSL_ASSERT(mxBorderWindow.is()); - OSL_ASSERT(mxContentWindow.is()); - if (!(mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is())) - return; - - const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); - const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder( - mxPaneId->getResourceURL(), - aBorderBox, - drawing::framework::BorderType_TOTAL_BORDER)); - mxContentWindow->setPosSize( - aInnerBox.X - aBorderBox.X, - aInnerBox.Y - aBorderBox.Y, - aInnerBox.Width, - aInnerBox.Height, - awt::PosSize::POSSIZE); -} - -bool PresenterPaneBase::IsVisible() const -{ - Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY); - if (xWindow2.is()) - return xWindow2->isVisible(); - - return false; -} - -void PresenterPaneBase::ThrowIfDisposed() -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterPane object has already been disposed", - static_cast<uno::XWeak*>(this)); - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneBase.hxx b/sdext/source/presenter/PresenterPaneBase.hxx deleted file mode 100644 index 6df93af3ecae..000000000000 --- a/sdext/source/presenter/PresenterPaneBase.hxx +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANEBASE_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANEBASE_HXX - -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/drawing/framework/XPaneBorderPainter.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <rtl/ref.hxx> - - -namespace sdext::presenter { - -class PresenterController; - -typedef ::cppu::WeakComponentImplHelper < - css::drawing::framework::XPane, - css::lang::XInitialization, - css::awt::XWindowListener, - css::awt::XPaintListener -> PresenterPaneBaseInterfaceBase; - -/** Base class of the panes used by the presenter screen. Pane objects are - stored in the PresenterPaneContainer. Sizes and positions are - controlled by the PresenterWindowManager. Interactive positioning and - resizing is managed by the PresenterPaneBorderManager. Borders around - panes are painted by the PresenterPaneBorderPainter. -*/ -class PresenterPaneBase - : protected ::cppu::BaseMutex, - public PresenterPaneBaseInterfaceBase -{ -public: - PresenterPaneBase ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterPaneBase() override; - PresenterPaneBase(const PresenterPaneBase&) = delete; - PresenterPaneBase& operator=(const PresenterPaneBase&) = delete; - - virtual void SAL_CALL disposing() override; - - const css::uno::Reference<css::awt::XWindow>& GetBorderWindow() const; - void SetTitle (const OUString& rsTitle); - const OUString& GetTitle() const; - const css::uno::Reference<css::drawing::framework::XPaneBorderPainter>& GetPaneBorderPainter() const; - - // XInitialization - - virtual void SAL_CALL initialize (const css::uno::Sequence<css::uno::Any>& rArguments) override; - - // XResourceId - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // lang::XEventListener - - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - -protected: - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::awt::XWindow> mxParentWindow; - css::uno::Reference<css::awt::XWindow> mxBorderWindow; - css::uno::Reference<css::rendering::XCanvas> mxBorderCanvas; - css::uno::Reference<css::awt::XWindow> mxContentWindow; - css::uno::Reference<css::rendering::XCanvas> mxContentCanvas; - css::uno::Reference<css::drawing::framework::XResourceId> mxPaneId; - css::uno::Reference<css::drawing::framework::XPaneBorderPainter> mxBorderPainter; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - OUString msTitle; - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - - virtual void CreateCanvases ( - const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas) = 0; - - void CreateWindows ( - const bool bIsWindowVisibleOnCreation); - void PaintBorder (const css::awt::Rectangle& rUpdateRectangle); - void ToTop(); - void LayoutContextWindow(); - bool IsVisible() const; - - /** @throws css::lang::DisposedException when the object has already been - disposed. - */ - void ThrowIfDisposed(); -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneBorderPainter.cxx b/sdext/source/presenter/PresenterPaneBorderPainter.cxx deleted file mode 100644 index 53d60faa2315..000000000000 --- a/sdext/source/presenter/PresenterPaneBorderPainter.cxx +++ /dev/null @@ -1,900 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterPaneBorderPainter.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterTheme.hxx" -#include <com/sun/star/awt/Point.hpp> -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/FillRule.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/rendering/XSpriteCanvas.hpp> -#include <map> -#include <memory> -#include <vector> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -namespace { - class BorderSize - { - public: - BorderSize(); - sal_Int32 mnLeft; - sal_Int32 mnTop; - sal_Int32 mnRight; - sal_Int32 mnBottom; - }; - - class RendererPaneStyle - { - public: - RendererPaneStyle ( - const std::shared_ptr<PresenterTheme>& rpTheme, - const OUString& rsStyleName); - - awt::Rectangle AddBorder ( - const awt::Rectangle& rBox, - drawing::framework::BorderType eBorderType) const; - awt::Rectangle RemoveBorder ( - const awt::Rectangle& rBox, - drawing::framework::BorderType eBorderType) const; - Reference<rendering::XCanvasFont> GetFont ( - const Reference<rendering::XCanvas>& rxCanvas) const; - - SharedBitmapDescriptor mpTopLeft; - SharedBitmapDescriptor mpTop; - SharedBitmapDescriptor mpTopRight; - SharedBitmapDescriptor mpLeft; - SharedBitmapDescriptor mpRight; - SharedBitmapDescriptor mpBottomLeft; - SharedBitmapDescriptor mpBottom; - SharedBitmapDescriptor mpBottomRight; - SharedBitmapDescriptor mpBottomCallout; - SharedBitmapDescriptor mpEmpty; - PresenterTheme::SharedFontDescriptor mpFont; - sal_Int32 mnFontXOffset; - sal_Int32 mnFontYOffset; - enum class Anchor { Left, Right, Center }; - Anchor meFontAnchor; - BorderSize maInnerBorderSize; - BorderSize maOuterBorderSize; - BorderSize maTotalBorderSize; - private: - void UpdateBorderSizes(); - SharedBitmapDescriptor GetBitmap( - const std::shared_ptr<PresenterTheme>& rpTheme, - const OUString& rsStyleName, - const OUString& rsBitmapName); - }; -} - -class PresenterPaneBorderPainter::Renderer -{ -public: - Renderer ( - const Reference<XComponentContext>& rxContext, - const std::shared_ptr<PresenterTheme>& rpTheme); - - void SetCanvas (const Reference<rendering::XCanvas>& rxCanvas); - void PaintBorder ( - const OUString& rsTitle, - const awt::Rectangle& rBBox, - const awt::Rectangle& rUpdateBox, - const OUString& rsPaneURL); - void PaintTitle ( - const OUString& rsTitle, - const std::shared_ptr<RendererPaneStyle>& rpStyle, - const awt::Rectangle& rUpdateBox, - const awt::Rectangle& rOuterBox, - const awt::Rectangle& rInnerBox); - void SetupClipping ( - const awt::Rectangle& rUpdateBox, - const awt::Rectangle& rOuterBox, - const OUString& rsPaneStyleName); - std::shared_ptr<RendererPaneStyle> GetRendererPaneStyle (const OUString& rsResourceURL); - void SetCalloutAnchor ( - const awt::Point& rCalloutAnchor); - -private: - std::shared_ptr<PresenterTheme> mpTheme; - typedef ::std::map<OUString, std::shared_ptr<RendererPaneStyle> > RendererPaneStyleContainer; - RendererPaneStyleContainer maRendererPaneStyles; - Reference<rendering::XCanvas> mxCanvas; - Reference<drawing::XPresenterHelper> mxPresenterHelper; - css::rendering::ViewState maViewState; - Reference<rendering::XPolyPolygon2D> mxViewStateClip; - bool mbHasCallout; - awt::Point maCalloutAnchor; - - void PaintBitmap( - const awt::Rectangle& rBox, - const awt::Rectangle& rUpdateBox, - const sal_Int32 nXPosition, - const sal_Int32 nYPosition, - const sal_Int32 nStartOffset, - const sal_Int32 nEndOffset, - const bool bExpand, - const SharedBitmapDescriptor& rpBitmap); -}; - -// ===== PresenterPaneBorderPainter =========================================== - -PresenterPaneBorderPainter::PresenterPaneBorderPainter ( - const Reference<XComponentContext>& rxContext) - : PresenterPaneBorderPainterInterfaceBase(m_aMutex), - mxContext(rxContext), - mpTheme(), - mpRenderer() -{ -} - -PresenterPaneBorderPainter::~PresenterPaneBorderPainter() -{ -} - -//----- XPaneBorderPainter ---------------------------------------------------- - -awt::Rectangle SAL_CALL PresenterPaneBorderPainter::addBorder ( - const OUString& rsPaneBorderStyleName, - const css::awt::Rectangle& rRectangle, - drawing::framework::BorderType eBorderType) -{ - ThrowIfDisposed(); - - ProvideTheme(); - - return AddBorder(rsPaneBorderStyleName, rRectangle, eBorderType); -} - -awt::Rectangle SAL_CALL PresenterPaneBorderPainter::removeBorder ( - const OUString& rsPaneBorderStyleName, - const css::awt::Rectangle& rRectangle, - drawing::framework::BorderType eBorderType) -{ - ThrowIfDisposed(); - - ProvideTheme(); - - return RemoveBorder(rsPaneBorderStyleName, rRectangle, eBorderType); -} - -void SAL_CALL PresenterPaneBorderPainter::paintBorder ( - const OUString& rsPaneBorderStyleName, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rOuterBorderRectangle, - const css::awt::Rectangle& rRepaintArea, - const OUString& rsTitle) -{ - ThrowIfDisposed(); - - // Early reject paints completely outside the repaint area. - if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width - || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height - || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X - || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y) - { - return; - } - ProvideTheme(rxCanvas); - - if (mpRenderer == nullptr) - return; - - mpRenderer->SetCanvas(rxCanvas); - mpRenderer->SetupClipping( - rRepaintArea, - rOuterBorderRectangle, - rsPaneBorderStyleName); - mpRenderer->PaintBorder( - rsTitle, - rOuterBorderRectangle, - rRepaintArea, - rsPaneBorderStyleName); -} - -void SAL_CALL PresenterPaneBorderPainter::paintBorderWithCallout ( - const OUString& rsPaneBorderStyleName, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rOuterBorderRectangle, - const css::awt::Rectangle& rRepaintArea, - const OUString& rsTitle, - const css::awt::Point& rCalloutAnchor) -{ - ThrowIfDisposed(); - - // Early reject paints completely outside the repaint area. - if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width - || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height - || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X - || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y) - { - return; - } - ProvideTheme(rxCanvas); - - if (mpRenderer == nullptr) - return; - - mpRenderer->SetCanvas(rxCanvas); - mpRenderer->SetupClipping( - rRepaintArea, - rOuterBorderRectangle, - rsPaneBorderStyleName); - mpRenderer->SetCalloutAnchor(rCalloutAnchor); - mpRenderer->PaintBorder( - rsTitle, - rOuterBorderRectangle, - rRepaintArea, - rsPaneBorderStyleName); -} - -awt::Point SAL_CALL PresenterPaneBorderPainter::getCalloutOffset ( - const OUString& rsPaneBorderStyleName) -{ - ThrowIfDisposed(); - ProvideTheme(); - if (mpRenderer != nullptr) - { - const std::shared_ptr<RendererPaneStyle> pRendererPaneStyle( - mpRenderer->GetRendererPaneStyle(rsPaneBorderStyleName)); - if (pRendererPaneStyle != nullptr && pRendererPaneStyle->mpBottomCallout) - { - return awt::Point ( - 0, - pRendererPaneStyle->mpBottomCallout->mnHeight - - pRendererPaneStyle->mpBottomCallout->mnYHotSpot); - } - } - - return awt::Point(0,0); -} - - -bool PresenterPaneBorderPainter::ProvideTheme (const Reference<rendering::XCanvas>& rxCanvas) -{ - bool bModified (false); - - if ( ! mxContext.is()) - return false; - - if (mpTheme != nullptr) - { - // Check if the theme already has a canvas. - if ( ! mpTheme->HasCanvas()) - { - mpTheme->ProvideCanvas(rxCanvas); - bModified = true; - } - } - else - { - mpTheme = std::make_shared<PresenterTheme>(mxContext, rxCanvas); - bModified = true; - } - - if (bModified) - { - if (mpRenderer == nullptr) - mpRenderer.reset(new Renderer(mxContext, mpTheme)); - else - mpRenderer->SetCanvas(rxCanvas); - } - - return bModified; -} - -void PresenterPaneBorderPainter::ProvideTheme() -{ - if (mpTheme == nullptr) - { - // Create a theme without bitmaps (no canvas => no bitmaps). - ProvideTheme(nullptr); - } - // When there already is a theme then without a canvas we can not - // add anything new. -} - -void PresenterPaneBorderPainter::SetTheme (const std::shared_ptr<PresenterTheme>& rpTheme) -{ - mpTheme = rpTheme; - if (mpRenderer == nullptr) - mpRenderer.reset(new Renderer(mxContext, mpTheme)); -} - -awt::Rectangle PresenterPaneBorderPainter::AddBorder ( - const OUString& rsPaneURL, - const awt::Rectangle& rInnerBox, - const css::drawing::framework::BorderType eBorderType) const -{ - if (mpRenderer != nullptr) - { - const std::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL)); - if (pRendererPaneStyle != nullptr) - return pRendererPaneStyle->AddBorder(rInnerBox, eBorderType); - } - return rInnerBox; -} - -awt::Rectangle PresenterPaneBorderPainter::RemoveBorder ( - const OUString& rsPaneURL, - const css::awt::Rectangle& rOuterBox, - const css::drawing::framework::BorderType eBorderType) const -{ - if (mpRenderer != nullptr) - { - const std::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL)); - if (pRendererPaneStyle != nullptr) - return pRendererPaneStyle->RemoveBorder(rOuterBox, eBorderType); - } - return rOuterBox; -} - -void PresenterPaneBorderPainter::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterPaneBorderPainter object has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -//===== PresenterPaneBorderPainter::Renderer ===================================== - -PresenterPaneBorderPainter::Renderer::Renderer ( - const Reference<XComponentContext>& rxContext, - const std::shared_ptr<PresenterTheme>& rpTheme) - : mpTheme(rpTheme), - maRendererPaneStyles(), - mxCanvas(), - mxPresenterHelper(), - maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), nullptr), - mxViewStateClip(), - mbHasCallout(false), - maCalloutAnchor() -{ - Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager()); - if (xFactory.is()) - { - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - rxContext), - UNO_QUERY_THROW); - } -} - -void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference<rendering::XCanvas>& rxCanvas) -{ - if (mxCanvas != rxCanvas) - { - mxCanvas = rxCanvas; - } -} - -void PresenterPaneBorderPainter::Renderer::PaintBorder ( - const OUString& rsTitle, - const awt::Rectangle& rBBox, - const awt::Rectangle& rUpdateBox, - const OUString& rsPaneURL) -{ - if ( ! mxCanvas.is()) - return; - - // Create the outer and inner border of the, ahm, border. - std::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneURL)); - if (pStyle == nullptr) - return; - - awt::Rectangle aOuterBox (rBBox); - awt::Rectangle aCenterBox ( - pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_OUTER_BORDER)); - awt::Rectangle aInnerBox ( - pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_TOTAL_BORDER)); - - // Prepare references for all used bitmaps. - SharedBitmapDescriptor pTop (pStyle->mpTop); - SharedBitmapDescriptor pTopLeft (pStyle->mpTopLeft); - SharedBitmapDescriptor pTopRight (pStyle->mpTopRight); - SharedBitmapDescriptor pLeft (pStyle->mpLeft); - SharedBitmapDescriptor pRight (pStyle->mpRight); - SharedBitmapDescriptor pBottomLeft (pStyle->mpBottomLeft); - SharedBitmapDescriptor pBottomRight (pStyle->mpBottomRight); - SharedBitmapDescriptor pBottom (pStyle->mpBottom); - - // Paint the sides. - PaintBitmap(aCenterBox, rUpdateBox, 0,-1, - pTopLeft->mnXOffset, pTopRight->mnXOffset, true, pTop); - PaintBitmap(aCenterBox, rUpdateBox, -1,0, - pTopLeft->mnYOffset, pBottomLeft->mnYOffset, true, pLeft); - PaintBitmap(aCenterBox, rUpdateBox, +1,0, - pTopRight->mnYOffset, pBottomRight->mnYOffset, true, pRight); - if (mbHasCallout && pStyle->mpBottomCallout->GetNormalBitmap().is()) - { - const sal_Int32 nCalloutWidth (pStyle->mpBottomCallout->mnWidth); - sal_Int32 nCalloutX (maCalloutAnchor.X - pStyle->mpBottomCallout->mnXHotSpot - - (aCenterBox.X - aOuterBox.X)); - if (nCalloutX < pBottomLeft->mnXOffset + aCenterBox.X) - nCalloutX = pBottomLeft->mnXOffset + aCenterBox.X; - if (nCalloutX > pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width) - nCalloutX = pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width; - // Paint bottom callout. - PaintBitmap(aCenterBox, rUpdateBox, 0,+1, nCalloutX,0, false, pStyle->mpBottomCallout); - // Paint regular bottom bitmap left and right. - PaintBitmap(aCenterBox, rUpdateBox, 0,+1, - pBottomLeft->mnXOffset, nCalloutX-aCenterBox.Width, true, pBottom); - PaintBitmap(aCenterBox, rUpdateBox, 0,+1, - nCalloutX+nCalloutWidth, pBottomRight->mnXOffset, true, pBottom); - } - else - { - // Stretch the bottom bitmap over the full width. - PaintBitmap(aCenterBox, rUpdateBox, 0,+1, - pBottomLeft->mnXOffset, pBottomRight->mnXOffset, true, pBottom); - } - - // Paint the corners. - PaintBitmap(aCenterBox, rUpdateBox, -1,-1, 0,0, false, pTopLeft); - PaintBitmap(aCenterBox, rUpdateBox, +1,-1, 0,0, false, pTopRight); - PaintBitmap(aCenterBox, rUpdateBox, -1,+1, 0,0, false, pBottomLeft); - PaintBitmap(aCenterBox, rUpdateBox, +1,+1, 0,0, false, pBottomRight); - - // Paint the title. - PaintTitle(rsTitle, pStyle, rUpdateBox, aOuterBox, aInnerBox); - - // In a double buffering environment request to make the changes visible. - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -void PresenterPaneBorderPainter::Renderer::PaintTitle ( - const OUString& rsTitle, - const std::shared_ptr<RendererPaneStyle>& rpStyle, - const awt::Rectangle& rUpdateBox, - const awt::Rectangle& rOuterBox, - const awt::Rectangle& rInnerBox) -{ - if ( ! mxCanvas.is()) - return; - - if (rsTitle.isEmpty()) - return; - - Reference<rendering::XCanvasFont> xFont (rpStyle->GetFont(mxCanvas)); - if ( ! xFont.is()) - return; - - rendering::StringContext aContext ( - rsTitle, - 0, - rsTitle.getLength()); - Reference<rendering::XTextLayout> xLayout (xFont->createTextLayout( - aContext, - rendering::TextDirection::WEAK_LEFT_TO_RIGHT, - 0)); - if ( ! xLayout.is()) - return; - - /// this is responsible of the texts above the slide windows - geometry::RealRectangle2D aBox (xLayout->queryTextBounds()); - const double nTextHeight = aBox.Y2 - aBox.Y1; - const double nTextWidth = aBox.X1 + aBox.X2; - const sal_Int32 nTitleBarHeight = rInnerBox.Y - rOuterBox.Y - 1; - double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1; - if (nY >= rInnerBox.Y) - nY = rInnerBox.Y - 1; - double nX; - switch (rpStyle->meFontAnchor) - { - case RendererPaneStyle::Anchor::Left: - nX = rInnerBox.X; - break; - case RendererPaneStyle::Anchor::Right: - nX = rInnerBox.X + rInnerBox.Width - nTextWidth; - break; - default: // RendererPaneStyle::Anchor::Center - nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2; - break; - } - nX += rpStyle->mnFontXOffset; - nY += rpStyle->mnFontYOffset; - - if (rUpdateBox.X >= nX+nTextWidth - || rUpdateBox.Y >= nY+nTextHeight - || rUpdateBox.X+rUpdateBox.Width <= nX - || rUpdateBox.Y+rUpdateBox.Height <= nY) - { - return; - } - - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,nX, 0,1,nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - PresenterCanvasHelper::SetDeviceColor( - aRenderState, - rpStyle->mpFont->mnColor); - - mxCanvas->drawTextLayout ( - xLayout, - maViewState, - aRenderState); -} - -std::shared_ptr<RendererPaneStyle> - PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString& rsResourceURL) -{ - OSL_ASSERT(mpTheme != nullptr); - - RendererPaneStyleContainer::const_iterator iStyle (maRendererPaneStyles.find(rsResourceURL)); - if (iStyle == maRendererPaneStyles.end()) - { - OUString sPaneStyleName ("DefaultRendererPaneStyle"); - - // Get pane layout name for resource URL. - const OUString sStyleName (mpTheme->GetStyleName(rsResourceURL)); - if (!sStyleName.isEmpty()) - sPaneStyleName = sStyleName; - - // Create a new pane style object and initialize it with bitmaps. - auto pStyle = std::make_shared<RendererPaneStyle>(mpTheme,sPaneStyleName); - iStyle = maRendererPaneStyles.emplace(rsResourceURL, pStyle).first; - } - if (iStyle != maRendererPaneStyles.end()) - return iStyle->second; - else - return std::shared_ptr<RendererPaneStyle>(); -} - -void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor ( - const awt::Point& rCalloutAnchor) -{ - mbHasCallout = true; - maCalloutAnchor = rCalloutAnchor; -} - -void PresenterPaneBorderPainter::Renderer::PaintBitmap( - const awt::Rectangle& rBox, - const awt::Rectangle& rUpdateBox, - const sal_Int32 nXPosition, - const sal_Int32 nYPosition, - const sal_Int32 nStartOffset, - const sal_Int32 nEndOffset, - const bool bExpand, - const SharedBitmapDescriptor& rpBitmap) -{ - bool bUseCanvas (mxCanvas.is()); - if ( ! bUseCanvas) - return; - - if (rpBitmap->mnWidth<=0 || rpBitmap->mnHeight<=0) - return; - - Reference<rendering::XBitmap> xBitmap = rpBitmap->GetNormalBitmap(); - if ( ! xBitmap.is()) - return; - - // Calculate position, and for side bitmaps, the size. - sal_Int32 nX = 0; - sal_Int32 nY = 0; - sal_Int32 nW = rpBitmap->mnWidth; - sal_Int32 nH = rpBitmap->mnHeight; - if (nXPosition < 0) - { - nX = rBox.X - rpBitmap->mnWidth + rpBitmap->mnXOffset; - } - else if (nXPosition > 0) - { - nX = rBox.X + rBox.Width + rpBitmap->mnXOffset; - } - else - { - nX = rBox.X + nStartOffset; - if (bExpand) - nW = rBox.Width - nStartOffset + nEndOffset; - } - - if (nYPosition < 0) - { - nY = rBox.Y - rpBitmap->mnHeight + rpBitmap->mnYOffset; - } - else if (nYPosition > 0) - { - nY = rBox.Y + rBox.Height + rpBitmap->mnYOffset; - } - else - { - nY = rBox.Y + nStartOffset; - if (bExpand) - nH = rBox.Height - nStartOffset + nEndOffset; - } - - // Do not paint when bitmap area does not intersect with update box. - if (nX >= rUpdateBox.X + rUpdateBox.Width - || nX+nW <= rUpdateBox.X - || nY >= rUpdateBox.Y + rUpdateBox.Height - || nY+nH <= rUpdateBox.Y) - { - return; - } - - /* - Reference<rendering::XBitmap> xMaskedBitmap ( - PresenterBitmapHelper::FillMaskedWithColor ( - mxCanvas, - Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY), - rBitmap.mxMaskBitmap, - 0x00ff0000, - rBackgroundBitmap.maReplacementColor)); - if (xMaskedBitmap.is()) - xBitmap = xMaskedBitmap; - else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is()) - { - const static sal_Int32 nOutsideMaskColor (0x00ff0000); - Reference<rendering::XIntegerBitmap> xMask ( - mxPresenterHelper->createMask( - mxCanvas, - rBitmap.mxMaskBitmap, - nOutsideMaskColor, - false)); - xBitmap = mxPresenterHelper->applyBitmapMaskWithColor( - mxCanvas, - Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY), - xMask, - rBackgroundBitmap.maReplacementColor); - } - */ - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D( - double(nW)/rpBitmap->mnWidth, 0, nX, - 0, double(nH)/rpBitmap->mnHeight, nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::OVER); - - if (xBitmap.is()) - mxCanvas->drawBitmap( - xBitmap, - maViewState, - aRenderState); -} - -void PresenterPaneBorderPainter::Renderer::SetupClipping ( - const awt::Rectangle& rUpdateBox, - const awt::Rectangle& rOuterBox, - const OUString& rsPaneStyleName) -{ - mxViewStateClip = nullptr; - maViewState.Clip = nullptr; - - if ( ! mxCanvas.is()) - return; - - std::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneStyleName)); - if (pStyle == nullptr) - { - mxViewStateClip = PresenterGeometryHelper::CreatePolygon( - rUpdateBox, - mxCanvas->getDevice()); - } - else - { - awt::Rectangle aInnerBox ( - pStyle->RemoveBorder(rOuterBox, drawing::framework::BorderType_TOTAL_BORDER)); - ::std::vector<awt::Rectangle> aRectangles; - aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, rOuterBox)); - aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, aInnerBox)); - mxViewStateClip = PresenterGeometryHelper::CreatePolygon( - aRectangles, - mxCanvas->getDevice()); - if (mxViewStateClip.is()) - mxViewStateClip->setFillRule(rendering::FillRule_EVEN_ODD); - } - maViewState.Clip = mxViewStateClip; -} - -namespace { - -//===== BorderSize ============================================================ - -BorderSize::BorderSize() - : mnLeft(0), - mnTop(0), - mnRight(0), - mnBottom(0) -{ -} - -//===== RendererPaneStyle ============================================================ - -RendererPaneStyle::RendererPaneStyle ( - const std::shared_ptr<PresenterTheme>& rpTheme, - const OUString& rsStyleName) - : mpTopLeft(), - mpTop(), - mpTopRight(), - mpLeft(), - mpRight(), - mpBottomLeft(), - mpBottom(), - mpBottomRight(), - mpBottomCallout(), - mpEmpty(std::make_shared<PresenterBitmapDescriptor>()), - mpFont(), - mnFontXOffset(0), - mnFontYOffset(0), - meFontAnchor(Anchor::Center), - maInnerBorderSize(), - maOuterBorderSize(), - maTotalBorderSize() -{ - if (rpTheme == nullptr) - return; - - mpTopLeft = GetBitmap(rpTheme, rsStyleName, "TopLeft"); - mpTop = GetBitmap(rpTheme, rsStyleName, "Top"); - mpTopRight = GetBitmap(rpTheme, rsStyleName, "TopRight"); - mpLeft = GetBitmap(rpTheme, rsStyleName,"Left"); - mpRight = GetBitmap(rpTheme, rsStyleName, "Right"); - mpBottomLeft = GetBitmap(rpTheme, rsStyleName, "BottomLeft"); - mpBottom = GetBitmap(rpTheme, rsStyleName, "Bottom"); - mpBottomRight = GetBitmap(rpTheme, rsStyleName, "BottomRight"); - mpBottomCallout = GetBitmap(rpTheme, rsStyleName, "BottomCallout"); - - // Get font description. - mpFont = rpTheme->GetFont(rsStyleName); - - OUString sAnchor ("Left"); - if (mpFont) - { - sAnchor = mpFont->msAnchor; - mnFontXOffset = mpFont->mnXOffset; - mnFontYOffset = mpFont->mnYOffset; - } - - if ( sAnchor == "Left" ) - meFontAnchor = Anchor::Left; - else if ( sAnchor == "Right" ) - meFontAnchor = Anchor::Right; - else - meFontAnchor = Anchor::Center; - - // Get border sizes. - try - { - ::std::vector<sal_Int32> aInnerBorder (rpTheme->GetBorderSize(rsStyleName, false)); - OSL_ASSERT(aInnerBorder.size()==4); - maInnerBorderSize.mnLeft = aInnerBorder[0]; - maInnerBorderSize.mnTop = aInnerBorder[1]; - maInnerBorderSize.mnRight = aInnerBorder[2]; - maInnerBorderSize.mnBottom = aInnerBorder[3]; - - ::std::vector<sal_Int32> aOuterBorder (rpTheme->GetBorderSize(rsStyleName, true)); - OSL_ASSERT(aOuterBorder.size()==4); - maOuterBorderSize.mnLeft = aOuterBorder[0]; - maOuterBorderSize.mnTop = aOuterBorder[1]; - maOuterBorderSize.mnRight = aOuterBorder[2]; - maOuterBorderSize.mnBottom = aOuterBorder[3]; - } - catch(beans::UnknownPropertyException&) - { - OSL_ASSERT(false); - } - - UpdateBorderSizes(); -} - -awt::Rectangle RendererPaneStyle::AddBorder ( - const awt::Rectangle& rBox, - const drawing::framework::BorderType eBorderType) const -{ - const BorderSize* pBorderSize = nullptr; - switch (eBorderType) - { - case drawing::framework::BorderType_INNER_BORDER: - pBorderSize = &maInnerBorderSize; - break; - case drawing::framework::BorderType_OUTER_BORDER: - pBorderSize = &maOuterBorderSize; - break; - case drawing::framework::BorderType_TOTAL_BORDER: - pBorderSize = &maTotalBorderSize; - break; - default: - return rBox; - } - return awt::Rectangle ( - rBox.X - pBorderSize->mnLeft, - rBox.Y - pBorderSize->mnTop, - rBox.Width + pBorderSize->mnLeft + pBorderSize->mnRight, - rBox.Height + pBorderSize->mnTop + pBorderSize->mnBottom); -} - -awt::Rectangle RendererPaneStyle::RemoveBorder ( - const awt::Rectangle& rBox, - const css::drawing::framework::BorderType eBorderType) const -{ - const BorderSize* pBorderSize = nullptr; - switch (eBorderType) - { - case drawing::framework::BorderType_INNER_BORDER: - pBorderSize = &maInnerBorderSize; - break; - case drawing::framework::BorderType_OUTER_BORDER: - pBorderSize = &maOuterBorderSize; - break; - case drawing::framework::BorderType_TOTAL_BORDER: - pBorderSize = &maTotalBorderSize; - break; - default: - return rBox; - } - return awt::Rectangle ( - rBox.X + pBorderSize->mnLeft, - rBox.Y + pBorderSize->mnTop, - rBox.Width - pBorderSize->mnLeft - pBorderSize->mnRight, - rBox.Height - pBorderSize->mnTop - pBorderSize->mnBottom); -} - -Reference<rendering::XCanvasFont> RendererPaneStyle::GetFont ( - const Reference<rendering::XCanvas>& rxCanvas) const -{ - if (mpFont) - { - mpFont->PrepareFont(rxCanvas); - return mpFont->mxFont; - } - return Reference<rendering::XCanvasFont>(); -} - -void RendererPaneStyle::UpdateBorderSizes() -{ - maTotalBorderSize.mnLeft = maInnerBorderSize.mnLeft + maOuterBorderSize.mnLeft; - maTotalBorderSize.mnTop = maInnerBorderSize.mnTop + maOuterBorderSize.mnTop; - maTotalBorderSize.mnRight = maInnerBorderSize.mnRight + maOuterBorderSize.mnRight; - maTotalBorderSize.mnBottom = maInnerBorderSize.mnBottom + maOuterBorderSize.mnBottom; -} - -SharedBitmapDescriptor RendererPaneStyle::GetBitmap( - const std::shared_ptr<PresenterTheme>& rpTheme, - const OUString& rsStyleName, - const OUString& rsBitmapName) -{ - SharedBitmapDescriptor pDescriptor (rpTheme->GetBitmap(rsStyleName, rsBitmapName)); - if (pDescriptor) - return pDescriptor; - else - return mpEmpty; -} - -} // end of anonymous namespace - -} // end of namespace ::sd::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneBorderPainter.hxx b/sdext/source/presenter/PresenterPaneBorderPainter.hxx deleted file mode 100644 index b7b9c0de1e06..000000000000 --- a/sdext/source/presenter/PresenterPaneBorderPainter.hxx +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANEBORDERPAINTER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANEBORDERPAINTER_HXX - -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/drawing/framework/XPaneBorderPainter.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <memory> - -namespace sdext::presenter { - -class PresenterPane; -class PresenterTheme; - -typedef ::cppu::WeakComponentImplHelper< - css::drawing::framework::XPaneBorderPainter -> PresenterPaneBorderPainterInterfaceBase; - -/** This class is responsible for painting window borders of PresenterPane - objects. -*/ -class PresenterPaneBorderPainter - : protected ::cppu::BaseMutex, - public PresenterPaneBorderPainterInterfaceBase -{ -public: - explicit PresenterPaneBorderPainter ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - virtual ~PresenterPaneBorderPainter() override; - PresenterPaneBorderPainter(const PresenterPaneBorderPainter&) = delete; - PresenterPaneBorderPainter& operator=(const PresenterPaneBorderPainter&) = delete; - - /** Transform the bounding box of the window content to the outer - bounding box of the border that is painted around it. - @param rsPaneURL - Specifies the pane style that is used to determine the border sizes. - @param rInnerBox - The rectangle of the inner window content. - */ - css::awt::Rectangle AddBorder ( - const OUString& rsPaneURL, - const css::awt::Rectangle& rInnerBox, - const css::drawing::framework::BorderType eBorderType) const; - - /** Transform the outer bounding box of a window to the bounding box of - the inner content area. - @param rsPaneURL - Specifies the pane style that is used to determine the border sizes. - @param rOuterBox - The bounding box of the rectangle around the window. - @param bIsTitleVisible - This flag controls whether the upper part of the frame is - supposed to contain the window title. - */ - css::awt::Rectangle RemoveBorder ( - const OUString& rsPaneURL, - const css::awt::Rectangle& rOuterBox, - const css::drawing::framework::BorderType eBorderType) const; - - void SetTheme (const std::shared_ptr<PresenterTheme>& rpTheme); - - class Renderer; - - // XPaneBorderPainter - - virtual css::awt::Rectangle SAL_CALL addBorder ( - const OUString& rsPaneBorderStyleName, - const css::awt::Rectangle& rRectangle, - css::drawing::framework::BorderType eBorderType) override; - - virtual css::awt::Rectangle SAL_CALL removeBorder ( - const OUString& rsPaneBorderStyleName, - const css::awt::Rectangle& rRectangle, - css::drawing::framework::BorderType eBorderType) override; - - virtual void SAL_CALL paintBorder ( - const OUString& rsPaneBorderStyleName, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rOuterBorderRectangle, - const css::awt::Rectangle& rRepaintArea, - const OUString& rsTitle) override; - - virtual void SAL_CALL paintBorderWithCallout ( - const OUString& rsPaneBorderStyleName, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rOuterBorderRectangle, - const css::awt::Rectangle& rRepaintArea, - const OUString& rsTitle, - const css::awt::Point& rCalloutAnchor) override; - - virtual css::awt::Point SAL_CALL getCalloutOffset ( - const OUString& rsPaneBorderStyleName) override; - -private: - css::uno::Reference<css::uno::XComponentContext> mxContext; - std::shared_ptr<PresenterTheme> mpTheme; - std::unique_ptr<Renderer> mpRenderer; - - /** When the theme for the border has not yet been loaded then try again - when this method is called. - @return - Returns <TRUE/> only one time when the theme is loaded and/or the - renderer is initialized. - */ - bool ProvideTheme ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - void ProvideTheme(); - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneContainer.cxx b/sdext/source/presenter/PresenterPaneContainer.cxx deleted file mode 100644 index a7320fdb2c09..000000000000 --- a/sdext/source/presenter/PresenterPaneContainer.cxx +++ /dev/null @@ -1,333 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterPaneContainer.hxx" -#include "PresenterPaneBase.hxx" - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -PresenterPaneContainer::PresenterPaneContainer ( - const Reference<XComponentContext>& rxContext) - : PresenterPaneContainerInterfaceBase(m_aMutex), - maPanes(), - mxPresenterHelper() -{ - Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager()); - if (xFactory.is()) - { - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - rxContext), - UNO_QUERY_THROW); - } -} - -PresenterPaneContainer::~PresenterPaneContainer() -{ -} - -void PresenterPaneContainer::PreparePane ( - const Reference<XResourceId>& rxPaneId, - const OUString& rsViewURL, - const OUString& rsTitle, - const OUString& rsAccessibleTitle, - const bool bIsOpaque, - const ViewInitializationFunction& rViewInitialization) -{ - if ( ! rxPaneId.is()) - return; - - SharedPaneDescriptor pPane (FindPaneURL(rxPaneId->getResourceURL())); - if (pPane) - return; - - // No entry found for the given pane id. Create a new one. - SharedPaneDescriptor pDescriptor = std::make_shared<PaneDescriptor>(); - pDescriptor->mxPaneId = rxPaneId; - pDescriptor->msViewURL = rsViewURL; - pDescriptor->mxPane = nullptr; - if (rsTitle.indexOf('%') < 0) - { - pDescriptor->msTitle = rsTitle; - pDescriptor->msTitleTemplate.clear(); - } - else - { - pDescriptor->msTitleTemplate = rsTitle; - pDescriptor->msTitle.clear(); - } - pDescriptor->msAccessibleTitleTemplate = rsAccessibleTitle; - pDescriptor->maViewInitialization = rViewInitialization; - pDescriptor->mbIsActive = true; - pDescriptor->mbIsOpaque = bIsOpaque; - pDescriptor->mbIsSprite = false; - - maPanes.push_back(pDescriptor); -} - -void SAL_CALL PresenterPaneContainer::disposing() -{ - for (const auto& rxPane : maPanes) - if (rxPane->mxPaneId.is()) - RemovePane(rxPane->mxPaneId); -} - -PresenterPaneContainer::SharedPaneDescriptor - PresenterPaneContainer::StorePane (const rtl::Reference<PresenterPaneBase>& rxPane) -{ - SharedPaneDescriptor pDescriptor; - - if (rxPane.is()) - { - OUString sPaneURL; - Reference<XResourceId> xPaneId (rxPane->getResourceId()); - if (xPaneId.is()) - sPaneURL = xPaneId->getResourceURL(); - - pDescriptor = FindPaneURL(sPaneURL); - if (!pDescriptor) - PreparePane(xPaneId, OUString(), OUString(), OUString(), - false, ViewInitializationFunction()); - pDescriptor = FindPaneURL(sPaneURL); - if (pDescriptor) - { - Reference<awt::XWindow> xWindow (rxPane->getWindow()); - pDescriptor->mxContentWindow = xWindow; - pDescriptor->mxPaneId = xPaneId; - pDescriptor->mxPane = rxPane; - pDescriptor->mxPane->SetTitle(pDescriptor->msTitle); - - if (xWindow.is()) - xWindow->addEventListener(this); - } - } - - return pDescriptor; -} - -PresenterPaneContainer::SharedPaneDescriptor - PresenterPaneContainer::StoreBorderWindow( - const Reference<XResourceId>& rxPaneId, - const Reference<awt::XWindow>& rxBorderWindow) -{ - // The content window may not be present. Use the resource URL of the - // pane id as key. - OUString sPaneURL; - if (rxPaneId.is()) - sPaneURL = rxPaneId->getResourceURL(); - - SharedPaneDescriptor pDescriptor (FindPaneURL(sPaneURL)); - if (pDescriptor) - { - pDescriptor->mxBorderWindow = rxBorderWindow; - return pDescriptor; - } - else - return SharedPaneDescriptor(); -} - -PresenterPaneContainer::SharedPaneDescriptor - PresenterPaneContainer::StoreView ( - const Reference<XView>& rxView) -{ - SharedPaneDescriptor pDescriptor; - - if (rxView.is()) - { - OUString sPaneURL; - Reference<XResourceId> xViewId (rxView->getResourceId()); - if (xViewId.is()) - { - Reference<XResourceId> xPaneId (xViewId->getAnchor()); - if (xPaneId.is()) - sPaneURL = xPaneId->getResourceURL(); - } - - pDescriptor = FindPaneURL(sPaneURL); - if (pDescriptor) - { - pDescriptor->mxView = rxView; - try - { - if (pDescriptor->maViewInitialization) - pDescriptor->maViewInitialization(rxView); - } - catch (RuntimeException&) - { - OSL_ASSERT(false); - } - } - } - - return pDescriptor; -} - -PresenterPaneContainer::SharedPaneDescriptor - PresenterPaneContainer::RemovePane (const Reference<XResourceId>& rxPaneId) -{ - SharedPaneDescriptor pDescriptor (FindPaneId(rxPaneId)); - if (pDescriptor) - { - if (pDescriptor->mxContentWindow.is()) - pDescriptor->mxContentWindow->removeEventListener(this); - pDescriptor->mxContentWindow = nullptr; - pDescriptor->mxBorderWindow = nullptr; - pDescriptor->mxPane = nullptr; - pDescriptor->mxView = nullptr; - pDescriptor->mbIsActive = false; - } - return pDescriptor; -} - -PresenterPaneContainer::SharedPaneDescriptor - PresenterPaneContainer::RemoveView (const Reference<XView>& rxView) -{ - SharedPaneDescriptor pDescriptor; - - if (rxView.is()) - { - OUString sPaneURL; - Reference<XResourceId> xViewId (rxView->getResourceId()); - if (xViewId.is()) - { - Reference<XResourceId> xPaneId (xViewId->getAnchor()); - if (xPaneId.is()) - sPaneURL = xPaneId->getResourceURL(); - } - - pDescriptor = FindPaneURL(sPaneURL); - if (pDescriptor) - { - pDescriptor->mxView = nullptr; - } - } - - return pDescriptor; -} - -PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindBorderWindow ( - const Reference<awt::XWindow>& rxBorderWindow) -{ - auto iPane = std::find_if(maPanes.begin(), maPanes.end(), - [&rxBorderWindow](const SharedPaneDescriptor& rxPane) { return rxPane->mxBorderWindow == rxBorderWindow; }); - if (iPane != maPanes.end()) - return *iPane; - return SharedPaneDescriptor(); -} - -PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindContentWindow ( - const Reference<awt::XWindow>& rxContentWindow) -{ - auto iPane = std::find_if(maPanes.begin(), maPanes.end(), - [&rxContentWindow](const SharedPaneDescriptor& rxPane) { return rxPane->mxContentWindow == rxContentWindow; }); - if (iPane != maPanes.end()) - return *iPane; - return SharedPaneDescriptor(); -} - -PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneURL ( - const OUString& rsPaneURL) -{ - auto iPane = std::find_if(maPanes.begin(), maPanes.end(), - [&rsPaneURL](const SharedPaneDescriptor& rxPane) { return rxPane->mxPaneId->getResourceURL() == rsPaneURL; }); - if (iPane != maPanes.end()) - return *iPane; - return SharedPaneDescriptor(); -} - -PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneId ( - const Reference<XResourceId>& rxPaneId) -{ - if ( ! rxPaneId.is()) - return SharedPaneDescriptor(); - - auto iPane = std::find_if(maPanes.begin(), maPanes.end(), - [&rxPaneId](const SharedPaneDescriptor& rxPane) { return rxPaneId->compareTo(rxPane->mxPaneId) == 0; }); - if (iPane != maPanes.end()) - return *iPane; - return SharedPaneDescriptor(); -} - -PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindViewURL ( - const OUString& rsViewURL) -{ - auto iPane = std::find_if(maPanes.begin(), maPanes.end(), - [&rsViewURL](const SharedPaneDescriptor& rxPane) { return rsViewURL == rxPane->msViewURL; }); - if (iPane != maPanes.end()) - return *iPane; - return SharedPaneDescriptor(); -} - -OUString PresenterPaneContainer::GetPaneURLForViewURL (const OUString& rsViewURL) -{ - SharedPaneDescriptor pDescriptor (FindViewURL(rsViewURL)); - if (pDescriptor) - if (pDescriptor->mxPaneId.is()) - return pDescriptor->mxPaneId->getResourceURL(); - return OUString(); -} - -void PresenterPaneContainer::ToTop (const SharedPaneDescriptor& rpDescriptor) -{ - if (!rpDescriptor) - return; - - // Find iterator for pDescriptor. - PaneList::iterator iEnd (maPanes.end()); - auto iPane = std::find_if(maPanes.begin(), iEnd, - [&rpDescriptor](SharedPaneDescriptor& rxPane) { return rxPane.get() == rpDescriptor.get(); }); - OSL_ASSERT(iPane!=iEnd); - if (iPane == iEnd) - return; - - if (mxPresenterHelper.is()) - mxPresenterHelper->toTop(rpDescriptor->mxBorderWindow); - - maPanes.erase(iPane); - maPanes.push_back(rpDescriptor); -} - -//----- XEventListener -------------------------------------------------------- - -void SAL_CALL PresenterPaneContainer::disposing ( - const css::lang::EventObject& rEvent) -{ - SharedPaneDescriptor pDescriptor ( - FindContentWindow(Reference<awt::XWindow>(rEvent.Source, UNO_QUERY))); - if (pDescriptor) - { - RemovePane(pDescriptor->mxPaneId); - } -} - -//===== PresenterPaneContainer::PaneDescriptor ================================ - -void PresenterPaneContainer::PaneDescriptor::SetActivationState (const bool bIsActive) -{ - mbIsActive = bIsActive; -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneContainer.hxx b/sdext/source/presenter/PresenterPaneContainer.hxx deleted file mode 100644 index 136c25690b16..000000000000 --- a/sdext/source/presenter/PresenterPaneContainer.hxx +++ /dev/null @@ -1,161 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANECONTAINER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANECONTAINER_HXX - -#include "PresenterPaneBase.hxx" -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/drawing/framework/XResourceId.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <rtl/ref.hxx> - -#include <functional> -#include <memory> -#include <vector> - -namespace sdext::presenter { - -class PresenterPaneBase; -class PresenterSprite; - -typedef ::cppu::WeakComponentImplHelper < - css::lang::XEventListener -> PresenterPaneContainerInterfaceBase; - -/** This class could also be called PresenterPaneAndViewContainer because it - stores not only references to all panes that belong to the presenter - screen but stores the views displayed in these panes as well. -*/ -class PresenterPaneContainer - : private ::cppu::BaseMutex, - public PresenterPaneContainerInterfaceBase -{ -public: - explicit PresenterPaneContainer ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - virtual ~PresenterPaneContainer() override; - PresenterPaneContainer(const PresenterPaneContainer&) = delete; - PresenterPaneContainer& operator=(const PresenterPaneContainer&) = delete; - - virtual void SAL_CALL disposing() override; - - typedef ::std::function<void (const css::uno::Reference<css::drawing::framework::XView>&)> - ViewInitializationFunction; - - /** Each pane descriptor holds references to one pane and the view - displayed in this pane as well as the other information that is used - to manage the pane window like an XWindow reference, the title, and - the coordinates. - - A initialization function for the view is stored as well. This - function is executed as soon as a view is created. - */ - class PaneDescriptor - { - public: - css::uno::Reference<css::drawing::framework::XResourceId> mxPaneId; - OUString msViewURL; - ::rtl::Reference<PresenterPaneBase> mxPane; - css::uno::Reference<css::drawing::framework::XView> mxView; - css::uno::Reference<css::awt::XWindow> mxContentWindow; - css::uno::Reference<css::awt::XWindow> mxBorderWindow; - OUString msTitleTemplate; - OUString msAccessibleTitleTemplate; - OUString msTitle; - ViewInitializationFunction maViewInitialization; - bool mbIsActive; - bool mbIsOpaque; - bool mbIsSprite; - - void SetActivationState (const bool bIsActive); - }; - typedef std::shared_ptr<PaneDescriptor> SharedPaneDescriptor; - typedef ::std::vector<SharedPaneDescriptor> PaneList; - PaneList maPanes; - - void PreparePane ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId, - const OUString& rsViewURL, - const OUString& rsTitle, - const OUString& rsAccessibleTitle, - const bool bIsOpaque, - const ViewInitializationFunction& rViewInitialization); - - SharedPaneDescriptor StorePane ( - const rtl::Reference<PresenterPaneBase>& rxPane); - - SharedPaneDescriptor StoreBorderWindow( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId, - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow); - - SharedPaneDescriptor StoreView ( - const css::uno::Reference<css::drawing::framework::XView>& rxView); - - SharedPaneDescriptor RemovePane ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId); - - SharedPaneDescriptor RemoveView ( - const css::uno::Reference<css::drawing::framework::XView>& rxView); - - /** Find the pane whose border window is identical to the given border - window. - */ - SharedPaneDescriptor FindBorderWindow ( - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow); - - /** Find the pane whose border window is identical to the given content - window. - */ - SharedPaneDescriptor FindContentWindow ( - const css::uno::Reference<css::awt::XWindow>& rxBorderWindow); - - /** Find the pane whose pane URL is identical to the given URL string. - */ - SharedPaneDescriptor FindPaneURL (const OUString& rsPaneURL); - - /** Find the pane whose resource id is identical to the given one. - */ - SharedPaneDescriptor FindPaneId (const css::uno::Reference< - css::drawing::framework::XResourceId>& rxPaneId); - - SharedPaneDescriptor FindViewURL (const OUString& rsViewURL); - - OUString GetPaneURLForViewURL (const OUString& rsViewURL); - - void ToTop (const SharedPaneDescriptor& rpDescriptor); - - // XEventListener - - virtual void SAL_CALL disposing ( - const css::lang::EventObject& rEvent) override; - -private: - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneFactory.cxx b/sdext/source/presenter/PresenterPaneFactory.cxx deleted file mode 100644 index a9c5bb907f25..000000000000 --- a/sdext/source/presenter/PresenterPaneFactory.cxx +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterPaneFactory.hxx" -#include "PresenterController.hxx" -#include "PresenterPane.hxx" -#include "PresenterPaneBorderPainter.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterSpritePane.hxx" -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/lang/XComponent.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -//===== PresenterPaneFactory ================================================== - -Reference<drawing::framework::XResourceFactory> PresenterPaneFactory::Create ( - const Reference<uno::XComponentContext>& rxContext, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) -{ - rtl::Reference<PresenterPaneFactory> pFactory ( - new PresenterPaneFactory(rxContext,rpPresenterController)); - pFactory->Register(rxController); - return Reference<drawing::framework::XResourceFactory>( - static_cast<XWeak*>(pFactory.get()), UNO_QUERY); -} - -PresenterPaneFactory::PresenterPaneFactory ( - const Reference<uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterPaneFactoryInterfaceBase(m_aMutex), - mxComponentContextWeak(rxContext), - mxConfigurationControllerWeak(), - mpPresenterController(rpPresenterController), - mpResourceCache() -{ -} - -void PresenterPaneFactory::Register (const Reference<frame::XController>& rxController) -{ - Reference<XConfigurationController> xCC; - try - { - // Get the configuration controller. - Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); - xCC.set(xCM->getConfigurationController()); - mxConfigurationControllerWeak = xCC; - if ( ! xCC.is()) - { - throw RuntimeException(); - } - xCC->addResourceFactory( - "private:resource/pane/Presenter/*", - this); - } - catch (RuntimeException&) - { - OSL_ASSERT(false); - if (xCC.is()) - xCC->removeResourceFactoryForReference(this); - mxConfigurationControllerWeak = WeakReference<XConfigurationController>(); - - throw; - } -} - -PresenterPaneFactory::~PresenterPaneFactory() -{ -} - -void SAL_CALL PresenterPaneFactory::disposing() -{ - Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); - if (xCC.is()) - xCC->removeResourceFactoryForReference(this); - mxConfigurationControllerWeak = WeakReference<XConfigurationController>(); - - // Dispose the panes in the cache. - if (mpResourceCache != nullptr) - { - for (const auto& rxPane : *mpResourceCache) - { - Reference<lang::XComponent> xPaneComponent (rxPane.second, UNO_QUERY); - if (xPaneComponent.is()) - xPaneComponent->dispose(); - } - mpResourceCache.reset(); - } -} - -//----- XPaneFactory ---------------------------------------------------------- - -Reference<XResource> SAL_CALL PresenterPaneFactory::createResource ( - const Reference<XResourceId>& rxPaneId) -{ - ThrowIfDisposed(); - - if ( ! rxPaneId.is()) - return nullptr; - - const OUString sPaneURL (rxPaneId->getResourceURL()); - if (sPaneURL.isEmpty()) - return nullptr; - - if (mpResourceCache != nullptr) - { - // Has the requested resource already been created? - ResourceContainer::const_iterator iResource (mpResourceCache->find(sPaneURL)); - if (iResource != mpResourceCache->end()) - { - // Yes. Mark it as active. - rtl::Reference<PresenterPaneContainer> pPaneContainer( - mpPresenterController->GetPaneContainer()); - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - pPaneContainer->FindPaneURL(sPaneURL)); - if (pDescriptor) - { - pDescriptor->SetActivationState(true); - if (pDescriptor->mxBorderWindow.is()) - pDescriptor->mxBorderWindow->setVisible(true); - pPaneContainer->StorePane(pDescriptor->mxPane); - } - - return iResource->second; - } - } - - // No. Create a new one. - Reference<XResource> xResource = CreatePane(rxPaneId); - return xResource; -} - -void SAL_CALL PresenterPaneFactory::releaseResource (const Reference<XResource>& rxResource) -{ - ThrowIfDisposed(); - - if ( ! rxResource.is()) - throw lang::IllegalArgumentException(); - - // Mark the pane as inactive. - rtl::Reference<PresenterPaneContainer> pPaneContainer( - mpPresenterController->GetPaneContainer()); - const OUString sPaneURL (rxResource->getResourceId()->getResourceURL()); - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - pPaneContainer->FindPaneURL(sPaneURL)); - if (!pDescriptor) - return; - - pDescriptor->SetActivationState(false); - if (pDescriptor->mxBorderWindow.is()) - pDescriptor->mxBorderWindow->setVisible(false); - - if (mpResourceCache != nullptr) - { - // Store the pane in the cache. - (*mpResourceCache)[sPaneURL] = rxResource; - } - else - { - // Dispose the pane. - Reference<lang::XComponent> xPaneComponent (rxResource, UNO_QUERY); - if (xPaneComponent.is()) - xPaneComponent->dispose(); - } -} - - -Reference<XResource> PresenterPaneFactory::CreatePane ( - const Reference<XResourceId>& rxPaneId) -{ - if ( ! rxPaneId.is()) - return nullptr; - - Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); - if ( ! xCC.is()) - return nullptr; - - Reference<XComponentContext> xContext (mxComponentContextWeak); - if ( ! xContext.is()) - return nullptr; - - Reference<XPane> xParentPane (xCC->getResource(rxPaneId->getAnchor()), UNO_QUERY); - if ( ! xParentPane.is()) - return nullptr; - - try - { - return CreatePane( - rxPaneId, - xParentPane, - rxPaneId->getFullResourceURL().Arguments == "Sprite=1"); - } - catch (Exception&) - { - OSL_ASSERT(false); - } - - return nullptr; -} - -Reference<XResource> PresenterPaneFactory::CreatePane ( - const Reference<XResourceId>& rxPaneId, - const Reference<drawing::framework::XPane>& rxParentPane, - const bool bIsSpritePane) -{ - Reference<XComponentContext> xContext (mxComponentContextWeak); - Reference<lang::XMultiComponentFactory> xFactory ( - xContext->getServiceManager(), UNO_SET_THROW); - - // Create a border window and canvas and store it in the pane - // container. - - // Create the pane. - ::rtl::Reference<PresenterPaneBase> xPane; - if (bIsSpritePane) - { - xPane.set( new PresenterSpritePane(xContext, mpPresenterController)); - } - else - { - xPane.set( new PresenterPane(xContext, mpPresenterController)); - } - - // Supply arguments. - Sequence<Any> aArguments (6); - aArguments[0] <<= rxPaneId; - aArguments[1] <<= rxParentPane->getWindow(); - aArguments[2] <<= rxParentPane->getCanvas(); - aArguments[3] <<= OUString(); - aArguments[4] <<= Reference<drawing::framework::XPaneBorderPainter>( - static_cast<XWeak*>(mpPresenterController->GetPaneBorderPainter().get()), - UNO_QUERY); - aArguments[5] <<= !bIsSpritePane; - xPane->initialize(aArguments); - - // Store pane and canvases and windows in container. - ::rtl::Reference<PresenterPaneContainer> pContainer ( - mpPresenterController->GetPaneContainer()); - PresenterPaneContainer::SharedPaneDescriptor pDescriptor( - pContainer->StoreBorderWindow(rxPaneId, xPane->GetBorderWindow())); - pContainer->StorePane(xPane); - if (pDescriptor) - { - pDescriptor->mbIsSprite = bIsSpritePane; - - // Get the window of the frame and make that visible. - Reference<awt::XWindow> xWindow (pDescriptor->mxBorderWindow, UNO_SET_THROW); - xWindow->setVisible(true); - } - - return Reference<XResource>(static_cast<XWeak*>(xPane.get()), UNO_QUERY_THROW); -} - -void PresenterPaneFactory::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterPaneFactory object has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -} // end of namespace sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterPaneFactory.hxx b/sdext/source/presenter/PresenterPaneFactory.hxx deleted file mode 100644 index 45f9541c65da..000000000000 --- a/sdext/source/presenter/PresenterPaneFactory.hxx +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANEFACTORY_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPANEFACTORY_HXX - -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/drawing/framework/XResourceFactory.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <rtl/ref.hxx> -#include <map> -#include <memory> - -namespace sdext::presenter { - -class PresenterController; - -typedef ::cppu::WeakComponentImplHelper < - css::drawing::framework::XResourceFactory -> PresenterPaneFactoryInterfaceBase; - -/** The PresenterPaneFactory provides a fixed set of panes. - - In order to make the presenter screen more easily extendable in the - future the set of supported panes could be made extendable on demand. -*/ -class PresenterPaneFactory - : public ::cppu::BaseMutex, - public PresenterPaneFactoryInterfaceBase -{ -public: - static constexpr OUStringLiteral msCurrentSlidePreviewPaneURL - = u"private:resource/pane/Presenter/Pane1"; - static constexpr OUStringLiteral msNextSlidePreviewPaneURL - = u"private:resource/pane/Presenter/Pane2"; - static constexpr OUStringLiteral msNotesPaneURL = u"private:resource/pane/Presenter/Pane3"; - static constexpr OUStringLiteral msToolBarPaneURL = u"private:resource/pane/Presenter/Pane4"; - static constexpr OUStringLiteral msSlideSorterPaneURL - = u"private:resource/pane/Presenter/Pane5"; - - /** Create a new instance of this class and register it as resource - factory in the drawing framework of the given controller. - This registration keeps it alive. When the drawing framework is - shut down and releases its reference to the factory then the factory - is destroyed. - */ - static css::uno::Reference<css::drawing::framework::XResourceFactory> Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterPaneFactory() override; - - virtual void SAL_CALL disposing() override; - - // XResourceFactory - - virtual css::uno::Reference<css::drawing::framework::XResource> - SAL_CALL createResource ( - const css::uno::Reference< - css::drawing::framework::XResourceId>& rxPaneId) override; - - virtual void SAL_CALL - releaseResource ( - const css::uno::Reference<css::drawing::framework::XResource>& - rxPane) override; - -private: - css::uno::WeakReference<css::uno::XComponentContext> mxComponentContextWeak; - css::uno::WeakReference<css::drawing::framework::XConfigurationController> - mxConfigurationControllerWeak; - ::rtl::Reference<PresenterController> mpPresenterController; - typedef ::std::map<OUString, css::uno::Reference<css::drawing::framework::XResource> > - ResourceContainer; - std::unique_ptr<ResourceContainer> mpResourceCache; - - PresenterPaneFactory ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController); - - void Register (const css::uno::Reference<css::frame::XController>& rxController); - - css::uno::Reference<css::drawing::framework::XResource> CreatePane ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId); - css::uno::Reference<css::drawing::framework::XResource> CreatePane ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId, - const css::uno::Reference<css::drawing::framework::XPane>& rxParentPane, - const bool bIsSpritePane); - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterProtocolHandler.cxx b/sdext/source/presenter/PresenterProtocolHandler.cxx deleted file mode 100644 index 0ee967ffe063..000000000000 --- a/sdext/source/presenter/PresenterProtocolHandler.cxx +++ /dev/null @@ -1,827 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <memory> -#include "PresenterProtocolHandler.hxx" -#include "PresenterController.hxx" -#include "PresenterNotesView.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterViewFactory.hxx" -#include "PresenterWindowManager.hxx" -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/supportsservice.hxx> -#include <algorithm> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -namespace { - class Command - { - public: - virtual ~Command() {} - virtual void Execute() = 0; - virtual bool IsEnabled() const { return true; } - virtual Any GetState() const { return Any(false); } - }; - - class GotoPreviousSlideCommand : public Command - { - public: - explicit GotoPreviousSlideCommand ( - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - virtual bool IsEnabled() const override; - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - - class GotoNextSlideCommand : public Command - { - public: - explicit GotoNextSlideCommand ( - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - // The next slide command is always enabled, even when the current slide - // is the last slide: from the last slide it goes to the pause slide, - // and from there it ends the slide show. - virtual bool IsEnabled() const override { return true; } - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - - class GotoNextEffectCommand : public Command - { - public: - explicit GotoNextEffectCommand ( - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - virtual bool IsEnabled() const override; - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - - class SwitchMonitorCommand : public Command - { - public: - explicit SwitchMonitorCommand ( - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - - class PauseResumeCommand : public Command - { - public: - explicit PauseResumeCommand(const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - virtual Any GetState() const override; - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - - /// This command restarts the presentation timer. - class RestartTimerCommand : public Command - { - public: - explicit RestartTimerCommand(const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - - class SetNotesViewCommand : public Command - { - public: - SetNotesViewCommand ( - const bool bOn, - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - virtual Any GetState() const override; - private: - bool mbOn; - rtl::Reference<PresenterController> mpPresenterController; - }; - - class SetSlideSorterCommand : public Command - { - public: - SetSlideSorterCommand ( - const bool bOn, - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - virtual Any GetState() const override; - private: - bool mbOn; - rtl::Reference<PresenterController> mpPresenterController; - }; - - class SetHelpViewCommand : public Command - { - public: - SetHelpViewCommand ( - const bool bOn, - const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - virtual Any GetState() const override; - private: - bool mbOn; - rtl::Reference<PresenterController> mpPresenterController; - }; - - class NotesFontSizeCommand : public Command - { - public: - NotesFontSizeCommand( - const rtl::Reference<PresenterController>& rpPresenterController, - const sal_Int32 nSizeChange); - virtual void Execute() override; - virtual Any GetState() const override; - protected: - ::rtl::Reference<PresenterNotesView> GetNotesView() const; - private: - rtl::Reference<PresenterController> mpPresenterController; - const sal_Int32 mnSizeChange; - }; - - class ExitPresenterCommand : public Command - { - public: - explicit ExitPresenterCommand(const rtl::Reference<PresenterController>& rpPresenterController); - virtual void Execute() override; - private: - rtl::Reference<PresenterController> mpPresenterController; - }; - -} // end of anonymous namespace - -namespace { - typedef ::cppu::WeakComponentImplHelper < - css::frame::XDispatch, - css::document::XEventListener - > PresenterDispatchInterfaceBase; -} - -class PresenterProtocolHandler::Dispatch - : protected ::cppu::BaseMutex, - public PresenterDispatchInterfaceBase -{ -public: - /** Create a new Dispatch object. When the given command name - (rsURLPath) is not known then an empty reference is returned. - */ - static Reference<frame::XDispatch> Create ( - const OUString& rsURLPath, - const ::rtl::Reference<PresenterController>& rpPresenterController); - - void SAL_CALL disposing() override; - static Command* CreateCommand ( - const OUString& rsURLPath, - const ::rtl::Reference<PresenterController>& rpPresenterController); - - // XDispatch - virtual void SAL_CALL dispatch( - const css::util::URL& aURL, - const css::uno::Sequence<css::beans::PropertyValue>& rArguments) override; - - virtual void SAL_CALL addStatusListener( - const css::uno::Reference<css::frame::XStatusListener>& rxListener, - const css::util::URL& rURL) override; - - virtual void SAL_CALL removeStatusListener ( - const css::uno::Reference<css::frame::XStatusListener>& rxListener, - const css::util::URL& rURL) override; - - // document::XEventListener - - virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent) override; - - // lang::XEventListener - - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - -private: - OUString msURLPath; - std::unique_ptr<Command> mpCommand; - ::rtl::Reference<PresenterController> mpPresenterController; - typedef ::std::vector<Reference<frame::XStatusListener> > StatusListenerContainer; - StatusListenerContainer maStatusListenerContainer; - bool mbIsListeningToWindowManager; - - Dispatch ( - const OUString& rsURLPath, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~Dispatch() override; -}; - - -//===== PresenterProtocolHandler ========================================================= - -PresenterProtocolHandler::PresenterProtocolHandler () - : PresenterProtocolHandlerInterfaceBase(m_aMutex) -{ -} - -PresenterProtocolHandler::~PresenterProtocolHandler() -{ -} - -void SAL_CALL PresenterProtocolHandler::disposing() -{ -} - -//----- XInitialize ----------------------------------------------------------- - -void SAL_CALL PresenterProtocolHandler::initialize (const Sequence<Any>& aArguments) -{ - ThrowIfDisposed(); - if (aArguments.getLength() <= 0) - return; - - try - { - Reference<frame::XFrame> xFrame; - if (aArguments[0] >>= xFrame) - { - mpPresenterController = PresenterController::Instance(xFrame); - } - } - catch (RuntimeException&) - { - OSL_ASSERT(false); - } -} - -OUString PresenterProtocolHandler::getImplementationName() -{ - return "org.libreoffice.comp.PresenterScreenProtocolHandler"; -} - -sal_Bool PresenterProtocolHandler::supportsService(OUString const & ServiceName) -{ - return cppu::supportsService(this, ServiceName); -} - -css::uno::Sequence<OUString> -PresenterProtocolHandler::getSupportedServiceNames() -{ - return { "com.sun.star.frame.ProtocolHandler" }; -} - -extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* -sdext_PresenterProtocolHandler_get_implementation( - css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&) -{ - return cppu::acquire(new PresenterProtocolHandler()); -} - -//----- XDispatchProvider ----------------------------------------------------- - -Reference<frame::XDispatch> SAL_CALL PresenterProtocolHandler::queryDispatch ( - const css::util::URL& rURL, - const OUString&, - sal_Int32) -{ - ThrowIfDisposed(); - - Reference<frame::XDispatch> xDispatch; - - if (rURL.Protocol == "vnd.org.libreoffice.presenterscreen:") - { - xDispatch.set(Dispatch::Create(rURL.Path, mpPresenterController)); - } - - return xDispatch; -} - -Sequence<Reference<frame::XDispatch> > SAL_CALL PresenterProtocolHandler::queryDispatches( - const Sequence<frame::DispatchDescriptor>&) -{ - ThrowIfDisposed(); - return Sequence<Reference<frame::XDispatch> >(); -} - - -void PresenterProtocolHandler::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterProtocolHandler object has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -//===== PresenterProtocolHandler::Dispatch ==================================== - -Reference<frame::XDispatch> PresenterProtocolHandler::Dispatch::Create ( - const OUString& rsURLPath, - const ::rtl::Reference<PresenterController>& rpPresenterController) -{ - ::rtl::Reference<Dispatch> pDispatch (new Dispatch (rsURLPath, rpPresenterController)); - if (pDispatch->mpCommand != nullptr) - return pDispatch; - else - return nullptr; -} - -PresenterProtocolHandler::Dispatch::Dispatch ( - const OUString& rsURLPath, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterDispatchInterfaceBase(m_aMutex), - msURLPath(rsURLPath), - mpCommand(CreateCommand(rsURLPath, rpPresenterController)), - mpPresenterController(rpPresenterController), - maStatusListenerContainer(), - mbIsListeningToWindowManager(false) -{ - if (mpCommand != nullptr) - { - mpPresenterController->GetWindowManager()->AddLayoutListener(this); - mbIsListeningToWindowManager = true; - } -} - -Command* PresenterProtocolHandler::Dispatch::CreateCommand ( - const OUString& rsURLPath, - const ::rtl::Reference<PresenterController>& rpPresenterController) -{ - if (rsURLPath.getLength() <= 5) - return nullptr; - - if (rsURLPath == "CloseNotes") - return new SetNotesViewCommand(false, rpPresenterController); - if (rsURLPath == "CloseSlideSorter") - return new SetSlideSorterCommand(false, rpPresenterController); - if (rsURLPath == "CloseHelp") - return new SetHelpViewCommand(false, rpPresenterController); - if (rsURLPath == "GrowNotesFont") - return new NotesFontSizeCommand(rpPresenterController, +1); - if (rsURLPath == "NextEffect") - return new GotoNextEffectCommand(rpPresenterController); - if (rsURLPath == "NextSlide") - return new GotoNextSlideCommand(rpPresenterController); - if (rsURLPath == "PrevSlide") - return new GotoPreviousSlideCommand(rpPresenterController); - if (rsURLPath == "SwitchMonitor") - return new SwitchMonitorCommand(rpPresenterController); - if (rsURLPath == "PauseResumeTimer") - return new PauseResumeCommand(rpPresenterController); - if (rsURLPath == "RestartTimer") - return new RestartTimerCommand(rpPresenterController); - if (rsURLPath == "ShowNotes") - return new SetNotesViewCommand(true, rpPresenterController); - if (rsURLPath == "ShowSlideSorter") - return new SetSlideSorterCommand(true, rpPresenterController); - if (rsURLPath == "ShowHelp") - return new SetHelpViewCommand(true, rpPresenterController); - if (rsURLPath == "ShrinkNotesFont") - return new NotesFontSizeCommand(rpPresenterController, -1); - if (rsURLPath == "ExitPresenter") - return new ExitPresenterCommand(rpPresenterController); - - return nullptr; -} - -PresenterProtocolHandler::Dispatch::~Dispatch() -{ -} - -void PresenterProtocolHandler::Dispatch::disposing() -{ - if (mbIsListeningToWindowManager) - { - if (mpPresenterController) - mpPresenterController->GetWindowManager()->RemoveLayoutListener(this); - mbIsListeningToWindowManager = false; - } - - msURLPath.clear(); - mpCommand.reset(); -} - -//----- XDispatch ------------------------------------------------------------- - -void SAL_CALL PresenterProtocolHandler::Dispatch::dispatch( - const css::util::URL& rURL, - const css::uno::Sequence<css::beans::PropertyValue>& /*rArguments*/) -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterProtocolHandler::Dispatch object has already been disposed", - static_cast<uno::XWeak*>(this)); - } - - if (rURL.Protocol != "vnd.org.libreoffice.presenterscreen:" - || rURL.Path != msURLPath) - { - // We can not throw an IllegalArgumentException - throw RuntimeException(); - } - - if (mpCommand != nullptr) - mpCommand->Execute(); -} - -void SAL_CALL PresenterProtocolHandler::Dispatch::addStatusListener( - const css::uno::Reference<css::frame::XStatusListener>& rxListener, - const css::util::URL& rURL) -{ - if (rURL.Path != msURLPath) - throw RuntimeException(); - - maStatusListenerContainer.push_back(rxListener); - - frame::FeatureStateEvent aEvent; - aEvent.FeatureURL = rURL; - aEvent.IsEnabled = mpCommand->IsEnabled(); - aEvent.Requery = false; - aEvent.State = mpCommand->GetState(); - rxListener->statusChanged(aEvent); -} - -void SAL_CALL PresenterProtocolHandler::Dispatch::removeStatusListener ( - const css::uno::Reference<css::frame::XStatusListener>& rxListener, - const css::util::URL& rURL) -{ - if (rURL.Path != msURLPath) - throw RuntimeException(); - - StatusListenerContainer::iterator iListener ( - ::std::find( - maStatusListenerContainer.begin(), - maStatusListenerContainer.end(), - rxListener)); - if (iListener != maStatusListenerContainer.end()) - maStatusListenerContainer.erase(iListener); -} - -//----- document::XEventListener ---------------------------------------------- - -void SAL_CALL PresenterProtocolHandler::Dispatch::notifyEvent ( - const css::document::EventObject&) -{ - mpCommand->GetState(); -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterProtocolHandler::Dispatch::disposing (const css::lang::EventObject&) -{ - mbIsListeningToWindowManager = false; -} - -//===== GotoPreviousSlideCommand ============================================== - -GotoPreviousSlideCommand::GotoPreviousSlideCommand ( - const rtl::Reference<PresenterController>& rpPresenterController) - : mpPresenterController(rpPresenterController) -{ -} - -void GotoPreviousSlideCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - if ( ! mpPresenterController->GetSlideShowController().is()) - return; - - mpPresenterController->GetSlideShowController()->gotoPreviousSlide(); -} - -bool GotoPreviousSlideCommand::IsEnabled() const -{ - if ( ! mpPresenterController.is()) - return false; - - if ( ! mpPresenterController->GetSlideShowController().is()) - return false; - - return mpPresenterController->GetSlideShowController()->getCurrentSlideIndex()>0; -} - -//===== GotoNextEffect ======================================================== - -GotoNextEffectCommand::GotoNextEffectCommand ( - const rtl::Reference<PresenterController>& rpPresenterController) - : mpPresenterController(rpPresenterController) -{ -} - -void GotoNextEffectCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - if ( ! mpPresenterController->GetSlideShowController().is()) - return; - - mpPresenterController->GetSlideShowController()->gotoNextEffect(); -} - -bool GotoNextEffectCommand::IsEnabled() const -{ - if ( ! mpPresenterController.is()) - return false; - - if ( ! mpPresenterController->GetSlideShowController().is()) - return false; - - return ( mpPresenterController->GetSlideShowController()->getNextSlideIndex() < mpPresenterController->GetSlideShowController()->getSlideCount() ); - -} - -//===== GotoNextSlide ========================================================= - -GotoNextSlideCommand::GotoNextSlideCommand ( - const rtl::Reference<PresenterController>& rpPresenterController) - : mpPresenterController(rpPresenterController) -{ -} - -void GotoNextSlideCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - if ( ! mpPresenterController->GetSlideShowController().is()) - return; - - mpPresenterController->GetSlideShowController()->gotoNextSlide(); -} - -//===== SwitchMonitorCommand ============================================== - -SwitchMonitorCommand::SwitchMonitorCommand ( - const rtl::Reference<PresenterController>& rpPresenterController) - : mpPresenterController(rpPresenterController) -{ -} - -void SwitchMonitorCommand::Execute() -{ - mpPresenterController->SwitchMonitors(); -} - -//===== PauseResumeCommand ============================================== - -PauseResumeCommand::PauseResumeCommand (const rtl::Reference<PresenterController>& rpPresenterController) -: mpPresenterController(rpPresenterController) -{ -} - -void PauseResumeCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return; - - IPresentationTime* pPresentationTime = mpPresenterController->GetPresentationTime(); - if (!pPresentationTime) - return; - - if(pPresentationTime->isPaused()) - { - pPresentationTime->setPauseStatus(false); - pWindowManager->SetPauseState(false); - } - else - { - pPresentationTime->setPauseStatus(true); - pWindowManager->SetPauseState(true); - } -} - -Any PauseResumeCommand::GetState() const -{ - if ( ! mpPresenterController.is()) - return Any(false); - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return Any(false); - - if (IPresentationTime* pPresentationTime = mpPresenterController->GetPresentationTime()) - { - return Any(pPresentationTime->isPaused()); - } - else - return Any(false); -} - -RestartTimerCommand::RestartTimerCommand (const rtl::Reference<PresenterController>& rpPresenterController) -: mpPresenterController(rpPresenterController) -{ -} - -void RestartTimerCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return; - - if (IPresentationTime* pPresentationTime = mpPresenterController->GetPresentationTime()) - { - //Resets the pause status and restarts the timer - pPresentationTime->setPauseStatus(false); - pWindowManager->SetPauseState(false); - pPresentationTime->restart(); - } -} - -//===== SetNotesViewCommand =================================================== - -SetNotesViewCommand::SetNotesViewCommand ( - const bool bOn, - const rtl::Reference<PresenterController>& rpPresenterController) - : mbOn(bOn), - mpPresenterController(rpPresenterController) -{ -} - -void SetNotesViewCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return; - - if (mbOn) - pWindowManager->SetViewMode(PresenterWindowManager::VM_Notes); - else - pWindowManager->SetViewMode(PresenterWindowManager::VM_Standard); -} - -Any SetNotesViewCommand::GetState() const -{ - if ( ! mpPresenterController.is()) - return Any(false); - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return Any(false); - - return Any(pWindowManager->GetViewMode() == PresenterWindowManager::VM_Notes); -} - -//===== SetSlideSorterCommand ================================================= - -SetSlideSorterCommand::SetSlideSorterCommand ( - const bool bOn, - const rtl::Reference<PresenterController>& rpPresenterController) - : mbOn(bOn), - mpPresenterController(rpPresenterController) -{ -} - -void SetSlideSorterCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return; - - pWindowManager->SetSlideSorterState(mbOn); -} - -Any SetSlideSorterCommand::GetState() const -{ - if ( ! mpPresenterController.is()) - return Any(false); - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return Any(false); - - return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_SlideOverview); -} - -//===== SetHelpViewCommand =================================================== - -SetHelpViewCommand::SetHelpViewCommand ( - const bool bOn, - const rtl::Reference<PresenterController>& rpPresenterController) - : mbOn(bOn), - mpPresenterController(rpPresenterController) -{ -} - -void SetHelpViewCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return; - - pWindowManager->SetHelpViewState(mbOn); -} - -Any SetHelpViewCommand::GetState() const -{ - if ( ! mpPresenterController.is()) - return Any(false); - - ::rtl::Reference<PresenterWindowManager> pWindowManager ( - mpPresenterController->GetWindowManager()); - if ( ! pWindowManager.is()) - return Any(false); - - return Any(pWindowManager->GetViewMode()==PresenterWindowManager::VM_Help); -} - -//===== NotesFontSizeCommand ================================================== - -NotesFontSizeCommand::NotesFontSizeCommand( - const rtl::Reference<PresenterController>& rpPresenterController, - const sal_Int32 nSizeChange) - : mpPresenterController(rpPresenterController), - mnSizeChange(nSizeChange) -{ -} - -::rtl::Reference<PresenterNotesView> NotesFontSizeCommand::GetNotesView() const -{ - if (!mpPresenterController) - return nullptr; - - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPresenterController->GetPaneContainer()->FindViewURL( - PresenterViewFactory::msNotesViewURL)); - if (!pDescriptor) - return nullptr; - - return dynamic_cast<PresenterNotesView*>(pDescriptor->mxView.get()); -} - -void NotesFontSizeCommand::Execute() -{ - ::rtl::Reference<PresenterNotesView> pView (GetNotesView()); - if (pView.is()) - pView->ChangeFontSize(mnSizeChange); -} - -Any NotesFontSizeCommand::GetState() const -{ - return Any(); -} - -//===== ExitPresenterCommand ================================================== - -ExitPresenterCommand::ExitPresenterCommand (const rtl::Reference<PresenterController>& rpPresenterController) -: mpPresenterController(rpPresenterController) -{ -} - -void ExitPresenterCommand::Execute() -{ - if ( ! mpPresenterController.is()) - return; - - mpPresenterController->ExitPresenter(); -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterProtocolHandler.hxx b/sdext/source/presenter/PresenterProtocolHandler.hxx deleted file mode 100644 index 3a5e33f3b8a6..000000000000 --- a/sdext/source/presenter/PresenterProtocolHandler.hxx +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPROTOCOLHANDLER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERPROTOCOLHANDLER_HXX - -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <com/sun/star/frame/XDispatchProvider.hpp> -#include <com/sun/star/frame/XDispatch.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <rtl/ref.hxx> - -namespace sdext::presenter { - -typedef ::cppu::WeakComponentImplHelper < - css::lang::XInitialization, - css::lang::XServiceInfo, - css::frame::XDispatchProvider -> PresenterProtocolHandlerInterfaceBase; - -class PresenterController; - -class PresenterProtocolHandler - : protected ::cppu::BaseMutex, - public PresenterProtocolHandlerInterfaceBase -{ -public: - PresenterProtocolHandler (); - virtual ~PresenterProtocolHandler() override; - - void SAL_CALL disposing() override; - - // XInitialization - - virtual void SAL_CALL initialize( - const css::uno::Sequence<css::uno::Any>& aArguments) override; - - OUString SAL_CALL getImplementationName() override; - - sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override; - - css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; - - // XDispatchProvider - - virtual css::uno::Reference<css::frame::XDispatch > SAL_CALL - queryDispatch ( - const css::util::URL& aURL, - const OUString& aTargetFrameName, - sal_Int32 nSearchFlags ) override; - - virtual css::uno::Sequence<css::uno::Reference<css::frame::XDispatch> > SAL_CALL - queryDispatches( - const css::uno::Sequence< css::frame::DispatchDescriptor>& rDescriptors) override; - -private: - class Dispatch; - ::rtl::Reference<PresenterController> mpPresenterController; - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterScreen.cxx b/sdext/source/presenter/PresenterScreen.cxx deleted file mode 100644 index c624adcdf614..000000000000 --- a/sdext/source/presenter/PresenterScreen.cxx +++ /dev/null @@ -1,812 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterScreen.hxx" -#include "PresenterConfigurationAccess.hxx" -#include "PresenterController.hxx" -#include "PresenterFrameworkObserver.hxx" -#include "PresenterHelper.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterPaneFactory.hxx" -#include "PresenterViewFactory.hxx" -#include "PresenterWindowManager.hxx" -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/drawing/framework/ResourceId.hpp> -#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp> -#include <com/sun/star/presentation/XPresentation2.hpp> -#include <com/sun/star/presentation/XPresentationSupplier.hpp> -#include <com/sun/star/document/XEventBroadcaster.hpp> -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/supportsservice.hxx> - -#include <vcl/svapp.hxx> -#include <sal/log.hxx> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::presentation; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -namespace { - typedef ::cppu::WeakComponentImplHelper < - css::document::XEventListener - > PresenterScreenListenerInterfaceBase; - - /** One instance of a PresenterScreenListener is registered per Impress - document and waits for the full screen slide show to start and to - end. - */ - class PresenterScreenListener - : private ::cppu::BaseMutex, - public PresenterScreenListenerInterfaceBase - { - public: - PresenterScreenListener ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XModel2>& rxModel); - PresenterScreenListener(const PresenterScreenListener&) = delete; - PresenterScreenListener& operator=(const PresenterScreenListener&) = delete; - - void Initialize(); - virtual void SAL_CALL disposing() override; - - // document::XEventListener - - virtual void SAL_CALL notifyEvent( const css::document::EventObject& Event ) override; - - // XEventListener - - virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent) override; - - private: - css::uno::Reference<css::frame::XModel2 > mxModel; - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - rtl::Reference<PresenterScreen> mpPresenterScreen; - }; -} - -//----- XServiceInfo --------------------------------------------------------------- - -Sequence< OUString > SAL_CALL PresenterScreenJob::getSupportedServiceNames() -{ - return { }; -} - -OUString SAL_CALL PresenterScreenJob::getImplementationName() -{ - return "org.libreoffice.comp.PresenterScreenJob"; -} - -sal_Bool SAL_CALL PresenterScreenJob::supportsService(const OUString& aServiceName) -{ - return cppu::supportsService(this, aServiceName); -} - - -extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* -sdext_PresenterScreenJob_get_implementation( - css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&) -{ - return cppu::acquire(new PresenterScreenJob(context)); -} - - -//===== PresenterScreenJob ==================================================== - -PresenterScreenJob::PresenterScreenJob (const Reference<XComponentContext>& rxContext) - : PresenterScreenJobInterfaceBase(m_aMutex), - mxComponentContext(rxContext) -{ -} - -PresenterScreenJob::~PresenterScreenJob() -{ -} - -void SAL_CALL PresenterScreenJob::disposing() -{ - mxComponentContext = nullptr; -} - -//----- XJob ----------------------------------------------------------- - -Any SAL_CALL PresenterScreenJob::execute( - const Sequence< beans::NamedValue >& Arguments ) -{ - Sequence< beans::NamedValue > lEnv; - auto pArg = std::find_if(Arguments.begin(), Arguments.end(), - [](const beans::NamedValue& rArg) { return rArg.Name == "Environment"; }); - if (pArg != Arguments.end()) - pArg->Value >>= lEnv; - - Reference<frame::XModel2> xModel; - auto pProp = std::find_if(lEnv.begin(), lEnv.end(), - [](const beans::NamedValue& rProp) { return rProp.Name == "Model"; }); - if (pProp != lEnv.end()) - pProp->Value >>= xModel; - - Reference< XServiceInfo > xInfo( xModel, UNO_QUERY ); - if( xInfo.is() && xInfo->supportsService("com.sun.star.presentation.PresentationDocument") ) - { - // Create a new listener that waits for the full screen presentation - // to start and to end. It takes care of its own lifetime. - ::rtl::Reference<PresenterScreenListener> pListener ( - new PresenterScreenListener(mxComponentContext, xModel)); - pListener->Initialize(); - } - - return Any(); -} - -//===== PresenterScreenListener =============================================== - -namespace { - -PresenterScreenListener::PresenterScreenListener ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XModel2>& rxModel) - : PresenterScreenListenerInterfaceBase(m_aMutex), - mxModel(rxModel), - mxComponentContext(rxContext), - mpPresenterScreen() -{ -} - -void PresenterScreenListener::Initialize() -{ - Reference< document::XEventListener > xDocListener( - static_cast< document::XEventListener* >(this), UNO_QUERY); - Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY ); - if( xDocBroadcaster.is() ) - xDocBroadcaster->addEventListener(xDocListener); -} - -void SAL_CALL PresenterScreenListener::disposing() -{ - Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY ); - if( xDocBroadcaster.is() ) - xDocBroadcaster->removeEventListener( - Reference<document::XEventListener>( - static_cast<document::XEventListener*>(this), UNO_QUERY)); - - if (mpPresenterScreen.is()) - { - mpPresenterScreen->RequestShutdownPresenterScreen(); - mpPresenterScreen = nullptr; - } -} - -// document::XEventListener - -void SAL_CALL PresenterScreenListener::notifyEvent( const css::document::EventObject& Event ) -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterScreenListener object has already been disposed", - static_cast<uno::XWeak*>(this)); - } - - if ( Event.EventName == "OnStartPresentation" ) - { - mpPresenterScreen = new PresenterScreen(mxComponentContext, mxModel); - if(PresenterScreen::isPresenterScreenEnabled(mxComponentContext)) - mpPresenterScreen->InitializePresenterScreen(); - } - else if ( Event.EventName == "OnEndPresentation" ) - { - if (mpPresenterScreen.is()) - { - mpPresenterScreen->RequestShutdownPresenterScreen(); - mpPresenterScreen = nullptr; - } - } -} - -// XEventListener - -void SAL_CALL PresenterScreenListener::disposing (const css::lang::EventObject&) -{ - if (mpPresenterScreen.is()) - { - mpPresenterScreen->RequestShutdownPresenterScreen(); - mpPresenterScreen = nullptr; - } -} - -} // end of anonymous namespace - -//===== PresenterScreen ======================================================= - -PresenterScreen::PresenterScreen ( - const Reference<XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XModel2>& rxModel) - : PresenterScreenInterfaceBase(m_aMutex), - mxModel(rxModel), - mxController(), - mxConfigurationControllerWeak(), - mxContextWeak(rxContext), - mpPresenterController(), - mxSavedConfiguration(), - mpPaneContainer(), - mxPaneFactory(), - mxViewFactory(), - maViewDescriptors() -{ -} - -PresenterScreen::~PresenterScreen() -{ -} - -bool PresenterScreen::isPresenterScreenEnabled(const css::uno::Reference<css::uno::XComponentContext>& rxContext) -{ - bool dEnablePresenterScreen=true; - PresenterConfigurationAccess aConfiguration ( - rxContext, - "/org.openoffice.Office.Impress/", - PresenterConfigurationAccess::READ_ONLY); - aConfiguration.GetConfigurationNode("Misc/Start/EnablePresenterScreen") - >>= dEnablePresenterScreen; - return dEnablePresenterScreen; -} -void SAL_CALL PresenterScreen::disposing() -{ - Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); - if (xCC.is() && mxSavedConfiguration.is()) - { - xCC->restoreConfiguration(mxSavedConfiguration); - } - mxConfigurationControllerWeak = Reference<XConfigurationController>(nullptr); - - Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY); - if (xViewFactoryComponent.is()) - xViewFactoryComponent->dispose(); - Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY); - if (xPaneFactoryComponent.is()) - xPaneFactoryComponent->dispose(); - - mxModel = nullptr; -} - -//----- XEventListener -------------------------------------------------------- - -void SAL_CALL PresenterScreen::disposing (const lang::EventObject& /*rEvent*/) -{ - RequestShutdownPresenterScreen(); -} - - -void PresenterScreen::InitializePresenterScreen() -{ - try - { - Reference<XComponentContext> xContext (mxContextWeak); - mpPaneContainer = new PresenterPaneContainer(xContext); - - Reference<XPresentationSupplier> xPS ( mxModel, UNO_QUERY_THROW); - Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW); - Reference<presentation::XSlideShowController> xSlideShowController( xPresentation->getController() ); - - if( !xSlideShowController.is() || !xSlideShowController->isFullScreen() ) - return; - - // find first controller that is not the current controller (the one with the slideshow - mxController = mxModel->getCurrentController(); - Reference< container::XEnumeration > xEnum( mxModel->getControllers() ); - if( xEnum.is() ) - { - while( xEnum->hasMoreElements() ) - { - Reference< frame::XController > xC( xEnum->nextElement(), UNO_QUERY ); - if( xC.is() && (xC != mxController) ) - { - mxController = xC; - break; - } - } - } - // Get the XController from the first argument. - Reference<XControllerManager> xCM(mxController, UNO_QUERY_THROW); - - Reference<XConfigurationController> xCC( xCM->getConfigurationController()); - mxConfigurationControllerWeak = xCC; - - Reference<drawing::framework::XResourceId> xMainPaneId( - GetMainPaneId(xPresentation)); - // An empty reference means that the presenter screen can - // not or must not be displayed. - if ( ! xMainPaneId.is()) - return; - - if (xCC.is() && xContext.is()) - { - // Store the current configuration so that we can restore it when - // the presenter view is deactivated. - mxSavedConfiguration = xCC->getRequestedConfiguration(); - xCC->lock(); - - try - { - // At the moment the presenter controller is displayed in its - // own full screen window that is controlled by the same - // configuration controller as the Impress document from - // which the presentation was started. Therefore the main - // pane is activated additionally to the already existing - // panes and does not replace them. - xCC->requestResourceActivation( - xMainPaneId, - ResourceActivationMode_ADD); - SetupConfiguration(xContext, xMainPaneId); - - mpPresenterController = new PresenterController( - css::uno::WeakReference<css::lang::XEventListener>(this), - xContext, - mxController, - xSlideShowController, - mpPaneContainer, - xMainPaneId); - - // Create pane and view factories and integrate them into the - // drawing framework. - SetupPaneFactory(xContext); - SetupViewFactory(xContext); - - mpPresenterController->GetWindowManager()->RestoreViewMode(); - } - catch (const RuntimeException&) - { - xCC->restoreConfiguration(mxSavedConfiguration); - } - xCC->unlock(); - } - } - catch (const Exception&) - { - } -} - -void PresenterScreen::SwitchMonitors() -{ - try { - Reference<XPresentationSupplier> xPS ( mxModel, UNO_QUERY_THROW); - Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW); - - // Get the existing presenter console screen, we want to switch the - // presentation to use that instead. - sal_Int32 nNewScreen = GetPresenterScreenNumber (xPresentation); - if (nNewScreen < 0) - return; - - // Adapt that display number to be the 'default' setting of 0 if it matches - sal_Int32 nExternalDisplay = Application::GetDisplayExternalScreen(); - - if (nNewScreen == nExternalDisplay) - nNewScreen = 0; // screen zero is best == the primary display - else - nNewScreen++; // otherwise we store screens offset by one. - - // Set the new presentation display - Reference<beans::XPropertySet> xProperties (xPresentation, UNO_QUERY_THROW); - xProperties->setPropertyValue("Display", Any(nNewScreen)); - } catch (const uno::Exception &) { - } -} - -/** - * Return the real VCL screen number to show the presenter console - * on or -1 to not show anything. - */ -sal_Int32 PresenterScreen::GetPresenterScreenNumber ( - const Reference<presentation::XPresentation2>& rxPresentation) const -{ - sal_Int32 nScreenNumber (0); - try - { - if ( ! rxPresentation.is()) - return -1; - - // Determine the screen on which the full screen presentation is being - // displayed. - sal_Int32 nDisplayNumber (-1); - if ( ! (rxPresentation->getPropertyValue("Display") >>= nDisplayNumber)) - return -1; - if (nDisplayNumber == -1) - { - // The special value -1 indicates that the slide show - // spans all available displays. That leaves no room for - // the presenter screen. - return -1; - } - - SAL_INFO("sdext.presenter", "Display number is " << nDisplayNumber); - - if (nDisplayNumber > 0) - { - nScreenNumber = nDisplayNumber - 1; - } - else if (nDisplayNumber == 0) - { - // A display number value of 0 indicates the primary screen. - // Find out which screen number that is. - nScreenNumber = Application::GetDisplayExternalScreen(); - } - - // We still have to determine the number of screens to decide - // whether the presenter screen may be shown at all. - sal_Int32 nScreenCount = Application::GetScreenCount(); - - if (nScreenCount < 2 || nDisplayNumber > nScreenCount) - { - // There is either only one screen or the full screen - // presentation spans all available screens. The presenter - // screen is shown only when a special flag in the configuration - // is set. - Reference<XComponentContext> xContext (mxContextWeak); - PresenterConfigurationAccess aConfiguration ( - xContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - bool bStartAlways (false); - if (aConfiguration.GetConfigurationNode( - "Presenter/StartAlways") >>= bStartAlways) - { - if (bStartAlways) - return GetPresenterScreenFromScreen(nScreenNumber); - } - return -1; - } - } - catch (const beans::UnknownPropertyException&) - { - OSL_ASSERT(false); - // For some reason we can not access the screen number. Use - // the default instead. - } - SAL_INFO("sdext.presenter", "Get presenter screen for screen " << nScreenNumber); - return GetPresenterScreenFromScreen(nScreenNumber); -} - -sal_Int32 PresenterScreen::GetPresenterScreenFromScreen( sal_Int32 nPresentationScreen ) -{ - // Setup the resource id of the full screen background pane so that - // it is displayed on another screen than the presentation. - sal_Int32 nPresenterScreenNumber (1); - switch (nPresentationScreen) - { - case 0: - nPresenterScreenNumber = 1; - break; - - case 1: - nPresenterScreenNumber = 0; - break; - - default: - SAL_INFO("sdext.presenter", "Warning unexpected, out of bound screen " - "mapped to 0" << nPresentationScreen); - // When the full screen presentation is displayed on a screen - // other than 0 or 1 then place the presenter on the first - // available screen. - nPresenterScreenNumber = 0; - break; - } - return nPresenterScreenNumber; -} - -Reference<drawing::framework::XResourceId> PresenterScreen::GetMainPaneId ( - const Reference<presentation::XPresentation2>& rxPresentation) const -{ - // A negative value means that the presentation spans all available - // displays. That leaves no room for the presenter. - const sal_Int32 nScreen(GetPresenterScreenNumber(rxPresentation)); - if (nScreen < 0) - return nullptr; - - return ResourceId::create( - Reference<XComponentContext>(mxContextWeak), - PresenterHelper::msFullScreenPaneURL - + "?FullScreen=true&ScreenNumber=" - + OUString::number(nScreen)); -} - -void PresenterScreen::RequestShutdownPresenterScreen() -{ - // Restore the configuration that was active before the presenter screen - // has been activated. Now, that the presenter screen is displayed in - // its own top level window this probably not necessary, but one never knows. - Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); - if (xCC.is() && mxSavedConfiguration.is()) - { - xCC->restoreConfiguration(mxSavedConfiguration); - mxSavedConfiguration = nullptr; - } - - if (xCC.is()) - { - // The actual restoration of the configuration takes place - // asynchronously. The view and pane factories can only by disposed - // after that. Therefore, set up a listener and wait for the - // restoration. - rtl::Reference<PresenterScreen> pSelf (this); - PresenterFrameworkObserver::RunOnUpdateEnd( - xCC, - [pSelf](bool){ return pSelf->ShutdownPresenterScreen(); }); - xCC->update(); - } -} - -void PresenterScreen::ShutdownPresenterScreen() -{ - Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY); - if (xViewFactoryComponent.is()) - xViewFactoryComponent->dispose(); - mxViewFactory = nullptr; - - Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY); - if (xPaneFactoryComponent.is()) - xPaneFactoryComponent->dispose(); - mxPaneFactory = nullptr; - - if (mpPresenterController) - { - mpPresenterController->dispose(); - mpPresenterController.clear(); - } - mpPaneContainer = new PresenterPaneContainer(Reference<XComponentContext>(mxContextWeak)); -} - -void PresenterScreen::SetupPaneFactory (const Reference<XComponentContext>& rxContext) -{ - try - { - if ( ! mxPaneFactory.is()) - mxPaneFactory = PresenterPaneFactory::Create( - rxContext, - mxController, - mpPresenterController); - } - catch (const RuntimeException&) - { - OSL_ASSERT(false); - } -} - -void PresenterScreen::SetupViewFactory (const Reference<XComponentContext>& rxContext) -{ - try - { - if ( ! mxViewFactory.is()) - mxViewFactory = PresenterViewFactory::Create( - rxContext, - mxController, - mpPresenterController); - } - catch (const RuntimeException&) - { - OSL_ASSERT(false); - } -} - -void PresenterScreen::SetupConfiguration ( - const Reference<XComponentContext>& rxContext, - const Reference<XResourceId>& rxAnchorId) -{ - try - { - PresenterConfigurationAccess aConfiguration ( - rxContext, - "org.openoffice.Office.PresenterScreen", - PresenterConfigurationAccess::READ_ONLY); - maViewDescriptors.clear(); - ProcessViewDescriptions(aConfiguration); - OUString sLayoutName ("DefaultLayout"); - aConfiguration.GetConfigurationNode( - "Presenter/CurrentLayout") >>= sLayoutName; - ProcessLayout(aConfiguration, sLayoutName, rxContext, rxAnchorId); - } - catch (const RuntimeException&) - { - } -} - -void PresenterScreen::ProcessLayout ( - PresenterConfigurationAccess& rConfiguration, - std::u16string_view rsLayoutName, - const Reference<XComponentContext>& rxContext, - const Reference<XResourceId>& rxAnchorId) -{ - try - { - Reference<container::XHierarchicalNameAccess> xLayoutNode ( - rConfiguration.GetConfigurationNode( - OUString::Concat("Presenter/Layouts/")+rsLayoutName), - UNO_QUERY_THROW); - - // Read the parent layout first, if one is referenced. - OUString sParentLayout; - PresenterConfigurationAccess::GetConfigurationNode( - xLayoutNode, - "ParentLayout") >>= sParentLayout; - if (!sParentLayout.isEmpty()) - { - // Prevent infinite recursion. - if (rsLayoutName != sParentLayout) - ProcessLayout(rConfiguration, sParentLayout, rxContext, rxAnchorId); - } - - // Process the actual layout list. - Reference<container::XNameAccess> xList ( - PresenterConfigurationAccess::GetConfigurationNode( - xLayoutNode, - "Layout"), - UNO_QUERY_THROW); - - ::std::vector<OUString> aProperties - { - "PaneURL", - "ViewURL", - "RelativeX", - "RelativeY", - "RelativeWidth", - "RelativeHeight" - }; - PresenterConfigurationAccess::ForAll( - xList, - aProperties, - [this, rxContext, rxAnchorId](std::vector<uno::Any> const& rArgs) - { - this->ProcessComponent(rArgs, rxContext, rxAnchorId); - }); - } - catch (const RuntimeException&) - { - } -} - -void PresenterScreen::ProcessViewDescriptions ( - PresenterConfigurationAccess& rConfiguration) -{ - try - { - Reference<container::XNameAccess> xViewDescriptionsNode ( - rConfiguration.GetConfigurationNode("Presenter/Views"), - UNO_QUERY_THROW); - - ::std::vector<OUString> aProperties - { - "ViewURL", - "Title", - "AccessibleTitle", - "IsOpaque" - }; - PresenterConfigurationAccess::ForAll( - xViewDescriptionsNode, - aProperties, - [this](std::vector<uno::Any> const& rArgs) - { - return this->ProcessViewDescription(rArgs); - }); - } - catch (const RuntimeException&) - { - OSL_ASSERT(false); - } -} - -void PresenterScreen::ProcessComponent ( - const ::std::vector<Any>& rValues, - const Reference<XComponentContext>& rxContext, - const Reference<XResourceId>& rxAnchorId) -{ - if (rValues.size() != 6) - return; - - try - { - OUString sPaneURL; - OUString sViewURL; - double nX = 0; - double nY = 0; - double nWidth = 0; - double nHeight = 0; - rValues[0] >>= sPaneURL; - rValues[1] >>= sViewURL; - rValues[2] >>= nX; - rValues[3] >>= nY; - rValues[4] >>= nWidth; - rValues[5] >>= nHeight; - - if (nX>=0 && nY>=0 && nWidth>0 && nHeight>0) - { - SetupView( - rxContext, - rxAnchorId, - sPaneURL, - sViewURL, - PresenterPaneContainer::ViewInitializationFunction()); - } - } - catch (const Exception&) - { - OSL_ASSERT(false); - } -} - -void PresenterScreen::ProcessViewDescription ( - const ::std::vector<Any>& rValues) -{ - if (rValues.size() != 4) - return; - - try - { - ViewDescriptor aViewDescriptor; - OUString sViewURL; - rValues[0] >>= sViewURL; - rValues[1] >>= aViewDescriptor.msTitle; - rValues[2] >>= aViewDescriptor.msAccessibleTitle; - rValues[3] >>= aViewDescriptor.mbIsOpaque; - if (aViewDescriptor.msAccessibleTitle.isEmpty()) - aViewDescriptor.msAccessibleTitle = aViewDescriptor.msTitle; - maViewDescriptors[sViewURL] = aViewDescriptor; - } - catch (const Exception&) - { - OSL_ASSERT(false); - } -} - -void PresenterScreen::SetupView( - const Reference<XComponentContext>& rxContext, - const Reference<XResourceId>& rxAnchorId, - const OUString& rsPaneURL, - const OUString& rsViewURL, - const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization) -{ - Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); - if (!xCC.is()) - return; - - Reference<XResourceId> xPaneId (ResourceId::createWithAnchor(rxContext,rsPaneURL,rxAnchorId)); - // Look up the view descriptor. - ViewDescriptor aViewDescriptor; - ViewDescriptorContainer::const_iterator iDescriptor (maViewDescriptors.find(rsViewURL)); - if (iDescriptor != maViewDescriptors.end()) - aViewDescriptor = iDescriptor->second; - - // Prepare the pane. - OSL_ASSERT(mpPaneContainer); - mpPaneContainer->PreparePane( - xPaneId, - rsViewURL, - aViewDescriptor.msTitle, - aViewDescriptor.msAccessibleTitle, - aViewDescriptor.mbIsOpaque, - rViewInitialization); -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterScreen.hxx b/sdext/source/presenter/PresenterScreen.hxx deleted file mode 100644 index e696c0dc646e..000000000000 --- a/sdext/source/presenter/PresenterScreen.hxx +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSCREEN_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSCREEN_HXX - -#include "PresenterConfigurationAccess.hxx" -#include "PresenterPaneContainer.hxx" -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/frame/XModel2.hpp> -#include <com/sun/star/task/XJob.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/presentation/XPresentation2.hpp> -#include <rtl/ref.hxx> - -#include <map> -#include <string_view> - -namespace sdext::presenter { - -class PresenterController; - -typedef ::cppu::WeakComponentImplHelper < - css::task::XJob, css::lang::XServiceInfo - > PresenterScreenJobInterfaceBase; - -/** The PresenterScreenJob service is instantiated every time a document is - created or loaded. In its execute() method it then filters out all - non-Impress documents and creates and registers a new PresenterScreen - object. -*/ -class PresenterScreenJob - : private ::cppu::BaseMutex, - public PresenterScreenJobInterfaceBase -{ -public: - PresenterScreenJob(const PresenterScreenJob&) = delete; - PresenterScreenJob& operator=(const PresenterScreenJob&) = delete; - - virtual void SAL_CALL disposing() override; - - // XServiceInfo - virtual OUString SAL_CALL getImplementationName() override; - virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; - virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames () override; - - // XJob - virtual css::uno::Any SAL_CALL execute( - const css::uno::Sequence<css::beans::NamedValue >& Arguments) override; - - explicit PresenterScreenJob (const css::uno::Reference<css::uno::XComponentContext>& rxContext); - virtual ~PresenterScreenJob() override; - -private: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; -}; - -/** This is the bootstrap class of the presenter screen. It is registered - as drawing framework startup service. That means that every drawing - framework instance creates an instance of this class. - - <p>A PresenterScreen object registers itself as listener for drawing - framework configuration changes. It waits for the full screen marker (a - top level resource) to appear in the current configuration. When that - happens the actual presenter screen is initialized. A new - PresenterController is created and takes over the task of controlling - the presenter screen.</p> -*/ -typedef ::cppu::WeakComponentImplHelper < - css::lang::XEventListener - > PresenterScreenInterfaceBase; -class PresenterScreen - : private ::cppu::BaseMutex, - public PresenterScreenInterfaceBase -{ -public: - PresenterScreen ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XModel2>& rxModel); - virtual ~PresenterScreen() override; - PresenterScreen(const PresenterScreen&) = delete; - PresenterScreen& operator=(const PresenterScreen&) = delete; - - virtual void SAL_CALL disposing() override; - - static bool isPresenterScreenEnabled( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - /** Make the presenter screen visible. - */ - void InitializePresenterScreen(); - - /** Do not call ShutdownPresenterScreen() directly. Call - RequestShutdownPresenterScreen() instead. It will issue an - asynchronous call to ShutdownPresenterScreen() when that is safe. - */ - void RequestShutdownPresenterScreen(); - - /** Switch / converse monitors between presenter view and slide output - */ - void SwitchMonitors(); - - // XEventListener - - virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent) override; - -private: - css::uno::Reference<css::frame::XModel2 > mxModel; - css::uno::Reference<css::frame::XController> mxController; - css::uno::WeakReference<css::drawing::framework::XConfigurationController> - mxConfigurationControllerWeak; - css::uno::WeakReference<css::uno::XComponentContext> mxContextWeak; - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::drawing::framework::XConfiguration> mxSavedConfiguration; - ::rtl::Reference<PresenterPaneContainer> mpPaneContainer; - css::uno::Reference<css::drawing::framework::XResourceFactory> mxPaneFactory; - css::uno::Reference<css::drawing::framework::XResourceFactory> mxViewFactory; - - class ViewDescriptor - { - public: - OUString msTitle; - OUString msAccessibleTitle; - bool mbIsOpaque; - ViewDescriptor() - : mbIsOpaque(false) - { - } - }; - typedef ::std::map<OUString,ViewDescriptor> ViewDescriptorContainer; - ViewDescriptorContainer maViewDescriptors; - - void ShutdownPresenterScreen(); - - /** Create and initialize the factory for presenter view specific panes. - */ - void SetupPaneFactory ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - - /** Create and initialize the factory for presenter view specific views. - */ - void SetupViewFactory ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - - /** Read the current layout from the configuration and call - ProcessLayout to bring it on to the screen. - */ - void SetupConfiguration ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId); - - /** Read one layout from the configuration and make resource activation - requests to bring it on to the screen. When one layout references a - parent layout then this method calls itself recursively. - */ - void ProcessLayout ( - PresenterConfigurationAccess& rConfiguration, - std::u16string_view rsLayoutName, - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId); - - /** Called by ProcessLayout for a single entry of a Layouts - configuration list. - */ - void ProcessComponent ( - const ::std::vector<css::uno::Any>& rValues, - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId); - - /** Read the view descriptions from the configuration. - */ - void ProcessViewDescriptions ( - PresenterConfigurationAccess& rConfiguration); - - /** Called by ProcessViewDescriptions for a single entry. - */ - void ProcessViewDescription ( - const ::std::vector<css::uno::Any>& rValues); - - void SetupView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId, - const OUString& rsPaneURL, - const OUString& rsViewURL, - const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization); - - /** Return the built-in screen number on the presentation will normally - display the presenter console. - @return - Returns -1 when the presenter screen can or shall not be - displayed. - */ - sal_Int32 GetPresenterScreenNumber ( - const css::uno::Reference<css::presentation::XPresentation2>& rxPresentation) const; - - static sal_Int32 GetPresenterScreenFromScreen( sal_Int32 nPresentationScreen ); - - /** Create a resource id for the full screen background pane so that it - is displayed on another screen than the full screen presentation. - */ - css::uno::Reference<css::drawing::framework::XResourceId> GetMainPaneId ( - const css::uno::Reference<css::presentation::XPresentation2>& rxPresentation) const; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterScrollBar.cxx b/sdext/source/presenter/PresenterScrollBar.cxx deleted file mode 100644 index d811c92cfaa0..000000000000 --- a/sdext/source/presenter/PresenterScrollBar.cxx +++ /dev/null @@ -1,837 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterScrollBar.hxx" -#include "PresenterBitmapContainer.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterTimer.hxx" -#include "PresenterUIPainter.hxx" -#include <com/sun/star/awt/PosSize.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/XPolyPolygon2D.hpp> - -#include <algorithm> -#include <memory> -#include <math.h> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -const double gnScrollBarGap (10); - -namespace sdext::presenter { - -//===== PresenterScrollBar::MousePressRepeater ================================ - -class PresenterScrollBar::MousePressRepeater - : public std::enable_shared_from_this<MousePressRepeater> -{ -public: - explicit MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar); - void Dispose(); - void Start (const PresenterScrollBar::Area& reArea); - void Stop(); - void SetMouseArea (const PresenterScrollBar::Area& reArea); - -private: - void Callback (); - void Execute(); - - sal_Int32 mnMousePressRepeaterTaskId; - ::rtl::Reference<PresenterScrollBar> mpScrollBar; - PresenterScrollBar::Area meMouseArea; -}; - -//===== PresenterScrollBar ==================================================== - -std::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps; - -PresenterScrollBar::PresenterScrollBar ( - const Reference<XComponentContext>& rxComponentContext, - const Reference<awt::XWindow>& rxParentWindow, - const std::shared_ptr<PresenterPaintManager>& rpPaintManager, - const ::std::function<void (double)>& rThumbMotionListener) - : PresenterScrollBarInterfaceBase(m_aMutex), - mxComponentContext(rxComponentContext), - mxWindow(), - mxCanvas(), - mxPresenterHelper(), - mpPaintManager(rpPaintManager), - mnThumbPosition(0), - mnTotalSize(0), - mnThumbSize(0), - mnLineHeight(10), - maDragAnchor(-1,-1), - maThumbMotionListener(rThumbMotionListener), - meButtonDownArea(None), - meMouseMoveArea(None), - mbIsNotificationActive(false), - mpBitmaps(), - mpPrevButtonDescriptor(), - mpNextButtonDescriptor(), - mpPagerStartDescriptor(), - mpPagerCenterDescriptor(), - mpPagerEndDescriptor(), - mpThumbStartDescriptor(), - mpThumbCenterDescriptor(), - mpThumbEndDescriptor(), - mpMousePressRepeater(std::make_shared<MousePressRepeater>(this)), - mpBackgroundBitmap(), - mpCanvasHelper(new PresenterCanvasHelper()) -{ - try - { - Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager()); - if ( ! xFactory.is()) - throw RuntimeException(); - - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - rxComponentContext), - UNO_QUERY_THROW); - - if (mxPresenterHelper.is()) - mxWindow = mxPresenterHelper->createWindow(rxParentWindow, - false, - false, - false, - false); - - // Make the background transparent. The slide show paints its own background. - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW); - xPeer->setBackground(0xff000000); - - mxWindow->setVisible(true); - mxWindow->addWindowListener(this); - mxWindow->addPaintListener(this); - mxWindow->addMouseListener(this); - mxWindow->addMouseMotionListener(this); - } - catch (RuntimeException&) - { - } -} - -PresenterScrollBar::~PresenterScrollBar() -{ -} - -void SAL_CALL PresenterScrollBar::disposing() -{ - mpMousePressRepeater->Dispose(); - - if (mxWindow.is()) - { - mxWindow->removeWindowListener(this); - mxWindow->removePaintListener(this); - mxWindow->removeMouseListener(this); - mxWindow->removeMouseMotionListener(this); - - Reference<lang::XComponent> xComponent = mxWindow; - mxWindow = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - mpBitmaps.reset(); -} - -void PresenterScrollBar::SetVisible (const bool bIsVisible) -{ - if (mxWindow.is()) - mxWindow->setVisible(bIsVisible); -} - -void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox) -{ - if (mxWindow.is()) - { - mxWindow->setPosSize( - sal_Int32(floor(rBox.X1)), - sal_Int32(ceil(rBox.Y1)), - sal_Int32(ceil(rBox.X2-rBox.X1)), - sal_Int32(floor(rBox.Y2-rBox.Y1)), - awt::PosSize::POSSIZE); - UpdateBorders(); - } -} - -void PresenterScrollBar::SetThumbPosition ( - double nPosition, - const bool bAsynchronousUpdate) -{ - nPosition = ValidateThumbPosition(nPosition); - - if (nPosition == mnThumbPosition || mbIsNotificationActive) - return; - - mnThumbPosition = nPosition; - - UpdateBorders(); - Repaint(GetRectangle(Total), bAsynchronousUpdate); - - mbIsNotificationActive = true; - try - { - maThumbMotionListener(mnThumbPosition); - } - catch (Exception&) - { - } - mbIsNotificationActive = false; -} - - -void PresenterScrollBar::SetTotalSize (const double nTotalSize) -{ - if (mnTotalSize != nTotalSize) - { - mnTotalSize = nTotalSize + 1; - UpdateBorders(); - Repaint(GetRectangle(Total), false); - } -} - -void PresenterScrollBar::SetThumbSize (const double nThumbSize) -{ - OSL_ASSERT(nThumbSize>=0); - if (mnThumbSize != nThumbSize) - { - mnThumbSize = nThumbSize; - UpdateBorders(); - Repaint(GetRectangle(Total), false); - } -} - - -void PresenterScrollBar::SetLineHeight (const double nLineHeight) -{ - mnLineHeight = nLineHeight; -} - - -void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas) -{ - if (mxCanvas == rxCanvas) - return; - - mxCanvas = rxCanvas; - if (!mxCanvas.is()) - return; - - if (mpBitmaps == nullptr) - { - mpBitmaps = mpSharedBitmaps.lock(); - if (!mpBitmaps) - { - try - { - mpBitmaps = std::make_shared<PresenterBitmapContainer>( - "PresenterScreenSettings/ScrollBar/Bitmaps", - std::shared_ptr<PresenterBitmapContainer>(), - mxComponentContext, - mxCanvas); - mpSharedBitmaps = mpBitmaps; - } - catch(Exception&) - { - OSL_ASSERT(false); - } - } - UpdateBitmaps(); - UpdateBorders(); - } - - Repaint(GetRectangle(Total), false); -} - -void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap) -{ - mpBackgroundBitmap = rpBackgroundBitmap; -} - -void PresenterScrollBar::CheckValues() -{ - mnThumbPosition = ValidateThumbPosition(mnThumbPosition); -} - -double PresenterScrollBar::ValidateThumbPosition (double nPosition) -{ - if (nPosition + mnThumbSize > mnTotalSize) - nPosition = mnTotalSize - mnThumbSize; - if (nPosition < 0) - nPosition = 0; - return nPosition; -} - -void PresenterScrollBar::Paint ( - const awt::Rectangle& rUpdateBox) -{ - if ( ! mxCanvas.is() || ! mxWindow.is()) - { - OSL_ASSERT(mxCanvas.is()); - OSL_ASSERT(mxWindow.is()); - return; - } - - if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize())) - return; - - PaintBackground(rUpdateBox); - PaintComposite(rUpdateBox, PagerUp, - mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor()); - PaintComposite(rUpdateBox, PagerDown, - SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor); - PaintComposite(rUpdateBox, Thumb, - mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor); - PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor); - PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor); - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent&) {} - -void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent&) {} - -void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject&) {} - -void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject&) {} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent) -{ - if (mxWindow.is()) - { - awt::Rectangle aRepaintBox (rEvent.UpdateRect); - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - aRepaintBox.X += aWindowBox.X; - aRepaintBox.Y += aWindowBox.Y; - Paint(aRepaintBox); - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); - } -} - -//----- XMouseListener -------------------------------------------------------- - -void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent) -{ - maDragAnchor.X = rEvent.X; - maDragAnchor.Y = rEvent.Y; - meButtonDownArea = GetArea(rEvent.X, rEvent.Y); - - mpMousePressRepeater->Start(meButtonDownArea); -} - -void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent&) -{ - mpMousePressRepeater->Stop(); - - if (mxPresenterHelper.is()) - mxPresenterHelper->releaseMouse(mxWindow); -} - -void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent&) {} - -void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent&) -{ - if (meMouseMoveArea != None) - { - const Area eOldMouseMoveArea (meMouseMoveArea); - meMouseMoveArea = None; - Repaint(GetRectangle(eOldMouseMoveArea), true); - } - meButtonDownArea = None; - meMouseMoveArea = None; - - mpMousePressRepeater->Stop(); -} - -//----- XMouseMotionListener -------------------------------------------------- - -void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent) -{ - const Area eArea (GetArea(rEvent.X, rEvent.Y)); - if (eArea != meMouseMoveArea) - { - const Area eOldMouseMoveArea (meMouseMoveArea); - meMouseMoveArea = eArea; - if (eOldMouseMoveArea != None) - Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None); - if (meMouseMoveArea != None) - Repaint(GetRectangle(meMouseMoveArea), true); - } - mpMousePressRepeater->SetMouseArea(eArea); -} - -void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent) -{ - if (meButtonDownArea != Thumb) - return; - - mpMousePressRepeater->Stop(); - - if (mxPresenterHelper.is()) - mxPresenterHelper->captureMouse(mxWindow); - - const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y)); - UpdateDragAnchor(nDragDistance); - if (nDragDistance != 0) - { - SetThumbPosition(mnThumbPosition + nDragDistance, false); - } -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent) -{ - if (rEvent.Source == mxWindow) - mxWindow = nullptr; -} - - -geometry::RealRectangle2D const & PresenterScrollBar::GetRectangle (const Area eArea) const -{ - OSL_ASSERT(eArea>=0 && eArea<AreaCount); - - return maBox[eArea]; -} - -void PresenterScrollBar::Repaint ( - const geometry::RealRectangle2D& rBox, - const bool bAsynchronousUpdate) -{ - if (mpPaintManager != nullptr) - mpPaintManager->Invalidate( - mxWindow, - PresenterGeometryHelper::ConvertRectangle(rBox), - bAsynchronousUpdate); -} - -void PresenterScrollBar::PaintBackground( - const css::awt::Rectangle& rUpdateBox) -{ - if (!mpBackgroundBitmap) - return; - - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - mpCanvasHelper->Paint( - mpBackgroundBitmap, - mxCanvas, - rUpdateBox, - aWindowBox, - awt::Rectangle()); -} - -void PresenterScrollBar::PaintBitmap( - const css::awt::Rectangle& rUpdateBox, - const Area eArea, - const SharedBitmapDescriptor& rpBitmaps) -{ - const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea)); - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - geometry::RealRectangle2D aBox (aLocalBox); - aBox.X1 += aWindowBox.X; - aBox.Y1 += aWindowBox.Y; - aBox.X2 += aWindowBox.X; - aBox.Y2 += aWindowBox.Y; - - Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps)); - - if (!xBitmap.is()) - return; - - Reference<rendering::XPolyPolygon2D> xClipPolygon ( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rUpdateBox, - PresenterGeometryHelper::ConvertRectangle(aBox)), - mxCanvas->getDevice())); - - const rendering::ViewState aViewState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - xClipPolygon); - - const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D( - 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2, - 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - mxCanvas->drawBitmap( - xBitmap, - aViewState, - aRenderState); -} - -PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const -{ - const geometry::RealPoint2D aPoint(nX, nY); - - if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint)) - { - if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint)) - return Thumb; - else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint)) - return PagerUp; - else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint)) - return PagerDown; - } - else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint)) - return PrevButton; - else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint)) - return NextButton; - - return None; -} - -void PresenterScrollBar::UpdateWidthOrHeight ( - sal_Int32& rSize, - const SharedBitmapDescriptor& rpDescriptor) -{ - if (rpDescriptor) - { - Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap()); - if (xBitmap.is()) - { - const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); - const sal_Int32 nBitmapSize = static_cast<sal_Int32>(GetMinor(aBitmapSize.Width, aBitmapSize.Height)); - if (nBitmapSize > rSize) - rSize = nBitmapSize; - } - } -} - -css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap ( - const Area eArea, - const SharedBitmapDescriptor& rpBitmaps) const -{ - if (!rpBitmaps) - return nullptr; - else - return rpBitmaps->GetBitmap(GetBitmapMode(eArea)); -} - -PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode ( - const Area eArea) const -{ - if (IsDisabled(eArea)) - return PresenterBitmapContainer::BitmapDescriptor::Disabled; - else if (eArea == meMouseMoveArea) - return PresenterBitmapContainer::BitmapDescriptor::MouseOver; - else - return PresenterBitmapContainer::BitmapDescriptor::Normal; -} - -bool PresenterScrollBar::IsDisabled (const Area eArea) const -{ - OSL_ASSERT(eArea>=0 && eArea<AreaCount); - - return ! maEnabledState[eArea]; -} - -//===== PresenterVerticalScrollBar ============================================ - -PresenterVerticalScrollBar::PresenterVerticalScrollBar ( - const Reference<XComponentContext>& rxComponentContext, - const Reference<awt::XWindow>& rxParentWindow, - const std::shared_ptr<PresenterPaintManager>& rpPaintManager, - const ::std::function<void (double)>& rThumbMotionListener) - : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), - mnScrollBarWidth(0) -{ -} - -PresenterVerticalScrollBar::~PresenterVerticalScrollBar() -{ -} - -double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32, const sal_Int32 nY) const -{ - const double nDistance (nY - maDragAnchor.Y); - if (nDistance == 0) - return 0; - else - { - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - const double nBarWidth (aWindowBox.Width); - const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); - const double nDragDistance (mnTotalSize / nPagerHeight * nDistance); - if (nDragDistance + mnThumbPosition < 0) - return -mnThumbPosition; - else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) - return mnTotalSize-mnThumbSize-mnThumbPosition; - else - return nDragDistance; - } -} - -void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance) -{ - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - const double nBarWidth (aWindowBox.Width); - const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); - maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize; -} - -sal_Int32 PresenterVerticalScrollBar::GetSize() const -{ - return mnScrollBarWidth; -} - -double PresenterVerticalScrollBar::GetMinor (const double nX, const double) const -{ - return nX; -} - -void PresenterVerticalScrollBar::UpdateBorders() -{ - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - double nBottom = aWindowBox.Height; - - if (mpNextButtonDescriptor) - { - Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); - if (xBitmap.is()) - { - geometry::IntegerSize2D aSize (xBitmap->getSize()); - maBox[NextButton] = geometry::RealRectangle2D( - 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); - nBottom -= aSize.Height + gnScrollBarGap; - } - } - if (mpPrevButtonDescriptor) - { - Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); - if (xBitmap.is()) - { - geometry::IntegerSize2D aSize (xBitmap->getSize()); - maBox[PrevButton] = geometry::RealRectangle2D( - 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); - nBottom -= aSize.Height + gnScrollBarGap; - } - } - const double nPagerHeight (nBottom); - maBox[Pager] = geometry::RealRectangle2D( - 0,0, aWindowBox.Width, nBottom); - if (mnTotalSize < 1) - { - maBox[Thumb] = maBox[Pager]; - - // Set up the enabled/disabled states. - maEnabledState[PrevButton] = false; - maEnabledState[PagerUp] = false; - maEnabledState[NextButton] = false; - maEnabledState[PagerDown] = false; - maEnabledState[Thumb] = false; - } - else - { - const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize); - const double nThumbPosition = ::std::clamp(mnThumbPosition, 0.0, mnTotalSize - nThumbSize); - maBox[Thumb] = geometry::RealRectangle2D( - 0, nThumbPosition / mnTotalSize * nPagerHeight, - aWindowBox.Width, - (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight); - - // Set up the enabled/disabled states. - maEnabledState[PrevButton] = nThumbPosition>0; - maEnabledState[PagerUp] = nThumbPosition>0; - maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize; - maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize; - maEnabledState[Thumb] = nThumbSize < mnTotalSize; - } - maBox[PagerUp] = geometry::RealRectangle2D( - maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1); - maBox[PagerDown] = geometry::RealRectangle2D( - maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2); - maBox[Total] = PresenterGeometryHelper::Union( - PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), - maBox[Pager]); -} - -void PresenterVerticalScrollBar::UpdateBitmaps() -{ - if (mpBitmaps == nullptr) - return; - - mpPrevButtonDescriptor = mpBitmaps->GetBitmap("Up"); - mpNextButtonDescriptor = mpBitmaps->GetBitmap("Down"); - mpPagerStartDescriptor = mpBitmaps->GetBitmap("PagerTop"); - mpPagerCenterDescriptor = mpBitmaps->GetBitmap("PagerVertical"); - mpPagerEndDescriptor = mpBitmaps->GetBitmap("PagerBottom"); - mpThumbStartDescriptor = mpBitmaps->GetBitmap("ThumbTop"); - mpThumbCenterDescriptor = mpBitmaps->GetBitmap("ThumbVertical"); - mpThumbEndDescriptor = mpBitmaps->GetBitmap("ThumbBottom"); - - mnScrollBarWidth = 0; - UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor); - UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor); - if (mnScrollBarWidth == 0) - mnScrollBarWidth = 20; -} - -void PresenterVerticalScrollBar::PaintComposite( - const css::awt::Rectangle& rUpdateBox, - const Area eArea, - const SharedBitmapDescriptor& rpStartBitmaps, - const SharedBitmapDescriptor& rpCenterBitmaps, - const SharedBitmapDescriptor& rpEndBitmaps) -{ - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - geometry::RealRectangle2D aBox (GetRectangle(eArea)); - aBox.X1 += aWindowBox.X; - aBox.Y1 += aWindowBox.Y; - aBox.X2 += aWindowBox.X; - aBox.Y2 += aWindowBox.Y; - - // Get bitmaps and sizes. - - PresenterUIPainter::PaintVerticalBitmapComposite( - mxCanvas, - rUpdateBox, - (eArea == Thumb - ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox) - : PresenterGeometryHelper::ConvertRectangle(aBox)), - GetBitmap(eArea, rpStartBitmaps), - GetBitmap(eArea, rpCenterBitmaps), - GetBitmap(eArea, rpEndBitmaps)); -} - -//===== PresenterScrollBar::MousePressRepeater ================================ - -PresenterScrollBar::MousePressRepeater::MousePressRepeater ( - const ::rtl::Reference<PresenterScrollBar>& rpScrollBar) - : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId), - mpScrollBar(rpScrollBar), - meMouseArea(PresenterScrollBar::None) -{ -} - -void PresenterScrollBar::MousePressRepeater::Dispose() -{ - Stop(); - mpScrollBar = nullptr; -} - -void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea) -{ - meMouseArea = reArea; - - if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId) - { - // Execute key press operation at least this one time. - Execute(); - - // Schedule repeated executions. - auto pThis(shared_from_this()); - mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask ( - mpScrollBar->GetComponentContext(), - [pThis] (TimeValue const&) { return pThis->Callback(); }, - 500000000, - 250000000); - } - else - { - // There is already an active repeating task. - } -} - -void PresenterScrollBar::MousePressRepeater::Stop() -{ - if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) - { - const sal_Int32 nTaskId (mnMousePressRepeaterTaskId); - mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId; - PresenterTimer::CancelTask(nTaskId); - } -} - -void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea) -{ - if (meMouseArea != reArea) - { - if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) - { - Stop(); - } - } -} - -void PresenterScrollBar::MousePressRepeater::Callback () -{ - if (!mpScrollBar) - { - Stop(); - return; - } - - Execute(); -} - -void PresenterScrollBar::MousePressRepeater::Execute() -{ - const double nThumbPosition (mpScrollBar->GetThumbPosition()); - switch (meMouseArea) - { - case PrevButton: - mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true); - break; - - case NextButton: - mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true); - break; - - case PagerUp: - mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true); - break; - - case PagerDown: - mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true); - break; - - default: - break; - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterScrollBar.hxx b/sdext/source/presenter/PresenterScrollBar.hxx deleted file mode 100644 index b131c8a43ab5..000000000000 --- a/sdext/source/presenter/PresenterScrollBar.hxx +++ /dev/null @@ -1,257 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSCROLLBAR_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSCROLLBAR_HXX - -#include "PresenterBitmapContainer.hxx" -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> - -#include <functional> -#include <memory> - -namespace sdext::presenter { - -class PresenterCanvasHelper; -class PresenterPaintManager; - -typedef ::cppu::WeakComponentImplHelper < - css::awt::XWindowListener, - css::awt::XPaintListener, - css::awt::XMouseListener, - css::awt::XMouseMotionListener -> PresenterScrollBarInterfaceBase; - -/** Base class of horizontal and vertical scroll bars. -*/ -class PresenterScrollBar - : private ::cppu::BaseMutex, - public PresenterScrollBarInterfaceBase -{ -public: - virtual ~PresenterScrollBar() override; - PresenterScrollBar(const PresenterScrollBar&) = delete; - PresenterScrollBar& operator=(const PresenterScrollBar&) = delete; - - virtual void SAL_CALL disposing() override; - - css::uno::Reference<css::uno::XComponentContext> const& - GetComponentContext() const { return mxComponentContext; } - - void SetVisible (const bool bIsVisible); - - /** Set the bounding box of the scroll bar. - */ - void SetPosSize (const css::geometry::RealRectangle2D& rBox); - - /** Set the position of the movable thumb. - @param nPosition - A value between 0 and the last value given to SetTotalSize() - minus the last value given to SetThumbSize(). - */ - void SetThumbPosition ( - double nPosition, - const bool bAsynchronousRepaint); - - double GetThumbPosition() const { return mnThumbPosition;} - - /** Set the upper border of the slider range. - */ - void SetTotalSize (const double nTotalSize); - - /** Set the size of the movable thumb. - @param nThumbSize - A value not larger than the last value given to SetTotalSize(). - */ - void SetThumbSize (const double nThumbSize); - double GetThumbSize() const { return mnThumbSize;} - - void SetLineHeight (const double nLineHeight); - double GetLineHeight() const { return mnLineHeight;} - - /** Set the canvas that is used for painting the scroll bar. - */ - void SetCanvas (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - - void SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap); - - /** Call this after changing total size or thumb position or size to - move the thumb to a valid position. - */ - void CheckValues(); - - /** On some occasions it is necessary to trigger the painting of a - scrollbar from the outside. - */ - void Paint ( - const css::awt::Rectangle& rUpdateBox); - - virtual sal_Int32 GetSize() const = 0; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XMouseListener - - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - - // XMouseMotionListener - - virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent) override; - - // lang::XEventListener - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - - enum Area { Total, Pager, Thumb, PagerUp, PagerDown, PrevButton, NextButton, None, - AreaCount = None }; - -protected: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - std::shared_ptr<PresenterPaintManager> mpPaintManager; - double mnThumbPosition; - double mnTotalSize; - double mnThumbSize; - double mnLineHeight; - css::geometry::RealPoint2D maDragAnchor; - ::std::function<void (double)> maThumbMotionListener; - Area meButtonDownArea; - Area meMouseMoveArea; - css::geometry::RealRectangle2D maBox[AreaCount]; - bool mbIsNotificationActive; - static std::weak_ptr<PresenterBitmapContainer> mpSharedBitmaps; - std::shared_ptr<PresenterBitmapContainer> mpBitmaps; - SharedBitmapDescriptor mpPrevButtonDescriptor; - SharedBitmapDescriptor mpNextButtonDescriptor; - SharedBitmapDescriptor mpPagerStartDescriptor; - SharedBitmapDescriptor mpPagerCenterDescriptor; - SharedBitmapDescriptor mpPagerEndDescriptor; - SharedBitmapDescriptor mpThumbStartDescriptor; - SharedBitmapDescriptor mpThumbCenterDescriptor; - SharedBitmapDescriptor mpThumbEndDescriptor; - bool maEnabledState[AreaCount]; - - css::geometry::RealRectangle2D const & GetRectangle (const Area eArea) const; - virtual double GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const = 0; - virtual void UpdateDragAnchor (const double nDragDistance) = 0; - virtual double GetMinor (const double nX, const double nY) const = 0; - virtual void UpdateBorders() = 0; - virtual void UpdateBitmaps() = 0; - virtual void PaintComposite( - const css::awt::Rectangle& rRepaintBox, - const Area eArea, - const SharedBitmapDescriptor& rpStartBitmaps, - const SharedBitmapDescriptor& rpCenterBitmaps, - const SharedBitmapDescriptor& rpEndBitmaps) = 0; - - PresenterScrollBar ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const std::shared_ptr<PresenterPaintManager>& rpPaintManager, - const ::std::function<void (double)>& rThumbMotionListener); - - void Repaint ( - const css::geometry::RealRectangle2D& rBox, - const bool bAsynchronous); - void PaintBackground ( - const css::awt::Rectangle& rRepaintBox); - void PaintBitmap( - const css::awt::Rectangle& rRepaintBox, - const Area eArea, - const SharedBitmapDescriptor& rpBitmaps); - void UpdateWidthOrHeight (sal_Int32& rSize, - const SharedBitmapDescriptor& rpDescriptor); - css::uno::Reference<css::rendering::XBitmap> GetBitmap ( - const Area eArea, - const SharedBitmapDescriptor& rpBitmaps) const; - PresenterBitmapContainer::BitmapDescriptor::Mode GetBitmapMode ( - const Area eArea) const; - bool IsDisabled (const Area eArea) const; - double ValidateThumbPosition (double nPosition); - -private: - class MousePressRepeater; - std::shared_ptr<MousePressRepeater> mpMousePressRepeater; - SharedBitmapDescriptor mpBackgroundBitmap; - std::unique_ptr<PresenterCanvasHelper> mpCanvasHelper; - - Area GetArea (const double nX, const double nY) const; -}; - -/** A vertical scroll bar. -*/ -class PresenterVerticalScrollBar : public PresenterScrollBar -{ -public: - PresenterVerticalScrollBar ( - const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext, - const css::uno::Reference<css::awt::XWindow>& rxParentWindow, - const std::shared_ptr<PresenterPaintManager>& rpPaintManager, - const ::std::function<void (double)>& rThumbMotionListener); - virtual ~PresenterVerticalScrollBar() override; - virtual sal_Int32 GetSize() const override; - -protected: - virtual double GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const override; - virtual void UpdateDragAnchor (const double nDragDistance) override; - virtual double GetMinor (const double nX, const double nY) const override; - virtual void UpdateBorders() override; - virtual void UpdateBitmaps() override; - virtual void PaintComposite( - const css::awt::Rectangle& rRepaintBox, - const Area eArea, - const SharedBitmapDescriptor& rpStartBitmaps, - const SharedBitmapDescriptor& rpCenterBitmaps, - const SharedBitmapDescriptor& rpEndBitmaps) override; - -private: - sal_Int32 mnScrollBarWidth; -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSlidePreview.cxx b/sdext/source/presenter/PresenterSlidePreview.cxx deleted file mode 100644 index f95d9a050947..000000000000 --- a/sdext/source/presenter/PresenterSlidePreview.cxx +++ /dev/null @@ -1,357 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterSlidePreview.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterBitmapContainer.hxx" -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace -{ - // Use a super sample factor greater than 1 to achieve a poor mans - // antialiasing effect for slide previews. - const sal_Int16 gnSuperSampleFactor = 2; -} - -namespace sdext::presenter { - -//===== PresenterSlidePreview ================================================= - -PresenterSlidePreview::PresenterSlidePreview ( - const Reference<XComponentContext>& rxContext, - const Reference<XResourceId>& rxViewId, - const Reference<XPane>& rxAnchorPane, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterSlidePreviewInterfaceBase(m_aMutex), - mpPresenterController(rpPresenterController), - mxViewId(rxViewId), - mxPreviewRenderer(), - mxPreview(), - mxCurrentSlide(), - mnSlideAspectRatio(28.0 / 21.0), - mxWindow(), - mxCanvas() -{ - if ( ! rxContext.is() - || ! rxViewId.is() - || ! rxAnchorPane.is() - || ! rpPresenterController.is()) - { - throw RuntimeException( - "PresenterSlidePreview can not be constructed due to empty argument", - static_cast<XWeak*>(this)); - } - - mxWindow = rxAnchorPane->getWindow(); - mxCanvas = rxAnchorPane->getCanvas(); - - if (mxWindow.is()) - { - mxWindow->addWindowListener(this); - mxWindow->addPaintListener(this); - - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->setBackground(util::Color(0xff000000)); - - mxWindow->setVisible(true); - } - - if (mpPresenterController) - mnSlideAspectRatio = mpPresenterController->GetSlideAspectRatio(); - - Reference<lang::XMultiComponentFactory> xFactory = rxContext->getServiceManager(); - if (xFactory.is()) - mxPreviewRenderer.set( - xFactory->createInstanceWithContext( - "com.sun.star.drawing.SlideRenderer", - rxContext), - UNO_QUERY); - mpBitmaps = std::make_shared<PresenterBitmapContainer>( - "PresenterScreenSettings/ScrollBar/Bitmaps", - std::shared_ptr<PresenterBitmapContainer>(), - rxContext, - mxCanvas); - Resize(); -} - -PresenterSlidePreview::~PresenterSlidePreview() -{ -} - -void SAL_CALL PresenterSlidePreview::disposing() -{ - if (mxWindow.is()) - { - mxWindow->removeWindowListener(this); - mxWindow->removePaintListener(this); - mxWindow = nullptr; - mxCanvas = nullptr; - } - - Reference<lang::XComponent> xComponent (mxPreviewRenderer, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); -} - -//----- XResourceId ----------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterSlidePreview::getResourceId() -{ - return mxViewId; -} - -sal_Bool SAL_CALL PresenterSlidePreview::isAnchorOnly() -{ - return false; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterSlidePreview::windowResized (const awt::WindowEvent&) -{ - ThrowIfDisposed(); - ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); - Resize(); -} - -void SAL_CALL PresenterSlidePreview::windowMoved (const awt::WindowEvent&) {} - -void SAL_CALL PresenterSlidePreview::windowShown (const lang::EventObject&) -{ - ThrowIfDisposed(); - ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); - Resize(); -} - -void SAL_CALL PresenterSlidePreview::windowHidden (const lang::EventObject&) {} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterSlidePreview::windowPaint (const awt::PaintEvent& rEvent) -{ - ThrowIfDisposed(); - - ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); - if (mxWindow.is()) - Paint(awt::Rectangle( - rEvent.UpdateRect.X, - rEvent.UpdateRect.Y, - rEvent.UpdateRect.Width, - rEvent.UpdateRect.Height)); -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterSlidePreview::disposing (const lang::EventObject& rEvent) -{ - if (rEvent.Source == mxWindow) - { - mxWindow = nullptr; - mxCanvas = nullptr; - mxPreview = nullptr; - } -} - -//----- XDrawView ------------------------------------------------------------- - -void SAL_CALL PresenterSlidePreview::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide) -{ - ThrowIfDisposed(); - ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); - SetSlide(rxSlide); -} - -Reference<drawing::XDrawPage> SAL_CALL PresenterSlidePreview::getCurrentPage() -{ - ThrowIfDisposed(); - return nullptr; -} - - -void PresenterSlidePreview::SetSlide (const Reference<drawing::XDrawPage>& rxPage) -{ - mxCurrentSlide = rxPage; - mxPreview = nullptr; - - // The preview is not transparent, therefore only this window, not its - // parent, has to be invalidated. - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); -} - -void PresenterSlidePreview::Paint (const awt::Rectangle& rBoundingBox) -{ - if ( ! mxWindow.is()) - return; - if ( ! mxCanvas.is()) - return; - if ( ! mxPreviewRenderer.is()) - return; - - // Make sure that a preview in the correct size exists. - awt::Rectangle aWindowBox (mxWindow->getPosSize()); - - bool bCustomAnimation = false; - bool bTransition = false; - if( mxCurrentSlide.is() ) - { - bCustomAnimation = PresenterController::HasCustomAnimation(mxCurrentSlide); - bTransition = PresenterController::HasTransition(mxCurrentSlide); - } - - if ( ! mxPreview.is() && mxCurrentSlide.is()) - { - // Create a new preview bitmap. - mxPreview = mxPreviewRenderer->createPreviewForCanvas( - mxCurrentSlide, - awt::Size(aWindowBox.Width, aWindowBox.Height), - gnSuperSampleFactor, - mxCanvas); - } - - // Determine the bounding box of the preview. - awt::Rectangle aPreviewBox; - if (mxPreview.is()) - { - const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize()); - aPreviewBox = awt::Rectangle( - (aWindowBox.Width - aPreviewSize.Width)/2, - (aWindowBox.Height - aPreviewSize.Height)/2, - aPreviewSize.Width, - aPreviewSize.Height); - } - else - { - if (mnSlideAspectRatio > 0) - { - const awt::Size aPreviewSize (mxPreviewRenderer->calculatePreviewSize( - mnSlideAspectRatio,awt::Size(aWindowBox.Width, aWindowBox.Height))); - aPreviewBox = awt::Rectangle( - (aWindowBox.Width - aPreviewSize.Width)/2, - (aWindowBox.Height - aPreviewSize.Height)/2, - aPreviewSize.Width, - aPreviewSize.Height); - } - } - - // Paint the background. - mpPresenterController->GetCanvasHelper()->Paint( - mpPresenterController->GetViewBackground(mxViewId->getResourceURL()), - mxCanvas, - rBoundingBox, - awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height), - aPreviewBox); - - // Paint the preview. - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - - Sequence<double> aBackgroundColor(4); - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1, 0, aPreviewBox.X, 0, 1, aPreviewBox.Y), - nullptr, - aBackgroundColor, - rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00000000); - if (mxPreview.is()) - { - mxCanvas->drawBitmap(mxPreview, aViewState, aRenderState); - if( bTransition ) - { - const awt::Rectangle aTransitionPreviewBox(5, aWindowBox.Height-20, 0, 0); - SharedBitmapDescriptor aTransitionDescriptor = mpBitmaps->GetBitmap("Transition"); - Reference<rendering::XBitmap> xTransitionIcon (aTransitionDescriptor->GetNormalBitmap()); - rendering::RenderState aTransitionRenderState ( - geometry::AffineMatrix2D(1, 0, aTransitionPreviewBox.X, 0, 1, aTransitionPreviewBox.Y), - nullptr, - aBackgroundColor, - rendering::CompositeOperation::SOURCE); - mxCanvas->drawBitmap(xTransitionIcon, aViewState, aTransitionRenderState); - } - if( bCustomAnimation ) - { - const awt::Rectangle aAnimationPreviewBox(5, aWindowBox.Height-40, 0, 0); - SharedBitmapDescriptor aAnimationDescriptor = mpBitmaps->GetBitmap("Animation"); - Reference<rendering::XBitmap> xAnimationIcon (aAnimationDescriptor->GetNormalBitmap()); - rendering::RenderState aAnimationRenderState ( - geometry::AffineMatrix2D(1, 0, aAnimationPreviewBox.X, 0, 1, aAnimationPreviewBox.Y), - nullptr, - aBackgroundColor, - rendering::CompositeOperation::SOURCE); - mxCanvas->drawBitmap(xAnimationIcon, aViewState, aAnimationRenderState); - } - } - else - { - if (mnSlideAspectRatio > 0) - { - Reference<rendering::XPolyPolygon2D> xPolygon ( - PresenterGeometryHelper::CreatePolygon(aPreviewBox, mxCanvas->getDevice())); - if (xPolygon.is()) - mxCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState); - } - } - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -void PresenterSlidePreview::Resize() -{ - if (mxPreviewRenderer.is() && mxPreview.is()) - { - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - const awt::Size aNewPreviewSize (mxPreviewRenderer->calculatePreviewSize( - mnSlideAspectRatio, - awt::Size(aWindowBox.Width, aWindowBox.Height))); - const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize()); - if (aNewPreviewSize.Width==aPreviewSize.Width - && aNewPreviewSize.Height==aPreviewSize.Height) - { - // The size of the window may have changed but the preview would - // be painted in the same size (but not necessarily at the same - // position.) - return; - } - } - SetSlide(mxCurrentSlide); -} - -void PresenterSlidePreview::ThrowIfDisposed() -{ - if (PresenterSlidePreviewInterfaceBase::rBHelper.bDisposed || PresenterSlidePreviewInterfaceBase::rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterSlidePreview object has already been disposed", - static_cast<uno::XWeak*>(this)); - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSlidePreview.hxx b/sdext/source/presenter/PresenterSlidePreview.hxx deleted file mode 100644 index 85107693a9fa..000000000000 --- a/sdext/source/presenter/PresenterSlidePreview.hxx +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSLIDEPREVIEW_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSLIDEPREVIEW_HXX - -#include "PresenterController.hxx" - -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/drawing/XDrawPage.hpp> -#include <com/sun/star/drawing/XDrawView.hpp> -#include <com/sun/star/drawing/XSlideRenderer.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <rtl/ref.hxx> - -namespace sdext::presenter { - -typedef ::cppu::WeakComponentImplHelper < - css::drawing::framework::XView, - css::drawing::XDrawView, - css::awt::XPaintListener, - css::awt::XWindowListener -> PresenterSlidePreviewInterfaceBase; - -/** Static preview of a slide. Typically used for the preview of the next - slide. - This implementation shows a preview of the slide given to the - setCurrentSlide. For showing the next slide the PresenterViewFactory - uses a derived class that overrides the setCurrentSlide() method. -*/ -class PresenterSlidePreview - : private ::cppu::BaseMutex, - public PresenterSlidePreviewInterfaceBase -{ -public: - PresenterSlidePreview ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterSlidePreview() override; - PresenterSlidePreview(const PresenterSlidePreview&) = delete; - PresenterSlidePreview& operator=(const PresenterSlidePreview&) = delete; - virtual void SAL_CALL disposing() override; - - // XResourceId - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // lang::XEventListener - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - - // XDrawView - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override; - - virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage() override; - -protected: - ::rtl::Reference<PresenterController> mpPresenterController; - -private: - css::uno::Reference<css::drawing::framework::XResourceId> mxViewId; - css::uno::Reference<css::drawing::XSlideRenderer> mxPreviewRenderer; - - /** This Image holds the preview of the current slide. After resize - requests the image may be empty. This results eventually in a call - to ProvideSlide() in order to created a preview in the correct new - size. - */ - css::uno::Reference<css::rendering::XBitmap> mxPreview; - std::shared_ptr<PresenterBitmapContainer> mpBitmaps; - - /** The current slide for which a preview is displayed. This may or - may not be the same as the current slide of the PresenterView. - */ - css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide; - double mnSlideAspectRatio; - - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - - /** Set the given slide as the current slide of the called PresenterSlidePreview - object. - */ - void SetSlide (const css::uno::Reference<css::drawing::XDrawPage>& rxPage); - - /** Paint the preview of the current slide centered in the window of the - anchor pane. - */ - void Paint (const css::awt::Rectangle& rBoundingBox); - - /** React to a resize of the anchor pane. - */ - void Resize(); - - /** @throws css::lang::DisposedException when the object has already been - disposed. - */ - void ThrowIfDisposed(); -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSlideShowView.cxx b/sdext/source/presenter/PresenterSlideShowView.cxx deleted file mode 100644 index 26239c0b2642..000000000000 --- a/sdext/source/presenter/PresenterSlideShowView.cxx +++ /dev/null @@ -1,970 +0,0 @@ - -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterSlideShowView.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterHelper.hxx" -#include "PresenterPaneContainer.hxx" -#include <com/sun/star/awt/InvalidateStyle.hpp> -#include <com/sun/star/awt/PosSize.hpp> -#include <com/sun/star/awt/Pointer.hpp> -#include <com/sun/star/awt/Toolkit.hpp> -#include <com/sun/star/awt/WindowAttribute.hpp> -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/rendering/TexturingMode.hpp> -#include <osl/mutex.hxx> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -//===== PresenterSlideShowView ================================================ - -PresenterSlideShowView::PresenterSlideShowView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterSlideShowViewInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - mpPresenterController(rpPresenterController), - mxViewId(rxViewId), - mxController(rxController), - mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)), - mxSlideShow(), - mxCanvas(), - mxViewCanvas(), - mxPointer(), - mxWindow(), - mxViewWindow(), - mxTopPane(), - mxPresenterHelper(), - mxBackgroundPolygon1(), - mxBackgroundPolygon2(), - mbIsViewAdded(false), - mnPageAspectRatio(28.0/21.0), - maBroadcaster(m_aMutex), - mpBackground(), - mbIsForcedPaintPending(false), - mbIsPaintPending(true), - msClickToExitPresentationText(), - msClickToExitPresentationTitle(), - msTitleTemplate(), - mbIsEndSlideVisible(false), - mxCurrentSlide() -{ - if (mpPresenterController) - { - mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio(); - mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL()); - } -} - -void PresenterSlideShowView::LateInit() -{ - mxSlideShow.set( mxSlideShowController->getSlideShow(), UNO_SET_THROW); - Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY); - xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this)); - - Reference<lang::XMultiComponentFactory> xFactory ( - mxComponentContext->getServiceManager(), UNO_SET_THROW); - mxPresenterHelper.set (xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - mxComponentContext), - UNO_QUERY_THROW); - - // Use view id and controller to retrieve window and canvas from - // configuration controller. - Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW); - Reference<XConfigurationController> xCC (xCM->getConfigurationController()); - - if (xCC.is()) - { - mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY); - - Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW); - - mxWindow = xPane->getWindow(); - mxCanvas = xPane->getCanvas(); - - if (mxWindow.is()) - { - mxWindow->addPaintListener(this); - mxWindow->addWindowListener(this); - } - - // The window does not have to paint a background. We do - // that ourself. - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->setBackground(util::Color(0xff000000)); - } - - // Create a window for the actual slide show view. It is places - // centered and with maximal size inside the pane. - mxViewWindow = CreateViewWindow(mxWindow); - - mxViewCanvas = CreateViewCanvas(mxViewWindow); - - if (mxViewWindow.is()) - { - // Register listeners at window. - mxViewWindow->addPaintListener(this); - mxViewWindow->addMouseListener(this); - mxViewWindow->addMouseMotionListener(this); - } - - if (mxViewWindow.is()) - Resize(); - - if (mxWindow.is()) - mxWindow->setVisible(true); - - // Add the new slide show view to the slide show. - if (mxSlideShow.is() && ! mbIsViewAdded) - { - impl_addAndConfigureView(); - mbIsViewAdded = true; - } - - // Read text for one past last slide. - PresenterConfigurationAccess aConfiguration ( - mxComponentContext, - PresenterConfigurationAccess::msPresenterScreenRootName, - PresenterConfigurationAccess::READ_ONLY); - aConfiguration.GetConfigurationNode( - "Presenter/Views/CurrentSlidePreview/" - "Strings/ClickToExitPresentationText/String") - >>= msClickToExitPresentationText; - aConfiguration.GetConfigurationNode( - "Presenter/Views/CurrentSlidePreview/" - "Strings/ClickToExitPresentationTitle/String") - >>= msClickToExitPresentationTitle; -} - -PresenterSlideShowView::~PresenterSlideShowView() -{ -} - -void PresenterSlideShowView::disposing() -{ - // Tell all listeners that we are disposed. - lang::EventObject aEvent; - aEvent.Source = static_cast<XWeak*>(this); - - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<lang::XEventListener>::get()); - if (pIterator != nullptr) - pIterator->disposeAndClear(aEvent); - - // Do this for - // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener? - - if (mxWindow.is()) - { - mxWindow->removePaintListener(this); - mxWindow->removeMouseListener(this); - mxWindow->removeMouseMotionListener(this); - mxWindow->removeWindowListener(this); - mxWindow = nullptr; - } - mxSlideShowController = nullptr; - mxSlideShow = nullptr; - if (mxViewCanvas.is()) - { - Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY); - mxViewCanvas = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - if (mxViewWindow.is()) - { - Reference<XComponent> xComponent = mxViewWindow; - mxViewWindow = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - if (mxPointer.is()) - { - Reference<XComponent> xComponent (mxPointer, UNO_QUERY); - mxPointer = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - if (mxBackgroundPolygon1.is()) - { - Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY); - mxBackgroundPolygon1 = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - if (mxBackgroundPolygon2.is()) - { - Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY); - mxBackgroundPolygon2 = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - mxComponentContext = nullptr; - mpPresenterController = nullptr; - mxViewId = nullptr; - mxController = nullptr; - mxCanvas = nullptr; - mpBackground.reset(); - msClickToExitPresentationText.clear(); - msClickToExitPresentationTitle.clear(); - msTitleTemplate.clear(); - mxCurrentSlide = nullptr; -} - -//----- XDrawView ------------------------------------------------------------- - -void SAL_CALL PresenterSlideShowView::setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) -{ - mxCurrentSlide = rxSlide; - if (mpPresenterController - && mxSlideShowController.is() - && ! mpPresenterController->GetCurrentSlide().is() - && ! mxSlideShowController->isPaused()) - { - mbIsEndSlideVisible = true; - Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT); - - // For the end slide we use a special title, without the (n of m) - // part. Save the title template for the case that the user goes - // backwards. - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL())); - if (pDescriptor) - { - msTitleTemplate = pDescriptor->msTitleTemplate; - pDescriptor->msTitleTemplate = msClickToExitPresentationTitle; - mpPresenterController->UpdatePaneTitles(); - } - } - else if (mbIsEndSlideVisible) - { - mbIsEndSlideVisible = false; - - // Restore the title template. - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL())); - if (pDescriptor) - { - pDescriptor->msTitleTemplate = msTitleTemplate; - pDescriptor->msTitle.clear(); - mpPresenterController->UpdatePaneTitles(); - } - } -} - -css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage() -{ - return mxCurrentSlide; -} - -//----- CachablePresenterView ------------------------------------------------- - -void PresenterSlideShowView::ReleaseView() -{ - if (mxSlideShow.is() && mbIsViewAdded) - { - mxSlideShow->removeView(this); - mbIsViewAdded = false; - } -} - -//----- XSlideShowView -------------------------------------------------------- - -Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas() -{ - ThrowIfDisposed(); - - return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY); -} - -void SAL_CALL PresenterSlideShowView::clear() -{ - ThrowIfDisposed(); - mbIsForcedPaintPending = false; - mbIsPaintPending = false; - - if (!(mxViewCanvas.is() && mxViewWindow.is())) - return; - - // Create a polygon for the window outline. - awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); - Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon( - awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height), - mxViewCanvas->getDevice())); - - rendering::ViewState aViewState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - double const aColor[4] = {0,0,0,0}; - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(aColor,4), - rendering::CompositeOperation::SOURCE); - mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState); -} - -geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation() -{ - ThrowIfDisposed(); - - if (mxViewWindow.is()) - { - // When the mbIsInModifyNotification is set then a slightly modified - // version of the transformation is returned in order to get past - // optimizations the avoid updates when the transformation is - // unchanged (when the window size changes then due to the constant - // aspect ratio the size of the preview may remain the same while - // the position changes. The position, however, is represented by - // the position of the view window. This transformation is given - // relative to the view window and therefore does not contain the - // position.) - const awt::Rectangle aWindowBox = mxViewWindow->getPosSize(); - return geometry::AffineMatrix2D( - aWindowBox.Width-1, 0, 0, - 0, aWindowBox.Height-1, 0); - } - else - { - return geometry::AffineMatrix2D(1,0,0, 0,1,0); - } -} - -geometry::IntegerSize2D SAL_CALL PresenterSlideShowView::getTranslationOffset() -{ - ThrowIfDisposed(); - return geometry::IntegerSize2D(0,0); -} - -void SAL_CALL PresenterSlideShowView::addTransformationChangedListener( - const Reference<util::XModifyListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.addListener( - cppu::UnoType<util::XModifyListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener( - const Reference<util::XModifyListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.removeListener( - cppu::UnoType<util::XModifyListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::addPaintListener( - const Reference<awt::XPaintListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.addListener( - cppu::UnoType<awt::XPaintListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::removePaintListener( - const Reference<awt::XPaintListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.removeListener( - cppu::UnoType<awt::XPaintListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::addMouseListener( - const Reference<awt::XMouseListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.addListener( - cppu::UnoType<awt::XMouseListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::removeMouseListener( - const Reference<awt::XMouseListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.removeListener( - cppu::UnoType<awt::XMouseListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::addMouseMotionListener( - const Reference<awt::XMouseMotionListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.addListener( - cppu::UnoType<awt::XMouseMotionListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::removeMouseMotionListener( - const Reference<awt::XMouseMotionListener>& rxListener) -{ - ThrowIfDisposed(); - maBroadcaster.removeListener( - cppu::UnoType<awt::XMouseMotionListener>::get(), - rxListener); -} - -void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape) -{ - ThrowIfDisposed(); - - // Create a pointer when it does not yet exist. - if ( ! mxPointer.is()) - { - mxPointer = awt::Pointer::create(mxComponentContext); - } - - // Set the pointer to the given shape and the window(peer) to the - // pointer. - Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY); - if (mxPointer.is() && xPeer.is()) - { - mxPointer->setType(nPointerShape); - xPeer->setPointer(mxPointer); - } -} - -awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( ) -{ - if( mxViewWindow.is() && mxTopPane.is() ) - return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() ); - - awt::Rectangle aRectangle; - - aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0; - - return aRectangle; -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent) -{ - if (rEvent.Source == mxViewWindow) - mxViewWindow = nullptr; - else if (rEvent.Source == mxSlideShow) - mxSlideShow = nullptr; -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent) -{ - // Deactivated views must not be painted. - if ( ! mbIsPresenterViewActive) - return; - - awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); - if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0) - return; - - if (rEvent.Source == mxWindow) - PaintOuterWindow(rEvent.UpdateRect); - else if (mbIsEndSlideVisible) - PaintEndSlide(rEvent.UpdateRect); - else - PaintInnerWindow(rEvent); -} - -//----- XMouseListener -------------------------------------------------------- - -void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent) -{ - awt::MouseEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent); - } - - // Only when the end slide is displayed we forward the mouse event to - // the PresenterController so that it switches to the next slide and - // ends the presentation. - if (mbIsEndSlideVisible) - if (mpPresenterController) - mpPresenterController->HandleMouseClick(rEvent); -} - -void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent) -{ - awt::MouseEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent); - } -} - -void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent) -{ - awt::MouseEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent); - } -} - -void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent) -{ - awt::MouseEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent); - } -} - -//----- XMouseMotionListener -------------------------------------------------- - -void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent) -{ - awt::MouseEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseMotionListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent); - } -} - -void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent) -{ - awt::MouseEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseMotionListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent); - } -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent&) -{ - ThrowIfDisposed(); - ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); - - Resize(); -} - -void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent&) -{ - if ( ! mbIsPaintPending) - mbIsForcedPaintPending = true; -} - -void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject&) -{ - Resize(); -} - -void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject&) {} - -//----- XView ----------------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId() -{ - return mxViewId; -} - -sal_Bool SAL_CALL PresenterSlideShowView::isAnchorOnly() -{ - return false; -} - -//----- CachablePresenterView ------------------------------------------------- - -void PresenterSlideShowView::ActivatePresenterView() -{ - if (mxSlideShow.is() && ! mbIsViewAdded) - { - impl_addAndConfigureView(); - mbIsViewAdded = true; - } -} - -void PresenterSlideShowView::DeactivatePresenterView() -{ - if (mxSlideShow.is() && mbIsViewAdded) - { - mxSlideShow->removeView(this); - mbIsViewAdded = false; - } -} - - -void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox) -{ - if ( ! mxCanvas.is()) - return; - - if (!mpBackground) - return; - - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice())); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap()); - if (xBackgroundBitmap.is()) - { - const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize()); - Sequence<rendering::Texture> aTextures - { - { - geometry::AffineMatrix2D( aBitmapSize.Width,0,0, 0,aBitmapSize.Height,0), - 1, - 0, - xBackgroundBitmap, - nullptr, - nullptr, - rendering::StrokeAttributes(), - rendering::TexturingMode::REPEAT, - rendering::TexturingMode::REPEAT - } - }; - - if (mxBackgroundPolygon1.is()) - mxCanvas->fillTexturedPolyPolygon( - mxBackgroundPolygon1, - aViewState, - aRenderState, - aTextures); - if (mxBackgroundPolygon2.is()) - mxCanvas->fillTexturedPolyPolygon( - mxBackgroundPolygon2, - aViewState, - aRenderState, - aTextures); - } - else - { - PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor); - - if (mxBackgroundPolygon1.is()) - mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState); - if (mxBackgroundPolygon2.is()) - mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState); - } -} - -void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox) -{ - if ( ! mxCanvas.is()) - return; - - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice())); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000)); - mxCanvas->fillPolyPolygon( - PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()), - aViewState, - aRenderState); - - do - { - if (!mpPresenterController) - break; - std::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme()); - if (pTheme == nullptr) - break; - - const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL())); - PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle)); - if (!pFont) - break; - - /// this is responsible of the " presentation exit " text inside the slide windows - PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff)); - aRenderState.AffineTransform.m02 = 20; - aRenderState.AffineTransform.m12 = 40; - const rendering::StringContext aContext ( - msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength()); - pFont->PrepareFont(mxCanvas); - const Reference<rendering::XTextLayout> xLayout ( - pFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0)); - mxCanvas->drawTextLayout( - xLayout, - aViewState, - aRenderState); - } - while (false); - - // Finally, in double buffered environments, request the changes to be - // made visible. - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(true); -} - -void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent) -{ - // Forward window paint to listeners. - awt::PaintEvent aEvent (rEvent); - aEvent.Source = static_cast<XWeak*>(this); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<awt::XPaintListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent); - } - - /** The slide show relies on the back buffer of the canvas not being - modified. With a shared canvas there are times when that can not be - guaranteed. - */ - if (mbIsForcedPaintPending && mxSlideShow.is() && mbIsViewAdded) - { - mxSlideShow->removeView(this); - impl_addAndConfigureView(); - } - - // Finally, in double buffered environments, request the changes to be - // made visible. - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(true); -} - -Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow ( - const Reference<awt::XWindow>& rxParentWindow) const -{ - Reference<awt::XWindow> xViewWindow; - try - { - Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager()); - if ( ! xFactory.is()) - return xViewWindow; - - Reference<awt::XToolkit2> xToolkit = awt::Toolkit::create(mxComponentContext); - awt::WindowDescriptor aWindowDescriptor ( - awt::WindowClass_CONTAINER, - OUString(), - Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW), - -1, // parent index not available - awt::Rectangle(0,0,10,10), - awt::WindowAttribute::SIZEABLE - | awt::WindowAttribute::MOVEABLE - | awt::WindowAttribute::NODECORATION); - xViewWindow.set( xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW); - - // Make the background transparent. The slide show paints its own background. - Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW); - xPeer->setBackground(0xff000000); - - xViewWindow->setVisible(true); - } - catch (RuntimeException&) - { - } - return xViewWindow; -} - -Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas ( - const Reference<awt::XWindow>& rxViewWindow) const -{ - // Create a canvas for the view window. - return mxPresenterHelper->createSharedCanvas( - Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY), - mxTopPane->getWindow(), - mxTopPane->getCanvas(), - mxTopPane->getWindow(), - rxViewWindow); -} - -void PresenterSlideShowView::Resize() -{ - if ( ! mxWindow.is() || ! mxViewWindow.is()) - return; - - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - if (aWindowBox.Height > 0) - { - awt::Rectangle aViewWindowBox; - const double nWindowAspectRatio ( - double(aWindowBox.Width) / double(aWindowBox.Height)); - if (nWindowAspectRatio > mnPageAspectRatio) - { - // Slides will be painted with the full parent window height. - aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5); - aViewWindowBox.Height = aWindowBox.Height; - aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2; - aViewWindowBox.Y = 0; - } - else - { - // Slides will be painted with the full parent window width. - aViewWindowBox.Width = aWindowBox.Width; - aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5); - aViewWindowBox.X = 0; - aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2; - } - mxViewWindow->setPosSize( - aViewWindowBox.X, - aViewWindowBox.Y, - aViewWindowBox.Width, - aViewWindowBox.Height, - awt::PosSize::POSSIZE); - } - - // Clear the background polygon so that on the next paint it is created - // for the new size. - CreateBackgroundPolygons(); - - // Notify listeners that the transformation that maps the view into the - // window has changed. - lang::EventObject aEvent (static_cast<XWeak*>(this)); - ::cppu::OInterfaceContainerHelper* pIterator - = maBroadcaster.getContainer(cppu::UnoType<util::XModifyListener>::get()); - if (pIterator != nullptr) - { - pIterator->notifyEach(&util::XModifyListener::modified, aEvent); - } - - // Due to constant aspect ratio resizing may lead a preview that changes - // its position but not its size. This invalidates the back buffer and - // we have to enforce a complete repaint. - if ( ! mbIsPaintPending) - mbIsForcedPaintPending = true; -} - -void PresenterSlideShowView::CreateBackgroundPolygons() -{ - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); - if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width) - { - mxBackgroundPolygon1 = nullptr; - mxBackgroundPolygon2 = nullptr; - } - else if (aWindowBox.Height == aViewWindowBox.Height) - { - // Paint two boxes to the left and right of the view window. - mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon( - awt::Rectangle( - 0, - 0, - aViewWindowBox.X, - aWindowBox.Height), - mxCanvas->getDevice()); - mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon( - awt::Rectangle( - aViewWindowBox.X + aViewWindowBox.Width, - 0, - aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width, - aWindowBox.Height), - mxCanvas->getDevice()); - } - else - { - // Paint two boxes above and below the view window. - mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon( - awt::Rectangle( - 0, - 0, - aWindowBox.Width, - aViewWindowBox.Y), - mxCanvas->getDevice()); - mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon( - awt::Rectangle( - 0, - aViewWindowBox.Y + aViewWindowBox.Height, - aWindowBox.Width, - aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height), - mxCanvas->getDevice()); - } -} - -void PresenterSlideShowView::ThrowIfDisposed() -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterSlideShowView object has already been disposed", - static_cast<uno::XWeak*>(this)); - } -} - -void PresenterSlideShowView::impl_addAndConfigureView() -{ - Reference<presentation::XSlideShowView> xView (this); - mxSlideShow->addView(xView); - // Prevent embedded sounds being played twice at the same time by - // disabling sound for the new slide show view. - beans::PropertyValue aProperty; - aProperty.Name = "IsSoundEnabled"; - Sequence<Any> aValues (2); - aValues[0] <<= xView; - aValues[1] <<= false; - aProperty.Value <<= aValues; - mxSlideShow->setProperty(aProperty); -} - -} // end of namespace ::sd::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSlideShowView.hxx b/sdext/source/presenter/PresenterSlideShowView.hxx deleted file mode 100644 index d009888f9fb8..000000000000 --- a/sdext/source/presenter/PresenterSlideShowView.hxx +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSLIDESHOWVIEW_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSLIDESHOWVIEW_HXX - -#include "PresenterViewFactory.hxx" -#include <com/sun/star/presentation/XSlideShowView.hpp> -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XMouseListener.hpp> -#include <com/sun/star/awt/XMouseMotionListener.hpp> -#include <com/sun/star/awt/XPointer.hpp> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/drawing/XDrawView.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/drawing/framework/XResourceId.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/presentation/XSlideShowController.hpp> -#include <com/sun/star/rendering/XPolyPolygon2D.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> - -namespace sdext::presenter { - -typedef cppu::WeakComponentImplHelper< - css::presentation::XSlideShowView, - css::awt::XPaintListener, - css::awt::XMouseListener, - css::awt::XMouseMotionListener, - css::awt::XWindowListener, - css::drawing::framework::XView, - css::drawing::XDrawView - > PresenterSlideShowViewInterfaceBase; - -/** Life view in a secondary window of a full screen slide show. -*/ -class PresenterSlideShowView - : protected ::cppu::BaseMutex, - public PresenterSlideShowViewInterfaceBase, - public CachablePresenterView -{ -public: - PresenterSlideShowView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterSlideShowView() override; - PresenterSlideShowView(const PresenterSlideShowView&) = delete; - PresenterSlideShowView& operator=(const PresenterSlideShowView&) = delete; - - void LateInit(); - virtual void SAL_CALL disposing() override; - - // CachablePresenterView - - virtual void ReleaseView() override; - - // XSlideShowView - - virtual css::uno::Reference< - css::rendering::XSpriteCanvas > SAL_CALL getCanvas() override; - - virtual void SAL_CALL clear() override; - - virtual css::geometry::AffineMatrix2D SAL_CALL getTransformation() override; - - virtual css::geometry::IntegerSize2D SAL_CALL getTranslationOffset() override; - - virtual void SAL_CALL addTransformationChangedListener( - const css::uno::Reference< - css::util::XModifyListener >& xListener) override; - - virtual void SAL_CALL removeTransformationChangedListener( - const css::uno::Reference< - css::util::XModifyListener >& xListener) override; - - virtual void SAL_CALL addPaintListener( - const css::uno::Reference< - css::awt::XPaintListener >& xListener) override; - - virtual void SAL_CALL removePaintListener( - const css::uno::Reference< - css::awt::XPaintListener >& xListener) override; - - virtual void SAL_CALL addMouseListener( - const css::uno::Reference< - css::awt::XMouseListener >& xListener) override; - - virtual void SAL_CALL removeMouseListener( - const css::uno::Reference< - css::awt::XMouseListener >& xListener) override; - - virtual void SAL_CALL addMouseMotionListener( - const css::uno::Reference< - css::awt::XMouseMotionListener >& xListener) override; - - virtual void SAL_CALL removeMouseMotionListener( - const css::uno::Reference< - css::awt::XMouseMotionListener >& xListener) override; - - virtual void SAL_CALL setMouseCursor(::sal_Int16 nPointerShape) override; - - virtual css::awt::Rectangle SAL_CALL getCanvasArea( ) override; - - // lang::XEventListener - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - - // XPaintListener - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XMouseListener - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - - // XMouseMotionListener - - virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent) override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XView - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL - getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - - // XDrawView - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override; - - virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage() override; - - // CachablePresenterView - - virtual void ActivatePresenterView() override; - - virtual void DeactivatePresenterView() override; - -private: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::drawing::framework::XResourceId> mxViewId; - css::uno::Reference<css::frame::XController> mxController; - css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController; - css::uno::Reference<css::presentation::XSlideShow> mxSlideShow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::rendering::XCanvas> mxViewCanvas; - css::uno::Reference<css::awt::XPointer> mxPointer; - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::awt::XWindow> mxViewWindow; - css::uno::Reference<css::drawing::framework::XPane> mxTopPane; - css::uno::Reference<css::drawing::XPresenterHelper> mxPresenterHelper; - css::uno::Reference<css::rendering::XPolyPolygon2D> mxBackgroundPolygon1; - css::uno::Reference<css::rendering::XPolyPolygon2D> mxBackgroundPolygon2; - bool mbIsViewAdded; - - /** Aspect ratio of the current slide. - */ - double mnPageAspectRatio; - - /** This broadcast helper is used to notify listeners registered to a - SlideShowView object. - */ - ::cppu::OBroadcastHelper maBroadcaster; - - SharedBitmapDescriptor mpBackground; - - bool mbIsForcedPaintPending; - bool mbIsPaintPending; - OUString msClickToExitPresentationText; - OUString msClickToExitPresentationTitle; - OUString msTitleTemplate; - bool mbIsEndSlideVisible; - css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide; - - /** Create the window into which the slide show will render its - content. This window has the correct aspect ratio and is displayed centered - and as large as possible in its parent window. - */ - css::uno::Reference<css::awt::XWindow> CreateViewWindow ( - const css::uno::Reference<css::awt::XWindow>& rxParentWindow) const; - css::uno::Reference<css::rendering::XCanvas> CreateViewCanvas ( - const css::uno::Reference<css::awt::XWindow>& rxWindow) const; - - void Resize(); - - void PaintOuterWindow (const css::awt::Rectangle& rRepaintBox); - void PaintInnerWindow (const css::awt::PaintEvent& rEvent); - void PaintEndSlide (const css::awt::Rectangle& rRepaintBox); - - void CreateBackgroundPolygons(); - - /** @throws css::lang::DisposedException when the object has already been - disposed. - */ - void ThrowIfDisposed(); - - void impl_addAndConfigureView(); -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSlideSorter.cxx b/sdext/source/presenter/PresenterSlideSorter.cxx deleted file mode 100644 index 493e33a39ce9..000000000000 --- a/sdext/source/presenter/PresenterSlideSorter.cxx +++ /dev/null @@ -1,1958 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <vcl/settings.hxx> - -#include "PresenterSlideSorter.hxx" -#include "PresenterButton.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterPaneBase.hxx" -#include "PresenterScrollBar.hxx" -#include "PresenterUIPainter.hxx" -#include "PresenterWindowManager.hxx" -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/rendering/XBitmapCanvas.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <algorithm> -#include <math.h> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace { - const sal_Int32 gnVerticalGap (10); - const sal_Int32 gnVerticalBorder (10); - const sal_Int32 gnHorizontalGap (10); - const sal_Int32 gnHorizontalBorder (10); - - const double gnMinimalPreviewWidth (200); - const double gnPreferredPreviewWidth (300); - const double gnMaximalPreviewWidth (400); - const sal_Int32 gnPreferredColumnCount (6); - const double gnMinimalHorizontalPreviewGap(15); - const double gnPreferredHorizontalPreviewGap(25); - const double gnMaximalHorizontalPreviewGap(50); - const double gnPreferredVerticalPreviewGap(25); - - const sal_Int32 gnHorizontalLabelBorder (3); - const sal_Int32 gnHorizontalLabelPadding (5); - - const sal_Int32 gnVerticalButtonPadding (gnVerticalGap); -} - -namespace sdext::presenter { - -namespace { - sal_Int32 round (const double nValue) { return sal::static_int_cast<sal_Int32>(0.5 + nValue); } - sal_Int32 floor (const double nValue) { return sal::static_int_cast<sal_Int32>(nValue); } -} - -//===== PresenterSlideSorter::Layout ========================================== - -class PresenterSlideSorter::Layout -{ -public: - explicit Layout (const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar); - - void Update (const geometry::RealRectangle2D& rBoundingBox, const double nSlideAspectRatio); - void SetupVisibleArea(); - void UpdateScrollBars(); - bool IsScrollBarNeeded (const sal_Int32 nSlideCount); - geometry::RealPoint2D GetLocalPosition (const geometry::RealPoint2D& rWindowPoint) const; - geometry::RealPoint2D GetWindowPosition(const geometry::RealPoint2D& rLocalPoint) const; - sal_Int32 GetColumn (const geometry::RealPoint2D& rLocalPoint) const; - sal_Int32 GetRow (const geometry::RealPoint2D& rLocalPoint, - const bool bReturnInvalidValue = false) const; - sal_Int32 GetSlideIndexForPosition (const css::geometry::RealPoint2D& rPoint) const; - css::geometry::RealPoint2D GetPoint ( - const sal_Int32 nSlideIndex, - const sal_Int32 nRelativeHorizontalPosition, - const sal_Int32 nRelativeVerticalPosition) const; - css::awt::Rectangle GetBoundingBox (const sal_Int32 nSlideIndex) const; - void ForAllVisibleSlides (const ::std::function<void (sal_Int32)>& rAction); - sal_Int32 GetFirstVisibleSlideIndex() const; - sal_Int32 GetLastVisibleSlideIndex() const; - bool SetHorizontalOffset (const double nOffset); - bool SetVerticalOffset (const double nOffset); - - css::geometry::RealRectangle2D maBoundingBox; - css::geometry::IntegerSize2D maPreviewSize; - sal_Int32 mnHorizontalOffset; - sal_Int32 mnVerticalOffset; - sal_Int32 mnHorizontalGap; - sal_Int32 mnVerticalGap; - sal_Int32 mnHorizontalBorder; - sal_Int32 mnVerticalBorder; - sal_Int32 mnRowCount; - sal_Int32 mnColumnCount; - sal_Int32 mnSlideCount; - sal_Int32 mnFirstVisibleColumn; - sal_Int32 mnLastVisibleColumn; - sal_Int32 mnFirstVisibleRow; - sal_Int32 mnLastVisibleRow; - -private: - ::rtl::Reference<PresenterScrollBar> mpVerticalScrollBar; - - sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const; - sal_Int32 GetRow (const sal_Int32 nSlideIndex) const; - sal_Int32 GetColumn (const sal_Int32 nSlideIndex) const; -}; - -//==== PresenterSlideSorter::MouseOverManager ================================= - -class PresenterSlideSorter::MouseOverManager -{ -public: - MouseOverManager ( - const Reference<container::XIndexAccess>& rxSlides, - const std::shared_ptr<PresenterTheme>& rpTheme, - const Reference<awt::XWindow>& rxInvalidateTarget, - const std::shared_ptr<PresenterPaintManager>& rpPaintManager); - MouseOverManager(const MouseOverManager&) = delete; - MouseOverManager& operator=(const MouseOverManager&) = delete; - - void Paint ( - const sal_Int32 nSlideIndex, - const Reference<rendering::XCanvas>& rxCanvas, - const Reference<rendering::XPolyPolygon2D>& rxClip); - - void SetSlide ( - const sal_Int32 nSlideIndex, - const awt::Rectangle& rBox); - -private: - Reference<rendering::XCanvas> mxCanvas; - const Reference<container::XIndexAccess> mxSlides; - SharedBitmapDescriptor mpLeftLabelBitmap; - SharedBitmapDescriptor mpCenterLabelBitmap; - SharedBitmapDescriptor mpRightLabelBitmap; - PresenterTheme::SharedFontDescriptor mpFont; - sal_Int32 mnSlideIndex; - awt::Rectangle maSlideBoundingBox; - OUString msText; - Reference<rendering::XBitmap> mxBitmap; - Reference<awt::XWindow> mxInvalidateTarget; - std::shared_ptr<PresenterPaintManager> mpPaintManager; - - void SetCanvas ( - const Reference<rendering::XCanvas>& rxCanvas); - /** Create a bitmap that shows the given text and is not wider than the - given maximal width. - */ - Reference<rendering::XBitmap> CreateBitmap ( - const OUString& rsText, - const sal_Int32 nMaximalWidth) const; - void Invalidate(); - geometry::IntegerSize2D CalculateLabelSize ( - const OUString& rsText) const; - OUString GetFittingText (const OUString& rsText, const double nMaximalWidth) const; - void PaintButtonBackground ( - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::IntegerSize2D& rSize) const; -}; - -//==== PresenterSlideSorter::CurrentSlideFrameRenderer ======================== - -class PresenterSlideSorter::CurrentSlideFrameRenderer -{ -public: - CurrentSlideFrameRenderer ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - - void PaintCurrentSlideFrame ( - const awt::Rectangle& rSlideBoundingBox, - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::RealRectangle2D& rClipBox); - - /** Enlarge the given rectangle to include the current slide indicator. - */ - awt::Rectangle GetBoundingBox ( - const awt::Rectangle& rSlideBoundingBox); - -private: - SharedBitmapDescriptor mpTopLeft; - SharedBitmapDescriptor mpTop; - SharedBitmapDescriptor mpTopRight; - SharedBitmapDescriptor mpLeft; - SharedBitmapDescriptor mpRight; - SharedBitmapDescriptor mpBottomLeft; - SharedBitmapDescriptor mpBottom; - SharedBitmapDescriptor mpBottomRight; - sal_Int32 mnTopFrameSize; - sal_Int32 mnLeftFrameSize; - sal_Int32 mnRightFrameSize; - sal_Int32 mnBottomFrameSize; - - static void PaintBitmapOnce( - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const Reference<rendering::XPolyPolygon2D>& rxClip, - const double nX, - const double nY); - static void PaintBitmapTiled( - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const geometry::RealRectangle2D& rClipBox, - const double nX, - const double nY, - const double nWidth, - const double nHeight); -}; - -//===== PresenterSlideSorter ================================================== - -PresenterSlideSorter::PresenterSlideSorter ( - const Reference<uno::XComponentContext>& rxContext, - const Reference<XResourceId>& rxViewId, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterSlideSorterInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - mxViewId(rxViewId), - mxPane(), - mxCanvas(), - mxWindow(), - mpPresenterController(rpPresenterController), - mxSlideShowController(mpPresenterController->GetSlideShowController()), - mxPreviewCache(), - mbIsLayoutPending(true), - mpLayout(), - mpVerticalScrollBar(), - mpCloseButton(), - mpMouseOverManager(), - mnSlideIndexMousePressed(-1), - mnCurrentSlideIndex(-1), - mnSeparatorY(0), - maSeparatorColor(0x00ffffff), - maCurrentSlideFrameBoundingBox(), - mpCurrentSlideFrameRenderer(), - mxPreviewFrame() -{ - if ( ! rxContext.is() - || ! rxViewId.is() - || ! rxController.is() - || ! rpPresenterController) - { - throw lang::IllegalArgumentException(); - } - - if ( ! mxSlideShowController.is()) - throw RuntimeException(); - - try - { - // Get pane and window. - Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); - Reference<XConfigurationController> xCC ( - xCM->getConfigurationController(), UNO_SET_THROW); - Reference<lang::XMultiComponentFactory> xFactory ( - mxComponentContext->getServiceManager(), UNO_SET_THROW); - - mxPane.set(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW); - mxWindow = mxPane->getWindow(); - - // Add window listener. - mxWindow->addWindowListener(this); - mxWindow->addPaintListener(this); - mxWindow->addMouseListener(this); - mxWindow->addMouseMotionListener(this); - mxWindow->setVisible(true); - - // Remember the current slide. - mnCurrentSlideIndex = mxSlideShowController->getCurrentSlideIndex(); - - // Create the scroll bar. - mpVerticalScrollBar.set( - new PresenterVerticalScrollBar( - rxContext, - mxWindow, - mpPresenterController->GetPaintManager(), - [this] (double const offset) { return this->SetVerticalOffset(offset); })); - - mpCloseButton = PresenterButton::Create( - rxContext, - mpPresenterController, - mpPresenterController->GetTheme(), - mxWindow, - mxCanvas, - "SlideSorterCloser"); - - if (mpPresenterController->GetTheme() != nullptr) - { - PresenterTheme::SharedFontDescriptor pFont ( - mpPresenterController->GetTheme()->GetFont("ButtonFont")); - if (pFont) - maSeparatorColor = pFont->mnColor; - } - - // Create the layout. - mpLayout = std::make_shared<Layout>(mpVerticalScrollBar); - - // Create the preview cache. - mxPreviewCache.set( - xFactory->createInstanceWithContext( - "com.sun.star.drawing.PresenterPreviewCache", - mxComponentContext), - UNO_QUERY_THROW); - Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY); - mxPreviewCache->setDocumentSlides(xSlides, rxController->getModel()); - mxPreviewCache->addPreviewCreationNotifyListener(this); - if (xSlides.is()) - { - mpLayout->mnSlideCount = xSlides->getCount(); - } - - // Create the mouse over manager. - mpMouseOverManager.reset(new MouseOverManager( - Reference<container::XIndexAccess>(mxSlideShowController, UNO_QUERY), - mpPresenterController->GetTheme(), - mxWindow, - mpPresenterController->GetPaintManager())); - - // Listen for changes of the current slide. - Reference<beans::XPropertySet> xControllerProperties (rxController, UNO_QUERY_THROW); - xControllerProperties->addPropertyChangeListener( - "CurrentPage", - this); - - // Move the current slide in the center of the window. - const awt::Rectangle aCurrentSlideBBox (mpLayout->GetBoundingBox(mnCurrentSlideIndex)); - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - SetHorizontalOffset(aCurrentSlideBBox.X - aWindowBox.Width/2.0); - } - catch (RuntimeException&) - { - disposing(); - throw; - } -} - -PresenterSlideSorter::~PresenterSlideSorter() -{ -} - -void SAL_CALL PresenterSlideSorter::disposing() -{ - mxComponentContext = nullptr; - mxViewId = nullptr; - mxPane = nullptr; - - if (mpVerticalScrollBar.is()) - { - Reference<lang::XComponent> xComponent ( - static_cast<XWeak*>(mpVerticalScrollBar.get()), UNO_QUERY); - mpVerticalScrollBar = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - if (mpCloseButton.is()) - { - Reference<lang::XComponent> xComponent ( - static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY); - mpCloseButton = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - if (mxCanvas.is()) - { - Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY); - if (xComponent.is()) - xComponent->removeEventListener(static_cast<awt::XWindowListener*>(this)); - mxCanvas = nullptr; - } - mpPresenterController = nullptr; - mxSlideShowController = nullptr; - mpLayout.reset(); - mpMouseOverManager.reset(); - - if (mxPreviewCache.is()) - { - mxPreviewCache->removePreviewCreationNotifyListener(this); - - Reference<XComponent> xComponent (mxPreviewCache, UNO_QUERY); - mxPreviewCache = nullptr; - if (xComponent.is()) - xComponent->dispose(); - } - - if (mxWindow.is()) - { - mxWindow->removeWindowListener(this); - mxWindow->removePaintListener(this); - mxWindow->removeMouseListener(this); - mxWindow->removeMouseMotionListener(this); - } -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL PresenterSlideSorter::disposing (const lang::EventObject& rEventObject) -{ - if (rEventObject.Source == mxWindow) - { - mxWindow = nullptr; - dispose(); - } - else if (rEventObject.Source == mxPreviewCache) - { - mxPreviewCache = nullptr; - dispose(); - } - else if (rEventObject.Source == mxCanvas) - { - mxCanvas = nullptr; - mbIsLayoutPending = true; - - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); - } -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterSlideSorter::windowResized (const awt::WindowEvent&) -{ - ThrowIfDisposed(); - mbIsLayoutPending = true; - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); -} - -void SAL_CALL PresenterSlideSorter::windowMoved (const awt::WindowEvent&) -{ - ThrowIfDisposed(); -} - -void SAL_CALL PresenterSlideSorter::windowShown (const lang::EventObject&) -{ - ThrowIfDisposed(); - mbIsLayoutPending = true; - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); -} - -void SAL_CALL PresenterSlideSorter::windowHidden (const lang::EventObject&) -{ - ThrowIfDisposed(); -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterSlideSorter::windowPaint (const css::awt::PaintEvent& rEvent) -{ - // Deactivated views must not be painted. - if ( ! mbIsPresenterViewActive) - return; - - Paint(rEvent.UpdateRect); - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -//----- XMouseListener -------------------------------------------------------- - -void SAL_CALL PresenterSlideSorter::mousePressed (const css::awt::MouseEvent& rEvent) -{ - css::awt::MouseEvent rTemp =rEvent; - /// check whether RTL interface or not - if(AllSettings::GetLayoutRTL()){ - awt::Rectangle aBox = mxWindow->getPosSize(); - rTemp.X=aBox.Width-rEvent.X; - } - const geometry::RealPoint2D aPosition(rTemp.X, rEvent.Y); - mnSlideIndexMousePressed = mpLayout->GetSlideIndexForPosition(aPosition); -} - -void SAL_CALL PresenterSlideSorter::mouseReleased (const css::awt::MouseEvent& rEvent) -{ - css::awt::MouseEvent rTemp =rEvent; - /// check whether RTL interface or not - if(AllSettings::GetLayoutRTL()){ - awt::Rectangle aBox = mxWindow->getPosSize(); - rTemp.X=aBox.Width-rEvent.X; - } - const geometry::RealPoint2D aPosition(rTemp.X, rEvent.Y); - const sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition)); - - if (nSlideIndex != mnSlideIndexMousePressed || mnSlideIndexMousePressed < 0) - return; - - switch (rEvent.ClickCount) - { - case 1: - default: - GotoSlide(nSlideIndex); - break; - - case 2: - OSL_ASSERT(mpPresenterController); - OSL_ASSERT(mpPresenterController->GetWindowManager()); - mpPresenterController->GetWindowManager()->SetSlideSorterState(false); - GotoSlide(nSlideIndex); - break; - } -} - -void SAL_CALL PresenterSlideSorter::mouseEntered (const css::awt::MouseEvent&) {} - -void SAL_CALL PresenterSlideSorter::mouseExited (const css::awt::MouseEvent&) -{ - mnSlideIndexMousePressed = -1; - if (mpMouseOverManager != nullptr) - mpMouseOverManager->SetSlide(mnSlideIndexMousePressed, awt::Rectangle(0,0,0,0)); -} - -//----- XMouseMotionListener -------------------------------------------------- - -void SAL_CALL PresenterSlideSorter::mouseMoved (const css::awt::MouseEvent& rEvent) -{ - if (mpMouseOverManager == nullptr) - return; - - css::awt::MouseEvent rTemp =rEvent; - /// check whether RTL interface or not - if(AllSettings::GetLayoutRTL()){ - awt::Rectangle aBox = mxWindow->getPosSize(); - rTemp.X=aBox.Width-rEvent.X; - } - const geometry::RealPoint2D aPosition(rTemp.X, rEvent.Y); - sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition)); - - if (nSlideIndex < 0) - { - mnSlideIndexMousePressed = -1; - mpMouseOverManager->SetSlide(nSlideIndex, awt::Rectangle(0,0,0,0)); - } - else - { - mpMouseOverManager->SetSlide( - nSlideIndex, - mpLayout->GetBoundingBox(nSlideIndex)); - } -} - -void SAL_CALL PresenterSlideSorter::mouseDragged (const css::awt::MouseEvent&) {} - -//----- XResourceId ----------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterSlideSorter::getResourceId() -{ - ThrowIfDisposed(); - return mxViewId; -} - -sal_Bool SAL_CALL PresenterSlideSorter::isAnchorOnly() -{ - return false; -} - -//----- XPropertyChangeListener ----------------------------------------------- - -void SAL_CALL PresenterSlideSorter::propertyChange ( - const css::beans::PropertyChangeEvent&) -{} - -//----- XSlidePreviewCacheListener -------------------------------------------- - -void SAL_CALL PresenterSlideSorter::notifyPreviewCreation ( - sal_Int32 nSlideIndex) -{ - OSL_ASSERT(mpLayout != nullptr); - - awt::Rectangle aBBox (mpLayout->GetBoundingBox(nSlideIndex)); - mpPresenterController->GetPaintManager()->Invalidate(mxWindow, aBBox, true); -} - -//----- XDrawView ------------------------------------------------------------- - -void SAL_CALL PresenterSlideSorter::setCurrentPage (const Reference<drawing::XDrawPage>&) -{ - ThrowIfDisposed(); - ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); - - if (!mxSlideShowController.is()) - return; - - const sal_Int32 nNewCurrentSlideIndex (mxSlideShowController->getCurrentSlideIndex()); - if (nNewCurrentSlideIndex == mnCurrentSlideIndex) - return; - - mnCurrentSlideIndex = nNewCurrentSlideIndex; - - // Request a repaint of the previous current slide to hide its - // current slide indicator. - mpPresenterController->GetPaintManager()->Invalidate( - mxWindow, - maCurrentSlideFrameBoundingBox); - - // Request a repaint of the new current slide to show its - // current slide indicator. - maCurrentSlideFrameBoundingBox = mpCurrentSlideFrameRenderer->GetBoundingBox( - mpLayout->GetBoundingBox(mnCurrentSlideIndex)); - mpPresenterController->GetPaintManager()->Invalidate( - mxWindow, - maCurrentSlideFrameBoundingBox); -} - -Reference<drawing::XDrawPage> SAL_CALL PresenterSlideSorter::getCurrentPage() -{ - ThrowIfDisposed(); - return nullptr; -} - - -void PresenterSlideSorter::UpdateLayout() -{ - if ( ! mxWindow.is()) - return; - - mbIsLayoutPending = false; - - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - sal_Int32 nLeftBorderWidth (aWindowBox.X); - - // Get border width. - PresenterPaneContainer::SharedPaneDescriptor pPane ( - mpPresenterController->GetPaneContainer()->FindViewURL( - mxViewId->getResourceURL())); - do - { - if (!pPane) - break; - if ( ! pPane->mxPane.is()) - break; - - Reference<drawing::framework::XPaneBorderPainter> xBorderPainter ( - pPane->mxPane->GetPaneBorderPainter()); - if ( ! xBorderPainter.is()) - break; - xBorderPainter->addBorder ( - mxViewId->getAnchor()->getResourceURL(), - awt::Rectangle(0, 0, aWindowBox.Width, aWindowBox.Height), - drawing::framework::BorderType_INNER_BORDER); - } - while(false); - - // Place vertical separator. - mnSeparatorY = aWindowBox.Height - mpCloseButton->GetSize().Height - gnVerticalButtonPadding; - - PlaceCloseButton(pPane, aWindowBox, nLeftBorderWidth); - - geometry::RealRectangle2D aUpperBox( - gnHorizontalBorder, - gnVerticalBorder, - aWindowBox.Width - 2*gnHorizontalBorder, - mnSeparatorY - gnVerticalGap); - - // Determine whether the scroll bar has to be displayed. - aUpperBox = PlaceScrollBars(aUpperBox); - - mpLayout->Update(aUpperBox, GetSlideAspectRatio()); - mpLayout->SetupVisibleArea(); - mpLayout->UpdateScrollBars(); - - // Tell the preview cache about some of the values. - mxPreviewCache->setPreviewSize(mpLayout->maPreviewSize); - mxPreviewCache->setVisibleRange( - mpLayout->GetFirstVisibleSlideIndex(), - mpLayout->GetLastVisibleSlideIndex()); - - // Clear the frame polygon so that it is re-created on the next paint. - mxPreviewFrame = nullptr; -} - -geometry::RealRectangle2D PresenterSlideSorter::PlaceScrollBars ( - const geometry::RealRectangle2D& rUpperBox) -{ - mpLayout->Update(rUpperBox, GetSlideAspectRatio()); - bool bIsScrollBarNeeded (false); - Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY_THROW); - bIsScrollBarNeeded = mpLayout->IsScrollBarNeeded(xSlides->getCount()); - if (mpVerticalScrollBar) - { - if (bIsScrollBarNeeded) - { - if(AllSettings::GetLayoutRTL()) - { - mpVerticalScrollBar->SetPosSize(geometry::RealRectangle2D( - rUpperBox.X1, - rUpperBox.Y1, - rUpperBox.X1 + mpVerticalScrollBar->GetSize(), - rUpperBox.Y2)); - mpVerticalScrollBar->SetVisible(true); - // Reduce area covered by the scroll bar from the available - // space. - return geometry::RealRectangle2D( - rUpperBox.X1 + gnHorizontalGap + mpVerticalScrollBar->GetSize(), - rUpperBox.Y1, - rUpperBox.X2, - rUpperBox.Y2); - } - else - { - // if it's not RTL place vertical scroll bar at right border. - mpVerticalScrollBar->SetPosSize(geometry::RealRectangle2D( - rUpperBox.X2 - mpVerticalScrollBar->GetSize(), - rUpperBox.Y1, - rUpperBox.X2, - rUpperBox.Y2)); - mpVerticalScrollBar->SetVisible(true); - // Reduce area covered by the scroll bar from the available - // space. - return geometry::RealRectangle2D( - rUpperBox.X1, - rUpperBox.Y1, - rUpperBox.X2 - mpVerticalScrollBar->GetSize() - gnHorizontalGap, - rUpperBox.Y2); - } - } - else - mpVerticalScrollBar->SetVisible(false); - } - return rUpperBox; -} - -void PresenterSlideSorter::PlaceCloseButton ( - const PresenterPaneContainer::SharedPaneDescriptor& rpPane, - const awt::Rectangle& rCenterBox, - const sal_Int32 nLeftBorderWidth) -{ - // Place button. When the callout is near the center then the button is - // centered over the callout. Otherwise it is centered with respect to - // the whole window. - sal_Int32 nCloseButtonCenter (rCenterBox.Width/2); - if (rpPane && rpPane->mxPane.is()) - { - const sal_Int32 nCalloutCenter (-nLeftBorderWidth); - const sal_Int32 nDistanceFromWindowCenter (abs(nCalloutCenter - rCenterBox.Width/2)); - const sal_Int32 nButtonWidth (mpCloseButton->GetSize().Width); - const static sal_Int32 nMaxDistanceForCalloutCentering (nButtonWidth * 2); - if (nDistanceFromWindowCenter < nMaxDistanceForCalloutCentering) - { - if (nCalloutCenter < nButtonWidth/2) - nCloseButtonCenter = nButtonWidth/2; - else if (nCalloutCenter > rCenterBox.Width-nButtonWidth/2) - nCloseButtonCenter = rCenterBox.Width-nButtonWidth/2; - else - nCloseButtonCenter = nCalloutCenter; - } - } - mpCloseButton->SetCenter(geometry::RealPoint2D( - nCloseButtonCenter, - rCenterBox.Height - mpCloseButton->GetSize().Height/ 2)); -} - -void PresenterSlideSorter::ClearBackground ( - const Reference<rendering::XCanvas>& rxCanvas, - const awt::Rectangle& rUpdateBox) -{ - OSL_ASSERT(rxCanvas.is()); - - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - mpPresenterController->GetCanvasHelper()->Paint( - mpPresenterController->GetViewBackground(mxViewId->getResourceURL()), - rxCanvas, - rUpdateBox, - awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height), - awt::Rectangle()); -} - -double PresenterSlideSorter::GetSlideAspectRatio() const -{ - double nSlideAspectRatio (28.0/21.0); - - try - { - Reference<container::XIndexAccess> xSlides(mxSlideShowController, UNO_QUERY_THROW); - if (mxSlideShowController.is() && xSlides->getCount()>0) - { - Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW); - sal_Int32 nWidth (28000); - sal_Int32 nHeight (21000); - if ((xProperties->getPropertyValue("Width") >>= nWidth) - && (xProperties->getPropertyValue("Height") >>= nHeight) - && nHeight > 0) - { - nSlideAspectRatio = double(nWidth) / double(nHeight); - } - } - } - catch (RuntimeException&) - { - OSL_ASSERT(false); - } - - return nSlideAspectRatio; -} - -Reference<rendering::XBitmap> PresenterSlideSorter::GetPreview (const sal_Int32 nSlideIndex) -{ - if (nSlideIndex < 0 || nSlideIndex>=mpLayout->mnSlideCount) - return nullptr; - else if (mxPane.is()) - return mxPreviewCache->getSlidePreview(nSlideIndex, mxPane->getCanvas()); - else - return nullptr; -} - -void PresenterSlideSorter::PaintPreview ( - const Reference<rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rUpdateBox, - const sal_Int32 nSlideIndex) -{ - OSL_ASSERT(rxCanvas.is()); - - geometry::IntegerSize2D aSize (mpLayout->maPreviewSize); - - if (PresenterGeometryHelper::AreRectanglesDisjoint( - rUpdateBox, - mpLayout->GetBoundingBox(nSlideIndex))) - { - return; - } - - Reference<rendering::XBitmap> xPreview (GetPreview(nSlideIndex)); - bool isRTL = AllSettings::GetLayoutRTL(); - - const geometry::RealPoint2D aTopLeft ( - mpLayout->GetWindowPosition( - mpLayout->GetPoint(nSlideIndex, isRTL?1:-1, -1))); - - PresenterBitmapContainer aContainer ( - "PresenterScreenSettings/ScrollBar/Bitmaps", - std::shared_ptr<PresenterBitmapContainer>(), - mxComponentContext, - rxCanvas); - Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY); - Reference<drawing::XDrawPage> xPage( xIndexAccess->getByIndex(nSlideIndex), UNO_QUERY); - bool bTransition = PresenterController::HasTransition(xPage); - bool bCustomAnimation = PresenterController::HasCustomAnimation(xPage); - - // Create clip rectangle as intersection of the current update area and - // the bounding box of all previews. - geometry::RealRectangle2D aBoundingBox (mpLayout->maBoundingBox); - aBoundingBox.Y2 += 1; - const geometry::RealRectangle2D aClipBox ( - PresenterGeometryHelper::Intersection( - PresenterGeometryHelper::ConvertRectangle(rUpdateBox), - aBoundingBox)); - Reference<rendering::XPolyPolygon2D> xClip ( - PresenterGeometryHelper::CreatePolygon(aClipBox, rxCanvas->getDevice())); - - const rendering::ViewState aViewState (geometry::AffineMatrix2D(1,0,0, 0,1,0), xClip); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D( - 1, 0, aTopLeft.X, - 0, 1, aTopLeft.Y), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - // Emphasize the current slide. - if (nSlideIndex == mnCurrentSlideIndex) - { - if (mpCurrentSlideFrameRenderer != nullptr) - { - const awt::Rectangle aSlideBoundingBox( - sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.X), - sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.Y), - aSize.Width, - aSize.Height); - maCurrentSlideFrameBoundingBox - = mpCurrentSlideFrameRenderer->GetBoundingBox(aSlideBoundingBox); - mpCurrentSlideFrameRenderer->PaintCurrentSlideFrame ( - aSlideBoundingBox, - mxCanvas, - aClipBox); - } - } - - // Paint the preview. - if (xPreview.is()) - { - aSize = xPreview->getSize(); - if (aSize.Width > 0 && aSize.Height > 0) - { - rxCanvas->drawBitmap(xPreview, aViewState, aRenderState); - if( bCustomAnimation ) - { - const awt::Rectangle aAnimationPreviewBox(aTopLeft.X+3, aTopLeft.Y+aSize.Height-40, 0, 0); - SharedBitmapDescriptor aAnimationDescriptor = aContainer.GetBitmap("Animation"); - Reference<rendering::XBitmap> xAnimationIcon (aAnimationDescriptor->GetNormalBitmap()); - rendering::RenderState aAnimationRenderState ( - geometry::AffineMatrix2D( - 1, 0, aAnimationPreviewBox.X, - 0, 1, aAnimationPreviewBox.Y), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - rxCanvas->drawBitmap(xAnimationIcon, aViewState, aAnimationRenderState); - } - if( bTransition ) - { - const awt::Rectangle aTransitionPreviewBox(aTopLeft.X+3, aTopLeft.Y+aSize.Height-20, 0, 0); - SharedBitmapDescriptor aTransitionDescriptor = aContainer.GetBitmap("Transition"); - Reference<rendering::XBitmap> xTransitionIcon (aTransitionDescriptor->GetNormalBitmap()); - rendering::RenderState aTransitionRenderState ( - geometry::AffineMatrix2D( - 1, 0, aTransitionPreviewBox.X, - 0, 1, aTransitionPreviewBox.Y), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - rxCanvas->drawBitmap(xTransitionIcon, aViewState, aTransitionRenderState); - } - } - } - - // Create a polygon that is used to paint a frame around previews. Its - // coordinates are chosen in the local coordinate system of a preview. - if ( ! mxPreviewFrame.is()) - mxPreviewFrame = PresenterGeometryHelper::CreatePolygon( - awt::Rectangle(-1, -1, aSize.Width+2, aSize.Height+2), - rxCanvas->getDevice()); - - // Paint a border around the preview. - if (mxPreviewFrame.is()) - { - const util::Color aFrameColor (0x00000000); - PresenterCanvasHelper::SetDeviceColor(aRenderState, aFrameColor); - rxCanvas->drawPolyPolygon(mxPreviewFrame, aViewState, aRenderState); - } - - // Paint mouse over effect. - mpMouseOverManager->Paint(nSlideIndex, mxCanvas, xClip); -} - -void PresenterSlideSorter::Paint (const awt::Rectangle& rUpdateBox) -{ - const bool bCanvasChanged ( ! mxCanvas.is()); - if ( ! ProvideCanvas()) - return; - - if (mpLayout->mnRowCount<=0 || mpLayout->mnColumnCount<=0) - { - OSL_ASSERT(mpLayout->mnRowCount>0 || mpLayout->mnColumnCount>0); - return; - } - - ClearBackground(mxCanvas, rUpdateBox); - - // Give the canvas to the controls. - if (bCanvasChanged) - { - if (mpVerticalScrollBar.is()) - mpVerticalScrollBar->SetCanvas(mxCanvas); - if (mpCloseButton.is()) - mpCloseButton->SetCanvas(mxCanvas, mxWindow); - } - - // Now that the controls have a canvas we can do the layouting. - if (mbIsLayoutPending) - UpdateLayout(); - - // Paint the horizontal separator. - rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, Sequence<double>(4), rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor); - mxCanvas->drawLine( - geometry::RealPoint2D(0, mnSeparatorY), - geometry::RealPoint2D(mxWindow->getPosSize().Width, mnSeparatorY), - rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), nullptr), - aRenderState); - - // Paint the slides. - if ( ! PresenterGeometryHelper::AreRectanglesDisjoint( - rUpdateBox, - PresenterGeometryHelper::ConvertRectangle(mpLayout->maBoundingBox))) - { - mpLayout->ForAllVisibleSlides( - [this, &rUpdateBox] (sal_Int32 const nIndex) { - return this->PaintPreview(this->mxCanvas, rUpdateBox, nIndex); - }); - } - - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -void PresenterSlideSorter::SetHorizontalOffset (const double nXOffset) -{ - if (mpLayout->SetHorizontalOffset(nXOffset)) - { - mxPreviewCache->setVisibleRange( - mpLayout->GetFirstVisibleSlideIndex(), - mpLayout->GetLastVisibleSlideIndex()); - - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); - } -} - -void PresenterSlideSorter::SetVerticalOffset (const double nYOffset) -{ - if (mpLayout->SetVerticalOffset(nYOffset)) - { - mxPreviewCache->setVisibleRange( - mpLayout->GetFirstVisibleSlideIndex(), - mpLayout->GetLastVisibleSlideIndex()); - - mpPresenterController->GetPaintManager()->Invalidate(mxWindow); - } -} - -void PresenterSlideSorter::GotoSlide (const sal_Int32 nSlideIndex) -{ - mxSlideShowController->gotoSlideIndex(nSlideIndex); -} - -bool PresenterSlideSorter::ProvideCanvas() -{ - if ( ! mxCanvas.is()) - { - if (mxPane.is()) - mxCanvas = mxPane->getCanvas(); - - // Register as event listener so that we are informed when the - // canvas is disposed (and we have to fetch another one). - Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY); - if (xComponent.is()) - xComponent->addEventListener(static_cast<awt::XWindowListener*>(this)); - - mpCurrentSlideFrameRenderer = - std::make_shared<CurrentSlideFrameRenderer>(mxComponentContext, mxCanvas); - } - return mxCanvas.is(); -} - -void PresenterSlideSorter::ThrowIfDisposed() -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterSlideSorter has been already disposed", - static_cast<uno::XWeak*>(this)); - } -} - -//===== PresenterSlideSorter::Layout ========================================== - -PresenterSlideSorter::Layout::Layout ( - const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar) - : maBoundingBox(), - maPreviewSize(), - mnHorizontalOffset(0), - mnVerticalOffset(0), - mnHorizontalGap(0), - mnVerticalGap(0), - mnHorizontalBorder(0), - mnVerticalBorder(0), - mnRowCount(1), - mnColumnCount(1), - mnSlideCount(0), - mnFirstVisibleColumn(-1), - mnLastVisibleColumn(-1), - mnFirstVisibleRow(-1), - mnLastVisibleRow(-1), - mpVerticalScrollBar(rpVerticalScrollBar) -{ -} - -void PresenterSlideSorter::Layout::Update ( - const geometry::RealRectangle2D& rBoundingBox, - const double nSlideAspectRatio) -{ - maBoundingBox = rBoundingBox; - - mnHorizontalBorder = gnHorizontalBorder; - mnVerticalBorder = gnVerticalBorder; - - const double nWidth (rBoundingBox.X2 - rBoundingBox.X1 - 2*mnHorizontalBorder); - const double nHeight (rBoundingBox.Y2 - rBoundingBox.Y1 - 2*mnVerticalBorder); - if (nWidth<=0 || nHeight<=0) - return; - - double nPreviewWidth; - - // Determine column count, preview width, and horizontal gap (borders - // are half the gap). Try to use the preferred values. Try more to - // stay in the valid intervals. This last constraint may be not - // fulfilled in some cases. - const double nElementWidth = nWidth / gnPreferredColumnCount; - if (nElementWidth < gnMinimalPreviewWidth + gnMinimalHorizontalPreviewGap) - { - // The preferred column count is too large. - // Can we use the preferred preview width? - if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth) - { - // Yes. - nPreviewWidth = gnPreferredPreviewWidth; - mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap) - / (nPreviewWidth+gnPreferredHorizontalPreviewGap)); - mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount); - } - else - { - // No. Set the column count to 1 and adapt preview width and - // gap. - mnColumnCount = 1; - mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap); - if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth) - nPreviewWidth = nWidth - gnMinimalHorizontalPreviewGap; - else - nPreviewWidth = ::std::max(gnMinimalPreviewWidth, nWidth-mnHorizontalGap); - } - } - else if (nElementWidth > gnMaximalPreviewWidth + gnMaximalHorizontalPreviewGap) - { - // The preferred column count is too small. - nPreviewWidth = gnPreferredPreviewWidth; - mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap) - / (nPreviewWidth+gnPreferredHorizontalPreviewGap)); - mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount); - } - else - { - // The preferred column count is possible. Determine gap and - // preview width. - mnColumnCount = gnPreferredColumnCount; - if (nElementWidth - gnPreferredPreviewWidth < gnMinimalHorizontalPreviewGap) - { - // Use the minimal gap and adapt the preview width. - mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap); - nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount; - } - else if (nElementWidth - gnPreferredPreviewWidth <= gnMaximalHorizontalPreviewGap) - { - // Use the maximal gap and adapt the preview width. - mnHorizontalGap = round(gnMaximalHorizontalPreviewGap); - nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount; - } - else - { - // Use the preferred preview width and adapt the gap. - nPreviewWidth = gnPreferredPreviewWidth; - mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount); - } - } - - // Now determine the row count, preview height, and vertical gap. - const double nPreviewHeight = nPreviewWidth / nSlideAspectRatio; - mnRowCount = ::std::max( - sal_Int32(1), - sal_Int32(ceil((nHeight+gnPreferredVerticalPreviewGap) - / (nPreviewHeight + gnPreferredVerticalPreviewGap)))); - mnVerticalGap = round(gnPreferredVerticalPreviewGap); - - maPreviewSize = geometry::IntegerSize2D(floor(nPreviewWidth), floor(nPreviewHeight)); - - // Reset the offset. - mnVerticalOffset = 0; - mnHorizontalOffset = round(-(nWidth - - mnColumnCount*maPreviewSize.Width - - (mnColumnCount-1)*mnHorizontalGap) - / 2); -} - -void PresenterSlideSorter::Layout::SetupVisibleArea() -{ - geometry::RealPoint2D aPoint (GetLocalPosition( - geometry::RealPoint2D(maBoundingBox.X1, maBoundingBox.Y1))); - mnFirstVisibleColumn = 0; - mnFirstVisibleRow = ::std::max(sal_Int32(0), GetRow(aPoint)); - - aPoint = GetLocalPosition(geometry::RealPoint2D( maBoundingBox.X2, maBoundingBox.Y2)); - mnLastVisibleColumn = mnColumnCount - 1; - mnLastVisibleRow = GetRow(aPoint, true); -} - -bool PresenterSlideSorter::Layout::IsScrollBarNeeded (const sal_Int32 nSlideCount) -{ - geometry::RealPoint2D aBottomRight = GetPoint( - mnColumnCount * (GetRow(nSlideCount)+1) - 1, +1, +1); - return aBottomRight.X > maBoundingBox.X2-maBoundingBox.X1 - || aBottomRight.Y > maBoundingBox.Y2-maBoundingBox.Y1; -} - -geometry::RealPoint2D PresenterSlideSorter::Layout::GetLocalPosition( - const geometry::RealPoint2D& rWindowPoint) const -{ - if(AllSettings::GetLayoutRTL()) - { - return css::geometry::RealPoint2D( - -rWindowPoint.X + maBoundingBox.X2 + mnHorizontalOffset, - rWindowPoint.Y - maBoundingBox.Y1 + mnVerticalOffset); - } - else - { - return css::geometry::RealPoint2D( - rWindowPoint.X - maBoundingBox.X1 + mnHorizontalOffset, - rWindowPoint.Y - maBoundingBox.Y1 + mnVerticalOffset); - } -} - -geometry::RealPoint2D PresenterSlideSorter::Layout::GetWindowPosition( - const geometry::RealPoint2D& rLocalPoint) const -{ - if(AllSettings::GetLayoutRTL()) - { - return css::geometry::RealPoint2D( - -rLocalPoint.X + mnHorizontalOffset + maBoundingBox.X2, - rLocalPoint.Y - mnVerticalOffset + maBoundingBox.Y1); - } - else - { - return css::geometry::RealPoint2D( - rLocalPoint.X - mnHorizontalOffset + maBoundingBox.X1, - rLocalPoint.Y - mnVerticalOffset + maBoundingBox.Y1); - } -} - -sal_Int32 PresenterSlideSorter::Layout::GetColumn ( - const css::geometry::RealPoint2D& rLocalPoint) const -{ - const sal_Int32 nColumn(floor( - (rLocalPoint.X + mnHorizontalGap/2.0) / (maPreviewSize.Width+mnHorizontalGap))); - if (nColumn>=mnFirstVisibleColumn && nColumn<=mnLastVisibleColumn) - { - return nColumn; - } - else - return -1; -} - -sal_Int32 PresenterSlideSorter::Layout::GetRow ( - const css::geometry::RealPoint2D& rLocalPoint, - const bool bReturnInvalidValue) const -{ - const sal_Int32 nRow (floor( - (rLocalPoint.Y + mnVerticalGap/2.0) / (maPreviewSize.Height+mnVerticalGap))); - if (bReturnInvalidValue - || (nRow>=mnFirstVisibleRow && nRow<=mnLastVisibleRow)) - { - return nRow; - } - else - return -1; -} - -sal_Int32 PresenterSlideSorter::Layout::GetSlideIndexForPosition ( - const css::geometry::RealPoint2D& rWindowPoint) const -{ - if ( ! PresenterGeometryHelper::IsInside(maBoundingBox, rWindowPoint)) - return -1; - - const css::geometry::RealPoint2D aLocalPosition (GetLocalPosition(rWindowPoint)); - const sal_Int32 nColumn (GetColumn(aLocalPosition)); - const sal_Int32 nRow (GetRow(aLocalPosition)); - - if (nColumn < 0 || nRow < 0) - return -1; - else - { - sal_Int32 nIndex (GetIndex(nRow, nColumn)); - if (nIndex >= mnSlideCount) - return -1; - else - return nIndex; - } -} - -geometry::RealPoint2D PresenterSlideSorter::Layout::GetPoint ( - const sal_Int32 nSlideIndex, - const sal_Int32 nRelativeHorizontalPosition, - const sal_Int32 nRelativeVerticalPosition) const -{ - sal_Int32 nColumn (GetColumn(nSlideIndex)); - sal_Int32 nRow (GetRow(nSlideIndex)); - - geometry::RealPoint2D aPosition ( - mnHorizontalBorder + nColumn*(maPreviewSize.Width+mnHorizontalGap), - mnVerticalBorder + nRow*(maPreviewSize.Height+mnVerticalGap)); - - if (nRelativeHorizontalPosition >= 0) - { - if (nRelativeHorizontalPosition > 0) - aPosition.X += maPreviewSize.Width; - else - aPosition.X += maPreviewSize.Width / 2.0; - } - if (nRelativeVerticalPosition >= 0) - { - if (nRelativeVerticalPosition > 0) - aPosition.Y += maPreviewSize.Height; - else - aPosition.Y += maPreviewSize.Height / 2.0; - } - - return aPosition; -} - -awt::Rectangle PresenterSlideSorter::Layout::GetBoundingBox (const sal_Int32 nSlideIndex) const -{ - bool isRTL = AllSettings::GetLayoutRTL(); - const geometry::RealPoint2D aWindowPosition(GetWindowPosition(GetPoint(nSlideIndex, isRTL?1:-1, -1))); - return PresenterGeometryHelper::ConvertRectangle( - geometry::RealRectangle2D( - aWindowPosition.X, - aWindowPosition.Y, - aWindowPosition.X + maPreviewSize.Width, - aWindowPosition.Y + maPreviewSize.Height)); -} - -void PresenterSlideSorter::Layout::ForAllVisibleSlides( - const ::std::function<void (sal_Int32)>& rAction) -{ - for (sal_Int32 nRow=mnFirstVisibleRow; nRow<=mnLastVisibleRow; ++nRow) - { - for (sal_Int32 nColumn=mnFirstVisibleColumn; nColumn<=mnLastVisibleColumn; ++nColumn) - { - const sal_Int32 nSlideIndex (GetIndex(nRow, nColumn)); - if (nSlideIndex >= mnSlideCount) - return; - rAction(nSlideIndex); - } - } -} - -sal_Int32 PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex() const -{ - return GetIndex(mnFirstVisibleRow, mnFirstVisibleColumn); -} - -sal_Int32 PresenterSlideSorter::Layout::GetLastVisibleSlideIndex() const -{ - return ::std::min( - GetIndex(mnLastVisibleRow, mnLastVisibleColumn), - mnSlideCount); -} - -bool PresenterSlideSorter::Layout::SetHorizontalOffset (const double nOffset) -{ - if (mnHorizontalOffset != nOffset) - { - mnHorizontalOffset = round(nOffset); - SetupVisibleArea(); - UpdateScrollBars(); - return true; - } - else - return false; -} - -bool PresenterSlideSorter::Layout::SetVerticalOffset (const double nOffset) -{ - if (mnVerticalOffset != nOffset) - { - mnVerticalOffset = round(nOffset); - SetupVisibleArea(); - UpdateScrollBars(); - return true; - } - else - return false; -} - -void PresenterSlideSorter::Layout::UpdateScrollBars() -{ - sal_Int32 nTotalRowCount = sal_Int32(ceil(double(mnSlideCount) / double(mnColumnCount))); - - if (mpVerticalScrollBar) - { - mpVerticalScrollBar->SetTotalSize( - nTotalRowCount * maPreviewSize.Height - + (nTotalRowCount-1) * mnVerticalGap - + 2*mnVerticalGap); - mpVerticalScrollBar->SetThumbPosition(mnVerticalOffset, false); - mpVerticalScrollBar->SetThumbSize(maBoundingBox.Y2 - maBoundingBox.Y1 + 1); - mpVerticalScrollBar->SetLineHeight(maPreviewSize.Height); - } - - // No place yet for the vertical scroll bar. -} - -sal_Int32 PresenterSlideSorter::Layout::GetIndex ( - const sal_Int32 nRow, - const sal_Int32 nColumn) const -{ - return nRow * mnColumnCount + nColumn; -} - -sal_Int32 PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex) const -{ - return nSlideIndex / mnColumnCount; -} - -sal_Int32 PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex) const -{ - return nSlideIndex % mnColumnCount; -} - -//===== PresenterSlideSorter::MouseOverManager ================================ - -PresenterSlideSorter::MouseOverManager::MouseOverManager ( - const Reference<container::XIndexAccess>& rxSlides, - const std::shared_ptr<PresenterTheme>& rpTheme, - const Reference<awt::XWindow>& rxInvalidateTarget, - const std::shared_ptr<PresenterPaintManager>& rpPaintManager) - : mxCanvas(), - mxSlides(rxSlides), - mpLeftLabelBitmap(), - mpCenterLabelBitmap(), - mpRightLabelBitmap(), - mpFont(), - mnSlideIndex(-1), - maSlideBoundingBox(), - mxInvalidateTarget(rxInvalidateTarget), - mpPaintManager(rpPaintManager) -{ - if (rpTheme != nullptr) - { - std::shared_ptr<PresenterBitmapContainer> pBitmaps (rpTheme->GetBitmapContainer()); - if (pBitmaps != nullptr) - { - mpLeftLabelBitmap = pBitmaps->GetBitmap("LabelLeft"); - mpCenterLabelBitmap = pBitmaps->GetBitmap("LabelCenter"); - mpRightLabelBitmap = pBitmaps->GetBitmap("LabelRight"); - } - - mpFont = rpTheme->GetFont("SlideSorterLabelFont"); - } -} - -void PresenterSlideSorter::MouseOverManager::Paint ( - const sal_Int32 nSlideIndex, - const Reference<rendering::XCanvas>& rxCanvas, - const Reference<rendering::XPolyPolygon2D>& rxClip) -{ - if (nSlideIndex != mnSlideIndex) - return; - - if (mxCanvas != rxCanvas) - SetCanvas(rxCanvas); - if (rxCanvas == nullptr) - return; - - if ( ! mxBitmap.is()) - mxBitmap = CreateBitmap(msText, maSlideBoundingBox.Width); - if (!mxBitmap.is()) - return; - - geometry::IntegerSize2D aSize (mxBitmap->getSize()); - const double nXOffset (maSlideBoundingBox.X - + (maSlideBoundingBox.Width - aSize.Width) / 2.0); - const double nYOffset (maSlideBoundingBox.Y - + (maSlideBoundingBox.Height - aSize.Height) / 2.0); - rxCanvas->drawBitmap( - mxBitmap, - rendering::ViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - rxClip), - rendering::RenderState( - geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE)); -} - -void PresenterSlideSorter::MouseOverManager::SetCanvas ( - const Reference<rendering::XCanvas>& rxCanvas) -{ - mxCanvas = rxCanvas; - if (mpFont) - mpFont->PrepareFont(mxCanvas); -} - -void PresenterSlideSorter::MouseOverManager::SetSlide ( - const sal_Int32 nSlideIndex, - const awt::Rectangle& rBox) -{ - if (mnSlideIndex == nSlideIndex) - return; - - mnSlideIndex = -1; - Invalidate(); - - maSlideBoundingBox = rBox; - mnSlideIndex = nSlideIndex; - - if (nSlideIndex >= 0) - { - if (mxSlides) - { - msText.clear(); - - Reference<beans::XPropertySet> xSlideProperties(mxSlides->getByIndex(nSlideIndex), UNO_QUERY); - if (xSlideProperties.is()) - xSlideProperties->getPropertyValue("LinkDisplayName") >>= msText; - - if (msText.isEmpty()) - msText = "Slide " + OUString::number(nSlideIndex + 1); - } - } - else - { - msText.clear(); - } - mxBitmap = nullptr; - - Invalidate(); -} - -Reference<rendering::XBitmap> PresenterSlideSorter::MouseOverManager::CreateBitmap ( - const OUString& rsText, - const sal_Int32 nMaximalWidth) const -{ - if ( ! mxCanvas.is()) - return nullptr; - - if (!mpFont || !mpFont->mxFont.is()) - return nullptr; - - // Long text has to be shortened. - const OUString sText (GetFittingText(rsText, nMaximalWidth - - 2*gnHorizontalLabelBorder - - 2*gnHorizontalLabelPadding)); - - // Determine the size of the label. Its height is defined by the - // bitmaps that are used to paints its background. The width is defined - // by the text. - geometry::IntegerSize2D aLabelSize (CalculateLabelSize(sText)); - - // Create a new bitmap that will contain the complete label. - Reference<rendering::XBitmap> xBitmap ( - mxCanvas->getDevice()->createCompatibleAlphaBitmap(aLabelSize)); - - if ( ! xBitmap.is()) - return nullptr; - - Reference<rendering::XBitmapCanvas> xBitmapCanvas (xBitmap, UNO_QUERY); - if ( ! xBitmapCanvas.is()) - return nullptr; - - // Paint the background. - PaintButtonBackground(xBitmapCanvas, aLabelSize); - - // Paint the text. - if (!sText.isEmpty()) - { - - const rendering::StringContext aContext (sText, 0, sText.getLength()); - const Reference<rendering::XTextLayout> xLayout (mpFont->mxFont->createTextLayout( - aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0)); - const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds()); - - const double nXOffset = (aLabelSize.Width - aTextBBox.X2 + aTextBBox.X1) / 2; - const double nYOffset = aLabelSize.Height - - (aLabelSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y2; - - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor); - - xBitmapCanvas->drawTextLayout ( - xLayout, - aViewState, - aRenderState); - } - - return xBitmap; -} - -OUString PresenterSlideSorter::MouseOverManager::GetFittingText ( - const OUString& rsText, - const double nMaximalWidth) const -{ - const double nTextWidth ( - PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText).Width); - if (nTextWidth > nMaximalWidth) - { - // Text is too wide. Shorten it by removing characters from the end - // and replacing them by ellipses. - - // Guess a start value of the final string length. - double nBestWidth (0); - OUString sBestCandidate; - sal_Int32 nLength (round(rsText.getLength() * nMaximalWidth / nTextWidth)); - static const OUStringLiteral sEllipses (u"..."); - while (true) - { - const OUString sCandidate (rsText.subView(0,nLength) + sEllipses); - const double nWidth ( - PresenterCanvasHelper::GetTextSize(mpFont->mxFont, sCandidate).Width); - if (nWidth > nMaximalWidth) - { - // Candidate still too wide, shorten it. - nLength -= 1; - if (nLength <= 0) - break; - } - else if (nWidth < nMaximalWidth) - { - // Candidate short enough. - if (nWidth > nBestWidth) - { - // Best length so far. - sBestCandidate = sCandidate; - nBestWidth = nWidth; - nLength += 1; - if (nLength >= rsText.getLength()) - break; - } - else - break; - } - else - { - // Candidate is exactly as long as it may be. Use it - // without looking any further. - sBestCandidate = sCandidate; - break; - } - } - return sBestCandidate; - } - else - return rsText; -} - -geometry::IntegerSize2D PresenterSlideSorter::MouseOverManager::CalculateLabelSize ( - const OUString& rsText) const -{ - // Height is specified by the label bitmaps. - sal_Int32 nHeight (32); - if (mpCenterLabelBitmap) - { - Reference<rendering::XBitmap> xBitmap (mpCenterLabelBitmap->GetNormalBitmap()); - if (xBitmap.is()) - nHeight = xBitmap->getSize().Height; - } - - // Width is specified by text width and maximal width. - const geometry::RealSize2D aTextSize ( - PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText)); - - const sal_Int32 nWidth (round(aTextSize.Width + 2*gnHorizontalLabelPadding)); - - return geometry::IntegerSize2D(nWidth, nHeight); -} - -void PresenterSlideSorter::MouseOverManager::PaintButtonBackground ( - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::IntegerSize2D& rSize) const -{ - // Get the bitmaps for painting the label background. - Reference<rendering::XBitmap> xLeftLabelBitmap; - if (mpLeftLabelBitmap) - xLeftLabelBitmap = mpLeftLabelBitmap->GetNormalBitmap(); - - Reference<rendering::XBitmap> xCenterLabelBitmap; - if (mpCenterLabelBitmap) - xCenterLabelBitmap = mpCenterLabelBitmap->GetNormalBitmap(); - - Reference<rendering::XBitmap> xRightLabelBitmap; - if (mpRightLabelBitmap) - xRightLabelBitmap = mpRightLabelBitmap->GetNormalBitmap(); - - PresenterUIPainter::PaintHorizontalBitmapComposite ( - rxCanvas, - awt::Rectangle(0,0, rSize.Width,rSize.Height), - awt::Rectangle(0,0, rSize.Width,rSize.Height), - xLeftLabelBitmap, - xCenterLabelBitmap, - xRightLabelBitmap); -} - -void PresenterSlideSorter::MouseOverManager::Invalidate() -{ - if (mpPaintManager != nullptr) - mpPaintManager->Invalidate(mxInvalidateTarget, maSlideBoundingBox, true); -} - -//===== PresenterSlideSorter::CurrentSlideFrameRenderer ======================= - -PresenterSlideSorter::CurrentSlideFrameRenderer::CurrentSlideFrameRenderer ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas) - : mpTopLeft(), - mpTop(), - mpTopRight(), - mpLeft(), - mpRight(), - mpBottomLeft(), - mpBottom(), - mpBottomRight(), - mnTopFrameSize(0), - mnLeftFrameSize(0), - mnRightFrameSize(0), - mnBottomFrameSize(0) -{ - PresenterConfigurationAccess aConfiguration ( - rxContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - Reference<container::XHierarchicalNameAccess> xBitmaps ( - aConfiguration.GetConfigurationNode( - "PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps"), - UNO_QUERY); - if ( ! xBitmaps.is()) - return; - - PresenterBitmapContainer aContainer ( - "PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps", - std::shared_ptr<PresenterBitmapContainer>(), - rxContext, - rxCanvas); - - mpTopLeft = aContainer.GetBitmap("TopLeft"); - mpTop = aContainer.GetBitmap("Top"); - mpTopRight = aContainer.GetBitmap("TopRight"); - mpLeft = aContainer.GetBitmap("Left"); - mpRight = aContainer.GetBitmap("Right"); - mpBottomLeft = aContainer.GetBitmap("BottomLeft"); - mpBottom = aContainer.GetBitmap("Bottom"); - mpBottomRight = aContainer.GetBitmap("BottomRight"); - - // Determine size of frame. - if (mpTop) - mnTopFrameSize = mpTop->mnHeight; - if (mpLeft) - mnLeftFrameSize = mpLeft->mnWidth; - if (mpRight) - mnRightFrameSize = mpRight->mnWidth; - if (mpBottom) - mnBottomFrameSize = mpBottom->mnHeight; - - if (mpTopLeft) - { - mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopLeft->mnHeight); - mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpTopLeft->mnWidth); - } - if (mpTopRight) - { - mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopRight->mnHeight); - mnRightFrameSize = ::std::max(mnRightFrameSize, mpTopRight->mnWidth); - } - if (mpBottomLeft) - { - mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpBottomLeft->mnWidth); - mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomLeft->mnHeight); - } - if (mpBottomRight) - { - mnRightFrameSize = ::std::max(mnRightFrameSize, mpBottomRight->mnWidth); - mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomRight->mnHeight); - } -} - -void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintCurrentSlideFrame ( - const awt::Rectangle& rSlideBoundingBox, - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::RealRectangle2D& rClipBox) -{ - if ( ! rxCanvas.is()) - return; - - const Reference<rendering::XPolyPolygon2D> xClip ( - PresenterGeometryHelper::CreatePolygon(rClipBox, rxCanvas->getDevice())); - - if (mpTop) - { - PaintBitmapTiled( - mpTop->GetNormalBitmap(), - rxCanvas, - rClipBox, - rSlideBoundingBox.X, - rSlideBoundingBox.Y - mpTop->mnHeight, - rSlideBoundingBox.Width, - mpTop->mnHeight); - } - if (mpLeft) - { - PaintBitmapTiled( - mpLeft->GetNormalBitmap(), - rxCanvas, - rClipBox, - rSlideBoundingBox.X - mpLeft->mnWidth, - rSlideBoundingBox.Y, - mpLeft->mnWidth, - rSlideBoundingBox.Height); - } - if (mpRight) - { - PaintBitmapTiled( - mpRight->GetNormalBitmap(), - rxCanvas, - rClipBox, - rSlideBoundingBox.X + rSlideBoundingBox.Width, - rSlideBoundingBox.Y, - mpRight->mnWidth, - rSlideBoundingBox.Height); - } - if (mpBottom) - { - PaintBitmapTiled( - mpBottom->GetNormalBitmap(), - rxCanvas, - rClipBox, - rSlideBoundingBox.X, - rSlideBoundingBox.Y + rSlideBoundingBox.Height, - rSlideBoundingBox.Width, - mpBottom->mnHeight); - } - if (mpTopLeft) - { - PaintBitmapOnce( - mpTopLeft->GetNormalBitmap(), - rxCanvas, - xClip, - rSlideBoundingBox.X - mpTopLeft->mnWidth, - rSlideBoundingBox.Y - mpTopLeft->mnHeight); - } - if (mpTopRight) - { - PaintBitmapOnce( - mpTopRight->GetNormalBitmap(), - rxCanvas, - xClip, - rSlideBoundingBox.X + rSlideBoundingBox.Width, - rSlideBoundingBox.Y - mpTopLeft->mnHeight); - } - if (mpBottomLeft) - { - PaintBitmapOnce( - mpBottomLeft->GetNormalBitmap(), - rxCanvas, - xClip, - rSlideBoundingBox.X - mpBottomLeft->mnWidth, - rSlideBoundingBox.Y + rSlideBoundingBox.Height); - } - if (mpBottomRight) - { - PaintBitmapOnce( - mpBottomRight->GetNormalBitmap(), - rxCanvas, - xClip, - rSlideBoundingBox.X + rSlideBoundingBox.Width, - rSlideBoundingBox.Y + rSlideBoundingBox.Height); - } -} - -awt::Rectangle PresenterSlideSorter::CurrentSlideFrameRenderer::GetBoundingBox ( - const awt::Rectangle& rSlideBoundingBox) -{ - return awt::Rectangle( - rSlideBoundingBox.X - mnLeftFrameSize, - rSlideBoundingBox.Y - mnTopFrameSize, - rSlideBoundingBox.Width + mnLeftFrameSize + mnRightFrameSize, - rSlideBoundingBox.Height + mnTopFrameSize + mnBottomFrameSize); -} - -void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapOnce( - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const Reference<rendering::XPolyPolygon2D>& rxClip, - const double nX, - const double nY) -{ - OSL_ASSERT(rxCanvas.is()); - if ( ! rxBitmap.is()) - return; - - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - rxClip); - - const rendering::RenderState aRenderState ( - geometry::AffineMatrix2D( - 1, 0, nX, - 0, 1, nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - rxCanvas->drawBitmap( - rxBitmap, - aViewState, - aRenderState); -} - -void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapTiled( - const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const geometry::RealRectangle2D& rClipBox, - const double nX0, - const double nY0, - const double nWidth, - const double nHeight) -{ - OSL_ASSERT(rxCanvas.is()); - if ( ! rxBitmap.is()) - return; - - geometry::IntegerSize2D aSize (rxBitmap->getSize()); - - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection( - rClipBox, - geometry::RealRectangle2D(nX0,nY0,nX0+nWidth,nY0+nHeight)), - rxCanvas->getDevice())); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D( - 1, 0, nX0, - 0, 1, nY0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - const double nX1 = nX0 + nWidth; - const double nY1 = nY0 + nHeight; - for (double nY=nY0; nY<nY1; nY+=aSize.Height) - for (double nX=nX0; nX<nX1; nX+=aSize.Width) - { - aRenderState.AffineTransform.m02 = nX; - aRenderState.AffineTransform.m12 = nY; - rxCanvas->drawBitmap( - rxBitmap, - aViewState, - aRenderState); - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSlideSorter.hxx b/sdext/source/presenter/PresenterSlideSorter.hxx deleted file mode 100644 index 807bc439929e..000000000000 --- a/sdext/source/presenter/PresenterSlideSorter.hxx +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSLIDESORTER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSLIDESORTER_HXX - -#include <memory> -#include "PresenterController.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterViewFactory.hxx" -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/beans/XPropertyChangeListener.hpp> -#include <com/sun/star/drawing/XDrawView.hpp> -#include <com/sun/star/drawing/XSlidePreviewCache.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/drawing/framework/XResourceId.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/geometry/RealRectangle2D.hpp> -#include <com/sun/star/rendering/XPolyPolygon2D.hpp> - -namespace sdext::presenter { - -class PresenterButton; -class PresenterScrollBar; - -typedef cppu::WeakComponentImplHelper< - css::drawing::framework::XView, - css::awt::XWindowListener, - css::awt::XPaintListener, - css::beans::XPropertyChangeListener, - css::drawing::XSlidePreviewCacheListener, - css::awt::XMouseListener, - css::awt::XMouseMotionListener, - css::drawing::XDrawView - > PresenterSlideSorterInterfaceBase; - -/** A simple slide sorter for the presenter screen. It uses a preview cache - to create the slide previews. Painting is done via a canvas. -*/ -class PresenterSlideSorter - : private ::cppu::BaseMutex, - public PresenterSlideSorterInterfaceBase, - public CachablePresenterView -{ -public: - PresenterSlideSorter ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterSlideSorter() override; - - virtual void SAL_CALL disposing() override; - - // lang::XEventListener - - virtual void SAL_CALL - disposing (const css::lang::EventObject& rEventObject) override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XMouseListener - - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - - // XMouseMotionListener - - virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent) override; - - // XResourceId - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - - // XPropertyChangeListener - - virtual void SAL_CALL propertyChange ( - const css::beans::PropertyChangeEvent& rEvent) override; - - // XSlidePreviewCacheListener - - virtual void SAL_CALL notifyPreviewCreation ( - sal_Int32 nSlideIndex) override; - - // XDrawView - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override; - - virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage() override; - -private: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - css::uno::Reference<css::drawing::framework::XResourceId> mxViewId; - css::uno::Reference<css::drawing::framework::XPane> mxPane; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::awt::XWindow> mxWindow; - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController; - css::uno::Reference<css::drawing::XSlidePreviewCache> mxPreviewCache; - bool mbIsLayoutPending; - class Layout; - std::shared_ptr<Layout> mpLayout; - ::rtl::Reference<PresenterScrollBar> mpVerticalScrollBar; - ::rtl::Reference<PresenterButton> mpCloseButton; - class MouseOverManager; - std::unique_ptr<MouseOverManager> mpMouseOverManager; - sal_Int32 mnSlideIndexMousePressed; - sal_Int32 mnCurrentSlideIndex; - sal_Int32 mnSeparatorY; - css::util::Color maSeparatorColor; - css::awt::Rectangle maCurrentSlideFrameBoundingBox; - class CurrentSlideFrameRenderer; - std::shared_ptr<CurrentSlideFrameRenderer> mpCurrentSlideFrameRenderer; - css::uno::Reference<css::rendering::XPolyPolygon2D> mxPreviewFrame; - - void UpdateLayout(); - css::geometry::RealRectangle2D PlaceScrollBars ( - const css::geometry::RealRectangle2D& rUpperBox); - void PlaceCloseButton ( - const PresenterPaneContainer::SharedPaneDescriptor& rpPane, - const css::awt::Rectangle& rCenterBox, - const sal_Int32 nLeftFrameWidth); - void ClearBackground ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRedrawArea); - double GetSlideAspectRatio() const; - css::uno::Reference<css::rendering::XBitmap> GetPreview (const sal_Int32 nSlideIndex); - void PaintPreview ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rUpdateBox, - const sal_Int32 nSlideIndex); - void Paint (const css::awt::Rectangle& rUpdateBox); - void SetHorizontalOffset (const double nXOffset); - void SetVerticalOffset (const double nYOffset); - void GotoSlide (const sal_Int32 nSlideIndex); - bool ProvideCanvas(); - - /** @throws css::lang::DisposedException when the object has already been - disposed. - */ - void ThrowIfDisposed(); -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSprite.cxx b/sdext/source/presenter/PresenterSprite.cxx deleted file mode 100644 index d58eefd21412..000000000000 --- a/sdext/source/presenter/PresenterSprite.cxx +++ /dev/null @@ -1,165 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterSprite.hxx" - -#include <com/sun/star/lang/XComponent.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/RenderState.hpp> -#include <com/sun/star/rendering/ViewState.hpp> - -using namespace ::com::sun::star; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::UNO_QUERY; - -namespace sdext::presenter { - -PresenterSprite::PresenterSprite() - : mxSpriteFactory(), - mxSprite(), - maSize(0,0), - maLocation(0,0), - mbIsVisible(false) -{ -} - -PresenterSprite::~PresenterSprite() -{ - if (mxSprite.is()) - { - mxSprite->hide(); - Reference<lang::XComponent> xComponent (mxSprite, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - mxSprite = nullptr; - } -} - -void PresenterSprite::SetFactory ( - const css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteFactory) -{ - if (mxSpriteFactory != rxSpriteFactory) - { - DisposeSprite(); - mxSpriteFactory = rxSpriteFactory; - if (mbIsVisible) - ProvideSprite(); - } -} - -css::uno::Reference<css::rendering::XCanvas> PresenterSprite::GetCanvas() -{ - ProvideSprite(); - if (mxSprite.is()) - return mxSprite->getContentCanvas(); - else - return nullptr; -} - -void PresenterSprite::Show() -{ - mbIsVisible = true; - if (mxSprite.is()) - mxSprite->show(); - else - ProvideSprite(); -} - -void PresenterSprite::Hide() -{ - mbIsVisible = false; - if (mxSprite.is()) - mxSprite->hide(); -} - -void PresenterSprite::Resize (const css::geometry::RealSize2D& rSize) -{ - maSize = rSize; - if (mxSprite.is()) - DisposeSprite(); - if (mbIsVisible) - ProvideSprite(); -} - -void PresenterSprite::MoveTo (const css::geometry::RealPoint2D& rLocation) -{ - maLocation = rLocation; - if (mxSprite.is()) - mxSprite->move( - maLocation, - rendering::ViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr), - rendering::RenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - uno::Sequence<double>(4), - rendering::CompositeOperation::SOURCE) - ); -} - -void PresenterSprite::Update() -{ - if (mxSpriteFactory.is()) - mxSpriteFactory->updateScreen(false); -} - -void PresenterSprite::ProvideSprite() -{ - if ( !(! mxSprite.is() - && mxSpriteFactory.is() - && maSize.Width>0 - && maSize.Height>0)) - return; - - mxSprite = mxSpriteFactory->createCustomSprite(maSize); - if (!mxSprite.is()) - return; - - mxSprite->move(maLocation, - rendering::ViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr), - rendering::RenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - uno::Sequence<double>(4), - rendering::CompositeOperation::SOURCE) - ); - mxSprite->setAlpha(1.0); - mxSprite->setPriority(0); - if (mbIsVisible) - mxSprite->show(); -} - -void PresenterSprite::DisposeSprite() -{ - if (mxSprite.is()) - { - mxSprite->hide(); - Reference<lang::XComponent> xComponent (mxSprite, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - mxSprite = nullptr; - } -} - -} //end of namespace sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSprite.hxx b/sdext/source/presenter/PresenterSprite.hxx deleted file mode 100644 index b550ec0a815f..000000000000 --- a/sdext/source/presenter/PresenterSprite.hxx +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSPRITE_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSPRITE_HXX - -#include <com/sun/star/rendering/XCustomSprite.hpp> -#include <com/sun/star/rendering/XSpriteCanvas.hpp> - -namespace sdext::presenter -{ -/** A wrapper around a css::rendering::XCustomSprite that allows - not only setting values like size, location, and transformation but also - provides read access to them. - It also handles the showing and hiding of a sprite. This includes not - to show the sprite when its size is not yet defined (results in a crash) - and hiding a sprite before disposing it (results in zombie sprites.) -*/ -class PresenterSprite final -{ -public: - PresenterSprite(); - ~PresenterSprite(); - PresenterSprite(const PresenterSprite&) = delete; - PresenterSprite& operator=(const PresenterSprite&) = delete; - - /** The given sprite canvas is used as factory to create the sprite that - is wrapped by objects of this class. - It is also used to call updateScreen() at (wrapped by the Update() method). - */ - void SetFactory(const css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteFactory); - - css::uno::Reference<css::rendering::XCanvas> GetCanvas(); - - void Show(); - void Hide(); - - void Resize(const css::geometry::RealSize2D& rSize); - void MoveTo(const css::geometry::RealPoint2D& rLocation); - - void Update(); - -private: - css::uno::Reference<css::rendering::XSpriteCanvas> mxSpriteFactory; - css::uno::Reference<css::rendering::XCustomSprite> mxSprite; - css::geometry::RealSize2D maSize; - css::geometry::RealPoint2D maLocation; - bool mbIsVisible; - - void ProvideSprite(); - void DisposeSprite(); -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSpritePane.cxx b/sdext/source/presenter/PresenterSpritePane.cxx deleted file mode 100644 index 8ce72a66a3f7..000000000000 --- a/sdext/source/presenter/PresenterSpritePane.cxx +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterSpritePane.hxx" -#include <com/sun/star/lang/XMultiComponentFactory.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -//===== PresenterSpritePane ========================================================= - -PresenterSpritePane::PresenterSpritePane (const Reference<XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterPaneBase(rxContext, rpPresenterController), - mxParentCanvas(), - mpSprite(std::make_shared<PresenterSprite>()) -{ - Reference<lang::XMultiComponentFactory> xFactory ( - mxComponentContext->getServiceManager(), UNO_SET_THROW); - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - mxComponentContext), - UNO_QUERY_THROW); -} - -PresenterSpritePane::~PresenterSpritePane() -{ -} - -void PresenterSpritePane::disposing() -{ - mpSprite->SetFactory(nullptr); - mxParentCanvas = nullptr; - PresenterPaneBase::disposing(); -} - -//----- XPane ----------------------------------------------------------------- - -Reference<awt::XWindow> SAL_CALL PresenterSpritePane::getWindow() -{ - ThrowIfDisposed(); - return mxContentWindow; -} - -Reference<rendering::XCanvas> SAL_CALL PresenterSpritePane::getCanvas() -{ - ThrowIfDisposed(); - - if ( ! mxContentCanvas.is()) - UpdateCanvases(); - - return mxContentCanvas; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterSpritePane::windowResized (const awt::WindowEvent& rEvent) -{ - PresenterPaneBase::windowResized(rEvent); - - mpSprite->Resize(geometry::RealSize2D(rEvent.Width, rEvent.Height)); - LayoutContextWindow(); - UpdateCanvases(); -} - -void SAL_CALL PresenterSpritePane::windowMoved (const awt::WindowEvent& rEvent) -{ - PresenterPaneBase::windowMoved(rEvent); - - awt::Rectangle aBox ( - mxPresenterHelper->getWindowExtentsRelative(mxBorderWindow, mxParentWindow)); - mpSprite->MoveTo(geometry::RealPoint2D(aBox.X, aBox.Y)); - mpSprite->Update(); -} - -void SAL_CALL PresenterSpritePane::windowShown (const lang::EventObject& rEvent) -{ - PresenterPaneBase::windowShown(rEvent); - - mpSprite->Show(); - ToTop(); - - if (mxContentWindow.is()) - { - LayoutContextWindow(); - mxContentWindow->setVisible(true); - } -} - -void SAL_CALL PresenterSpritePane::windowHidden (const lang::EventObject& rEvent) -{ - PresenterPaneBase::windowHidden(rEvent); - - mpSprite->Hide(); - if (mxContentWindow.is()) - mxContentWindow->setVisible(false); -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterSpritePane::windowPaint (const awt::PaintEvent&) -{ - ThrowIfDisposed(); - - /* - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(sal_False); - */ -} - - -void PresenterSpritePane::UpdateCanvases() -{ - Reference<XComponent> xContentCanvasComponent (mxContentCanvas, UNO_QUERY); - if (xContentCanvasComponent.is()) - xContentCanvasComponent->dispose(); - - // The border canvas is the content canvas of the sprite. - mxBorderCanvas = mpSprite->GetCanvas(); - - // The content canvas is a wrapper of the border canvas. - if (mxBorderCanvas.is()) - mxContentCanvas = mxPresenterHelper->createSharedCanvas( - mxParentCanvas, - mxParentWindow, - mxBorderCanvas, - mxBorderWindow, - mxContentWindow); - - const awt::Rectangle aWindowBox (mxBorderWindow->getPosSize()); - PaintBorder(awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height)); -} - -void PresenterSpritePane::CreateCanvases ( - const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas) -{ - OSL_ASSERT(!mxParentCanvas.is() || mxParentCanvas==rxParentCanvas); - mxParentCanvas = rxParentCanvas; - - mpSprite->SetFactory(mxParentCanvas); - if (mxBorderWindow.is()) - { - const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); - mpSprite->Resize(geometry::RealSize2D(aBorderBox.Width, aBorderBox.Height)); - } - - UpdateCanvases(); -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterSpritePane.hxx b/sdext/source/presenter/PresenterSpritePane.hxx deleted file mode 100644 index 377d5fa7898e..000000000000 --- a/sdext/source/presenter/PresenterSpritePane.hxx +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSPRITEPANE_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSPRITEPANE_HXX - -#include "PresenterPaneBase.hxx" -#include "PresenterSprite.hxx" -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/rendering/XSpriteCanvas.hpp> -#include <rtl/ref.hxx> -#include <memory> - -namespace sdext::presenter -{ -/** Use a sprite to display the contents and the border of a pane. Windows - are still used to define the locations and sizes of both the border and - the pane content. Note that every resize results in a disposed canvas. - Therefore call getCanvas in every repaint or at least after every resize. -*/ -class PresenterSpritePane : public PresenterPaneBase -{ -public: - PresenterSpritePane(const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterSpritePane() override; - - virtual void SAL_CALL disposing() override; - - using PresenterPaneBase::disposing; - - // XPane - - virtual css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow() override; - - virtual css::uno::Reference<css::rendering::XCanvas> SAL_CALL getCanvas() override; - - // XWindowListener - - virtual void SAL_CALL windowResized(const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved(const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown(const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden(const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint(const css::awt::PaintEvent& rEvent) override; - -private: - css::uno::Reference<css::rendering::XSpriteCanvas> mxParentCanvas; - std::shared_ptr<PresenterSprite> mpSprite; - - virtual void CreateCanvases( - const css::uno::Reference<css::rendering::XSpriteCanvas>& rxParentCanvas) override; - void UpdateCanvases(); -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterTextView.cxx b/sdext/source/presenter/PresenterTextView.cxx deleted file mode 100644 index 2acc432ee1fd..000000000000 --- a/sdext/source/presenter/PresenterTextView.cxx +++ /dev/null @@ -1,1204 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterTextView.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterTimer.hxx" - -#include <algorithm> -#include <cmath> -#include <numeric> - -#include <com/sun/star/accessibility/AccessibleTextType.hpp> -#include <com/sun/star/container/XEnumerationAccess.hpp> -#include <com/sun/star/i18n/BreakIterator.hpp> -#include <com/sun/star/i18n/CharacterIteratorMode.hpp> -#include <com/sun/star/i18n/ScriptDirection.hpp> -#include <com/sun/star/i18n/WordType.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/text/WritingMode2.hpp> -#include <o3tl/safeint.hxx> -#include <tools/diagnose_ex.h> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::uno; - -const sal_Int64 CaretBlinkInterval = 500 * 1000 * 1000; - -//#define SHOW_CHARACTER_BOXES - -namespace { - sal_Int32 Signum (const sal_Int32 nValue) - { - if (nValue < 0) - return -1; - else if (nValue > 0) - return +1; - else - return 0; - } -} - -namespace sdext::presenter { - -//===== PresenterTextView ===================================================== - -PresenterTextView::PresenterTextView ( - const Reference<XComponentContext>& rxContext, - const Reference<rendering::XCanvas>& rxCanvas, - const ::std::function<void (const css::awt::Rectangle&)>& rInvalidator) - : mxCanvas(rxCanvas), - mxBreakIterator(), - mxScriptTypeDetector(), - maLocation(0,0), - maSize(0,0), - mpFont(), - maParagraphs(), - mpCaret(std::make_shared<PresenterTextCaret>( - rxContext, - [this] (sal_Int32 const nParagraphIndex, sal_Int32 const nCharacterIndex) - { return this->GetCaretBounds(nParagraphIndex, nCharacterIndex); }, - rInvalidator)), - mnLeftOffset(0), - mnTopOffset(0), - mbIsFormatPending(false), - maTextChangeBroadcaster() -{ - Reference<lang::XMultiComponentFactory> xFactory = - rxContext->getServiceManager(); - if ( ! xFactory.is()) - return; - - // Create the break iterator that we use to break text into lines. - mxBreakIterator = i18n::BreakIterator::create(rxContext); - - // Create the script type detector that is used to split paragraphs into - // portions of the same text direction. - mxScriptTypeDetector.set( - xFactory->createInstanceWithContext( - "com.sun.star.i18n.ScriptTypeDetector", - rxContext), - UNO_QUERY_THROW); -} - -void PresenterTextView::SetText (const Reference<text::XText>& rxText) -{ - maParagraphs.clear(); - - Reference<container::XEnumerationAccess> xParagraphAccess (rxText, UNO_QUERY); - if ( ! xParagraphAccess.is()) - return; - - Reference<container::XEnumeration> xParagraphs = - xParagraphAccess->createEnumeration(); - if ( ! xParagraphs.is()) - return; - - if ( ! mpFont || ! mpFont->PrepareFont(mxCanvas)) - return; - - sal_Int32 nCharacterCount (0); - while (xParagraphs->hasMoreElements()) - { - SharedPresenterTextParagraph pParagraph = std::make_shared<PresenterTextParagraph>( - maParagraphs.size(), - mxBreakIterator, - mxScriptTypeDetector, - Reference<text::XTextRange>(xParagraphs->nextElement(), UNO_QUERY), - mpCaret); - pParagraph->SetupCellArray(mpFont); - pParagraph->SetCharacterOffset(nCharacterCount); - nCharacterCount += pParagraph->GetCharacterCount(); - maParagraphs.push_back(pParagraph); - } - - if (mpCaret) - mpCaret->HideCaret(); - - RequestFormat(); -} - -void PresenterTextView::SetTextChangeBroadcaster ( - const ::std::function<void ()>& rBroadcaster) -{ - maTextChangeBroadcaster = rBroadcaster; -} - -void PresenterTextView::SetLocation (const css::geometry::RealPoint2D& rLocation) -{ - maLocation = rLocation; - - for (auto& rxParagraph : maParagraphs) - { - rxParagraph->SetOrigin( - maLocation.X - mnLeftOffset, - maLocation.Y - mnTopOffset); - } -} - -void PresenterTextView::SetSize (const css::geometry::RealSize2D& rSize) -{ - maSize = rSize; - RequestFormat(); -} - -double PresenterTextView::GetTotalTextHeight() -{ - if (mbIsFormatPending) - { - if ( ! mpFont->PrepareFont(mxCanvas)) - return 0; - Format(); - } - - return std::accumulate(maParagraphs.begin(), maParagraphs.end(), double(0), - [](const double& nTotalHeight, const SharedPresenterTextParagraph& rxParagraph) { - return nTotalHeight + rxParagraph->GetTotalTextHeight(); - }); -} - -void PresenterTextView::SetFont (const PresenterTheme::SharedFontDescriptor& rpFont) -{ - mpFont = rpFont; - RequestFormat(); -} - -void PresenterTextView::SetOffset( - const double nLeft, - const double nTop) -{ - mnLeftOffset = nLeft; - mnTopOffset = nTop; - - // Trigger an update of the text origin stored at the individual paragraphs. - SetLocation(maLocation); -} - -void PresenterTextView::MoveCaret ( - const sal_Int32 nDistance, - const sal_Int16 nTextType) -{ - if ( ! mpCaret) - return; - - // When the caret has not been visible yet then move it to the beginning - // of the text. - if (mpCaret->GetParagraphIndex() < 0) - { - mpCaret->SetPosition(0,0); - return; - } - - sal_Int32 nParagraphIndex (mpCaret->GetParagraphIndex()); - sal_Int32 nCharacterIndex (mpCaret->GetCharacterIndex()); - switch (nTextType) - { - default: - case AccessibleTextType::CHARACTER: - nCharacterIndex += nDistance; - break; - - case AccessibleTextType::WORD: - { - sal_Int32 nRemainingDistance (nDistance); - while (nRemainingDistance != 0) - { - SharedPresenterTextParagraph pParagraph (GetParagraph(nParagraphIndex)); - if (pParagraph) - { - const sal_Int32 nDelta (Signum(nDistance)); - nCharacterIndex = pParagraph->GetWordBoundary(nCharacterIndex, nDelta); - if (nCharacterIndex < 0) - { - // Go to previous or next paragraph. - nParagraphIndex += nDelta; - if (nParagraphIndex < 0) - { - nParagraphIndex = 0; - nCharacterIndex = 0; - nRemainingDistance = 0; - } - else if (o3tl::make_unsigned(nParagraphIndex) >= maParagraphs.size()) - { - nParagraphIndex = maParagraphs.size()-1; - pParagraph = GetParagraph(nParagraphIndex); - if (pParagraph) - nCharacterIndex = pParagraph->GetCharacterCount(); - nRemainingDistance = 0; - } - else - { - nRemainingDistance -= nDelta; - - // Move caret one character to the end of - // the previous or the start of the next paragraph. - pParagraph = GetParagraph(nParagraphIndex); - if (pParagraph) - { - if (nDistance<0) - nCharacterIndex = pParagraph->GetCharacterCount(); - else - nCharacterIndex = 0; - } - } - } - else - nRemainingDistance -= nDelta; - } - else - break; - } - break; - } - } - - // Move the caret to the new position. - mpCaret->SetPosition(nParagraphIndex, nCharacterIndex); -} - -void PresenterTextView::Paint ( - const css::awt::Rectangle& rUpdateBox) -{ - if ( ! mxCanvas.is()) - return; - if ( ! mpFont->PrepareFont(mxCanvas)) - return; - - if (mbIsFormatPending) - Format(); - - // Setup the clipping rectangle. Horizontally we make it a little - // larger to allow characters (and the caret) to stick out of their - // bounding boxes. This can happen on some characters (like the - // uppercase J) for typographical reasons. - const sal_Int32 nAdditionalLeftBorder (10); - const sal_Int32 nAdditionalRightBorder (5); - double nX (maLocation.X - mnLeftOffset); - double nY (maLocation.Y - mnTopOffset); - const sal_Int32 nClipLeft (::std::max( - PresenterGeometryHelper::Round(maLocation.X)-nAdditionalLeftBorder, rUpdateBox.X)); - const sal_Int32 nClipTop (::std::max( - PresenterGeometryHelper::Round(maLocation.Y), rUpdateBox.Y)); - const sal_Int32 nClipRight (::std::min( - PresenterGeometryHelper::Round(maLocation.X+maSize.Width)+nAdditionalRightBorder, rUpdateBox.X+rUpdateBox.Width)); - const sal_Int32 nClipBottom (::std::min( - PresenterGeometryHelper::Round(maLocation.Y+maSize.Height), rUpdateBox.Y+rUpdateBox.Height)); - if (nClipLeft>=nClipRight || nClipTop>=nClipBottom) - return; - - const awt::Rectangle aClipBox( - nClipLeft, - nClipTop, - nClipRight - nClipLeft, - nClipBottom - nClipTop); - Reference<rendering::XPolyPolygon2D> xClipPolygon ( - PresenterGeometryHelper::CreatePolygon(aClipBox, mxCanvas->getDevice())); - - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - xClipPolygon); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,nX, 0,1,nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor); - - for (const auto& rxParagraph : maParagraphs) - { - rxParagraph->Paint( - mxCanvas, - maSize, - mpFont, - aViewState, - aRenderState, - mnTopOffset, - nClipTop, - nClipBottom); - } - - aRenderState.AffineTransform.m02 = 0; - aRenderState.AffineTransform.m12 = 0; - -#ifdef SHOW_CHARACTER_BOXES - PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00808080); - for (sal_Int32 nParagraphIndex(0), nParagraphCount(GetParagraphCount()); - nParagraphIndex<nParagraphCount; - ++nParagraphIndex) - { - const SharedPresenterTextParagraph pParagraph (GetParagraph(nParagraphIndex)); - if ( ! pParagraph) - continue; - for (sal_Int32 nCharacterIndex(0),nCharacterCount(pParagraph->GetCharacterCount()); - nCharacterIndex<nCharacterCount; ++nCharacterIndex) - { - const awt::Rectangle aBox (pParagraph->GetCharacterBounds(nCharacterIndex, false)); - mxCanvas->drawPolyPolygon ( - PresenterGeometryHelper::CreatePolygon( - aBox, - mxCanvas->getDevice()), - aViewState, - aRenderState); - } - } - PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor); -#endif - - if (mpCaret && mpCaret->IsVisible()) - { - mxCanvas->fillPolyPolygon ( - PresenterGeometryHelper::CreatePolygon( - mpCaret->GetBounds(), - mxCanvas->getDevice()), - aViewState, - aRenderState); - } -} - -const SharedPresenterTextCaret& PresenterTextView::GetCaret() const -{ - return mpCaret; -} - -awt::Rectangle PresenterTextView::GetCaretBounds ( - sal_Int32 nParagraphIndex, - const sal_Int32 nCharacterIndex) const -{ - SharedPresenterTextParagraph pParagraph (GetParagraph(nParagraphIndex)); - - if (pParagraph) - return pParagraph->GetCharacterBounds(nCharacterIndex, true); - else - return awt::Rectangle(0,0,0,0); -} - -//----- private --------------------------------------------------------------- - -void PresenterTextView::RequestFormat() -{ - mbIsFormatPending = true; -} - -void PresenterTextView::Format() -{ - mbIsFormatPending = false; - - double nY (0); - for (const auto& rxParagraph : maParagraphs) - { - rxParagraph->Format(nY, maSize.Width, mpFont); - nY += rxParagraph->GetTotalTextHeight(); - } - - if (maTextChangeBroadcaster) - maTextChangeBroadcaster(); -} - -sal_Int32 PresenterTextView::GetParagraphCount() const -{ - return maParagraphs.size(); -} - -SharedPresenterTextParagraph PresenterTextView::GetParagraph ( - const sal_Int32 nParagraphIndex) const -{ - if (nParagraphIndex < 0) - return SharedPresenterTextParagraph(); - else if (nParagraphIndex>=sal_Int32(maParagraphs.size())) - return SharedPresenterTextParagraph(); - else - return maParagraphs[nParagraphIndex]; -} - -//===== PresenterTextParagraph ================================================ - -PresenterTextParagraph::PresenterTextParagraph ( - const sal_Int32 nParagraphIndex, - const Reference<i18n::XBreakIterator>& rxBreakIterator, - const Reference<i18n::XScriptTypeDetector>& rxScriptTypeDetector, - const Reference<text::XTextRange>& rxTextRange, - const SharedPresenterTextCaret& rpCaret) - : msParagraphText(), - mnParagraphIndex(nParagraphIndex), - mpCaret(rpCaret), - mxBreakIterator(rxBreakIterator), - mxScriptTypeDetector(rxScriptTypeDetector), - maLines(), - mnVerticalOffset(0), - mnXOrigin(0), - mnYOrigin(0), - mnWidth(0), - mnAscent(0), - mnDescent(0), - mnLineHeight(-1), - mnWritingMode (text::WritingMode2::LR_TB), - mnCharacterOffset(0), - maCells() -{ - if (!rxTextRange.is()) - return; - - Reference<beans::XPropertySet> xProperties (rxTextRange, UNO_QUERY); - try - { - xProperties->getPropertyValue("WritingMode") >>= mnWritingMode; - } - catch(beans::UnknownPropertyException&) - { - // Ignore the exception. Use the default value. - } - - msParagraphText = rxTextRange->getString(); -} - -void PresenterTextParagraph::Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const geometry::RealSize2D& rSize, - const PresenterTheme::SharedFontDescriptor& rpFont, - const rendering::ViewState& rViewState, - rendering::RenderState& rRenderState, - const double nTopOffset, - const double nClipTop, - const double nClipBottom) -{ - if (mnLineHeight <= 0) - return; - - sal_Int8 nTextDirection (GetTextDirection()); - - const double nSavedM12 (rRenderState.AffineTransform.m12); - - if ( ! IsTextReferencePointLeft()) - rRenderState.AffineTransform.m02 += rSize.Width; - -#ifdef SHOW_CHARACTER_BOXES - for (sal_Int32 nIndex=0,nCount=maLines.size(); - nIndex<nCount; - ++nIndex) - { - Line& rLine (maLines[nIndex]); - rLine.ProvideLayoutedLine(msParagraphText, rpFont, nTextDirection); - } -#endif - - for (sal_Int32 nIndex=0,nCount=maLines.size(); - nIndex<nCount; - ++nIndex, rRenderState.AffineTransform.m12 += mnLineHeight) - { - Line& rLine (maLines[nIndex]); - - // Paint only visible lines. - const double nLineTop = rLine.mnBaseLine - mnAscent - nTopOffset; - if (nLineTop + mnLineHeight< nClipTop) - continue; - else if (nLineTop > nClipBottom) - break; - rLine.ProvideLayoutedLine(msParagraphText, rpFont, nTextDirection); - - rRenderState.AffineTransform.m12 = nSavedM12 + rLine.mnBaseLine; - - rxCanvas->drawTextLayout ( - rLine.mxLayoutedLine, - rViewState, - rRenderState); - } - rRenderState.AffineTransform.m12 = nSavedM12; - - if ( ! IsTextReferencePointLeft()) - rRenderState.AffineTransform.m02 -= rSize.Width; -} - -void PresenterTextParagraph::Format ( - const double nY, - const double nWidth, - const PresenterTheme::SharedFontDescriptor& rpFont) -{ - // Make sure that the text view is in a valid and sane state. - if ( ! mxBreakIterator.is() || ! mxScriptTypeDetector.is()) - return; - if (nWidth<=0) - return; - if ( ! rpFont || ! rpFont->mxFont.is()) - return; - - sal_Int32 nPosition (0); - - mnWidth = nWidth; - maLines.clear(); - mnLineHeight = 0; - mnAscent = 0; - mnDescent = 0; - mnVerticalOffset = nY; - maWordBoundaries.clear(); - maWordBoundaries.push_back(0); - - const rendering::FontMetrics aMetrics (rpFont->mxFont->getFontMetrics()); - mnAscent = aMetrics.Ascent; - mnDescent = aMetrics.Descent; - mnLineHeight = aMetrics.Ascent + aMetrics.Descent + aMetrics.ExternalLeading; - nPosition = 0; - i18n::Boundary aCurrentLine(0,0); - while (true) - { - const i18n::Boundary aWordBoundary = mxBreakIterator->nextWord( - msParagraphText, - nPosition, - lang::Locale(), - i18n::WordType::ANYWORD_IGNOREWHITESPACES); - AddWord(nWidth, aCurrentLine, aWordBoundary.startPos, rpFont); - - // Remember the new word boundary for caret travelling by words. - // Prevent duplicates. - if (aWordBoundary.startPos > maWordBoundaries.back()) - maWordBoundaries.push_back(aWordBoundary.startPos); - - if (aWordBoundary.endPos>aWordBoundary.startPos) - AddWord(nWidth, aCurrentLine, aWordBoundary.endPos, rpFont); - - if (aWordBoundary.startPos<0 || aWordBoundary.endPos<0) - break; - if (nPosition >= aWordBoundary.endPos) - break; - nPosition = aWordBoundary.endPos; - } - - if (aCurrentLine.endPos>aCurrentLine.startPos) - AddLine(aCurrentLine); - -} - -sal_Int32 PresenterTextParagraph::GetWordBoundary( - const sal_Int32 nLocalCharacterIndex, - const sal_Int32 nDistance) -{ - OSL_ASSERT(nDistance==-1 || nDistance==+1); - - if (nLocalCharacterIndex < 0) - { - // The caller asked for the start or end position of the paragraph. - if (nDistance < 0) - return 0; - else - return GetCharacterCount(); - } - - sal_Int32 nIndex (0); - for (sal_Int32 nCount (maWordBoundaries.size()); nIndex<nCount; ++nIndex) - { - if (maWordBoundaries[nIndex] >= nLocalCharacterIndex) - { - // When inside the word (not at its start or end) then - // first move to the start or end before going the previous or - // next word. - if (maWordBoundaries[nIndex] > nLocalCharacterIndex) - if (nDistance > 0) - --nIndex; - break; - } - } - - nIndex += nDistance; - - if (nIndex < 0) - return -1; - else if (o3tl::make_unsigned(nIndex)>=maWordBoundaries.size()) - return -1; - else - return maWordBoundaries[nIndex]; -} - -sal_Int32 PresenterTextParagraph::GetCaretPosition() const -{ - if (mpCaret && mpCaret->GetParagraphIndex()==mnParagraphIndex) - return mpCaret->GetCharacterIndex(); - else - return -1; -} - -void PresenterTextParagraph::SetCaretPosition (const sal_Int32 nPosition) const -{ - if (mpCaret && mpCaret->GetParagraphIndex()==mnParagraphIndex) - return mpCaret->SetPosition(mnParagraphIndex, nPosition); -} - -void PresenterTextParagraph::SetOrigin (const double nXOrigin, const double nYOrigin) -{ - mnXOrigin = nXOrigin; - mnYOrigin = nYOrigin; -} - -awt::Point PresenterTextParagraph::GetRelativeLocation() const -{ - return awt::Point( - sal_Int32(mnXOrigin), - sal_Int32(mnYOrigin + mnVerticalOffset)); -} - -awt::Size PresenterTextParagraph::GetSize() const -{ - return awt::Size( - sal_Int32(mnWidth), - sal_Int32(GetTotalTextHeight())); -} - -void PresenterTextParagraph::AddWord ( - const double nWidth, - i18n::Boundary& rCurrentLine, - const sal_Int32 nWordBoundary, - const PresenterTheme::SharedFontDescriptor& rpFont) -{ - sal_Int32 nLineStart (0); - if ( ! maLines.empty()) - nLineStart = rCurrentLine.startPos; - - const OUString sLineCandidate ( - msParagraphText.copy(nLineStart, nWordBoundary-nLineStart)); - - css::geometry::RealRectangle2D aLineBox ( - PresenterCanvasHelper::GetTextBoundingBox ( - rpFont->mxFont, - sLineCandidate, - mnWritingMode)); - const double nLineWidth (aLineBox.X2 - aLineBox.X1); - - if (nLineWidth >= nWidth) - { - // Add new line with a single word (so far). - AddLine(rCurrentLine); - } - rCurrentLine.endPos = nWordBoundary; -} - -void PresenterTextParagraph::AddLine ( - i18n::Boundary& rCurrentLine) -{ - Line aLine (rCurrentLine.startPos, rCurrentLine.endPos); - - // Find the start and end of the line with respect to cells. - if (!maLines.empty()) - { - aLine.mnLineStartCellIndex = maLines.back().mnLineEndCellIndex; - aLine.mnBaseLine = maLines.back().mnBaseLine + mnLineHeight; - } - else - { - aLine.mnLineStartCellIndex = 0; - aLine.mnBaseLine = mnVerticalOffset + mnAscent; - } - sal_Int32 nCellIndex (aLine.mnLineStartCellIndex); - double nWidth (0); - for ( ; nCellIndex<sal_Int32(maCells.size()); ++nCellIndex) - { - const Cell& rCell (maCells[nCellIndex]); - if (rCell.mnCharacterIndex+rCell.mnCharacterCount > aLine.mnLineEndCharacterIndex) - break; - nWidth += rCell.mnCellWidth; - } - aLine.mnLineEndCellIndex = nCellIndex; - aLine.mnWidth = nWidth; - - maLines.push_back(aLine); - - rCurrentLine.startPos = rCurrentLine.endPos; -} - -double PresenterTextParagraph::GetTotalTextHeight() const -{ - return maLines.size() * mnLineHeight; -} - -void PresenterTextParagraph::SetCharacterOffset (const sal_Int32 nCharacterOffset) -{ - mnCharacterOffset = nCharacterOffset; -} - -sal_Int32 PresenterTextParagraph::GetCharacterCount() const -{ - return msParagraphText.getLength(); -} - -sal_Unicode PresenterTextParagraph::GetCharacter ( - const sal_Int32 nGlobalCharacterIndex) const -{ - if (nGlobalCharacterIndex<mnCharacterOffset - || nGlobalCharacterIndex>=mnCharacterOffset+msParagraphText.getLength()) - { - return sal_Unicode(); - } - else - { - return msParagraphText[nGlobalCharacterIndex - mnCharacterOffset]; - } -} - -const OUString& PresenterTextParagraph::GetText() const -{ - return msParagraphText; -} - -TextSegment PresenterTextParagraph::GetTextSegment ( - const sal_Int32 nOffset, - const sal_Int32 nIndex, - const sal_Int16 nTextType) const -{ - switch(nTextType) - { - case AccessibleTextType::PARAGRAPH: - return TextSegment( - msParagraphText, - mnCharacterOffset, - mnCharacterOffset+msParagraphText.getLength()); - - case AccessibleTextType::SENTENCE: - if (mxBreakIterator.is()) - { - const sal_Int32 nStart (mxBreakIterator->beginOfSentence( - msParagraphText, nIndex-mnCharacterOffset, lang::Locale())); - const sal_Int32 nEnd (mxBreakIterator->endOfSentence( - msParagraphText, nIndex-mnCharacterOffset, lang::Locale())); - if (nStart < nEnd) - return TextSegment( - msParagraphText.copy(nStart, nEnd-nStart), - nStart+mnCharacterOffset, - nEnd+mnCharacterOffset); - } - break; - - case AccessibleTextType::WORD: - if (mxBreakIterator.is()) - return GetWordTextSegment(nOffset, nIndex); - break; - - case AccessibleTextType::LINE: - { - auto iLine = std::find_if(maLines.begin(), maLines.end(), - [nIndex](const Line& rLine) { return nIndex < rLine.mnLineEndCharacterIndex; }); - if (iLine != maLines.end()) - { - return TextSegment( - msParagraphText.copy( - iLine->mnLineStartCharacterIndex, - iLine->mnLineEndCharacterIndex - iLine->mnLineStartCharacterIndex), - iLine->mnLineStartCharacterIndex, - iLine->mnLineEndCharacterIndex); - } - } - break; - - // Handle GLYPH and ATTRIBUTE_RUN like CHARACTER because we can not - // do better at the moment. - case AccessibleTextType::CHARACTER: - case AccessibleTextType::GLYPH: - case AccessibleTextType::ATTRIBUTE_RUN: - return CreateTextSegment(nIndex+nOffset, nIndex+nOffset+1); - } - - return TextSegment(OUString(), 0,0); -} - -TextSegment PresenterTextParagraph::GetWordTextSegment ( - const sal_Int32 nOffset, - const sal_Int32 nIndex) const -{ - sal_Int32 nCurrentOffset (nOffset); - sal_Int32 nCurrentIndex (nIndex); - - i18n::Boundary aWordBoundary; - if (nCurrentOffset == 0) - aWordBoundary = mxBreakIterator->getWordBoundary( - msParagraphText, - nIndex, - lang::Locale(), - i18n::WordType::ANYWORD_IGNOREWHITESPACES, - true); - else if (nCurrentOffset < 0) - { - while (nCurrentOffset<0 && nCurrentIndex>0) - { - aWordBoundary = mxBreakIterator->previousWord( - msParagraphText, - nCurrentIndex, - lang::Locale(), - i18n::WordType::ANYWORD_IGNOREWHITESPACES); - nCurrentIndex = aWordBoundary.startPos; - ++nCurrentOffset; - } - } - else - { - while (nCurrentOffset>0 && nCurrentIndex<=GetCharacterCount()) - { - aWordBoundary = mxBreakIterator->nextWord( - msParagraphText, - nCurrentIndex, - lang::Locale(), - i18n::WordType::ANYWORD_IGNOREWHITESPACES); - nCurrentIndex = aWordBoundary.endPos; - --nCurrentOffset; - } - } - - return CreateTextSegment(aWordBoundary.startPos, aWordBoundary.endPos); -} - -TextSegment PresenterTextParagraph::CreateTextSegment ( - sal_Int32 nStartIndex, - sal_Int32 nEndIndex) const -{ - if (nEndIndex <= nStartIndex) - return TextSegment( - OUString(), - nStartIndex, - nEndIndex); - else - return TextSegment( - msParagraphText.copy(nStartIndex, nEndIndex-nStartIndex), - nStartIndex, - nEndIndex); -} - -awt::Rectangle PresenterTextParagraph::GetCharacterBounds ( - sal_Int32 nGlobalCharacterIndex, - const bool bCaretBox) -{ - // Find the line that contains the requested character and accumulate - // the previous line heights. - double nX (mnXOrigin); - double nY (mnYOrigin + mnVerticalOffset + mnAscent); - const sal_Int8 nTextDirection (GetTextDirection()); - for (sal_Int32 nLineIndex=0,nLineCount=maLines.size(); - nLineIndex<nLineCount; - ++nLineIndex, nY+=mnLineHeight) - { - Line& rLine (maLines[nLineIndex]); - // Skip lines before the indexed character. - if (nGlobalCharacterIndex >= rLine.mnLineEndCharacterIndex) - // When in the last line then allow the index past the last char. - if (nLineIndex<nLineCount-1) - continue; - - rLine.ProvideCellBoxes(); - - const sal_Int32 nCellIndex (nGlobalCharacterIndex - rLine.mnLineStartCharacterIndex); - - // The cell bounding box is defined relative to the origin of - // the current line. Therefore we have to add the absolute - // position of the line. - geometry::RealRectangle2D rCellBox (rLine.maCellBoxes[ - ::std::min(nCellIndex, rLine.maCellBoxes.getLength()-1)]); - - double nLeft = nX + rCellBox.X1; - double nRight = nX + rCellBox.X2; - if (nTextDirection == rendering::TextDirection::WEAK_RIGHT_TO_LEFT) - { - const double nOldRight (nRight); - nRight = rLine.mnWidth - nLeft; - nLeft = rLine.mnWidth - nOldRight; - } - double nTop = nY - mnAscent; - double nBottom; - if (bCaretBox) - { - nBottom = nTop + mnLineHeight; - if (nCellIndex >= rLine.maCellBoxes.getLength()) - nLeft = nRight-2; - if (nLeft < nX) - nLeft = nX; - nRight = nLeft+2; - } - else - { - nBottom = nTop + mnAscent + mnDescent; - } - const sal_Int32 nX1 = sal_Int32(floor(nLeft)); - const sal_Int32 nY1 = sal_Int32(floor(nTop)); - const sal_Int32 nX2 = sal_Int32(ceil(nRight)); - const sal_Int32 nY2 = sal_Int32(ceil(nBottom)); - - return awt::Rectangle(nX1,nY1,nX2-nX1+1,nY2-nY1+1); - } - - // We are still here. That means that the given index lies past the - // last character in the paragraph. - // Return an empty box that lies past the last character. Better than nothing. - return awt::Rectangle(sal_Int32(nX+0.5), sal_Int32(nY+0.5), 0, 0); -} - -sal_Int8 PresenterTextParagraph::GetTextDirection() const -{ - // Find first portion that has a non-neutral text direction. - sal_Int32 nPosition (0); - sal_Int32 nTextLength (msParagraphText.getLength()); - while (nPosition < nTextLength) - { - const sal_Int16 nScriptDirection ( - mxScriptTypeDetector->getScriptDirection( - msParagraphText, nPosition, i18n::ScriptDirection::NEUTRAL)); - switch (nScriptDirection) - { - case i18n::ScriptDirection::NEUTRAL: - // continue looping. - break; - case i18n::ScriptDirection::LEFT_TO_RIGHT: - return rendering::TextDirection::WEAK_LEFT_TO_RIGHT; - - case i18n::ScriptDirection::RIGHT_TO_LEFT: - return rendering::TextDirection::WEAK_RIGHT_TO_LEFT; - } - - nPosition = mxScriptTypeDetector->endOfScriptDirection( - msParagraphText, nPosition, nScriptDirection); - } - - // All text in paragraph is neutral. Fall back on writing mode taken - // from the XText (which may not be properly initialized.) - sal_Int8 nTextDirection(rendering::TextDirection::WEAK_LEFT_TO_RIGHT); - switch(mnWritingMode) - { - case text::WritingMode2::LR_TB: - nTextDirection = rendering::TextDirection::WEAK_LEFT_TO_RIGHT; - break; - - case text::WritingMode2::RL_TB: - nTextDirection = rendering::TextDirection::WEAK_RIGHT_TO_LEFT; - break; - - default: - case text::WritingMode2::TB_RL: - case text::WritingMode2::TB_LR: - // Can not handle this. Use default and hope for the best. - break; - } - return nTextDirection; -} - -bool PresenterTextParagraph::IsTextReferencePointLeft() const -{ - return mnWritingMode != text::WritingMode2::RL_TB; -} - -void PresenterTextParagraph::SetupCellArray ( - const PresenterTheme::SharedFontDescriptor& rpFont) -{ - maCells.clear(); - - if ( ! rpFont || ! rpFont->mxFont.is()) - return; - - sal_Int32 nPosition (0); - sal_Int32 nIndex (0); - const sal_Int32 nTextLength (msParagraphText.getLength()); - const sal_Int8 nTextDirection (GetTextDirection()); - while (nPosition < nTextLength) - { - const sal_Int32 nNewPosition (mxBreakIterator->nextCharacters( - msParagraphText, - nPosition, - lang::Locale(), - i18n::CharacterIteratorMode::SKIPCELL, - 1, - nIndex)); - - rendering::StringContext aContext (msParagraphText, nPosition, nNewPosition-nPosition); - Reference<rendering::XTextLayout> xLayout ( - rpFont->mxFont->createTextLayout(aContext, nTextDirection, 0)); - css::geometry::RealRectangle2D aCharacterBox (xLayout->queryTextBounds()); - - maCells.emplace_back( - nPosition, - nNewPosition-nPosition, - aCharacterBox.X2-aCharacterBox.X1); - - nPosition = nNewPosition; - } -} - -//===== PresenterTextCaret ================================================---- - -PresenterTextCaret::PresenterTextCaret ( - uno::Reference<uno::XComponentContext> const& xContext, - const ::std::function<css::awt::Rectangle (const sal_Int32,const sal_Int32)>& rCharacterBoundsAccess, - const ::std::function<void (const css::awt::Rectangle&)>& rInvalidator) - : m_xContext(xContext) - , mnParagraphIndex(-1), - mnCharacterIndex(-1), - mnCaretBlinkTaskId(0), - mbIsCaretVisible(false), - maCharacterBoundsAccess(rCharacterBoundsAccess), - maInvalidator(rInvalidator), - maBroadcaster(), - maCaretBounds() -{ -} - -PresenterTextCaret::~PresenterTextCaret() -{ - try - { - HideCaret(); - } - catch (uno::Exception const&) - { - TOOLS_WARN_EXCEPTION("sdext.presenter", "unexpected exception in ~PresenterTextCaret"); - } -} - -void PresenterTextCaret::ShowCaret() -{ - if (mnCaretBlinkTaskId == 0) - { - mnCaretBlinkTaskId = PresenterTimer::ScheduleRepeatedTask ( - m_xContext, - [this] (TimeValue const&) { return this->InvertCaret(); }, - CaretBlinkInterval, - CaretBlinkInterval); - } - mbIsCaretVisible = true; -} - -void PresenterTextCaret::HideCaret() -{ - if (mnCaretBlinkTaskId != 0) - { - PresenterTimer::CancelTask(mnCaretBlinkTaskId); - mnCaretBlinkTaskId = 0; - } - mbIsCaretVisible = false; - // Reset the caret position. - mnParagraphIndex = -1; - mnCharacterIndex = -1; -} - - -void PresenterTextCaret::SetPosition ( - const sal_Int32 nParagraphIndex, - const sal_Int32 nCharacterIndex) -{ - if (mnParagraphIndex == nParagraphIndex - && mnCharacterIndex == nCharacterIndex) - return; - - if (mnParagraphIndex >= 0) - maInvalidator(maCaretBounds); - - const sal_Int32 nOldParagraphIndex (mnParagraphIndex); - const sal_Int32 nOldCharacterIndex (mnCharacterIndex); - mnParagraphIndex = nParagraphIndex; - mnCharacterIndex = nCharacterIndex; - maCaretBounds = maCharacterBoundsAccess(mnParagraphIndex, mnCharacterIndex); - if (mnParagraphIndex >= 0) - ShowCaret(); - else - HideCaret(); - - if (mnParagraphIndex >= 0) - maInvalidator(maCaretBounds); - - if (maBroadcaster) - maBroadcaster( - nOldParagraphIndex, - nOldCharacterIndex, - mnParagraphIndex, - mnCharacterIndex); -} - - -void PresenterTextCaret::SetCaretMotionBroadcaster ( - const ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)>& rBroadcaster) -{ - maBroadcaster = rBroadcaster; -} - -const css::awt::Rectangle& PresenterTextCaret::GetBounds() const -{ - return maCaretBounds; -} - -void PresenterTextCaret::InvertCaret() -{ - mbIsCaretVisible = !mbIsCaretVisible; - if (mnParagraphIndex >= 0) - maInvalidator(maCaretBounds); -} - -//===== PresenterTextParagraph::Cell ========================================== - -PresenterTextParagraph::Cell::Cell ( - const sal_Int32 nCharacterIndex, - const sal_Int32 nCharacterCount, - const double nCellWidth) - : mnCharacterIndex(nCharacterIndex), - mnCharacterCount(nCharacterCount), - mnCellWidth(nCellWidth) -{ -} - -//===== PresenterTextParagraph::Line ========================================== - -PresenterTextParagraph::Line::Line ( - const sal_Int32 nLineStartCharacterIndex, - const sal_Int32 nLineEndCharacterIndex) - : mnLineStartCharacterIndex(nLineStartCharacterIndex), - mnLineEndCharacterIndex(nLineEndCharacterIndex), - mnLineStartCellIndex(-1), mnLineEndCellIndex(-1), - mxLayoutedLine(), - mnBaseLine(0), mnWidth(0), - maCellBoxes() -{ -} - -void PresenterTextParagraph::Line::ProvideCellBoxes() -{ - if ( mnLineStartCharacterIndex < mnLineEndCharacterIndex && !maCellBoxes.hasElements() ) - { - if (mxLayoutedLine.is()) - maCellBoxes = mxLayoutedLine->queryInkMeasures(); - else - { - OSL_ASSERT(mxLayoutedLine.is()); - } - } -} - -void PresenterTextParagraph::Line::ProvideLayoutedLine ( - const OUString& rsParagraphText, - const PresenterTheme::SharedFontDescriptor& rpFont, - const sal_Int8 nTextDirection) -{ - if ( ! mxLayoutedLine.is()) - { - const rendering::StringContext aContext ( - rsParagraphText, - mnLineStartCharacterIndex, - mnLineEndCharacterIndex - mnLineStartCharacterIndex); - - mxLayoutedLine = rpFont->mxFont->createTextLayout( - aContext, - nTextDirection, - 0); - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterTextView.hxx b/sdext/source/presenter/PresenterTextView.hxx deleted file mode 100644 index a732978e6113..000000000000 --- a/sdext/source/presenter/PresenterTextView.hxx +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTEXTVIEW_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTEXTVIEW_HXX - -#include "PresenterTheme.hxx" -#include <com/sun/star/accessibility/TextSegment.hpp> -#include <com/sun/star/awt/Point.hpp> -#include <com/sun/star/awt/Size.hpp> -#include <com/sun/star/geometry/RealPoint2D.hpp> -#include <com/sun/star/geometry/RealSize2D.hpp> -#include <com/sun/star/i18n/XBreakIterator.hpp> -#include <com/sun/star/i18n/XScriptTypeDetector.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/text/XText.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> - -#include <functional> - -namespace sdext::presenter { - -class PresenterTextCaret -{ -public: - PresenterTextCaret ( - css::uno::Reference<css::uno::XComponentContext> const& xContext, - const ::std::function<css::awt::Rectangle (const sal_Int32,const sal_Int32)>& - rCharacterBoundsAccess, - const ::std::function<void (const css::awt::Rectangle&)>& - rInvalidator); - ~PresenterTextCaret(); - - void ShowCaret(); - void HideCaret(); - - sal_Int32 GetParagraphIndex() const { return mnParagraphIndex;} - sal_Int32 GetCharacterIndex() const { return mnCharacterIndex;} - void SetPosition ( - const sal_Int32 nParagraphIndex, - const sal_Int32 nCharacterIndex); - - bool IsVisible() const { return mbIsCaretVisible;} - - /** Set a (possibly empty) functor that broadcasts changes of the caret - position. This is used when a PresenterTextView object is set at - the accessibility object so that accessibility events can be sent - when the caret changes position. - */ - void SetCaretMotionBroadcaster ( - const ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)>& rBroadcaster); - - const css::awt::Rectangle& GetBounds() const; - -private: - css::uno::Reference<css::uno::XComponentContext> const& m_xContext; - sal_Int32 mnParagraphIndex; - sal_Int32 mnCharacterIndex; - sal_Int32 mnCaretBlinkTaskId; - bool mbIsCaretVisible; - const ::std::function<css::awt::Rectangle (const sal_Int32,const sal_Int32)> maCharacterBoundsAccess; - const ::std::function<void (const css::awt::Rectangle&)> maInvalidator; - ::std::function<void (sal_Int32,sal_Int32,sal_Int32,sal_Int32)> maBroadcaster; - css::awt::Rectangle maCaretBounds; - - void InvertCaret(); -}; -typedef std::shared_ptr<PresenterTextCaret> SharedPresenterTextCaret; - -//===== PresenterTextParagraph ================================================ - -class PresenterTextParagraph -{ -public: - PresenterTextParagraph ( - const sal_Int32 nParagraphIndex, - const css::uno::Reference<css::i18n::XBreakIterator>& rxBreakIterator, - const css::uno::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector, - const css::uno::Reference<css::text::XTextRange>& rxTextRange, - const SharedPresenterTextCaret& rpCaret); - - void Paint ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::geometry::RealSize2D& rSize, - const PresenterTheme::SharedFontDescriptor& rpFont, - const css::rendering::ViewState& rViewState, - css::rendering::RenderState& rRenderState, - const double nTopOffset, - const double nClipTop, - const double nClipBottom); - - double GetTotalTextHeight() const; - - void SetCharacterOffset (const sal_Int32 nCharacterOffset); - sal_Int32 GetCharacterCount() const; - sal_Unicode GetCharacter (const sal_Int32 nGlobalCharacterIndex) const; - const OUString& GetText() const; - css::accessibility::TextSegment GetTextSegment ( - const sal_Int32 nOffset, - const sal_Int32 nGlobalCharacterIndex, - const sal_Int16 nTextType) const; - css::accessibility::TextSegment GetWordTextSegment ( - const sal_Int32 nOffset, - const sal_Int32 nIndex) const; - css::accessibility::TextSegment CreateTextSegment ( - sal_Int32 nStartIndex, - sal_Int32 nEndIndex) const; - css::awt::Rectangle GetCharacterBounds ( - sal_Int32 nGlobalCharacterIndex, - const bool bCaretBox); - void SetupCellArray ( - const PresenterTheme::SharedFontDescriptor& rpFont); - void Format ( - const double nY, - const double nWidth, - const PresenterTheme::SharedFontDescriptor& rpFont); - sal_Int32 GetWordBoundary( - const sal_Int32 nLocalCharacterIndex, - const sal_Int32 nDistance); - sal_Int32 GetCaretPosition() const; - void SetCaretPosition (const sal_Int32 nPosition) const; - void SetOrigin (const double nXOrigin, const double nYOrigin); - css::awt::Point GetRelativeLocation() const; - css::awt::Size GetSize() const; - -private: - OUString msParagraphText; - const sal_Int32 mnParagraphIndex; - SharedPresenterTextCaret mpCaret; - - /** A portion of a string that encodes one unicode cell. It describes - number of characters in the unicode string that make up the cell and its - width in pixel (with respect to some configuration that is stored - externally or implicitly). - */ - class Cell - { - public: - Cell (const sal_Int32 nCharacterIndex, const sal_Int32 nCharacterCount, const double nCellWidth); - sal_Int32 mnCharacterIndex; - sal_Int32 mnCharacterCount; - double mnCellWidth; - }; - - class Line - { - public: - Line (const sal_Int32 nLineStartCharacterIndex, const sal_Int32 nLineEndCharacterIndex); - sal_Int32 mnLineStartCharacterIndex; - sal_Int32 mnLineEndCharacterIndex; - sal_Int32 mnLineStartCellIndex; - sal_Int32 mnLineEndCellIndex; - css::uno::Reference<css::rendering::XTextLayout> mxLayoutedLine; - double mnBaseLine; - double mnWidth; - css::uno::Sequence<css::geometry::RealRectangle2D> maCellBoxes; - - void ProvideLayoutedLine ( - const OUString& rsParagraphText, - const PresenterTheme::SharedFontDescriptor& rpFont, - const sal_Int8 nTextDirection); - void ProvideCellBoxes(); - }; - - css::uno::Reference<css::i18n::XBreakIterator> mxBreakIterator; - css::uno::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector; - ::std::vector<Line> maLines; - ::std::vector<sal_Int32> maWordBoundaries; - // Offset of the top of the paragraph with respect to the origin of the - // whole text (specified by mnXOrigin and mnYOrigin). - double mnVerticalOffset; - double mnXOrigin; - double mnYOrigin; - double mnWidth; - double mnAscent; - double mnDescent; - double mnLineHeight; - sal_Int8 mnWritingMode; - /// The index of the first character in this paragraph with respect to - /// the whole text. - sal_Int32 mnCharacterOffset; - ::std::vector<Cell> maCells; - - void AddWord ( - const double nWidth, - css::i18n::Boundary& rCurrentLine, - const sal_Int32 nWordBoundary, - const PresenterTheme::SharedFontDescriptor& rpFont); - void AddLine ( - css::i18n::Boundary& rCurrentLine); - sal_Int8 GetTextDirection() const; - bool IsTextReferencePointLeft() const; -}; -typedef std::shared_ptr<PresenterTextParagraph> SharedPresenterTextParagraph; - -/** A simple text view that paints text onto a given canvas. -*/ -class PresenterTextView -{ -public: - - PresenterTextView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const ::std::function<void (const css::awt::Rectangle&)>& rInvalidator); - void SetText (const css::uno::Reference<css::text::XText>& rxText); - void SetTextChangeBroadcaster(const ::std::function<void ()>& rBroadcaster); - - void SetLocation (const css::geometry::RealPoint2D& rLocation); - void SetSize (const css::geometry::RealSize2D& rSize); - double GetTotalTextHeight(); - - void SetFont (const PresenterTheme::SharedFontDescriptor& rpFont); - - void SetOffset ( - const double nLeft, - const double nTop); - - /** Move the caret forward or backward by character or by word. - @param nDistance - Should be either -1 or +1 to move caret backwards or forwards, - respectively. - @param nTextType - Valid values are the - css::accessibility::AccessibleTextType constants. - */ - void MoveCaret ( - const sal_Int32 nDistance, - const sal_Int16 nTextType); - - void Paint (const css::awt::Rectangle& rUpdateBox); - - const SharedPresenterTextCaret& GetCaret() const; - - sal_Int32 GetParagraphCount() const; - SharedPresenterTextParagraph GetParagraph (const sal_Int32 nParagraphIndex) const; - -private: - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::i18n::XBreakIterator> mxBreakIterator; - css::uno::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector; - css::geometry::RealPoint2D maLocation; - css::geometry::RealSize2D maSize; - PresenterTheme::SharedFontDescriptor mpFont; - ::std::vector<SharedPresenterTextParagraph> maParagraphs; - SharedPresenterTextCaret mpCaret; - double mnLeftOffset; - double mnTopOffset; - bool mbIsFormatPending; - ::std::function<void ()> maTextChangeBroadcaster; - - void RequestFormat(); - void Format(); - css::awt::Rectangle GetCaretBounds ( - const sal_Int32 nParagraphIndex, - const sal_Int32 nCharacterIndex) const; -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterTheme.cxx b/sdext/source/presenter/PresenterTheme.cxx deleted file mode 100644 index bf911dd970c4..000000000000 --- a/sdext/source/presenter/PresenterTheme.cxx +++ /dev/null @@ -1,1076 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterTheme.hxx" -#include "PresenterBitmapContainer.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterConfigurationAccess.hxx" -#include <com/sun/star/drawing/XPresenterHelper.hpp> -#include <com/sun/star/rendering/PanoseWeight.hpp> -#include <osl/diagnose.h> -#include <map> -#include <numeric> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::std; - -namespace sdext::presenter { - -namespace { - -class BorderSize -{ -public: - const static sal_Int32 mnInvalidValue = -10000; - - BorderSize() : mnLeft(mnInvalidValue), - mnTop(mnInvalidValue), - mnRight(mnInvalidValue), - mnBottom(mnInvalidValue) {} - - sal_Int32 mnLeft; - sal_Int32 mnTop; - sal_Int32 mnRight; - sal_Int32 mnBottom; - - vector<sal_Int32> ToVector() - { - return - { - mnLeft == mnInvalidValue ? 0 : mnLeft, - mnTop == mnInvalidValue ? 0 : mnTop, - mnRight == mnInvalidValue ? 0 : mnRight, - mnBottom == mnInvalidValue ? 0 : mnBottom - }; - }; - - void Merge (const BorderSize& rBorderSize) - { - if (mnLeft == mnInvalidValue) - mnLeft = rBorderSize.mnLeft; - if (mnTop == mnInvalidValue) - mnTop = rBorderSize.mnTop; - if (mnRight == mnInvalidValue) - mnRight = rBorderSize.mnRight; - if (mnBottom == mnInvalidValue) - mnBottom = rBorderSize.mnBottom; - } -}; - -/** Reading a theme from the configurations is done in various classes. The - ReadContext gives access to frequently used objects and functions to make - the configuration handling easier. -*/ -class ReadContext -{ -public: - Reference<XComponentContext> mxComponentContext; - Reference<rendering::XCanvas> mxCanvas; - Reference<drawing::XPresenterHelper> mxPresenterHelper; - - ReadContext ( - const Reference<XComponentContext>& rxContext, - const Reference<rendering::XCanvas>& rxCanvas); - - /** Read data describing a font from the node that can be reached from - the given root via the given path. - @param rsFontPath - May be empty. - */ - static PresenterTheme::SharedFontDescriptor ReadFont ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme, - const PresenterTheme::SharedFontDescriptor& rpDefault); - static PresenterTheme::SharedFontDescriptor ReadFont ( - const Reference<beans::XPropertySet>& rxFontProperties, - const PresenterTheme::SharedFontDescriptor& rpDefault); - - std::shared_ptr<PresenterTheme::Theme> ReadTheme ( - PresenterConfigurationAccess& rConfiguration, - const OUString& rsThemeName); - - static BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode); - -private: - static Any GetByName ( - const Reference<container::XNameAccess>& rxNode, - const OUString& rsName); -}; - -/** A PaneStyle describes how a pane is rendered. -*/ -class PaneStyle -{ -public: - PaneStyle(); - - SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; - - OUString msStyleName; - std::shared_ptr<PaneStyle> mpParentStyle; - PresenterTheme::SharedFontDescriptor mpFont; - BorderSize maInnerBorderSize; - BorderSize maOuterBorderSize; - std::shared_ptr<PresenterBitmapContainer> mpBitmaps; - - PresenterTheme::SharedFontDescriptor GetFont() const; -}; - -typedef std::shared_ptr<PaneStyle> SharedPaneStyle; - -class PaneStyleContainer -{ -private: - ::std::vector<SharedPaneStyle> mStyles; - -public: - void Read ( - const ReadContext& rReadContext, - const Reference<container::XHierarchicalNameAccess>& rThemeRoot); - - SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; - -private: - void ProcessPaneStyle ( - ReadContext const & rReadContext, - const ::std::vector<css::uno::Any>& rValues); -}; - -/** A ViewStyle describes how a view is displayed. -*/ -class ViewStyle -{ -public: - ViewStyle(); - - SharedBitmapDescriptor GetBitmap (std::u16string_view sBitmapName) const; - - PresenterTheme::SharedFontDescriptor GetFont() const; - - OUString msStyleName; - std::shared_ptr<ViewStyle> mpParentStyle; - PresenterTheme::SharedFontDescriptor mpFont; - SharedBitmapDescriptor mpBackground; -}; - -typedef std::shared_ptr<ViewStyle> SharedViewStyle; - -class ViewStyleContainer -{ -private: - ::std::vector<SharedViewStyle> mStyles; - -public: - void Read ( - const ReadContext& rReadContext, - const Reference<container::XHierarchicalNameAccess>& rThemeRoot); - - SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; - -private: - void ProcessViewStyle( - ReadContext const & rReadContext, - const Reference<beans::XPropertySet>& rxProperties); -}; - -class StyleAssociationContainer -{ -public: - void Read ( - const Reference<container::XHierarchicalNameAccess>& rThemeRoot); - - OUString GetStyleName (const OUString& rsResourceName) const; - -private: - typedef map<OUString, OUString> StyleAssociations; - StyleAssociations maStyleAssociations; - - void ProcessStyleAssociation( - const ::std::vector<css::uno::Any>& rValues); -}; - -} // end of anonymous namespace - -class PresenterTheme::Theme -{ -public: - Theme ( - const Reference<container::XHierarchicalNameAccess>& rThemeRoot, - const OUString& rsNodeName); - - void Read ( - PresenterConfigurationAccess& rConfiguration, - ReadContext& rReadContext); - - OUString msConfigurationNodeName; - std::shared_ptr<Theme> mpParentTheme; - SharedBitmapDescriptor mpBackground; - PaneStyleContainer maPaneStyles; - ViewStyleContainer maViewStyles; - StyleAssociationContainer maStyleAssociations; - Reference<container::XHierarchicalNameAccess> mxThemeRoot; - std::shared_ptr<PresenterBitmapContainer> mpIconContainer; - typedef map<OUString,SharedFontDescriptor> FontContainer; - FontContainer maFontContainer; - - SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; - SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; - -private: - void ProcessFont( - const OUString& rsKey, - const Reference<beans::XPropertySet>& rxProperties); -}; - -//===== PresenterTheme ======================================================== - -PresenterTheme::PresenterTheme ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas) - : mxContext(rxContext), - mpTheme(), - mxCanvas(rxCanvas) -{ - mpTheme = ReadTheme(); -} - -PresenterTheme::~PresenterTheme() -{ -} - -std::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme() -{ - ReadContext aReadContext(mxContext, mxCanvas); - - PresenterConfigurationAccess aConfiguration ( - mxContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - - return aReadContext.ReadTheme(aConfiguration, OUString()); -} - -bool PresenterTheme::HasCanvas() const -{ - return mxCanvas.is(); -} - -void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas) -{ - if ( ! mxCanvas.is() && rxCanvas.is()) - { - mxCanvas = rxCanvas; - ReadTheme(); - } -} - -OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const -{ - OUString sStyleName; - std::shared_ptr<Theme> pTheme (mpTheme); - while (sStyleName.isEmpty() && pTheme != nullptr) - { - sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL); - pTheme = pTheme->mpParentTheme; - } - return sStyleName; -} - -::std::vector<sal_Int32> PresenterTheme::GetBorderSize ( - const OUString& rsStyleName, - const bool bOuter) const -{ - OSL_ASSERT(mpTheme != nullptr); - - SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); - if (pPaneStyle) - if (bOuter) - return pPaneStyle->maOuterBorderSize.ToVector(); - else - return pPaneStyle->maInnerBorderSize.ToVector(); - else - { - return ::std::vector<sal_Int32>(4,0); - } -} - -PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont ( - const Reference<container::XHierarchicalNameAccess>& rxNode, - const PresenterTheme::SharedFontDescriptor& rpDefault) -{ - return ReadContext::ReadFont(rxNode, rpDefault); -} - -bool PresenterTheme::ConvertToColor ( - const Any& rColorSequence, - sal_uInt32& rColor) -{ - Sequence<sal_Int8> aByteSequence; - if (rColorSequence >>= aByteSequence) - { - rColor = std::accumulate(aByteSequence.begin(), aByteSequence.end(), sal_uInt32(0), - [](const sal_uInt32 nRes, const sal_uInt8 nByte) { return (nRes << 8) | nByte; }); - return true; - } - else - return false; -} - -std::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle ( - const OUString& rsStyleName) const -{ - if (mpTheme == nullptr) - return std::shared_ptr<PresenterConfigurationAccess>(); - - // Open configuration for writing. - auto pConfiguration = std::make_shared<PresenterConfigurationAccess>( - mxContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_WRITE); - - // Get configuration node for the view style container of the current - // theme. - if (pConfiguration->GoToChild( OUString( - "Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles"))) - { - pConfiguration->GoToChild( - [&rsStyleName] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps) - { - return PresenterConfigurationAccess::IsStringPropertyEqual( - rsStyleName, "StyleName", xProps); - }); - } - return pConfiguration; -} - -SharedBitmapDescriptor PresenterTheme::GetBitmap ( - const OUString& rsStyleName, - const OUString& rsBitmapName) const -{ - if (mpTheme != nullptr) - { - if (rsStyleName.isEmpty()) - { - if (rsBitmapName == "Background") - { - std::shared_ptr<Theme> pTheme (mpTheme); - while (pTheme != nullptr && !pTheme->mpBackground) - pTheme = pTheme->mpParentTheme; - if (pTheme != nullptr) - return pTheme->mpBackground; - else - return SharedBitmapDescriptor(); - } - } - else - { - SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); - if (pPaneStyle) - { - SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName)); - if (pBitmap) - return pBitmap; - } - - SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); - if (pViewStyle) - { - SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName)); - if (pBitmap) - return pBitmap; - } - } - } - - return SharedBitmapDescriptor(); -} - -SharedBitmapDescriptor PresenterTheme::GetBitmap ( - const OUString& rsBitmapName) const -{ - if (mpTheme != nullptr) - { - if (rsBitmapName == "Background") - { - std::shared_ptr<Theme> pTheme (mpTheme); - while (pTheme != nullptr && !pTheme->mpBackground) - pTheme = pTheme->mpParentTheme; - if (pTheme != nullptr) - return pTheme->mpBackground; - else - return SharedBitmapDescriptor(); - } - else - { - if (mpTheme->mpIconContainer != nullptr) - return mpTheme->mpIconContainer->GetBitmap(rsBitmapName); - } - } - - return SharedBitmapDescriptor(); -} - -std::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer() const -{ - if (mpTheme != nullptr) - return mpTheme->mpIconContainer; - else - return std::shared_ptr<PresenterBitmapContainer>(); -} - -PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont ( - const OUString& rsStyleName) const -{ - if (mpTheme != nullptr) - { - SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); - if (pPaneStyle) - return pPaneStyle->GetFont(); - - SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); - if (pViewStyle) - return pViewStyle->GetFont(); - - std::shared_ptr<Theme> pTheme (mpTheme); - while (pTheme != nullptr) - { - Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName)); - if (iFont != pTheme->maFontContainer.end()) - return iFont->second; - - pTheme = pTheme->mpParentTheme; - } - } - - return SharedFontDescriptor(); -} - -//===== FontDescriptor ======================================================== - -PresenterTheme::FontDescriptor::FontDescriptor ( - const std::shared_ptr<FontDescriptor>& rpDescriptor) - : msFamilyName(), - msStyleName(), - mnSize(12), - mnColor(0x00000000), - msAnchor(OUString("Left")), - mnXOffset(0), - mnYOffset(0) -{ - if (rpDescriptor != nullptr) - { - msFamilyName = rpDescriptor->msFamilyName; - msStyleName = rpDescriptor->msStyleName; - mnSize = rpDescriptor->mnSize; - mnColor = rpDescriptor->mnColor; - msAnchor = rpDescriptor->msAnchor; - mnXOffset = rpDescriptor->mnXOffset; - mnYOffset = rpDescriptor->mnYOffset; - } -} - -bool PresenterTheme::FontDescriptor::PrepareFont ( - const Reference<rendering::XCanvas>& rxCanvas) -{ - if (mxFont.is()) - return true; - - if ( ! rxCanvas.is()) - return false; - - const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize)); - mxFont = CreateFont(rxCanvas, nCellSize); - - return mxFont.is(); -} - -Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont ( - const Reference<rendering::XCanvas>& rxCanvas, - const double nCellSize) const -{ - rendering::FontRequest aFontRequest; - aFontRequest.FontDescription.FamilyName = msFamilyName; - if (msFamilyName.isEmpty()) - aFontRequest.FontDescription.FamilyName = "Tahoma"; - aFontRequest.FontDescription.StyleName = msStyleName; - aFontRequest.CellSize = nCellSize; - - // Make an attempt at translating the style name(s)into a corresponding - // font description. - if (msStyleName == "Bold") - aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY; - - return rxCanvas->createFont( - aFontRequest, - Sequence<beans::PropertyValue>(), - geometry::Matrix2D(1,0,0,1)); -} - -double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize ( - const Reference<rendering::XCanvas>& rxCanvas, - const double nDesignSize) const -{ - // Use the given design size as initial value in calculating the cell - // size. - double nCellSize (nDesignSize); - - if ( ! rxCanvas.is()) - { - // We need the canvas to do the conversion. Return the design size, - // it is the our best guess in this circumstance. - return nDesignSize; - } - - Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize)); - if ( ! xFont.is()) - return nDesignSize; - - geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X")); - - const double nAscent (-aBox.Y1); - //tdf#112408 - if (nAscent == 0) - return nDesignSize; - const double nDescent (aBox.Y2); - const double nScale = (nAscent+nDescent) / nAscent; - return nDesignSize * nScale; -} - -//===== Theme ================================================================= - -PresenterTheme::Theme::Theme ( - const Reference<container::XHierarchicalNameAccess>& rxThemeRoot, - const OUString& rsNodeName) - : msConfigurationNodeName(rsNodeName), - mpParentTheme(), - maPaneStyles(), - maViewStyles(), - maStyleAssociations(), - mxThemeRoot(rxThemeRoot), - mpIconContainer() -{ -} - -void PresenterTheme::Theme::Read ( - PresenterConfigurationAccess& rConfiguration, - ReadContext& rReadContext) -{ - // Parent theme name. - OUString sParentThemeName; - if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme") - >>= sParentThemeName) - && !sParentThemeName.isEmpty()) - { - mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName); - } - - // Background. - mpBackground = PresenterBitmapContainer::LoadBitmap( - mxThemeRoot, - "Background", - rReadContext.mxPresenterHelper, - rReadContext.mxCanvas, - SharedBitmapDescriptor()); - - // Style associations. - maStyleAssociations.Read(mxThemeRoot); - - // Pane styles. - maPaneStyles.Read(rReadContext, mxThemeRoot); - - // View styles. - maViewStyles.Read(rReadContext, mxThemeRoot); - - // Read bitmaps. - mpIconContainer = std::make_shared<PresenterBitmapContainer>( - Reference<container::XNameAccess>( - PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY), - mpParentTheme != nullptr ? mpParentTheme->mpIconContainer - : std::shared_ptr<PresenterBitmapContainer>(), - rReadContext.mxComponentContext, rReadContext.mxCanvas); - - // Read fonts. - Reference<container::XNameAccess> xFontNode( - PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Fonts"), - UNO_QUERY); - PresenterConfigurationAccess::ForAll( - xFontNode, - [this] (OUString const& rKey, uno::Reference<beans::XPropertySet> const& xProps) - { - return this->ProcessFont(rKey, xProps); - }); -} - -SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const -{ - SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName)); - if (pPaneStyle) - return pPaneStyle; - else if (mpParentTheme != nullptr) - return mpParentTheme->GetPaneStyle(rsStyleName); - else - return SharedPaneStyle(); -} - -SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const -{ - SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName)); - if (pViewStyle) - return pViewStyle; - else if (mpParentTheme != nullptr) - return mpParentTheme->GetViewStyle(rsStyleName); - else - return SharedViewStyle(); -} - -void PresenterTheme::Theme::ProcessFont( - const OUString& rsKey, - const Reference<beans::XPropertySet>& rxProperties) -{ - maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor()); -} - -namespace { - -//===== ReadContext =========================================================== - -ReadContext::ReadContext ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const Reference<rendering::XCanvas>& rxCanvas) - : mxComponentContext(rxContext), - mxCanvas(rxCanvas), - mxPresenterHelper() -{ - Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager()); - if (xFactory.is()) - { - mxPresenterHelper.set( - xFactory->createInstanceWithContext( - "com.sun.star.comp.Draw.PresenterHelper", - rxContext), - UNO_QUERY_THROW); - } -} - -PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( - const Reference<container::XHierarchicalNameAccess>& rxNode, - const PresenterTheme::SharedFontDescriptor& rpDefault) -{ - if ( ! rxNode.is()) - return PresenterTheme::SharedFontDescriptor(); - - try - { - Reference<container::XHierarchicalNameAccess> xFont ( - PresenterConfigurationAccess::GetConfigurationNode( - rxNode, - /*rsFontPath*/""), - UNO_QUERY_THROW); - - Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW); - return ReadFont(xProperties, rpDefault); - } - catch (Exception&) - { - OSL_ASSERT(false); - } - - return PresenterTheme::SharedFontDescriptor(); -} - -PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( - const Reference<beans::XPropertySet>& rxProperties, - const PresenterTheme::SharedFontDescriptor& rpDefault) -{ - auto pDescriptor = std::make_shared<PresenterTheme::FontDescriptor>(rpDefault); - - PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName; - PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName; - PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize; - PresenterTheme::ConvertToColor( - PresenterConfigurationAccess::GetProperty(rxProperties, "Color"), - pDescriptor->mnColor); - PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor; - PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset; - PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset; - - return pDescriptor; -} - -Any ReadContext::GetByName ( - const Reference<container::XNameAccess>& rxNode, - const OUString& rsName) -{ - OSL_ASSERT(rxNode.is()); - if (rxNode->hasByName(rsName)) - return rxNode->getByName(rsName); - else - return Any(); -} - -std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme ( - PresenterConfigurationAccess& rConfiguration, - const OUString& rsThemeName) -{ - std::shared_ptr<PresenterTheme::Theme> pTheme; - - OUString sCurrentThemeName (rsThemeName); - if (sCurrentThemeName.isEmpty()) - { - // No theme name given. Look up the CurrentTheme property. - rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName; - if (sCurrentThemeName.isEmpty()) - { - // Still no name. Use "DefaultTheme". - sCurrentThemeName = "DefaultTheme"; - } - } - - Reference<container::XNameAccess> xThemes ( - rConfiguration.GetConfigurationNode("Presenter/Themes"), - UNO_QUERY); - if (xThemes.is()) - { - // Iterate over all themes and search the one with the given name. - const Sequence<OUString> aKeys (xThemes->getElementNames()); - for (const OUString& rsKey : aKeys) - { - Reference<container::XHierarchicalNameAccess> xTheme ( - xThemes->getByName(rsKey), UNO_QUERY); - if (xTheme.is()) - { - OUString sThemeName; - PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName") - >>= sThemeName; - if (sThemeName == sCurrentThemeName) - { - pTheme = std::make_shared<PresenterTheme::Theme>(xTheme,rsKey); - break; - } - } - } - } - - if (pTheme != nullptr) - { - pTheme->Read(rConfiguration, *this); - } - - return pTheme; -} - -BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode) -{ - BorderSize aBorderSize; - - if (rxNode.is()) - { - GetByName(rxNode, "Left") >>= aBorderSize.mnLeft; - GetByName(rxNode, "Top") >>= aBorderSize.mnTop; - GetByName(rxNode, "Right") >>= aBorderSize.mnRight; - GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom; - } - - return aBorderSize; -} - -//===== PaneStyleContainer ==================================================== - -void PaneStyleContainer::Read ( - const ReadContext& rReadContext, - const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) -{ - Reference<container::XNameAccess> xPaneStyleList ( - PresenterConfigurationAccess::GetConfigurationNode( - rxThemeRoot, - "PaneStyles"), - UNO_QUERY); - if (!xPaneStyleList.is()) - return; - - ::std::vector<OUString> aProperties; - aProperties.reserve(6); - aProperties.emplace_back("StyleName"); - aProperties.emplace_back("ParentStyle"); - aProperties.emplace_back("TitleFont"); - aProperties.emplace_back("InnerBorderSize"); - aProperties.emplace_back("OuterBorderSize"); - aProperties.emplace_back("BorderBitmapList"); - PresenterConfigurationAccess::ForAll( - xPaneStyleList, - aProperties, - [this, &rReadContext] (std::vector<uno::Any> const& rValues) - { - return this->ProcessPaneStyle(rReadContext, rValues); - }); -} - -void PaneStyleContainer::ProcessPaneStyle( - ReadContext const & rReadContext, - const ::std::vector<Any>& rValues) -{ - if (rValues.size() != 6) - return; - - auto pStyle = std::make_shared<PaneStyle>(); - - rValues[0] >>= pStyle->msStyleName; - - OUString sParentStyleName; - if (rValues[1] >>= sParentStyleName) - { - // Find parent style. - auto iStyle = std::find_if(mStyles.begin(), mStyles.end(), - [&sParentStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; }); - if (iStyle != mStyles.end()) - pStyle->mpParentStyle = *iStyle; - } - - Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY); - pStyle->mpFont = ReadContext::ReadFont( - xFontNode, PresenterTheme::SharedFontDescriptor()); - - Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY); - pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode); - Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY); - pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode); - - if (pStyle->mpParentStyle != nullptr) - { - pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize); - pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize); - } - - if (rReadContext.mxCanvas.is()) - { - Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY); - pStyle->mpBitmaps = std::make_shared<PresenterBitmapContainer>( - xBitmapsNode, - pStyle->mpParentStyle != nullptr ? pStyle->mpParentStyle->mpBitmaps - : std::shared_ptr<PresenterBitmapContainer>(), - rReadContext.mxComponentContext, rReadContext.mxCanvas, - rReadContext.mxPresenterHelper); - } - - mStyles.push_back(pStyle); -} - -SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const -{ - auto iStyle = std::find_if(mStyles.begin(), mStyles.end(), - [&rsStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; }); - if (iStyle != mStyles.end()) - return *iStyle; - return SharedPaneStyle(); -} - -//===== PaneStyle ============================================================= - -PaneStyle::PaneStyle() - : msStyleName(), - mpParentStyle(), - mpFont(), - maInnerBorderSize(), - maOuterBorderSize(), - mpBitmaps() -{ -} - -SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const -{ - if (mpBitmaps != nullptr) - { - SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName); - if (pBitmap) - return pBitmap; - } - - if (mpParentStyle != nullptr) - return mpParentStyle->GetBitmap(rsBitmapName); - else - return SharedBitmapDescriptor(); -} - -PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const -{ - if (mpFont) - return mpFont; - else if (mpParentStyle != nullptr) - return mpParentStyle->GetFont(); - else - return PresenterTheme::SharedFontDescriptor(); -} - -//===== ViewStyleContainer ==================================================== - -void ViewStyleContainer::Read ( - const ReadContext& rReadContext, - const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) -{ - Reference<container::XNameAccess> xViewStyleList ( - PresenterConfigurationAccess::GetConfigurationNode( - rxThemeRoot, - "ViewStyles"), - UNO_QUERY); - if (xViewStyleList.is()) - { - PresenterConfigurationAccess::ForAll( - xViewStyleList, - [this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps) - { - return this->ProcessViewStyle(rReadContext, xProps); - }); - } -} - -void ViewStyleContainer::ProcessViewStyle( - ReadContext const & rReadContext, - const Reference<beans::XPropertySet>& rxProperties) -{ - auto pStyle = std::make_shared<ViewStyle>(); - - PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName") - >>= pStyle->msStyleName; - - OUString sParentStyleName; - if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle") - >>= sParentStyleName) - { - // Find parent style. - auto iStyle = std::find_if(mStyles.begin(), mStyles.end(), - [&sParentStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; }); - if (iStyle != mStyles.end()) - { - pStyle->mpParentStyle = *iStyle; - pStyle->mpFont = (*iStyle)->mpFont; - pStyle->mpBackground = (*iStyle)->mpBackground; - } - } - - Reference<container::XHierarchicalNameAccess> xFontNode ( - PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY); - PresenterTheme::SharedFontDescriptor pFont ( - ReadContext::ReadFont(xFontNode, PresenterTheme::SharedFontDescriptor())); - if (pFont) - pStyle->mpFont = pFont; - - Reference<container::XHierarchicalNameAccess> xBackgroundNode ( - PresenterConfigurationAccess::GetProperty(rxProperties, "Background"), - UNO_QUERY); - SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap( - xBackgroundNode, - OUString(), - rReadContext.mxPresenterHelper, - rReadContext.mxCanvas, - SharedBitmapDescriptor())); - if (pBackground && pBackground->GetNormalBitmap().is()) - pStyle->mpBackground = pBackground; - - mStyles.push_back(pStyle); -} - -SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const -{ - auto iStyle = std::find_if(mStyles.begin(), mStyles.end(), - [&rsStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; }); - if (iStyle != mStyles.end()) - return *iStyle; - return SharedViewStyle(); -} - -//===== ViewStyle ============================================================= - -ViewStyle::ViewStyle() - : msStyleName(), - mpParentStyle(), - mpFont(), - mpBackground() -{ -} - -SharedBitmapDescriptor ViewStyle::GetBitmap (std::u16string_view rsBitmapName) const -{ - if (rsBitmapName == u"Background") - return mpBackground; - else - return SharedBitmapDescriptor(); -} - -PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const -{ - if (mpFont) - return mpFont; - else if (mpParentStyle != nullptr) - return mpParentStyle->GetFont(); - else - return PresenterTheme::SharedFontDescriptor(); -} - -//===== StyleAssociationContainer ============================================= - -void StyleAssociationContainer::Read ( - const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) -{ - Reference<container::XNameAccess> xStyleAssociationList ( - PresenterConfigurationAccess::GetConfigurationNode( - rxThemeRoot, - "StyleAssociations"), - UNO_QUERY); - if (!xStyleAssociationList.is()) - return; - - ::std::vector<OUString> aProperties { "ResourceURL", "StyleName" }; - PresenterConfigurationAccess::ForAll( - xStyleAssociationList, - aProperties, - [this] (std::vector<uno::Any> const& rValues) - { - return this->ProcessStyleAssociation(rValues); - }); -} - -OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const -{ - StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName)); - if (iAssociation != maStyleAssociations.end()) - return iAssociation->second; - else - return OUString(); -} - -void StyleAssociationContainer::ProcessStyleAssociation( - const ::std::vector<Any>& rValues) -{ - if (rValues.size() != 2) - return; - - OUString sResourceURL; - OUString sStyleName; - if ((rValues[0] >>= sResourceURL) - && (rValues[1] >>= sStyleName)) - { - maStyleAssociations[sResourceURL] = sStyleName; - } -} - -} // end of anonymous namespace - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterTheme.hxx b/sdext/source/presenter/PresenterTheme.hxx deleted file mode 100644 index 97fff4842d4f..000000000000 --- a/sdext/source/presenter/PresenterTheme.hxx +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTHEME_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTHEME_HXX - -#include "PresenterBitmapContainer.hxx" -#include "PresenterConfigurationAccess.hxx" -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/rendering/XCanvasFont.hpp> -#include <memory> - -namespace sdext::presenter { - -/** A theme is a set of properties describing fonts, colors, and bitmaps to be used to draw - background, pane borders, and view content. - - At the moment the properties can be accessed via the getPropertyValue() method. - - For a resource URL of a pane or a view you get the name of the - associated PaneStyle or ViewStyle. - - For the name of pane or view style suffixed with and underscore and the - name of configuration property, and maybe additionally suffixed by - another underscore and sub property name you get the associated - property. - - Example: you want to access the top left bitmap of a pane border - (simplified code): - - OUString sStyleName = getPropertyValue("private:resource/pane/Presenter/Pane1"); - XBitmap xBitmap = getPropertyValue(sStyleName + "_TopLeftBitmap"); - - For the offset of the bitmap you can call - Point aOffset = getPropertyValue(sStyleName + "_TopLeftOffset"); - - This is work in progress. -*/ -class PresenterTheme -{ -public: - PresenterTheme ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - ~PresenterTheme(); - - bool HasCanvas() const; - void ProvideCanvas (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - - OUString GetStyleName (const OUString& rsResourceURL) const; - ::std::vector<sal_Int32> GetBorderSize ( - const OUString& rsStyleName, - const bool bOuter) const; - - class Theme; - class FontDescriptor - { - public: - explicit FontDescriptor (const std::shared_ptr<FontDescriptor>& rpDescriptor); - - OUString msFamilyName; - OUString msStyleName; - sal_Int32 mnSize; - sal_uInt32 mnColor; - OUString msAnchor; - sal_Int32 mnXOffset; - sal_Int32 mnYOffset; - css::uno::Reference<css::rendering::XCanvasFont> mxFont; - - bool PrepareFont (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - - private: - css::uno::Reference<css::rendering::XCanvasFont> CreateFont ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const double nCellSize) const; - double GetCellSizeForDesignSize ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const double nDesignSize) const; - }; - typedef std::shared_ptr<FontDescriptor> SharedFontDescriptor; - - SharedBitmapDescriptor GetBitmap ( - const OUString& rsStyleName, - const OUString& rsBitmapName) const; - - SharedBitmapDescriptor GetBitmap ( - const OUString& rsBitmapName) const; - - std::shared_ptr<PresenterBitmapContainer> GetBitmapContainer() const; - - SharedFontDescriptor GetFont ( - const OUString& rsStyleName) const; - - static SharedFontDescriptor ReadFont ( - const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode, - const SharedFontDescriptor& rDefaultFount); - - static bool ConvertToColor ( - const css::uno::Any& rColorSequence, - sal_uInt32& rColor); - - std::shared_ptr<PresenterConfigurationAccess> GetNodeForViewStyle ( - const OUString& rsStyleName) const; - -private: - css::uno::Reference<css::uno::XComponentContext> mxContext; - std::shared_ptr<Theme> mpTheme; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - - std::shared_ptr<Theme> ReadTheme(); -}; - -} // end of namespace ::sd::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterTimer.cxx b/sdext/source/presenter/PresenterTimer.cxx deleted file mode 100644 index f46fcd288ee0..000000000000 --- a/sdext/source/presenter/PresenterTimer.cxx +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterTimer.hxx" - -#include <com/sun/star/lang/XMultiComponentFactory.hpp> -#include <com/sun/star/frame/Desktop.hpp> -#include <com/sun/star/frame/XTerminateListener.hpp> - -#include <osl/thread.hxx> -#include <osl/conditn.hxx> - -#include <algorithm> -#include <memory> -#include <mutex> -#include <set> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -namespace { -class TimerTask -{ -public: - TimerTask ( - const PresenterTimer::Task& rTask, - const TimeValue& rDueTime, - const sal_Int64 nRepeatInterval, - const sal_Int32 nTaskId); - - PresenterTimer::Task maTask; - TimeValue maDueTime; - const sal_Int64 mnRepeatInterval; - const sal_Int32 mnTaskId; - bool mbIsCanceled; -}; - -typedef std::shared_ptr<TimerTask> SharedTimerTask; - -class TimerTaskComparator -{ -public: - bool operator() (const SharedTimerTask& rpTask1, const SharedTimerTask& rpTask2) const - { - return rpTask1->maDueTime.Seconds < rpTask2->maDueTime.Seconds - || (rpTask1->maDueTime.Seconds == rpTask2->maDueTime.Seconds - && rpTask1->maDueTime.Nanosec < rpTask2->maDueTime.Nanosec); - } -}; - -/** Queue all scheduled tasks and process them when their time has come. -*/ -class TimerScheduler - : public std::enable_shared_from_this<TimerScheduler>, - public ::osl::Thread -{ -public: - static std::shared_ptr<TimerScheduler> Instance( - uno::Reference<uno::XComponentContext> const& xContext); - static SharedTimerTask CreateTimerTask ( - const PresenterTimer::Task& rTask, - const TimeValue& rDueTime, - const sal_Int64 nRepeatInterval); - - void ScheduleTask (const SharedTimerTask& rpTask); - void CancelTask (const sal_Int32 nTaskId); - - static bool GetCurrentTime (TimeValue& rCurrentTime); - static sal_Int64 GetTimeDifference ( - const TimeValue& rTargetTime, - const TimeValue& rCurrentTime); - static void ConvertToTimeValue ( - TimeValue& rTimeValue, - const sal_Int64 nTimeDifference); - static sal_Int64 ConvertFromTimeValue ( - const TimeValue& rTimeValue); - - static void NotifyTermination(); -#if !defined NDEBUG - static bool HasInstance() { return mpInstance != nullptr; } -#endif - -private: - static std::shared_ptr<TimerScheduler> mpInstance; - static std::mutex maInstanceMutex; - std::shared_ptr<TimerScheduler> mpLateDestroy; // for clean exit - static sal_Int32 mnTaskId; - - std::mutex maTaskContainerMutex; - typedef ::std::set<SharedTimerTask,TimerTaskComparator> TaskContainer; - TaskContainer maScheduledTasks; - std::mutex maCurrentTaskMutex; - SharedTimerTask mpCurrentTask; - ::osl::Condition m_Shutdown; - - TimerScheduler( - uno::Reference<uno::XComponentContext> const& xContext); -public: - virtual void SAL_CALL run() override; - virtual void SAL_CALL onTerminated() override { mpLateDestroy.reset(); } -}; - -class TerminateListener - : public ::cppu::WeakImplHelper<frame::XTerminateListener> -{ - virtual ~TerminateListener() override - { - assert(!TimerScheduler::HasInstance()); - } - - virtual void SAL_CALL disposing(lang::EventObject const&) override - { - } - - virtual void SAL_CALL queryTermination(lang::EventObject const&) override - { - } - - virtual void SAL_CALL notifyTermination(lang::EventObject const&) override - { - TimerScheduler::NotifyTermination(); - } -}; - -} // end of anonymous namespace - -//===== PresenterTimer ======================================================== - -sal_Int32 PresenterTimer::ScheduleRepeatedTask ( - const uno::Reference<uno::XComponentContext>& xContext, - const Task& rTask, - const sal_Int64 nDelay, - const sal_Int64 nInterval) -{ - assert(xContext.is()); - TimeValue aCurrentTime; - if (TimerScheduler::GetCurrentTime(aCurrentTime)) - { - TimeValue aDueTime; - TimerScheduler::ConvertToTimeValue( - aDueTime, - TimerScheduler::ConvertFromTimeValue (aCurrentTime) + nDelay); - SharedTimerTask pTask (TimerScheduler::CreateTimerTask(rTask, aDueTime, nInterval)); - TimerScheduler::Instance(xContext)->ScheduleTask(pTask); - return pTask->mnTaskId; - } - - return NotAValidTaskId; -} - -void PresenterTimer::CancelTask (const sal_Int32 nTaskId) -{ - auto const pInstance(TimerScheduler::Instance(nullptr)); - if (pInstance) - { - pInstance->CancelTask(nTaskId); - } -} - -//===== TimerScheduler ======================================================== - -std::shared_ptr<TimerScheduler> TimerScheduler::mpInstance; -std::mutex TimerScheduler::maInstanceMutex; -sal_Int32 TimerScheduler::mnTaskId = PresenterTimer::NotAValidTaskId; - -std::shared_ptr<TimerScheduler> TimerScheduler::Instance( - uno::Reference<uno::XComponentContext> const& xContext) -{ - std::lock_guard aGuard (maInstanceMutex); - if (mpInstance == nullptr) - { - if (!xContext.is()) - return nullptr; - mpInstance.reset(new TimerScheduler(xContext)); - mpInstance->create(); - } - return mpInstance; -} - -TimerScheduler::TimerScheduler( - uno::Reference<uno::XComponentContext> const& xContext) - : maTaskContainerMutex(), - maScheduledTasks(), - maCurrentTaskMutex(), - mpCurrentTask() -{ - uno::Reference<frame::XDesktop> const xDesktop( - frame::Desktop::create(xContext)); - uno::Reference<frame::XTerminateListener> const xListener( - new TerminateListener); - // assuming the desktop can take ownership - xDesktop->addTerminateListener(xListener); -} - -SharedTimerTask TimerScheduler::CreateTimerTask ( - const PresenterTimer::Task& rTask, - const TimeValue& rDueTime, - const sal_Int64 nRepeatInterval) -{ - return std::make_shared<TimerTask>(rTask, rDueTime, nRepeatInterval, ++mnTaskId); -} - -void TimerScheduler::ScheduleTask (const SharedTimerTask& rpTask) -{ - if (!rpTask) - return; - if (rpTask->mbIsCanceled) - return; - - { - std::lock_guard aTaskGuard (maTaskContainerMutex); - maScheduledTasks.insert(rpTask); - } -} - -void TimerScheduler::CancelTask (const sal_Int32 nTaskId) -{ - // Set of scheduled tasks is sorted after their due times, not their - // task ids. Therefore we have to do a linear search for the task to - // cancel. - { - std::lock_guard aGuard (maTaskContainerMutex); - auto iTask = std::find_if(maScheduledTasks.begin(), maScheduledTasks.end(), - [nTaskId](const SharedTimerTask& rxTask) { return rxTask->mnTaskId == nTaskId; }); - if (iTask != maScheduledTasks.end()) - maScheduledTasks.erase(iTask); - } - - // The task that is to be canceled may be currently about to be - // processed. Mark it with a flag that a) prevents a repeating task - // from being scheduled again and b) tries to prevent its execution. - { - std::lock_guard aGuard (maCurrentTaskMutex); - if (mpCurrentTask - && mpCurrentTask->mnTaskId == nTaskId) - mpCurrentTask->mbIsCanceled = true; - } - - // Let the main-loop cleanup in its own time -} - -void TimerScheduler::NotifyTermination() -{ - std::shared_ptr<TimerScheduler> const pInstance(TimerScheduler::mpInstance); - if (!pInstance) - { - return; - } - - { - std::lock_guard aGuard(pInstance->maTaskContainerMutex); - pInstance->maScheduledTasks.clear(); - } - - { - std::lock_guard aGuard(pInstance->maCurrentTaskMutex); - if (pInstance->mpCurrentTask) - { - pInstance->mpCurrentTask->mbIsCanceled = true; - } - } - - pInstance->m_Shutdown.set(); - - // rhbz#1425304 join thread before shutdown - pInstance->join(); -} - -void SAL_CALL TimerScheduler::run() -{ - osl_setThreadName("sdext::presenter::TimerScheduler"); - - while (true) - { - // Get the current time. - TimeValue aCurrentTime; - if ( ! GetCurrentTime(aCurrentTime)) - { - // We can not get the current time and thus can not schedule anything. - break; - } - - // Restrict access to the maScheduledTasks member to one, mutex - // guarded, block. - SharedTimerTask pTask; - sal_Int64 nDifference = 0; - { - std::lock_guard aGuard (maTaskContainerMutex); - - // There are no more scheduled task. Leave this loop, function and - // live of the TimerScheduler. - if (maScheduledTasks.empty()) - break; - - nDifference = GetTimeDifference( - (*maScheduledTasks.begin())->maDueTime, - aCurrentTime); - if (nDifference <= 0) - { - pTask = *maScheduledTasks.begin(); - maScheduledTasks.erase(maScheduledTasks.begin()); - } - } - - // Acquire a reference to the current task. - { - std::lock_guard aGuard (maCurrentTaskMutex); - mpCurrentTask = pTask; - } - - if (!pTask) - { - // Wait until the first task becomes due. - TimeValue aTimeValue; - ConvertToTimeValue(aTimeValue, nDifference); - // wait on condition variable, so the thread can be stopped - m_Shutdown.wait(&aTimeValue); - } - else - { - // Execute task. - if (pTask->maTask && !pTask->mbIsCanceled) - { - pTask->maTask(aCurrentTime); - - // Re-schedule repeating tasks. - if (pTask->mnRepeatInterval > 0) - { - ConvertToTimeValue( - pTask->maDueTime, - ConvertFromTimeValue(pTask->maDueTime) - + pTask->mnRepeatInterval); - ScheduleTask(pTask); - } - } - - } - - // Release reference to the current task. - { - std::lock_guard aGuard (maCurrentTaskMutex); - mpCurrentTask.reset(); - } - } - - // While holding maInstanceMutex - std::lock_guard aInstance( maInstanceMutex ); - mpLateDestroy = mpInstance; - mpInstance.reset(); -} - -bool TimerScheduler::GetCurrentTime (TimeValue& rCurrentTime) -{ - TimeValue aSystemTime; - if (osl_getSystemTime(&aSystemTime)) - return osl_getLocalTimeFromSystemTime(&aSystemTime, &rCurrentTime); - return false; -} - -sal_Int64 TimerScheduler::GetTimeDifference ( - const TimeValue& rTargetTime, - const TimeValue& rCurrentTime) -{ - return ConvertFromTimeValue(rTargetTime) - ConvertFromTimeValue(rCurrentTime); -} - -void TimerScheduler::ConvertToTimeValue ( - TimeValue& rTimeValue, - const sal_Int64 nTimeDifference) -{ - rTimeValue.Seconds = sal::static_int_cast<sal_Int32>(nTimeDifference / 1000000000L); - rTimeValue.Nanosec = sal::static_int_cast<sal_Int32>(nTimeDifference % 1000000000L); -} - -sal_Int64 TimerScheduler::ConvertFromTimeValue ( - const TimeValue& rTimeValue) -{ - return sal_Int64(rTimeValue.Seconds) * 1000000000L + rTimeValue.Nanosec; -} - -//===== TimerTask ============================================================= - -namespace { - -TimerTask::TimerTask ( - const PresenterTimer::Task& rTask, - const TimeValue& rDueTime, - const sal_Int64 nRepeatInterval, - const sal_Int32 nTaskId) - : maTask(rTask), - maDueTime(rDueTime), - mnRepeatInterval(nRepeatInterval), - mnTaskId(nTaskId), - mbIsCanceled(false) -{ -} - -} // end of anonymous namespace - -//===== PresenterTimer ======================================================== - -::rtl::Reference<PresenterClockTimer> PresenterClockTimer::mpInstance; - -::rtl::Reference<PresenterClockTimer> PresenterClockTimer::Instance ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext) -{ - ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex()); - - ::rtl::Reference<PresenterClockTimer> pTimer; - if (mpInstance.is()) - { - pTimer = mpInstance; - } - if ( ! pTimer.is()) - { - pTimer.set(new PresenterClockTimer(rxContext)); - mpInstance = pTimer; - } - return pTimer; -} - -PresenterClockTimer::PresenterClockTimer (const Reference<XComponentContext>& rxContext) - : PresenterClockTimerInterfaceBase(m_aMutex), - maListeners(), - maDateTime(), - mnTimerTaskId(PresenterTimer::NotAValidTaskId), - mbIsCallbackPending(false), - mxRequestCallback() - , m_xContext(rxContext) -{ - assert(m_xContext.is()); - Reference<lang::XMultiComponentFactory> xFactory = - rxContext->getServiceManager(); - if (xFactory.is()) - mxRequestCallback.set( - xFactory->createInstanceWithContext( - "com.sun.star.awt.AsyncCallback", - rxContext), - UNO_QUERY_THROW); -} - -PresenterClockTimer::~PresenterClockTimer() -{ - if (mnTimerTaskId != PresenterTimer::NotAValidTaskId) - { - PresenterTimer::CancelTask(mnTimerTaskId); - mnTimerTaskId = PresenterTimer::NotAValidTaskId; - } - - Reference<lang::XComponent> xComponent (mxRequestCallback, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - mxRequestCallback = nullptr; -} - -void PresenterClockTimer::AddListener (const SharedListener& rListener) -{ - osl::MutexGuard aGuard (maMutex); - - maListeners.push_back(rListener); - - // Create a timer task when the first listener is added. - if (mnTimerTaskId==PresenterTimer::NotAValidTaskId) - { - mnTimerTaskId = PresenterTimer::ScheduleRepeatedTask( - m_xContext, - [this] (TimeValue const& rTime) { return this->CheckCurrentTime(rTime); }, - 0, - 250000000 /*ns*/); - } -} - -void PresenterClockTimer::RemoveListener (const SharedListener& rListener) -{ - osl::MutexGuard aGuard (maMutex); - - ListenerContainer::iterator iListener (::std::find( - maListeners.begin(), - maListeners.end(), - rListener)); - if (iListener != maListeners.end()) - maListeners.erase(iListener); - if (maListeners.empty()) - { - // We have no more clients and therefore are not interested in time changes. - if (mnTimerTaskId != PresenterTimer::NotAValidTaskId) - { - PresenterTimer::CancelTask(mnTimerTaskId); - mnTimerTaskId = PresenterTimer::NotAValidTaskId; - } - mpInstance = nullptr; - } -} - -oslDateTime PresenterClockTimer::GetCurrentTime() -{ - TimeValue aCurrentTime; - TimerScheduler::GetCurrentTime(aCurrentTime); - oslDateTime aDateTime; - osl_getDateTimeFromTimeValue(&aCurrentTime, &aDateTime); - return aDateTime; -} - -void PresenterClockTimer::CheckCurrentTime (const TimeValue& rCurrentTime) -{ - css::uno::Reference<css::awt::XRequestCallback> xRequestCallback; - css::uno::Reference<css::awt::XCallback> xCallback; - { - osl::MutexGuard aGuard (maMutex); - - TimeValue aCurrentTime (rCurrentTime); - oslDateTime aDateTime; - if (osl_getDateTimeFromTimeValue(&aCurrentTime, &aDateTime)) - { - if (aDateTime.Seconds != maDateTime.Seconds - || aDateTime.Minutes != maDateTime.Minutes - || aDateTime.Hours != maDateTime.Hours) - { - // The displayed part of the current time has changed. - // Prepare to call the listeners. - maDateTime = aDateTime; - - // Schedule notification of listeners. - if (mxRequestCallback.is() && ! mbIsCallbackPending) - { - mbIsCallbackPending = true; - xRequestCallback = mxRequestCallback; - xCallback = this; - } - } - } - } - if (xRequestCallback.is() && xCallback.is()) - xRequestCallback->addCallback(xCallback, Any()); -} - -//----- XCallback ------------------------------------------------------------- - -void SAL_CALL PresenterClockTimer::notify (const css::uno::Any&) -{ - ListenerContainer aListenerCopy; - - { - osl::MutexGuard aGuard (maMutex); - - mbIsCallbackPending = false; - - aListenerCopy = maListeners; - } - - for (const auto& rxListener : aListenerCopy) - { - rxListener->TimeHasChanged(maDateTime); - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterTimer.hxx b/sdext/source/presenter/PresenterTimer.hxx deleted file mode 100644 index 1c2b6530b759..000000000000 --- a/sdext/source/presenter/PresenterTimer.hxx +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTIMER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTIMER_HXX - -#include <com/sun/star/awt/XCallback.hpp> -#include <com/sun/star/awt/XRequestCallback.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <osl/mutex.hxx> -#include <osl/time.h> -#include <rtl/ref.hxx> -#include <sal/types.h> - -#include <functional> -#include <memory> -#include <vector> - -namespace com::sun::star::uno { class XComponentContext; } - -namespace sdext::presenter { - -/** The timer allows tasks to be scheduled for execution at a specified time - in the future. -*/ -class PresenterTimer -{ -public: - /** A task is called with the current time. - */ - typedef ::std::function<void (const TimeValue&)> Task; - - static const sal_Int32 NotAValidTaskId = 0; - - /** Schedule a task to be executed repeatedly. The task is executed the - first time after nFirst nano-seconds (1000000000 corresponds to one - second). After that task is executed in intervals that are - nInterval ns long until CancelTask is called. - */ - static sal_Int32 ScheduleRepeatedTask ( - const css::uno::Reference<css::uno::XComponentContext>& xContext, - const Task& rTask, - const sal_Int64 nFirst, - const sal_Int64 nInterval); - - static void CancelTask (const sal_Int32 nTaskId); -}; - -typedef cppu::WeakComponentImplHelper< - css::awt::XCallback - > PresenterClockTimerInterfaceBase; - -/** A timer that calls its listeners, typically clocks, every second to - update their current time value. -*/ -class PresenterClockTimer - : protected ::cppu::BaseMutex, - public PresenterClockTimerInterfaceBase -{ -public: - class Listener { - public: - virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0; - - protected: - ~Listener() {} - }; - typedef std::shared_ptr<Listener> SharedListener; - - static ::rtl::Reference<PresenterClockTimer> Instance ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - - void AddListener (const SharedListener& rListener); - void RemoveListener (const SharedListener& rListener); - - static oslDateTime GetCurrentTime(); - - // XCallback - - virtual void SAL_CALL notify (const css::uno::Any& rUserData) override; - -private: - static ::rtl::Reference<PresenterClockTimer> mpInstance; - - ::osl::Mutex maMutex; - typedef ::std::vector<SharedListener> ListenerContainer; - ListenerContainer maListeners; - oslDateTime maDateTime; - sal_Int32 mnTimerTaskId; - bool mbIsCallbackPending; - css::uno::Reference<css::awt::XRequestCallback> mxRequestCallback; - const css::uno::Reference<css::uno::XComponentContext> m_xContext; - - PresenterClockTimer ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext); - virtual ~PresenterClockTimer() override; - - void CheckCurrentTime (const TimeValue& rCurrentTime); -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterToolBar.cxx b/sdext/source/presenter/PresenterToolBar.cxx deleted file mode 100644 index 9f9af15da731..000000000000 --- a/sdext/source/presenter/PresenterToolBar.cxx +++ /dev/null @@ -1,2037 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <vcl/settings.hxx> -#include "PresenterToolBar.hxx" - -#include "PresenterBitmapContainer.hxx" -#include "PresenterCanvasHelper.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterTimer.hxx" -#include "PresenterWindowManager.hxx" - -#include <cppuhelper/compbase.hxx> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/drawing/framework/XControllerManager.hpp> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/geometry/AffineMatrix2D.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/RenderState.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/rendering/ViewState.hpp> -#include <com/sun/star/rendering/XSpriteCanvas.hpp> -#include <com/sun/star/util/Color.hpp> -#include <rtl/ustrbuf.hxx> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -const sal_Int32 gnGapSize (20); - -namespace { - - class Text - { - public: - Text(); - Text ( - const OUString& rsText, - const PresenterTheme::SharedFontDescriptor& rpFont); - - void SetText (const OUString& rsText); - const OUString& GetText() const; - const PresenterTheme::SharedFontDescriptor& GetFont() const; - - void Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState, - const awt::Rectangle& rBoundingBox); - - geometry::RealRectangle2D GetBoundingBox ( - const Reference<rendering::XCanvas>& rxCanvas); - - private: - OUString msText; - PresenterTheme::SharedFontDescriptor mpFont; - }; - - class ElementMode - { - public: - ElementMode(); - ElementMode(const ElementMode&) = delete; - ElementMode& operator=(const ElementMode&) = delete; - - SharedBitmapDescriptor mpIcon; - OUString msAction; - Text maText; - - void ReadElementMode ( - const Reference<beans::XPropertySet>& rxProperties, - const OUString& rsModeName, - std::shared_ptr<ElementMode> const & rpDefaultMode, - ::sdext::presenter::PresenterToolBar::Context const & rContext); - }; - typedef std::shared_ptr<ElementMode> SharedElementMode; - -} // end of anonymous namespace - -class PresenterToolBar::Context -{ -public: - Context() = default; - Context(const Context&) = delete; - Context& operator=(const Context&) = delete; - Reference<drawing::XPresenterHelper> mxPresenterHelper; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; -}; - -//===== PresenterToolBar::Element ============================================= - -namespace { - typedef cppu::WeakComponentImplHelper< - css::document::XEventListener, - css::frame::XStatusListener - > ElementInterfaceBase; - - class Element - : private ::cppu::BaseMutex, - public ElementInterfaceBase - { - public: - explicit Element (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - Element(const Element&) = delete; - Element& operator=(const Element&) = delete; - - virtual void SAL_CALL disposing() override; - - virtual void SetModes ( - const SharedElementMode& rpNormalMode, - const SharedElementMode& rpMouseOverMode, - const SharedElementMode& rpSelectedMode, - const SharedElementMode& rpDisabledMode, - const SharedElementMode& rpMouseOverSelectedMode); - void CurrentSlideHasChanged(); - void SetLocation (const awt::Point& rLocation); - void SetSize (const geometry::RealSize2D& rSize); - virtual void Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) = 0; - awt::Size const & GetBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas); - awt::Rectangle GetBoundingBox() const; - virtual bool SetState (const bool bIsOver, const bool bIsPressed); - void Invalidate (const bool bSynchronous); - bool IsOutside (const awt::Rectangle& rBox); - virtual bool IsFilling() const; - void UpdateState(); - - // lang::XEventListener - - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - - // document::XEventListener - - virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent) override; - - // frame::XStatusListener - - virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent) override; - - protected: - ::rtl::Reference<PresenterToolBar> mpToolBar; - awt::Point maLocation; - awt::Size maSize; - SharedElementMode mpNormal; - SharedElementMode mpMouseOver; - SharedElementMode mpSelected; - SharedElementMode mpDisabled; - SharedElementMode mpMouseOverSelected; - SharedElementMode mpMode; - bool mbIsOver; - bool mbIsPressed; - bool mbIsSelected; - - virtual awt::Size CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) = 0; - - bool IsEnabled() const { return mbIsEnabled;} - private: - bool mbIsEnabled; - }; - -} // end of anonymous namespace - -class PresenterToolBar::ElementContainerPart - : public ::std::vector<rtl::Reference<Element> > -{ -}; - -//===== Button ================================================================ - -namespace { - - class Button : public Element - { - public: - static ::rtl::Reference<Element> Create ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar); - - virtual void SAL_CALL disposing() override; - - virtual void Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) override; - - // lang::XEventListener - - virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override; - - protected: - virtual awt::Size CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) override; - - private: - bool mbIsListenerRegistered; - - Button (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - void Initialize(); - void PaintIcon ( - const Reference<rendering::XCanvas>& rxCanvas, - const sal_Int32 nTextHeight, - const rendering::ViewState& rViewState); - PresenterBitmapDescriptor::Mode GetMode() const; - }; - -//===== Label ================================================================= - - class Label : public Element - { - public: - explicit Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - - void SetText (const OUString& rsText); - virtual void Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) override; - virtual bool SetState (const bool bIsOver, const bool bIsPressed) override; - - protected: - virtual awt::Size CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) override; - }; - -// Some specialized controls. - - class TimeFormatter - { - public: - static OUString FormatTime (const oslDateTime& rTime); - }; - - class TimeLabel : public Label - { - public: - void ConnectToTimer(); - virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0; - protected: - explicit TimeLabel(const ::rtl::Reference<PresenterToolBar>& rpToolBar); - using Element::disposing; - virtual void SAL_CALL disposing() override; - private: - class Listener : public PresenterClockTimer::Listener - { - public: - explicit Listener (const ::rtl::Reference<TimeLabel>& rxLabel) - : mxLabel(rxLabel) {} - virtual ~Listener() {} - virtual void TimeHasChanged (const oslDateTime& rCurrentTime) override - { if (mxLabel.is()) mxLabel->TimeHasChanged(rCurrentTime); } - private: - ::rtl::Reference<TimeLabel> mxLabel; - }; - std::shared_ptr<PresenterClockTimer::Listener> mpListener; - }; - - class CurrentTimeLabel : public TimeLabel - { - public: - static ::rtl::Reference<Element> Create ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar); - virtual void SetModes ( - const SharedElementMode& rpNormalMode, - const SharedElementMode& rpMouseOverMode, - const SharedElementMode& rpSelectedMode, - const SharedElementMode& rpDisabledMode, - const SharedElementMode& rpMouseOverSelectedMode) override; - private: - CurrentTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - virtual ~CurrentTimeLabel() override; - virtual void TimeHasChanged (const oslDateTime& rCurrentTime) override; - }; - - class PresentationTimeLabel : public TimeLabel, public IPresentationTime - { - public: - static ::rtl::Reference<Element> Create ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar); - virtual void SetModes ( - const SharedElementMode& rpNormalMode, - const SharedElementMode& rpMouseOverMode, - const SharedElementMode& rpSelectedMode, - const SharedElementMode& rpDisabledMode, - const SharedElementMode& rpMouseOverSelectedMode) override; - virtual void restart() override; - virtual bool isPaused() override; - virtual void setPauseStatus(const bool pauseStatus) override; - TimeValue getPauseTimeValue() const; - void setPauseTimeValue(const TimeValue pauseTime); - private: - TimeValue maStartTimeValue; - TimeValue pauseTimeValue; - PresentationTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - bool paused; - virtual ~PresentationTimeLabel() override; - virtual void TimeHasChanged (const oslDateTime& rCurrentTime) override; - }; - - class VerticalSeparator : public Element - { - public: - explicit VerticalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - virtual void Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) override; - virtual bool IsFilling() const override; - - protected: - virtual awt::Size CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) override; - }; - - class HorizontalSeparator : public Element - { - public: - explicit HorizontalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar); - virtual void Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) override; - virtual bool IsFilling() const override; - - protected: - virtual awt::Size CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) override; - }; -} // end of anonymous namespace - -//===== PresenterToolBar ====================================================== - -PresenterToolBar::PresenterToolBar ( - const Reference<XComponentContext>& rxContext, - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const Anchor eAnchor) - : PresenterToolBarInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - maElementContainer(), - mpCurrentContainerPart(), - mxWindow(rxWindow), - mxCanvas(rxCanvas), - mxSlideShowController(), - mxCurrentSlide(), - mpPresenterController(rpPresenterController), - mbIsLayoutPending(false), - meAnchor(eAnchor), - maMinimalSize() -{ -} - -void PresenterToolBar::Initialize ( - const OUString& rsConfigurationPath) -{ - try - { - CreateControls(rsConfigurationPath); - - if (mxWindow.is()) - { - mxWindow->addWindowListener(this); - mxWindow->addPaintListener(this); - mxWindow->addMouseListener(this); - mxWindow->addMouseMotionListener(this); - - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->setBackground(util::Color(0xff000000)); - - mxWindow->setVisible(true); - } - - mxSlideShowController = mpPresenterController->GetSlideShowController(); - UpdateSlideNumber(); - mbIsLayoutPending = true; - } - catch (RuntimeException&) - { - mpCurrentContainerPart.reset(); - maElementContainer.clear(); - throw; - } -} - -PresenterToolBar::~PresenterToolBar() -{ -} - -void SAL_CALL PresenterToolBar::disposing() -{ - if (mxWindow.is()) - { - mxWindow->removeWindowListener(this); - mxWindow->removePaintListener(this); - mxWindow->removeMouseListener(this); - mxWindow->removeMouseMotionListener(this); - mxWindow = nullptr; - } - - // Dispose tool bar elements. - for (const auto& rxPart : maElementContainer) - { - OSL_ASSERT(rxPart != nullptr); - for (rtl::Reference<Element>& pElement : *rxPart) - { - if (pElement) - { - Reference<lang::XComponent> xComponent ( - static_cast<XWeak*>(pElement.get()), UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - } - } - } - - mpCurrentContainerPart.reset(); - maElementContainer.clear(); -} - -void PresenterToolBar::InvalidateArea ( - const awt::Rectangle& rRepaintBox, - const bool bSynchronous) -{ - std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager()); - if (!xManager) - return; - xManager->Invalidate( - mxWindow, - rRepaintBox, - bSynchronous); -} - -void PresenterToolBar::RequestLayout() -{ - mbIsLayoutPending = true; - - std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager()); - if (!xManager) - return; - - xManager->Invalidate(mxWindow); -} - -geometry::RealSize2D const & PresenterToolBar::GetMinimalSize() -{ - if (mbIsLayoutPending) - Layout(mxCanvas); - return maMinimalSize; -} - -const ::rtl::Reference<PresenterController>& PresenterToolBar::GetPresenterController() const -{ - return mpPresenterController; -} - -const Reference<XComponentContext>& PresenterToolBar::GetComponentContext() const -{ - return mxComponentContext; -} - -//----- lang::XEventListener ------------------------------------------------- - -void SAL_CALL PresenterToolBar::disposing (const lang::EventObject& rEventObject) -{ - if (rEventObject.Source == mxWindow) - mxWindow = nullptr; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterToolBar::windowResized (const awt::WindowEvent&) -{ - mbIsLayoutPending = true; -} - -void SAL_CALL PresenterToolBar::windowMoved (const awt::WindowEvent&) {} - -void SAL_CALL PresenterToolBar::windowShown (const lang::EventObject&) -{ - mbIsLayoutPending = true; -} - -void SAL_CALL PresenterToolBar::windowHidden (const lang::EventObject&) {} - -//----- XPaintListener -------------------------------------------------------- -void SAL_CALL PresenterToolBar::windowPaint (const css::awt::PaintEvent& rEvent) -{ - if ( ! mxCanvas.is()) - return; - - if ( ! mbIsPresenterViewActive) - return; - - const rendering::ViewState aViewState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice())); - - if (mbIsLayoutPending) - Layout(mxCanvas); - - Paint(rEvent.UpdateRect, aViewState); - - // Make the back buffer visible. - Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); - if (xSpriteCanvas.is()) - xSpriteCanvas->updateScreen(false); -} - -//----- XMouseListener -------------------------------------------------------- -void SAL_CALL PresenterToolBar::mousePressed (const css::awt::MouseEvent& rEvent) -{ - ThrowIfDisposed(); - CheckMouseOver(rEvent, true, true); -} - -void SAL_CALL PresenterToolBar::mouseReleased (const css::awt::MouseEvent& rEvent) -{ - ThrowIfDisposed(); - CheckMouseOver(rEvent, true); -} - -void SAL_CALL PresenterToolBar::mouseEntered (const css::awt::MouseEvent& rEvent) -{ - ThrowIfDisposed(); - CheckMouseOver(rEvent, true); -} - -void SAL_CALL PresenterToolBar::mouseExited (const css::awt::MouseEvent& rEvent) -{ - ThrowIfDisposed(); - CheckMouseOver(rEvent, false); - } - -//----- XMouseMotionListener -------------------------------------------------- - -void SAL_CALL PresenterToolBar::mouseMoved (const css::awt::MouseEvent& rEvent) -{ - ThrowIfDisposed(); - CheckMouseOver(rEvent, true); - } - -void SAL_CALL PresenterToolBar::mouseDragged (const css::awt::MouseEvent&) -{ - ThrowIfDisposed(); -} - -//----- XDrawView ------------------------------------------------------------- - -void SAL_CALL PresenterToolBar::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide) -{ - if (rxSlide != mxCurrentSlide) - { - mxCurrentSlide = rxSlide; - UpdateSlideNumber(); - } -} - -Reference<drawing::XDrawPage> SAL_CALL PresenterToolBar::getCurrentPage() -{ - return mxCurrentSlide; -} - - -void PresenterToolBar::CreateControls ( - const OUString& rsConfigurationPath) -{ - if ( ! mxWindow.is()) - return; - - // Expand the macro in the bitmap file names. - PresenterConfigurationAccess aConfiguration ( - mxComponentContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - - mpCurrentContainerPart = std::make_shared<ElementContainerPart>(); - maElementContainer.clear(); - maElementContainer.push_back(mpCurrentContainerPart); - - Reference<container::XHierarchicalNameAccess> xToolBarNode ( - aConfiguration.GetConfigurationNode(rsConfigurationPath), - UNO_QUERY); - if (!xToolBarNode.is()) - return; - - Reference<container::XNameAccess> xEntries ( - PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode, "Entries"), - UNO_QUERY); - Context aContext; - aContext.mxPresenterHelper = mpPresenterController->GetPresenterHelper(); - aContext.mxCanvas = mxCanvas; - if (xEntries.is() - && aContext.mxPresenterHelper.is() - && aContext.mxCanvas.is()) - { - PresenterConfigurationAccess::ForAll( - xEntries, - [this, &aContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps) - { - return this->ProcessEntry(xProps, aContext); - }); - } -} - -void PresenterToolBar::ProcessEntry ( - const Reference<beans::XPropertySet>& rxProperties, - Context const & rContext) -{ - if ( ! rxProperties.is()) - return; - - // Type has to be present. - OUString sType; - if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, "Type") >>= sType)) - return; - - // Read mode specific values. - SharedElementMode pNormalMode = std::make_shared<ElementMode>(); - SharedElementMode pMouseOverMode = std::make_shared<ElementMode>(); - SharedElementMode pSelectedMode = std::make_shared<ElementMode>(); - SharedElementMode pDisabledMode = std::make_shared<ElementMode>(); - SharedElementMode pMouseOverSelectedMode = std::make_shared<ElementMode>(); - pNormalMode->ReadElementMode(rxProperties, "Normal", pNormalMode, rContext); - pMouseOverMode->ReadElementMode(rxProperties, "MouseOver", pNormalMode, rContext); - pSelectedMode->ReadElementMode(rxProperties, "Selected", pNormalMode, rContext); - pDisabledMode->ReadElementMode(rxProperties, "Disabled", pNormalMode, rContext); - pMouseOverSelectedMode->ReadElementMode(rxProperties, "MouseOverSelected", pSelectedMode, rContext); - - // Create new element. - ::rtl::Reference<Element> pElement; - if ( sType == "Button" ) - pElement = Button::Create(this); - else if ( sType == "CurrentTimeLabel" ) - pElement = CurrentTimeLabel::Create(this); - else if ( sType == "PresentationTimeLabel" ) - pElement = PresentationTimeLabel::Create(this); - else if ( sType == "VerticalSeparator" ) - pElement.set(new VerticalSeparator(this)); - else if ( sType == "HorizontalSeparator" ) - pElement.set(new HorizontalSeparator(this)); - else if ( sType == "Label" ) - pElement.set(new Label(this)); - else if ( sType == "ChangeOrientation" ) - { - mpCurrentContainerPart = std::make_shared<ElementContainerPart>(); - maElementContainer.push_back(mpCurrentContainerPart); - return; - } - if (pElement.is()) - { - pElement->SetModes( pNormalMode, pMouseOverMode, pSelectedMode, pDisabledMode, pMouseOverSelectedMode); - pElement->UpdateState(); - if (mpCurrentContainerPart) - mpCurrentContainerPart->push_back(pElement); - } -} - -void PresenterToolBar::Layout ( - const Reference<rendering::XCanvas>& rxCanvas) -{ - if (maElementContainer.empty()) - return; - - mbIsLayoutPending = false; - - const awt::Rectangle aWindowBox (mxWindow->getPosSize()); - ::std::vector<geometry::RealSize2D> aPartSizes (maElementContainer.size()); - geometry::RealSize2D aTotalSize (0,0); - bool bIsHorizontal (true); - sal_Int32 nIndex (0); - double nTotalHorizontalGap (0); - sal_Int32 nGapCount (0); - for (const auto& rxPart : maElementContainer) - { - geometry::RealSize2D aSize (CalculatePartSize(rxCanvas, rxPart, bIsHorizontal)); - - // Remember the size of each part for later. - aPartSizes[nIndex] = aSize; - - // Add gaps between elements. - if (rxPart->size()>1 && bIsHorizontal) - { - nTotalHorizontalGap += (rxPart->size() - 1) * gnGapSize; - nGapCount += rxPart->size() - 1; - } - - // Orientation changes for each part. - bIsHorizontal = !bIsHorizontal; - // Width is accumulated. - aTotalSize.Width += aSize.Width; - // Height is the maximum height of all parts. - aTotalSize.Height = ::std::max(aTotalSize.Height, aSize.Height); - ++nIndex; - } - // Add gaps between parts. - if (maElementContainer.size() > 1) - { - nTotalHorizontalGap += (maElementContainer.size() - 1) * gnGapSize; - nGapCount += maElementContainer.size()-1; - } - - // Done to introduce gap between the end of the toolbar and the last button - aTotalSize.Width += gnGapSize/2; - - // Calculate the minimal size so that the window size of the tool bar - // can be adapted accordingly. - maMinimalSize = aTotalSize; - maMinimalSize.Width += nTotalHorizontalGap; - - // Calculate the gaps between elements. - double nGapWidth (0); - if (nGapCount > 0) - { - if (aTotalSize.Width + nTotalHorizontalGap > aWindowBox.Width) - nTotalHorizontalGap = aWindowBox.Width - aTotalSize.Width; - nGapWidth = nTotalHorizontalGap / nGapCount; - } - - // Determine the location of the left edge. - double nX (0); - switch (meAnchor) - { - case Left : nX = 0; break; - case Center: nX = (aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap) / 2; break; - } - - // Place the parts. - double nY ((aWindowBox.Height - aTotalSize.Height) / 2); - bIsHorizontal = true; - - /* push front or back ? ... */ - /// check whether RTL interface or not - if(!AllSettings::GetLayoutRTL()){ - nIndex = 0; - for (const auto& rxPart : maElementContainer) - { - geometry::RealRectangle2D aBoundingBox( - nX, nY, - nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height); - - // Add space for gaps between elements. - if (rxPart->size() > 1 && bIsHorizontal) - aBoundingBox.X2 += (rxPart->size() - 1) * nGapWidth; - - LayoutPart(rxCanvas, rxPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal); - bIsHorizontal = !bIsHorizontal; - nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth; - ++nIndex; - } - } - else { - ElementContainer::iterator iPart; - ElementContainer::iterator iBegin (maElementContainer.begin()); - for (iPart=maElementContainer.end()-1, nIndex=2; iPart!=iBegin-1; --iPart, --nIndex) - { - geometry::RealRectangle2D aBoundingBox( - nX, nY, - nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height); - - // Add space for gaps between elements. - if ((*iPart)->size() > 1) - if (bIsHorizontal) - aBoundingBox.X2 += ((*iPart)->size()-1) * nGapWidth; - - LayoutPart(rxCanvas, *iPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal); - bIsHorizontal = !bIsHorizontal; - nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth; - } - } - - // The whole window has to be repainted. - std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager()); - if (!xManager) - return; - xManager->Invalidate(mxWindow); -} - -geometry::RealSize2D PresenterToolBar::CalculatePartSize ( - const Reference<rendering::XCanvas>& rxCanvas, - const SharedElementContainerPart& rpPart, - const bool bIsHorizontal) -{ - geometry::RealSize2D aTotalSize (0,0); - - if (mxWindow.is()) - { - // Calculate the summed width of all elements. - for (const auto& rxElement : *rpPart) - { - if (!rxElement) - continue; - - const awt::Size aBSize (rxElement->GetBoundingSize(rxCanvas)); - if (bIsHorizontal) - { - aTotalSize.Width += aBSize.Width; - if (aBSize.Height > aTotalSize.Height) - aTotalSize.Height = aBSize.Height; - } - else - { - aTotalSize.Height += aBSize.Height; - if (aBSize.Width > aTotalSize.Width) - aTotalSize.Width = aBSize.Width; - } - } - } - return aTotalSize; -} - -void PresenterToolBar::LayoutPart ( - const Reference<rendering::XCanvas>& rxCanvas, - const SharedElementContainerPart& rpPart, - const geometry::RealRectangle2D& rBoundingBox, - const geometry::RealSize2D& rPartSize, - const bool bIsHorizontal) -{ - double nGap (0); - if (rpPart->size() > 1) - { - if (bIsHorizontal) - nGap = (rBoundingBox.X2 - rBoundingBox.X1 - rPartSize.Width) / (rpPart->size()-1); - else - nGap = (rBoundingBox.Y2 - rBoundingBox.Y1 - rPartSize.Height) / (rpPart->size()-1); - } - - // Place the elements. - double nX (rBoundingBox.X1); - double nY (rBoundingBox.Y1); - - /// check whether RTL interface or not - if(!AllSettings::GetLayoutRTL()){ - for (auto& rxElement : *rpPart) - { - if (!rxElement) - continue; - - const awt::Size aElementSize (rxElement->GetBoundingSize(rxCanvas)); - if (bIsHorizontal) - { - if (rxElement->IsFilling()) - { - nY = rBoundingBox.Y1; - rxElement->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1)); - } - else - nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2; - rxElement->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY))); - nX += aElementSize.Width + nGap; - } - else - { - if (rxElement->IsFilling()) - { - nX = rBoundingBox.X1; - rxElement->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aElementSize.Height)); - } - else - nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aElementSize.Width) / 2; - rxElement->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY))); - nY += aElementSize.Height + nGap; - } - } - } - else { - ElementContainerPart::const_iterator iElement; - ElementContainerPart::const_iterator iBegin (rpPart->begin()); - - for (iElement=rpPart->end()-1; iElement!=iBegin-1; --iElement) - { - if (iElement->get() == nullptr) - continue; - - const awt::Size aElementSize ((*iElement)->GetBoundingSize(rxCanvas)); - if (bIsHorizontal) - { - if ((*iElement)->IsFilling()) - { - nY = rBoundingBox.Y1; - (*iElement)->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1)); - } - else - nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2; - (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY))); - nX += aElementSize.Width + nGap; - } - else - { - // reverse presentation time with current time - if (iElement==iBegin){ - iElement=iBegin+2; - } - else if (iElement==iBegin+2){ - iElement=iBegin; - } - const awt::Size aNewElementSize ((*iElement)->GetBoundingSize(rxCanvas)); - if ((*iElement)->IsFilling()) - { - nX = rBoundingBox.X1; - (*iElement)->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aNewElementSize.Height)); - } - else - nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aNewElementSize.Width) / 2; - (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY))); - nY += aNewElementSize.Height + nGap; - - // return the index as it was before the reversing - if (iElement==iBegin) - iElement=iBegin+2; - else if (iElement==iBegin+2) - iElement=iBegin; - } - } - } -} - -void PresenterToolBar::Paint ( - const awt::Rectangle& rUpdateBox, - const rendering::ViewState& rViewState) -{ - OSL_ASSERT(mxCanvas.is()); - - for (const auto& rxPart : maElementContainer) - { - for (auto& rxElement : *rxPart) - { - if (rxElement) - { - if ( ! rxElement->IsOutside(rUpdateBox)) - rxElement->Paint(mxCanvas, rViewState); - } - } - } -} - -void PresenterToolBar::UpdateSlideNumber() -{ - if( mxSlideShowController.is() ) - { - for (const auto& rxPart : maElementContainer) - { - for (auto& rxElement : *rxPart) - { - if (rxElement) - rxElement->CurrentSlideHasChanged(); - } - } - } -} - -void PresenterToolBar::CheckMouseOver ( - const css::awt::MouseEvent& rEvent, - const bool bOverWindow, - const bool bMouseDown) -{ - css::awt::MouseEvent rTemp =rEvent; - if(AllSettings::GetLayoutRTL()){ - awt::Rectangle aWindowBox = mxWindow->getPosSize(); - rTemp.X=aWindowBox.Width-rTemp.X; - } - for (const auto& rxPart : maElementContainer) - { - for (auto& rxElement : *rxPart) - { - if (!rxElement) - continue; - - awt::Rectangle aBox (rxElement->GetBoundingBox()); - const bool bIsOver = bOverWindow - && aBox.X <= rTemp.X - && aBox.Width+aBox.X-1 >= rTemp.X - && aBox.Y <= rTemp.Y - && aBox.Height+aBox.Y-1 >= rTemp.Y; - rxElement->SetState( - bIsOver, - bIsOver && rTemp.Buttons!=0 && bMouseDown && rTemp.ClickCount>0); - } - } -} - -void PresenterToolBar::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterToolBar has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -//===== PresenterToolBarView ================================================== - -PresenterToolBarView::PresenterToolBarView ( - const Reference<XComponentContext>& rxContext, - const Reference<XResourceId>& rxViewId, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterToolBarViewInterfaceBase(m_aMutex), - mxPane(), - mxViewId(rxViewId), - mxWindow(), - mxCanvas(), - mpPresenterController(rpPresenterController), - mpToolBar() -{ - try - { - Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); - Reference<XConfigurationController> xCC(xCM->getConfigurationController(),UNO_SET_THROW); - mxPane.set(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW); - - mxWindow = mxPane->getWindow(); - mxCanvas = mxPane->getCanvas(); - - mpToolBar = new PresenterToolBar( - rxContext, - mxWindow, - mxCanvas, - rpPresenterController, - PresenterToolBar::Center); - mpToolBar->Initialize("PresenterScreenSettings/ToolBars/ToolBar"); - - if (mxWindow.is()) - { - mxWindow->addPaintListener(this); - - Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->setBackground(util::Color(0xff000000)); - - mxWindow->setVisible(true); - } - } - catch (RuntimeException&) - { - mxViewId = nullptr; - throw; - } -} - -PresenterToolBarView::~PresenterToolBarView() -{ -} - -void SAL_CALL PresenterToolBarView::disposing() -{ - Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY); - mpToolBar = nullptr; - if (xComponent.is()) - xComponent->dispose(); - - if (mxWindow.is()) - { - mxWindow->removePaintListener(this); - mxWindow = nullptr; - } - mxCanvas = nullptr; - mxViewId = nullptr; - mxPane = nullptr; - mpPresenterController = nullptr; -} - -const ::rtl::Reference<PresenterToolBar>& PresenterToolBarView::GetPresenterToolBar() const -{ - return mpToolBar; -} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterToolBarView::windowPaint (const css::awt::PaintEvent& rEvent) -{ - awt::Rectangle aWindowBox (mxWindow->getPosSize()); - mpPresenterController->GetCanvasHelper()->Paint( - mpPresenterController->GetViewBackground(mxViewId->getResourceURL()), - mxCanvas, - rEvent.UpdateRect, - awt::Rectangle(0,0,aWindowBox.Width, aWindowBox.Height), - awt::Rectangle()); -} - -//----- lang::XEventListener ------------------------------------------------- - -void SAL_CALL PresenterToolBarView::disposing (const lang::EventObject& rEventObject) -{ - if (rEventObject.Source == mxWindow) - mxWindow = nullptr; -} - -//----- XResourceId ----------------------------------------------------------- - -Reference<XResourceId> SAL_CALL PresenterToolBarView::getResourceId() -{ - return mxViewId; -} - -sal_Bool SAL_CALL PresenterToolBarView::isAnchorOnly() -{ - return false; -} - -//----- XDrawView ------------------------------------------------------------- - -void SAL_CALL PresenterToolBarView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide) -{ - Reference<drawing::XDrawView> xToolBar (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY); - if (xToolBar.is()) - xToolBar->setCurrentPage(rxSlide); -} - -Reference<drawing::XDrawPage> SAL_CALL PresenterToolBarView::getCurrentPage() -{ - return nullptr; -} - -//===== PresenterToolBar::Element ============================================= - -namespace { - -Element::Element ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : ElementInterfaceBase(m_aMutex), - mpToolBar(rpToolBar), - maLocation(), - maSize(), - mpNormal(), - mpMouseOver(), - mpSelected(), - mpDisabled(), - mpMouseOverSelected(), - mpMode(), - mbIsOver(false), - mbIsPressed(false), - mbIsSelected(false), - mbIsEnabled(true) -{ - if (mpToolBar) - { - OSL_ASSERT(mpToolBar->GetPresenterController().is()); - OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is()); - } -} - -void Element::SetModes ( - const SharedElementMode& rpNormalMode, - const SharedElementMode& rpMouseOverMode, - const SharedElementMode& rpSelectedMode, - const SharedElementMode& rpDisabledMode, - const SharedElementMode& rpMouseOverSelectedMode) -{ - mpNormal = rpNormalMode; - mpMouseOver = rpMouseOverMode; - mpSelected = rpSelectedMode; - mpDisabled = rpDisabledMode; - mpMouseOverSelected = rpMouseOverSelectedMode; - mpMode = rpNormalMode; -} - -void Element::disposing() -{ -} - -awt::Size const & Element::GetBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) -{ - maSize = CreateBoundingSize(rxCanvas); - return maSize; -} - -awt::Rectangle Element::GetBoundingBox() const -{ - return awt::Rectangle(maLocation.X,maLocation.Y, maSize.Width, maSize.Height); -} - -void Element::CurrentSlideHasChanged() -{ - UpdateState(); -} - -void Element::SetLocation (const awt::Point& rLocation) -{ - maLocation = rLocation; -} - -void Element::SetSize (const geometry::RealSize2D& rSize) -{ - maSize = awt::Size(sal_Int32(0.5+rSize.Width), sal_Int32(0.5+rSize.Height)); -} - -bool Element::SetState ( - const bool bIsOver, - const bool bIsPressed) -{ - bool bModified (mbIsOver != bIsOver || mbIsPressed != bIsPressed); - bool bClicked (mbIsPressed && bIsOver && ! bIsPressed); - - mbIsOver = bIsOver; - mbIsPressed = bIsPressed; - - // When the element is disabled then ignore mouse over or selection. - // When the element is selected then ignore mouse over. - if ( ! mbIsEnabled) - mpMode = mpDisabled; - else if (mbIsSelected && mbIsOver) - mpMode = mpMouseOverSelected; - else if (mbIsSelected) - mpMode = mpSelected; - else if (mbIsOver) - mpMode = mpMouseOver; - else - mpMode = mpNormal; - - if (bClicked && mbIsEnabled) - { - if (mpMode) - { - do - { - if (mpMode->msAction.isEmpty()) - break; - - if (!mpToolBar) - break; - - if (!mpToolBar->GetPresenterController()) - break; - - mpToolBar->GetPresenterController()->DispatchUnoCommand(mpMode->msAction); - mpToolBar->RequestLayout(); - } - while (false); - } - - } - else if (bModified) - { - Invalidate(true); - } - - return bModified; -} - -void Element::Invalidate (const bool bSynchronous) -{ - OSL_ASSERT(mpToolBar.is()); - mpToolBar->InvalidateArea(GetBoundingBox(), bSynchronous); -} - -bool Element::IsOutside (const awt::Rectangle& rBox) -{ - if (rBox.X >= maLocation.X+maSize.Width) - return true; - else if (rBox.Y >= maLocation.Y+maSize.Height) - return true; - else if (maLocation.X >= rBox.X+rBox.Width) - return true; - else if (maLocation.Y >= rBox.Y+rBox.Height) - return true; - else - return false; -} - - -bool Element::IsFilling() const -{ - return false; -} - -void Element::UpdateState() -{ - OSL_ASSERT(mpToolBar); - OSL_ASSERT(mpToolBar->GetPresenterController()); - - if (!mpMode) - return; - - util::URL aURL (mpToolBar->GetPresenterController()->CreateURLFromString(mpMode->msAction)); - Reference<frame::XDispatch> xDispatch (mpToolBar->GetPresenterController()->GetDispatch(aURL)); - if (xDispatch.is()) - { - xDispatch->addStatusListener(this, aURL); - xDispatch->removeStatusListener(this, aURL); - } -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL Element::disposing (const css::lang::EventObject&) {} - -//----- document::XEventListener ---------------------------------------------- - -void SAL_CALL Element::notifyEvent (const css::document::EventObject&) -{ - UpdateState(); -} - -//----- frame::XStatusListener ------------------------------------------------ - -void SAL_CALL Element::statusChanged (const css::frame::FeatureStateEvent& rEvent) -{ - bool bIsSelected (mbIsSelected); - bool bIsEnabled (rEvent.IsEnabled); - rEvent.State >>= bIsSelected; - - if (bIsSelected != mbIsSelected || bIsEnabled != mbIsEnabled) - { - mbIsEnabled = bIsEnabled; - mbIsSelected = bIsSelected; - SetState(mbIsOver, mbIsPressed); - mpToolBar->RequestLayout(); - } -} - -} // end of anonymous namespace - -//===== ElementMode =========================================================== - -namespace { - -ElementMode::ElementMode() - : mpIcon(), - msAction(), - maText() -{ -} - -void ElementMode::ReadElementMode ( - const Reference<beans::XPropertySet>& rxElementProperties, - const OUString& rsModeName, - std::shared_ptr<ElementMode> const & rpDefaultMode, - ::sdext::presenter::PresenterToolBar::Context const & rContext) -{ - try - { - Reference<container::XHierarchicalNameAccess> xNode ( - PresenterConfigurationAccess::GetProperty(rxElementProperties, rsModeName), - UNO_QUERY); - Reference<beans::XPropertySet> xProperties ( - PresenterConfigurationAccess::GetNodeProperties(xNode, OUString())); - if (!xProperties.is() && rpDefaultMode != nullptr) - { - // The mode is not specified. Use the given, possibly empty, - // default mode instead. - mpIcon = rpDefaultMode->mpIcon; - msAction = rpDefaultMode->msAction; - maText = rpDefaultMode->maText; - } - - // Read action. - if ( ! (PresenterConfigurationAccess::GetProperty(xProperties, "Action") >>= msAction)) - if (rpDefaultMode != nullptr) - msAction = rpDefaultMode->msAction; - - // Read text and font - OUString sText(rpDefaultMode != nullptr ? rpDefaultMode->maText.GetText() : OUString()); - PresenterConfigurationAccess::GetProperty(xProperties, "Text") >>= sText; - Reference<container::XHierarchicalNameAccess> xFontNode ( - PresenterConfigurationAccess::GetProperty(xProperties, "Font"), UNO_QUERY); - PresenterTheme::SharedFontDescriptor pFont(PresenterTheme::ReadFont( - xFontNode, rpDefaultMode != nullptr ? rpDefaultMode->maText.GetFont() - : PresenterTheme::SharedFontDescriptor())); - maText = Text(sText,pFont); - - // Read bitmaps to display as icons. - Reference<container::XHierarchicalNameAccess> xIconNode ( - PresenterConfigurationAccess::GetProperty(xProperties, "Icon"), UNO_QUERY); - mpIcon = PresenterBitmapContainer::LoadBitmap( - xIconNode, "", rContext.mxPresenterHelper, rContext.mxCanvas, - rpDefaultMode != nullptr ? rpDefaultMode->mpIcon : SharedBitmapDescriptor()); - } - catch(Exception&) - { - OSL_ASSERT(false); - } -} - -} // end of anonymous namespace - -//===== Button ================================================================ - -namespace { - -::rtl::Reference<Element> Button::Create ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) -{ - ::rtl::Reference<Button> pElement (new Button(rpToolBar)); - pElement->Initialize(); - return pElement; -} - -Button::Button ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : Element(rpToolBar), - mbIsListenerRegistered(false) -{ - OSL_ASSERT(mpToolBar); - OSL_ASSERT(mpToolBar->GetPresenterController().is()); - OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is()); -} - -void Button::Initialize() -{ - mpToolBar->GetPresenterController()->GetWindowManager()->AddLayoutListener(this); - mbIsListenerRegistered = true; -} - -void Button::disposing() -{ - OSL_ASSERT(mpToolBar); - if (mpToolBar && mbIsListenerRegistered) - { - OSL_ASSERT(mpToolBar->GetPresenterController().is()); - OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is()); - - mbIsListenerRegistered = false; - mpToolBar->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this); - } - Element::disposing(); -} - -void Button::Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) -{ - OSL_ASSERT(rxCanvas.is()); - - if (!mpMode) - return; - - if (!mpMode->mpIcon) - return; - - geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas)); - sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1)); - - PaintIcon(rxCanvas, nTextHeight, rViewState); - mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox()); -} - -awt::Size Button::CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) -{ - if (!mpMode) - return awt::Size(); - - geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas)); - - // tdf#128964 This ensures that if the text of a button changes due to a change in - // the state of the button the other buttons of the toolbar do not move. The button is - // allotted the maximum size so that it doesn't resize during a change of state. - geometry::RealRectangle2D aTextBBoxNormal (mpNormal->maText.GetBoundingBox(rxCanvas)); - geometry::RealRectangle2D aTextBBoxMouseOver (mpMouseOver->maText.GetBoundingBox(rxCanvas)); - geometry::RealRectangle2D aTextBBoxSelected (mpSelected->maText.GetBoundingBox(rxCanvas)); - geometry::RealRectangle2D aTextBBoxDisabled (mpDisabled->maText.GetBoundingBox(rxCanvas)); - geometry::RealRectangle2D aTextBBoxMouseOverSelected (mpMouseOverSelected->maText.GetBoundingBox(rxCanvas)); - std::vector<sal_Int32> widths; - widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxNormal.X2 - aTextBBoxNormal.X1)); - widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOver.X2 - aTextBBoxMouseOver.X1)); - widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxSelected.X2 - aTextBBoxSelected.X1)); - widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxDisabled.X2 - aTextBBoxDisabled.X1)); - widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOverSelected.X2 - aTextBBoxMouseOverSelected.X1)); - - sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1)); - Reference<rendering::XBitmap> xBitmap; - if (mpMode->mpIcon) - xBitmap = mpMode->mpIcon->GetNormalBitmap(); - if (xBitmap.is()) - { - const sal_Int32 nGap (5); - geometry::IntegerSize2D aSize (xBitmap->getSize()); - return awt::Size( - ::std::max(aSize.Width, *std::max_element(widths.begin(), widths.end())), - aSize.Height + nGap + nTextHeight); - } - else - { - return awt::Size(*std::max_element(widths.begin(), widths.end()), nTextHeight); - } -} - -void Button::PaintIcon ( - const Reference<rendering::XCanvas>& rxCanvas, - const sal_Int32 nTextHeight, - const rendering::ViewState& rViewState) -{ - if (!mpMode) - return; - - Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode())); - if (!xBitmap.is()) - return; - - /// check whether RTL interface or not - if(!AllSettings::GetLayoutRTL()){ - const sal_Int32 nX (maLocation.X - + (maSize.Width-xBitmap->getSize().Width) / 2); - const sal_Int32 nY (maLocation.Y - + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2); - const rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,nX, 0,1,nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::OVER); - rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState); - } - else { - const sal_Int32 nX (maLocation.X - + (maSize.Width+xBitmap->getSize().Width) / 2); - const sal_Int32 nY (maLocation.Y - + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2); - const rendering::RenderState aRenderState( - geometry::AffineMatrix2D(-1,0,nX, 0,1,nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::OVER); - rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState); - } -} - -PresenterBitmapDescriptor::Mode Button::GetMode() const -{ - if ( ! IsEnabled()) - return PresenterBitmapDescriptor::Disabled; - else if (mbIsPressed) - return PresenterBitmapDescriptor::ButtonDown; - else if (mbIsOver) - return PresenterBitmapDescriptor::MouseOver; - else - return PresenterBitmapDescriptor::Normal; -} - -//----- lang::XEventListener -------------------------------------------------- - -void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent) -{ - mbIsListenerRegistered = false; - Element::disposing(rEvent); -} - -} // end of anonymous namespace - -//===== PresenterToolBar::Label =============================================== - -namespace { - -Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : Element(rpToolBar) -{ -} - -awt::Size Label::CreateBoundingSize ( - const Reference<rendering::XCanvas>& rxCanvas) -{ - if (!mpMode) - return awt::Size(0,0); - - geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas)); - return awt::Size( - sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1), - sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1)); -} - -void Label::SetText (const OUString& rsText) -{ - OSL_ASSERT(mpToolBar); - if (!mpMode) - return; - - const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength()); - - mpMode->maText.SetText(rsText); - // Just use the character count for determining whether a layout is - // necessary. This is an optimization to avoid layouts every time a new - // time value is set on some labels. - if (bRequestLayout) - mpToolBar->RequestLayout(); - else - Invalidate(false); -} - -void Label::Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) -{ - OSL_ASSERT(rxCanvas.is()); - if (!mpMode) - return; - - mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox()); -} - -bool Label::SetState (const bool, const bool) -{ - // For labels there is no mouse over effect. - return Element::SetState(false, false); -} - -} // end of anonymous namespace - -//===== Text ================================================================== - -namespace { - -Text::Text() - : msText(), - mpFont() -{ -} - -Text::Text ( - const OUString& rsText, - const PresenterTheme::SharedFontDescriptor& rpFont) - : msText(rsText), - mpFont(rpFont) -{ -} - -void Text::SetText (const OUString& rsText) -{ - msText = rsText; -} - -const OUString& Text::GetText() const -{ - return msText; -} - -const PresenterTheme::SharedFontDescriptor& Text::GetFont() const -{ - return mpFont; -} - -void Text::Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState, - const awt::Rectangle& rBoundingBox) -{ - OSL_ASSERT(rxCanvas.is()); - - if (msText.isEmpty()) - return; - if (!mpFont) - return; - - if ( ! mpFont->mxFont.is()) - mpFont->PrepareFont(rxCanvas); - if ( ! mpFont->mxFont.is()) - return; - - rendering::StringContext aContext (msText, 0, msText.getLength()); - - Reference<rendering::XTextLayout> xLayout ( - mpFont->mxFont->createTextLayout( - aContext, - rendering::TextDirection::WEAK_LEFT_TO_RIGHT, - 0)); - geometry::RealRectangle2D aBox (xLayout->queryTextBounds()); - const double nTextWidth = aBox.X2 - aBox.X1; - const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2; - const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2; - - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,nX, 0,1,nY), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor); - rxCanvas->drawTextLayout( - xLayout, - rViewState, - aRenderState); -} - -geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas) -{ - if (mpFont && !msText.isEmpty()) - { - if ( ! mpFont->mxFont.is()) - mpFont->PrepareFont(rxCanvas); - if (mpFont->mxFont.is()) - { - rendering::StringContext aContext (msText, 0, msText.getLength()); - Reference<rendering::XTextLayout> xLayout ( - mpFont->mxFont->createTextLayout( - aContext, - rendering::TextDirection::WEAK_LEFT_TO_RIGHT, - 0)); - return xLayout->queryTextBounds(); - } - } - return geometry::RealRectangle2D(0,0,0,0); -} - -//===== TimeFormatter ========================================================= - -OUString TimeFormatter::FormatTime (const oslDateTime& rTime) -{ - OUStringBuffer sText; - - const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours)); - const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes)); - const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds)); - // Hours - sText.append(nHours); - - sText.append(":"); - - // Minutes - const OUString sMinutes (OUString::number(nMinutes)); - if (sMinutes.getLength() == 1) - sText.append("0"); - sText.append(sMinutes); - - // Seconds - sText.append(":"); - const OUString sSeconds (OUString::number(nSeconds)); - if (sSeconds.getLength() == 1) - sText.append("0"); - sText.append(sSeconds); - return sText.makeStringAndClear(); -} - -//===== TimeLabel ============================================================= - -TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : Label(rpToolBar), - mpListener() -{ -} - -void SAL_CALL TimeLabel::disposing() -{ - PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener); - mpListener.reset(); -} - -void TimeLabel::ConnectToTimer() -{ - mpListener = std::make_shared<Listener>(this); - PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener); -} - -//===== CurrentTimeLabel ====================================================== - -::rtl::Reference<Element> CurrentTimeLabel::Create ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) -{ - ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar)); - pElement->ConnectToTimer(); - return pElement; -} - -CurrentTimeLabel::~CurrentTimeLabel() -{ -} - -CurrentTimeLabel::CurrentTimeLabel ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : TimeLabel(rpToolBar) -{ -} - -void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime) -{ - SetText(TimeFormatter::FormatTime(rCurrentTime)); - Invalidate(false); -} - -void CurrentTimeLabel::SetModes ( - const SharedElementMode& rpNormalMode, - const SharedElementMode& rpMouseOverMode, - const SharedElementMode& rpSelectedMode, - const SharedElementMode& rpDisabledMode, - const SharedElementMode& rpMouseOverSelectedMode) -{ - TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode); - SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime())); -} - -//===== PresentationTimeLabel ================================================= - -::rtl::Reference<Element> PresentationTimeLabel::Create ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) -{ - ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar)); - pElement->ConnectToTimer(); - return pElement; -} - -PresentationTimeLabel::~PresentationTimeLabel() -{ - mpToolBar->GetPresenterController()->SetPresentationTime(nullptr); -} - -PresentationTimeLabel::PresentationTimeLabel ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : TimeLabel(rpToolBar), - maStartTimeValue() -{ - restart(); - setPauseStatus(false); - TimeValue pauseTime(0,0); - setPauseTimeValue(pauseTime); - mpToolBar->GetPresenterController()->SetPresentationTime(this); -} - -void PresentationTimeLabel::restart() -{ - TimeValue pauseTime(0, 0); - setPauseTimeValue(pauseTime); - maStartTimeValue.Seconds = 0; - maStartTimeValue.Nanosec = 0; -} - -bool PresentationTimeLabel::isPaused() -{ - return paused; -} - -void PresentationTimeLabel::setPauseStatus(const bool pauseStatus) -{ - paused = pauseStatus; -} - -TimeValue PresentationTimeLabel::getPauseTimeValue() const -{ - return pauseTimeValue; -} - -void PresentationTimeLabel::setPauseTimeValue(const TimeValue pauseTime) -{ - //store the time at which the presentation was paused - pauseTimeValue = pauseTime; -} - -void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime) -{ - TimeValue aCurrentTimeValue; - if (!osl_getTimeValueFromDateTime(&rCurrentTime, &aCurrentTimeValue)) - return; - - if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0) - { - // This method is called for the first time. Initialize the - // start time. The start time is rounded to nearest second to - // keep the time updates synchronized with the current time label. - maStartTimeValue = aCurrentTimeValue; - if (maStartTimeValue.Nanosec >= 500000000) - maStartTimeValue.Seconds += 1; - maStartTimeValue.Nanosec = 0; - } - - //The start time value is incremented by the amount of time - //the presentation was paused for in order to continue the - //timer from the same position - if(!isPaused()) - { - TimeValue pauseTime = getPauseTimeValue(); - if(pauseTime.Seconds != 0 || pauseTime.Nanosec != 0) - { - TimeValue incrementValue(0, 0); - incrementValue.Seconds = aCurrentTimeValue.Seconds - pauseTime.Seconds; - if(pauseTime.Nanosec > aCurrentTimeValue.Nanosec) - { - incrementValue.Nanosec = 1000000000 + aCurrentTimeValue.Nanosec - pauseTime.Nanosec; - } - else - { - incrementValue.Nanosec = aCurrentTimeValue.Nanosec - pauseTime.Nanosec; - } - - maStartTimeValue.Seconds += incrementValue.Seconds; - maStartTimeValue.Nanosec += incrementValue.Nanosec; - if(maStartTimeValue.Nanosec >= 1000000000) - { - maStartTimeValue.Seconds += 1; - maStartTimeValue.Nanosec -= 1000000000; - } - - TimeValue pauseTime_(0, 0); - setPauseTimeValue(pauseTime_); - } - } - else - { - TimeValue pauseTime = getPauseTimeValue(); - if(pauseTime.Seconds == 0 && pauseTime.Nanosec == 0) - { - setPauseTimeValue(aCurrentTimeValue); - } - } - - TimeValue aElapsedTimeValue; - aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds; - aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec; - - oslDateTime aElapsedDateTime; - if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime) && !isPaused()) - { - SetText(TimeFormatter::FormatTime(aElapsedDateTime)); - Invalidate(false); - } -} - -void PresentationTimeLabel::SetModes ( - const SharedElementMode& rpNormalMode, - const SharedElementMode& rpMouseOverMode, - const SharedElementMode& rpSelectedMode, - const SharedElementMode& rpDisabledMode, - const SharedElementMode& rpMouseOverSelectedMode) -{ - TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode); - - oslDateTime aStartDateTime; - if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime)) - { - SetText(TimeFormatter::FormatTime(aStartDateTime)); - } -} - -//===== VerticalSeparator ===================================================== - -VerticalSeparator::VerticalSeparator ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : Element(rpToolBar) -{ -} - -void VerticalSeparator::Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) -{ - OSL_ASSERT(rxCanvas.is()); - - awt::Rectangle aBBox (GetBoundingBox()); - - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,aBBox.X, 0,1,aBBox.Y), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::OVER); - if (mpMode) - { - PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont()); - if (pFont) - PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor); - } - - Reference<rendering::XBitmap> xBitmap(mpToolBar->GetPresenterController()->GetPresenterHelper()->loadBitmap("bitmaps/Separator.png", rxCanvas)); - if (!xBitmap.is()) - return; - - rxCanvas->drawBitmap( - xBitmap, - rViewState, - aRenderState); -} - -awt::Size VerticalSeparator::CreateBoundingSize ( - const Reference<rendering::XCanvas>&) -{ - return awt::Size(1,20); -} - -bool VerticalSeparator::IsFilling() const -{ - return true; -} - -//===== HorizontalSeparator =================================================== - -HorizontalSeparator::HorizontalSeparator ( - const ::rtl::Reference<PresenterToolBar>& rpToolBar) - : Element(rpToolBar) -{ -} - -void HorizontalSeparator::Paint ( - const Reference<rendering::XCanvas>& rxCanvas, - const rendering::ViewState& rViewState) -{ - OSL_ASSERT(rxCanvas.is()); - - awt::Rectangle aBBox (GetBoundingBox()); - - rendering::RenderState aRenderState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::OVER); - if (mpMode) - { - PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont()); - if (pFont) - PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor); - } - - rxCanvas->fillPolyPolygon( - PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()), - rViewState, - aRenderState); -} - -awt::Size HorizontalSeparator::CreateBoundingSize ( - const Reference<rendering::XCanvas>&) -{ - return awt::Size(20,1); -} - -bool HorizontalSeparator::IsFilling() const -{ - return true; -} - -} // end of anonymous namespace - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterToolBar.hxx b/sdext/source/presenter/PresenterToolBar.hxx deleted file mode 100644 index 90931df311a5..000000000000 --- a/sdext/source/presenter/PresenterToolBar.hxx +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTOOLBAR_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERTOOLBAR_HXX - -#include "PresenterController.hxx" -#include "PresenterViewFactory.hxx" - -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <com/sun/star/awt/XMouseListener.hpp> -#include <com/sun/star/awt/XMouseMotionListener.hpp> -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/drawing/XDrawPage.hpp> -#include <com/sun/star/drawing/XDrawView.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/drawing/framework/XResourceId.hpp> -#include <com/sun/star/frame/XController.hpp> - -#include <functional> - -namespace sdext::presenter { - -typedef cppu::WeakComponentImplHelper< - css::awt::XWindowListener, - css::awt::XPaintListener, - css::awt::XMouseListener, - css::awt::XMouseMotionListener, - css::drawing::XDrawView - > PresenterToolBarInterfaceBase; - -typedef cppu::WeakComponentImplHelper< - css::awt::XPaintListener, - css::drawing::framework::XView, - css::drawing::XDrawView - > PresenterToolBarViewInterfaceBase; - -/** A simple tool bar that can display bitmapped buttons and labels. At the - moment there are buttons for moving to the next and previous slide and - to the next effect. A label displays the index of the current slide - and the total number of slides. -*/ -class PresenterToolBar - : private ::cppu::BaseMutex, - public PresenterToolBarInterfaceBase, - public CachablePresenterView -{ -public: - typedef ::std::function<void ()> Action; - - enum Anchor { Left, Center }; - - PresenterToolBar ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::awt::XWindow>& rxWindow, - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const ::rtl::Reference<PresenterController>& rpPresenterController, - const Anchor eAnchor); - virtual ~PresenterToolBar() override; - PresenterToolBar(const PresenterToolBar&) = delete; - PresenterToolBar& operator=(const PresenterToolBar&) = delete; - - void Initialize ( - const OUString& rsConfigurationPath); - - virtual void SAL_CALL disposing() override; - - void InvalidateArea ( - const css::awt::Rectangle& rRepaintBox, - const bool bSynchronous); - - void RequestLayout(); - css::geometry::RealSize2D const & GetMinimalSize(); - const ::rtl::Reference<PresenterController>& GetPresenterController() const; - const css::uno::Reference<css::uno::XComponentContext>& GetComponentContext() const; - - // lang::XEventListener - - virtual void SAL_CALL - disposing (const css::lang::EventObject& rEventObject) override; - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XMouseListener - - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - - // XMouseMotionListener - - virtual void SAL_CALL mouseMoved (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseDragged (const css::awt::MouseEvent& rEvent) override; - - // XDrawView - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override; - - virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage() override; - - class Context; - -private: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - - class ElementContainerPart; - typedef std::shared_ptr<ElementContainerPart> SharedElementContainerPart; - typedef ::std::vector<SharedElementContainerPart> ElementContainer; - ElementContainer maElementContainer; - SharedElementContainerPart mpCurrentContainerPart; - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - css::uno::Reference<css::presentation::XSlideShowController> mxSlideShowController; - css::uno::Reference<css::drawing::XDrawPage> mxCurrentSlide; - ::rtl::Reference<PresenterController> mpPresenterController; - bool mbIsLayoutPending; - const Anchor meAnchor; - /** The minimal size that is necessary to display all elements without - overlap and with minimal gaps between them. - */ - css::geometry::RealSize2D maMinimalSize; - - void CreateControls ( - const OUString& rsConfigurationPath); - void Layout (const css::uno::Reference<css::rendering::XCanvas>& rxCanvas); - css::geometry::RealSize2D CalculatePartSize ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const SharedElementContainerPart& rpPart, - const bool bIsHorizontal); - static void LayoutPart ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const SharedElementContainerPart& rpPart, - const css::geometry::RealRectangle2D& rBoundingBox, - const css::geometry::RealSize2D& rPartSize, - const bool bIsHorizontal); - void Paint ( - const css::awt::Rectangle& rUpdateBox, - const css::rendering::ViewState& rViewState); - - void UpdateSlideNumber(); - - void CheckMouseOver ( - const css::awt::MouseEvent& rEvent, - const bool bOverWindow, - const bool bMouseDown=false); - - void ProcessEntry ( - const css::uno::Reference<css::beans::XPropertySet>& rProperties, - Context const & rContext); - - /** @throws css::lang::DisposedException when the object has already been - disposed. - */ - void ThrowIfDisposed() const; -}; - -/** View for the PresenterToolBar. -*/ -class PresenterToolBarView - : private ::cppu::BaseMutex, - public PresenterToolBarViewInterfaceBase -{ -public: - explicit PresenterToolBarView ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterToolBarView() override; - PresenterToolBarView(const PresenterToolBarView&) = delete; - PresenterToolBarView& operator=(const PresenterToolBarView&) = delete; - - virtual void SAL_CALL disposing() override; - - const ::rtl::Reference<PresenterToolBar>& GetPresenterToolBar() const; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // lang::XEventListener - - virtual void SAL_CALL - disposing (const css::lang::EventObject& rEventObject) override; - - // XResourceId - - virtual css::uno::Reference<css::drawing::framework::XResourceId> SAL_CALL getResourceId() override; - - virtual sal_Bool SAL_CALL isAnchorOnly() override; - - // XDrawView - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override; - - virtual css::uno::Reference<css::drawing::XDrawPage> SAL_CALL getCurrentPage() override; - -private: - // css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - css::uno::Reference<css::drawing::framework::XPane> mxPane; - css::uno::Reference<css::drawing::framework::XResourceId> mxViewId; - css::uno::Reference<css::awt::XWindow> mxWindow; - css::uno::Reference<css::rendering::XCanvas> mxCanvas; - ::rtl::Reference<PresenterController> mpPresenterController; - ::rtl::Reference<PresenterToolBar> mpToolBar; - -}; - -} // end of namespace ::sdext::presenter - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterUIPainter.cxx b/sdext/source/presenter/PresenterUIPainter.cxx deleted file mode 100644 index 7b37736ff39d..000000000000 --- a/sdext/source/presenter/PresenterUIPainter.cxx +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include <algorithm> - -#include "PresenterUIPainter.hxx" - -#include "PresenterGeometryHelper.hxx" -#include <com/sun/star/rendering/CompositeOperation.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace sdext::presenter { - -void PresenterUIPainter::PaintHorizontalBitmapComposite ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::awt::Rectangle& rBoundingBox, - const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap) -{ - if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox)) - { - // The bounding box lies completely outside the repaint area. - // Nothing has to be repainted. - return; - } - - // Get bitmap sizes. - geometry::IntegerSize2D aLeftBitmapSize; - if (rxLeftBitmap.is()) - aLeftBitmapSize = rxLeftBitmap->getSize(); - geometry::IntegerSize2D aCenterBitmapSize; - if (rxRepeatableCenterBitmap.is()) - aCenterBitmapSize = rxRepeatableCenterBitmap->getSize(); - geometry::IntegerSize2D aRightBitmapSize; - if (rxRightBitmap.is()) - aRightBitmapSize = rxRightBitmap->getSize(); - - // Prepare painting. - rendering::ViewState aViewState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - // Paint the left bitmap once. - if (rxLeftBitmap.is()) - { - const awt::Rectangle aLeftBoundingBox ( - rBoundingBox.X, - rBoundingBox.Y, - ::std::min(aLeftBitmapSize.Width, rBoundingBox.Width), - rBoundingBox.Height); - aViewState.Clip.set( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rRepaintBox, aLeftBoundingBox), - rxCanvas->getDevice())); - aRenderState.AffineTransform.m02 = aLeftBoundingBox.X; - aRenderState.AffineTransform.m12 - = aLeftBoundingBox.Y + (aLeftBoundingBox.Height - aLeftBitmapSize.Height) / 2; - rxCanvas->drawBitmap(rxLeftBitmap, aViewState, aRenderState); - } - - // Paint the right bitmap once. - if (rxRightBitmap.is()) - { - const awt::Rectangle aRightBoundingBox ( - rBoundingBox.X + rBoundingBox.Width - aRightBitmapSize.Width, - rBoundingBox.Y, - ::std::min(aRightBitmapSize.Width, rBoundingBox.Width), - rBoundingBox.Height); - aViewState.Clip.set( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rRepaintBox, aRightBoundingBox), - rxCanvas->getDevice())); - aRenderState.AffineTransform.m02 - = aRightBoundingBox.X + aRightBoundingBox.Width - aRightBitmapSize.Width; - aRenderState.AffineTransform.m12 - = aRightBoundingBox.Y + (aRightBoundingBox.Height - aRightBitmapSize.Height) / 2; - rxCanvas->drawBitmap(rxRightBitmap, aViewState, aRenderState); - } - - // Paint the center bitmap to fill the remaining space. - if (!rxRepeatableCenterBitmap.is()) - return; - - const awt::Rectangle aCenterBoundingBox ( - rBoundingBox.X + aLeftBitmapSize.Width, - rBoundingBox.Y, - rBoundingBox.Width - aLeftBitmapSize.Width - aRightBitmapSize.Width, - rBoundingBox.Height); - if (aCenterBoundingBox.Width <= 0) - return; - - aViewState.Clip.set( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox), - rxCanvas->getDevice())); - sal_Int32 nX (aCenterBoundingBox.X); - const sal_Int32 nRight (aCenterBoundingBox.X + aCenterBoundingBox.Width - 1); - aRenderState.AffineTransform.m12 - = aCenterBoundingBox.Y + (aCenterBoundingBox.Height-aCenterBitmapSize.Height) / 2; - while(nX <= nRight) - { - aRenderState.AffineTransform.m02 = nX; - rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState); - nX += aCenterBitmapSize.Width; - } -} - -void PresenterUIPainter::PaintVerticalBitmapComposite ( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, - const css::awt::Rectangle& rBoundingBox, - const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap) -{ - if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox)) - { - // The bounding box lies completely outside the repaint area. - // Nothing has to be repainted. - return; - } - - // Get bitmap sizes. - geometry::IntegerSize2D aTopBitmapSize; - if (rxTopBitmap.is()) - aTopBitmapSize = rxTopBitmap->getSize(); - geometry::IntegerSize2D aCenterBitmapSize; - if (rxRepeatableCenterBitmap.is()) - aCenterBitmapSize = rxRepeatableCenterBitmap->getSize(); - geometry::IntegerSize2D aBottomBitmapSize; - if (rxBottomBitmap.is()) - aBottomBitmapSize = rxBottomBitmap->getSize(); - - // Prepare painting. - rendering::ViewState aViewState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr); - - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - nullptr, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - // Paint the top bitmap once. - if (rxTopBitmap.is()) - { - const awt::Rectangle aTopBoundingBox ( - rBoundingBox.X, - rBoundingBox.Y, - rBoundingBox.Width, - ::std::min(aTopBitmapSize.Height, rBoundingBox.Height)); - aViewState.Clip.set( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rRepaintBox, aTopBoundingBox), - rxCanvas->getDevice())); - aRenderState.AffineTransform.m02 - = aTopBoundingBox.X + (aTopBoundingBox.Width - aTopBitmapSize.Width) / 2; - aRenderState.AffineTransform.m12 = aTopBoundingBox.Y; - rxCanvas->drawBitmap(rxTopBitmap, aViewState, aRenderState); - } - - // Paint the bottom bitmap once. - if (rxBottomBitmap.is()) - { - const sal_Int32 nBBoxHeight (::std::min(aBottomBitmapSize.Height, rBoundingBox.Height)); - const awt::Rectangle aBottomBoundingBox ( - rBoundingBox.X, - rBoundingBox.Y + rBoundingBox.Height - nBBoxHeight, - rBoundingBox.Width, - nBBoxHeight); - aViewState.Clip.set( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rRepaintBox, aBottomBoundingBox), - rxCanvas->getDevice())); - aRenderState.AffineTransform.m02 - = aBottomBoundingBox.X + (aBottomBoundingBox.Width - aBottomBitmapSize.Width) / 2; - aRenderState.AffineTransform.m12 - = aBottomBoundingBox.Y + aBottomBoundingBox.Height - aBottomBitmapSize.Height; - rxCanvas->drawBitmap(rxBottomBitmap, aViewState, aRenderState); - } - - // Paint the center bitmap to fill the remaining space. - if (!rxRepeatableCenterBitmap.is()) - return; - - const awt::Rectangle aCenterBoundingBox ( - rBoundingBox.X, - rBoundingBox.Y + aTopBitmapSize.Height, - rBoundingBox.Width, - rBoundingBox.Height - aTopBitmapSize.Height - aBottomBitmapSize.Height); - if (aCenterBoundingBox.Height <= 0) - return; - - aViewState.Clip.set( - PresenterGeometryHelper::CreatePolygon( - PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox), - rxCanvas->getDevice())); - sal_Int32 nY (aCenterBoundingBox.Y); - const sal_Int32 nBottom (aCenterBoundingBox.Y + aCenterBoundingBox.Height - 1); - aRenderState.AffineTransform.m02 - = aCenterBoundingBox.X + (aCenterBoundingBox.Width-aCenterBitmapSize.Width) / 2; - while(nY <= nBottom) - { - aRenderState.AffineTransform.m12 = nY; - rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState); - nY += aCenterBitmapSize.Height; - } -} - -} // end of namespace sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterUIPainter.hxx b/sdext/source/presenter/PresenterUIPainter.hxx deleted file mode 100644 index f21ca291a147..000000000000 --- a/sdext/source/presenter/PresenterUIPainter.hxx +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERUIPAINTER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERUIPAINTER_HXX - -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/rendering/XCanvas.hpp> -#include <com/sun/star/rendering/XBitmap.hpp> - -namespace sdext::presenter -{ -/** Functions for painting UI elements. -*/ -class PresenterUIPainter -{ -public: - PresenterUIPainter() = delete; - PresenterUIPainter(const PresenterUIPainter&) = delete; - PresenterUIPainter& operator=(const PresenterUIPainter&) = delete; - - static void PaintHorizontalBitmapComposite( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, const css::awt::Rectangle& rBoundingBox, - const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap); - - static void PaintVerticalBitmapComposite( - const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, - const css::awt::Rectangle& rRepaintBox, const css::awt::Rectangle& rBoundingBox, - const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, - const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap); -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterViewFactory.cxx b/sdext/source/presenter/PresenterViewFactory.cxx deleted file mode 100644 index 01b40d6e2ab8..000000000000 --- a/sdext/source/presenter/PresenterViewFactory.cxx +++ /dev/null @@ -1,506 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PresenterViewFactory.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterHelpView.hxx" -#include "PresenterNotesView.hxx" -#include "PresenterSlideShowView.hxx" -#include "PresenterSlidePreview.hxx" -#include "PresenterSlideSorter.hxx" -#include "PresenterToolBar.hxx" -#include <com/sun/star/drawing/framework/XControllerManager.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -namespace { - -/** By default the PresenterSlidePreview shows the preview of the current - slide. This adapter class makes it display the preview of the next - slide. -*/ -class NextSlidePreview : public PresenterSlidePreview -{ -public: - NextSlidePreview ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController) - { - } - - virtual void SAL_CALL setCurrentPage ( - const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override - { - Reference<presentation::XSlideShowController> xSlideShowController ( - mpPresenterController->GetSlideShowController()); - Reference<drawing::XDrawPage> xSlide; - if (xSlideShowController.is()) - { - const sal_Int32 nCount (xSlideShowController->getSlideCount()); - sal_Int32 nNextSlideIndex (-1); - if (xSlideShowController->getCurrentSlide() == rxSlide) - { - nNextSlideIndex = xSlideShowController->getNextSlideIndex(); - } - else - { - for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) - { - if (rxSlide == xSlideShowController->getSlideByIndex(nIndex)) - { - nNextSlideIndex = nIndex + 1; - } - } - } - if (nNextSlideIndex >= 0) - { - if (nNextSlideIndex < nCount) - { - xSlide = xSlideShowController->getSlideByIndex(nNextSlideIndex); - } - } - } - PresenterSlidePreview::setCurrentPage(xSlide); - } -}; - -} // end of anonymous namespace - -//===== PresenterViewFactory ============================================== - -PresenterViewFactory::PresenterViewFactory ( - const Reference<uno::XComponentContext>& rxContext, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterViewFactoryInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - mxConfigurationController(), - mxControllerWeak(rxController), - mpPresenterController(rpPresenterController), - mpResourceCache() -{ -} - -Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create ( - const Reference<uno::XComponentContext>& rxContext, - const Reference<frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController) -{ - rtl::Reference<PresenterViewFactory> pFactory ( - new PresenterViewFactory(rxContext,rxController,rpPresenterController)); - pFactory->Register(rxController); - return Reference<drawing::framework::XResourceFactory>( - static_cast<XWeak*>(pFactory.get()), UNO_QUERY); -} - -void PresenterViewFactory::Register (const Reference<frame::XController>& rxController) -{ - try - { - // Get the configuration controller. - Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); - mxConfigurationController = xCM->getConfigurationController(); - if ( ! mxConfigurationController.is()) - { - throw RuntimeException(); - } - mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this); - mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this); - mxConfigurationController->addResourceFactory(msNotesViewURL, this); - mxConfigurationController->addResourceFactory(msToolBarViewURL, this); - mxConfigurationController->addResourceFactory(msSlideSorterURL, this); - mxConfigurationController->addResourceFactory(msHelpViewURL, this); - } - catch (RuntimeException&) - { - OSL_ASSERT(false); - if (mxConfigurationController.is()) - mxConfigurationController->removeResourceFactoryForReference(this); - mxConfigurationController = nullptr; - - throw; - } -} - -PresenterViewFactory::~PresenterViewFactory() -{ -} - -void SAL_CALL PresenterViewFactory::disposing() -{ - if (mxConfigurationController.is()) - mxConfigurationController->removeResourceFactoryForReference(this); - mxConfigurationController = nullptr; - - if (mpResourceCache == nullptr) - return; - - // Dispose all views in the cache. - for (const auto& rView : *mpResourceCache) - { - try - { - Reference<lang::XComponent> xComponent (rView.second.first, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - } - catch (lang::DisposedException&) - { - } - } - mpResourceCache.reset(); -} - -//----- XViewFactory ---------------------------------------------------------- - -Reference<XResource> SAL_CALL PresenterViewFactory::createResource ( - const Reference<XResourceId>& rxViewId) -{ - ThrowIfDisposed(); - - Reference<XResource> xView; - - if (rxViewId.is()) - { - Reference<XPane> xAnchorPane ( - mxConfigurationController->getResource(rxViewId->getAnchor()), - UNO_QUERY_THROW); - xView = GetViewFromCache(rxViewId, xAnchorPane); - if (xView == nullptr) - xView = CreateView(rxViewId, xAnchorPane); - - // Activate the view. - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor())); - if (pDescriptor) - pDescriptor->SetActivationState(true); - } - - return xView; -} - -void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView) -{ - ThrowIfDisposed(); - - if ( ! rxView.is()) - return; - - // Deactivate the view. - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPresenterController->GetPaneContainer()->FindPaneId( - rxView->getResourceId()->getAnchor())); - if (pDescriptor) - pDescriptor->SetActivationState(false); - - // Dispose only views that we can not put into the cache. - CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get()); - if (pView == nullptr || mpResourceCache == nullptr) - { - try - { - if (pView != nullptr) - pView->ReleaseView(); - Reference<lang::XComponent> xComponent (rxView, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - } - catch (lang::DisposedException&) - { - // Do not let disposed exceptions get out. It might be interpreted - // as coming from the factory, which would then be removed from the - // drawing framework. - } - } - else - { - // Put cacheable views in the cache. - Reference<XResourceId> xViewId (rxView->getResourceId()); - if (xViewId.is()) - { - Reference<XPane> xAnchorPane ( - mxConfigurationController->getResource(xViewId->getAnchor()), - UNO_QUERY_THROW); - (*mpResourceCache)[xViewId->getResourceURL()] - = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane); - pView->DeactivatePresenterView(); - } - } -} - - -Reference<XResource> PresenterViewFactory::GetViewFromCache( - const Reference<XResourceId>& rxViewId, - const Reference<XPane>& rxAnchorPane) const -{ - if (mpResourceCache == nullptr) - return nullptr; - - try - { - const OUString sResourceURL (rxViewId->getResourceURL()); - - // Can we use a view from the cache? - ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL)); - if (iView != mpResourceCache->end()) - { - // The view is in the container but it can only be used if - // the anchor pane is the same now as it was at creation of - // the view. - if (iView->second.second == rxAnchorPane) - { - CachablePresenterView* pView - = dynamic_cast<CachablePresenterView*>(iView->second.first.get()); - if (pView != nullptr) - pView->ActivatePresenterView(); - return iView->second.first; - } - - // Right view, wrong pane. Create a new view. - } - } - catch (RuntimeException&) - { - } - return nullptr; -} - -Reference<XResource> PresenterViewFactory::CreateView( - const Reference<XResourceId>& rxViewId, - const Reference<XPane>& rxAnchorPane) -{ - Reference<XView> xView; - - try - { - const OUString sResourceURL (rxViewId->getResourceURL()); - - if (sResourceURL == msCurrentSlidePreviewViewURL) - { - xView = CreateSlideShowView(rxViewId); - } - else if (sResourceURL == msNotesViewURL) - { - xView = CreateNotesView(rxViewId); - } - else if (sResourceURL == msNextSlidePreviewViewURL) - { - xView = CreateSlidePreviewView(rxViewId, rxAnchorPane); - } - else if (sResourceURL == msToolBarViewURL) - { - xView = CreateToolBarView(rxViewId); - } - else if (sResourceURL == msSlideSorterURL) - { - xView = CreateSlideSorterView(rxViewId); - } - else if (sResourceURL == msHelpViewURL) - { - xView = CreateHelpView(rxViewId); - } - - // Activate it. - CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get()); - if (pView != nullptr) - pView->ActivatePresenterView(); - } - catch (RuntimeException&) - { - xView = nullptr; - } - - return xView; -} - -Reference<XView> PresenterViewFactory::CreateSlideShowView( - const Reference<XResourceId>& rxViewId) const -{ - Reference<XView> xView; - - if ( ! mxConfigurationController.is()) - return xView; - if ( ! mxComponentContext.is()) - return xView; - - try - { - rtl::Reference<PresenterSlideShowView> pShowView ( - new PresenterSlideShowView( - mxComponentContext, - rxViewId, - Reference<frame::XController>(mxControllerWeak), - mpPresenterController)); - pShowView->LateInit(); - xView = pShowView; - } - catch (RuntimeException&) - { - xView = nullptr; - } - - return xView; -} - -Reference<XView> PresenterViewFactory::CreateSlidePreviewView( - const Reference<XResourceId>& rxViewId, - const Reference<XPane>& rxAnchorPane) const -{ - Reference<XView> xView; - - if ( ! mxConfigurationController.is()) - return xView; - if ( ! mxComponentContext.is()) - return xView; - - try - { - xView.set( - static_cast<XWeak*>(new NextSlidePreview( - mxComponentContext, - rxViewId, - rxAnchorPane, - mpPresenterController)), - UNO_QUERY_THROW); - } - catch (RuntimeException&) - { - xView = nullptr; - } - - return xView; -} - -Reference<XView> PresenterViewFactory::CreateToolBarView( - const Reference<XResourceId>& rxViewId) const -{ - return new PresenterToolBarView( - mxComponentContext, - rxViewId, - Reference<frame::XController>(mxControllerWeak), - mpPresenterController); -} - -Reference<XView> PresenterViewFactory::CreateNotesView( - const Reference<XResourceId>& rxViewId) const -{ - Reference<XView> xView; - - if ( ! mxConfigurationController.is()) - return xView; - if ( ! mxComponentContext.is()) - return xView; - - try - { - xView.set(static_cast<XWeak*>( - new PresenterNotesView( - mxComponentContext, - rxViewId, - Reference<frame::XController>(mxControllerWeak), - mpPresenterController)), - UNO_QUERY_THROW); - } - catch (RuntimeException&) - { - xView = nullptr; - } - - return xView; -} - -Reference<XView> PresenterViewFactory::CreateSlideSorterView( - const Reference<XResourceId>& rxViewId) const -{ - Reference<XView> xView; - - if ( ! mxConfigurationController.is()) - return xView; - if ( ! mxComponentContext.is()) - return xView; - - try - { - rtl::Reference<PresenterSlideSorter> pView ( - new PresenterSlideSorter( - mxComponentContext, - rxViewId, - Reference<frame::XController>(mxControllerWeak), - mpPresenterController)); - xView = pView.get(); - } - catch (RuntimeException&) - { - xView = nullptr; - } - - return xView; -} - -Reference<XView> PresenterViewFactory::CreateHelpView( - const Reference<XResourceId>& rxViewId) const -{ - return Reference<XView>(new PresenterHelpView( - mxComponentContext, - rxViewId, - Reference<frame::XController>(mxControllerWeak), - mpPresenterController)); -} - -void PresenterViewFactory::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterViewFactory object has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -//===== CachablePresenterView ================================================= - -CachablePresenterView::CachablePresenterView() - : mbIsPresenterViewActive(true) -{ -} - -void CachablePresenterView::ActivatePresenterView() -{ - mbIsPresenterViewActive = true; -} - -void CachablePresenterView::DeactivatePresenterView() -{ - mbIsPresenterViewActive = false; -} - -void CachablePresenterView::ReleaseView() -{ -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterViewFactory.hxx b/sdext/source/presenter/PresenterViewFactory.hxx deleted file mode 100644 index 30d488cfc0a7..000000000000 --- a/sdext/source/presenter/PresenterViewFactory.hxx +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERVIEWFACTORY_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERVIEWFACTORY_HXX - -#include "PresenterController.hxx" -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> -#include <com/sun/star/drawing/framework/XConfigurationController.hpp> -#include <com/sun/star/drawing/framework/XResourceFactory.hpp> -#include <com/sun/star/drawing/framework/XView.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <rtl/ref.hxx> -#include <memory> - -namespace sdext::presenter { - -typedef ::cppu::WeakComponentImplHelper < - css::drawing::framework::XResourceFactory -> PresenterViewFactoryInterfaceBase; - -/** Base class for presenter views that allows the view factory to store - them in a cache and reuse deactivated views. -*/ -class CachablePresenterView -{ -public: - virtual void ActivatePresenterView(); - - /** Called when the view is put into a cache. The view must not paint - itself while being deactivated. - */ - virtual void DeactivatePresenterView(); - - /** Called before the view is disposed. This gives the view the - opportunity to trigger actions that may lead to (synchronous) - callbacks that do not result in DisposedExceptions. - */ - virtual void ReleaseView(); - -protected: - bool mbIsPresenterViewActive; - - CachablePresenterView(); - - ~CachablePresenterView() {} -}; - -/** Factory of the presenter screen specific views. The supported set of - views includes: - a life view of the current slide, - a static preview of the next slide, - the notes of the current slide, - a tool bar -*/ -class PresenterViewFactory - : public ::cppu::BaseMutex, - public PresenterViewFactoryInterfaceBase -{ -public: - static constexpr OUStringLiteral msCurrentSlidePreviewViewURL - = u"private:resource/view/Presenter/CurrentSlidePreview"; - static constexpr OUStringLiteral msNextSlidePreviewViewURL - = u"private:resource/view/Presenter/NextSlidePreview"; - static constexpr OUStringLiteral msNotesViewURL = u"private:resource/view/Presenter/Notes"; - static constexpr OUStringLiteral msToolBarViewURL = u"private:resource/view/Presenter/ToolBar"; - static constexpr OUStringLiteral msSlideSorterURL - = u"private:resource/view/Presenter/SlideSorter"; - static constexpr OUStringLiteral msHelpViewURL = u"private:resource/view/Presenter/Help"; - - /** Create a new instance of this class and register it as resource - factory in the drawing framework of the given controller. - This registration keeps it alive. When the drawing framework is - shut down and releases its reference to the factory then the factory - is destroyed. - */ - static css::uno::Reference<css::drawing::framework::XResourceFactory> Create ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterViewFactory() override; - - virtual void SAL_CALL disposing() override; - - // XResourceFactory - - virtual css::uno::Reference<css::drawing::framework::XResource> - SAL_CALL createResource ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) override; - - virtual void SAL_CALL - releaseResource ( - const css::uno::Reference<css::drawing::framework::XResource>& rxPane) override; - -private: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - css::uno::Reference<css::drawing::framework::XConfigurationController> - mxConfigurationController; - css::uno::WeakReference<css::frame::XController> mxControllerWeak; - ::rtl::Reference<PresenterController> mpPresenterController; - typedef ::std::pair<css::uno::Reference<css::drawing::framework::XView>, - css::uno::Reference<css::drawing::framework::XPane> > ViewResourceDescriptor; - typedef ::std::map<OUString, ViewResourceDescriptor> ResourceContainer; - std::unique_ptr<ResourceContainer> mpResourceCache; - - PresenterViewFactory ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const css::uno::Reference<css::frame::XController>& rxController, - const ::rtl::Reference<PresenterController>& rpPresenterController); - - void Register (const css::uno::Reference<css::frame::XController>& rxController); - - css::uno::Reference<css::drawing::framework::XView> CreateSlideShowView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const; - - css::uno::Reference<css::drawing::framework::XView> CreateSlidePreviewView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::drawing::framework::XPane>& rxPane) const; - - css::uno::Reference<css::drawing::framework::XView> CreateToolBarView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const; - - css::uno::Reference<css::drawing::framework::XView> CreateNotesView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const; - - css::uno::Reference<css::drawing::framework::XView> CreateSlideSorterView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const; - - css::uno::Reference<css::drawing::framework::XView> CreateHelpView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId) const; - - css::uno::Reference<css::drawing::framework::XResource> GetViewFromCache ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane) const; - css::uno::Reference<css::drawing::framework::XResource> CreateView( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, - const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane); - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterWindowManager.cxx b/sdext/source/presenter/PresenterWindowManager.cxx deleted file mode 100644 index f6ff53852ea6..000000000000 --- a/sdext/source/presenter/PresenterWindowManager.cxx +++ /dev/null @@ -1,1051 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <vcl/settings.hxx> -#include "PresenterWindowManager.hxx" -#include "PresenterController.hxx" -#include "PresenterGeometryHelper.hxx" -#include "PresenterPaintManager.hxx" -#include "PresenterPaneBorderPainter.hxx" -#include "PresenterPaneContainer.hxx" -#include "PresenterPaneFactory.hxx" -#include "PresenterToolBar.hxx" -#include "PresenterViewFactory.hxx" -#include "PresenterTheme.hxx" -#include <com/sun/star/awt/InvalidateStyle.hpp> -#include <com/sun/star/awt/PosSize.hpp> -#include <com/sun/star/awt/XWindow2.hpp> -#include <com/sun/star/awt/XWindowPeer.hpp> -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/rendering/FillRule.hpp> -#include <com/sun/star/rendering/Texture.hpp> -#include <com/sun/star/rendering/TexturingMode.hpp> -#include <math.h> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::drawing::framework; - -namespace sdext::presenter { - -//===== PresenterWindowManager ================================================ - -PresenterWindowManager::PresenterWindowManager ( - const Reference<XComponentContext>& rxContext, - const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer, - const ::rtl::Reference<PresenterController>& rpPresenterController) - : PresenterWindowManagerInterfaceBase(m_aMutex), - mxComponentContext(rxContext), - mpPresenterController(rpPresenterController), - mxParentWindow(), - mxParentCanvas(), - mxPaneBorderManager(), - mpPaneBorderPainter(), - mpPaneContainer(rpPaneContainer), - mbIsLayoutPending(true), - mbIsLayouting(false), - mpTheme(), - mpBackgroundBitmap(), - mxScaledBackgroundBitmap(), - mxClipPolygon(), - meLayoutMode(LM_Generic), - mbIsSlideSorterActive(false), - mbIsHelpViewActive(false), - mbisPaused(false), - maLayoutListeners(), - mbIsMouseClickPending(false) -{ - -} - -PresenterWindowManager::~PresenterWindowManager() -{ -} - -void SAL_CALL PresenterWindowManager::disposing() -{ - NotifyDisposing(); - - SetParentPane(nullptr); - - Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - mxPaneBorderManager = nullptr; - - for (const auto& rxPane : mpPaneContainer->maPanes) - { - if (rxPane->mxBorderWindow.is()) - { - rxPane->mxBorderWindow->removeWindowListener(this); - rxPane->mxBorderWindow->removeFocusListener(this); - rxPane->mxBorderWindow->removeMouseListener(this); - } - } -} - -void PresenterWindowManager::SetParentPane ( - const Reference<drawing::framework::XPane>& rxPane) -{ - if (mxParentWindow.is()) - { - mxParentWindow->removeWindowListener(this); - mxParentWindow->removePaintListener(this); - mxParentWindow->removeMouseListener(this); - mxParentWindow->removeFocusListener(this); - } - mxParentWindow = nullptr; - mxParentCanvas = nullptr; - - if (rxPane.is()) - { - mxParentWindow = rxPane->getWindow(); - mxParentCanvas = rxPane->getCanvas(); - } - else - { - mxParentWindow = nullptr; - } - - if (mxParentWindow.is()) - { - mxParentWindow->addWindowListener(this); - mxParentWindow->addPaintListener(this); - mxParentWindow->addMouseListener(this); - mxParentWindow->addFocusListener(this); - - // We paint our own background, make that of the parent window transparent. - Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY); - if (xPeer.is()) - xPeer->setBackground(util::Color(0xff000000)); - } -} - -void PresenterWindowManager::SetTheme (const std::shared_ptr<PresenterTheme>& rpTheme) -{ - mpTheme = rpTheme; - - // Get background bitmap or background color from the theme. - - if (mpTheme != nullptr) - { - mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), "Background"); - } -} - -void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView) -{ - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor())); - OSL_ASSERT(pDescriptor); - if (pDescriptor) - { - Layout(); - - mpPresenterController->GetPaintManager()->Invalidate( - pDescriptor->mxContentWindow, - sal_Int16(awt::InvalidateStyle::TRANSPARENT - | awt::InvalidateStyle::CHILDREN)); - } -} - -void PresenterWindowManager::SetPanePosSizeAbsolute ( - const OUString& rsPaneURL, - const double nX, - const double nY, - const double nWidth, - const double nHeight) -{ - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPaneContainer->FindPaneURL(rsPaneURL)); - if (pDescriptor) - { - if (pDescriptor->mxBorderWindow.is()) - pDescriptor->mxBorderWindow->setPosSize( - ::sal::static_int_cast<sal_Int32>(nX), - ::sal::static_int_cast<sal_Int32>(nY), - ::sal::static_int_cast<sal_Int32>(nWidth), - ::sal::static_int_cast<sal_Int32>(nHeight), - awt::PosSize::POSSIZE); - } -} - -void PresenterWindowManager::SetPaneBorderPainter ( - const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter) -{ - mpPaneBorderPainter = rPainter; -} - -//----- XWindowListener ------------------------------------------------------- - -void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent) -{ - ThrowIfDisposed(); - if (rEvent.Source == mxParentWindow) - { - Layout(); - } - else - { - Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY); - if (xWindow.is()) - { - UpdateWindowSize(xWindow); - - // Make sure the background of a transparent window is painted. - mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow); - } - } -} - -void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent) -{ - ThrowIfDisposed(); - if (rEvent.Source != mxParentWindow) - { - Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY); - UpdateWindowSize(xWindow); - - // Make sure the background of a transparent window is painted. - mpPresenterController->GetPaintManager()->Invalidate(xWindow); - } -} - -void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject&) {} - -void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject&) {} - -//----- XPaintListener -------------------------------------------------------- - -void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent) -{ - ThrowIfDisposed(); - - if ( ! mxParentWindow.is()) - return; - if ( ! mxParentCanvas.is()) - return; - - if (mpTheme == nullptr) - return; - - try - { - if (mbIsLayoutPending) - Layout(); - PaintBackground(rEvent.UpdateRect); - PaintChildren(rEvent); - } - catch (RuntimeException&) - { - OSL_FAIL("paint failed!"); - } -} - -//----- XMouseListener -------------------------------------------------------- - -void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent&) -{ - if (!mbIsSlideSorterActive) // tdf#127921 - mbIsMouseClickPending = true; -} - -void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent) -{ - if (mbIsMouseClickPending) - { - mbIsMouseClickPending = false; - mpPresenterController->HandleMouseClick(rEvent); - } -} - -void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent&) -{ - mbIsMouseClickPending = false; -} - -void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent&) -{ - mbIsMouseClickPending = false; -} - -//----- XFocusListener -------------------------------------------------------- - -void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& /*rEvent*/) -{ - ThrowIfDisposed(); -} - -void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent&) -{ - ThrowIfDisposed(); -} - -//----- XEventListener -------------------------------------------------------- - -void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent) -{ - if (rEvent.Source == mxParentWindow) - mxParentWindow = nullptr; -} - - -void PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const -{ - // Call windowPaint on all children that lie in or touch the - // update rectangle. - for (const auto& rxPane : mpPaneContainer->maPanes) - { - try - { - // Make sure that the pane shall and can be painted. - if ( ! rxPane->mbIsActive) - continue; - if (rxPane->mbIsSprite) - continue; - if ( ! rxPane->mxPane.is()) - continue; - if ( ! rxPane->mxBorderWindow.is()) - continue; - Reference<awt::XWindow> xBorderWindow (rxPane->mxBorderWindow); - if ( ! xBorderWindow.is()) - continue; - - // Get the area in which the border of the pane has to be painted. - const awt::Rectangle aBorderBox (xBorderWindow->getPosSize()); - const awt::Rectangle aBorderUpdateBox( - PresenterGeometryHelper::Intersection( - rEvent.UpdateRect, - aBorderBox)); - if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0) - continue; - - const awt::Rectangle aLocalBorderUpdateBox( - PresenterGeometryHelper::TranslateRectangle( - aBorderUpdateBox, - -aBorderBox.X, - -aBorderBox.Y)); - - // Invalidate the area of the content window. - mpPresenterController->GetPaintManager()->Invalidate( - xBorderWindow, - aLocalBorderUpdateBox, - sal_Int16(awt::InvalidateStyle::CHILDREN - | awt::InvalidateStyle::NOTRANSPARENT)); - } - catch (RuntimeException&) - { - OSL_FAIL("paint children failed!"); - } - } -} - -void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode) -{ - OSL_ASSERT(mpPresenterController); - - if (meLayoutMode == eMode - && !mbIsSlideSorterActive - && !mbIsHelpViewActive) - return; - - meLayoutMode = eMode; - mbIsSlideSorterActive = false; - mbIsHelpViewActive = false; - - mpPresenterController->RequestViews( - mbIsSlideSorterActive, - meLayoutMode==LM_Notes, - mbIsHelpViewActive); - Layout(); - NotifyLayoutModeChange(); -} - -void PresenterWindowManager::SetSlideSorterState (bool bIsActive) -{ - if (mbIsSlideSorterActive == bIsActive) - return; - - mbIsSlideSorterActive = bIsActive; - if (mbIsSlideSorterActive) - mbIsHelpViewActive = false; - StoreViewMode(GetViewMode()); - - mpPresenterController->RequestViews( - mbIsSlideSorterActive, - meLayoutMode==LM_Notes, - mbIsHelpViewActive); - Layout(); - NotifyLayoutModeChange(); -} - -void PresenterWindowManager::SetHelpViewState (bool bIsActive) -{ - if (mbIsHelpViewActive == bIsActive) - return; - - mbIsHelpViewActive = bIsActive; - if (mbIsHelpViewActive) - mbIsSlideSorterActive = false; - StoreViewMode(GetViewMode()); - - mpPresenterController->RequestViews( - mbIsSlideSorterActive, - meLayoutMode==LM_Notes, - mbIsHelpViewActive); - Layout(); - NotifyLayoutModeChange(); -} - -void PresenterWindowManager::SetPauseState (bool bIsPaused) -{ - if (mbisPaused == bIsPaused) - return; - - mbisPaused = bIsPaused; - - NotifyLayoutModeChange(); -} - -void PresenterWindowManager::SetViewMode (const ViewMode eMode) -{ - switch (eMode) - { - case VM_Standard: - SetSlideSorterState(false); - SetHelpViewState(false); - SetLayoutMode(LM_Standard); - break; - - case VM_Notes: - SetSlideSorterState(false); - SetHelpViewState(false); - SetLayoutMode(LM_Notes); - break; - - case VM_SlideOverview: - SetHelpViewState(false); - SetSlideSorterState(true); - break; - - case VM_Help: - SetHelpViewState(true); - SetSlideSorterState(false); - break; - } - - StoreViewMode(eMode); -} - -PresenterWindowManager::ViewMode PresenterWindowManager::GetViewMode() const -{ - if (mbIsHelpViewActive) - return VM_Help; - else if (mbIsSlideSorterActive) - return VM_SlideOverview; - else if (meLayoutMode == LM_Notes) - return VM_Notes; - else - return VM_Standard; -} - -void PresenterWindowManager::RestoreViewMode() -{ - sal_Int32 nMode (0); - PresenterConfigurationAccess aConfiguration ( - mxComponentContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_ONLY); - aConfiguration.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode; - switch (nMode) - { - default: - case 0: - SetViewMode(VM_Standard); - break; - - case 1: - SetViewMode(VM_Notes); - break; - - case 2: - SetViewMode(VM_SlideOverview); - break; - } -} - -void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode) -{ - try - { - PresenterConfigurationAccess aConfiguration ( - mxComponentContext, - "/org.openoffice.Office.PresenterScreen/", - PresenterConfigurationAccess::READ_WRITE); - aConfiguration.GoToChild("Presenter"); - Any aValue; - switch (eViewMode) - { - default: - case VM_Standard: - aValue <<= sal_Int32(0); - break; - - case VM_Notes: - aValue <<= sal_Int32(1); - break; - - case VM_SlideOverview: - aValue <<= sal_Int32(2); - break; - } - - aConfiguration.SetProperty ("InitialViewMode", aValue); - aConfiguration.CommitChanges(); - } - catch (Exception&) - { - } -} - -void PresenterWindowManager::AddLayoutListener ( - const Reference<document::XEventListener>& rxListener) -{ - maLayoutListeners.push_back(rxListener); -} - -void PresenterWindowManager::RemoveLayoutListener ( - const Reference<document::XEventListener>& rxListener) -{ - // Assume that there are no multiple entries. - auto iListener = std::find(maLayoutListeners.begin(), maLayoutListeners.end(), rxListener); - if (iListener != maLayoutListeners.end()) - maLayoutListeners.erase(iListener); -} - -void PresenterWindowManager::Layout() -{ - if (!mxParentWindow.is() || mbIsLayouting) - return; - - mbIsLayoutPending = false; - mbIsLayouting = true; - mxScaledBackgroundBitmap = nullptr; - mxClipPolygon = nullptr; - - try - { - if (mbIsSlideSorterActive) - LayoutSlideSorterMode(); - else if (mbIsHelpViewActive) - LayoutHelpMode(); - else - switch (meLayoutMode) - { - case LM_Standard: - default: - LayoutStandardMode(); - break; - - case LM_Notes: - LayoutNotesMode(); - break; - } - } - catch (Exception&) - { - OSL_ASSERT(false); - throw; - } - - mbIsLayouting = false; -} - -void PresenterWindowManager::LayoutStandardMode() -{ - awt::Rectangle aBox = mxParentWindow->getPosSize(); - - const double nGoldenRatio ((1 + sqrt(5.0)) / 2); - const double nGap (20); - const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio); - double nSlidePreviewTop (0); - - - // For the current slide view calculate the outer height from the outer - // width. This takes into account the slide aspect ratio and thus has to - // go over the inner pane size. - PresenterPaneContainer::SharedPaneDescriptor pPane ( - mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL)); - if (pPane) - { - const awt::Size aCurrentSlideOuterBox(CalculatePaneSize( - nHorizontalSlideDivide - 1.5*nGap, - PresenterPaneFactory::msCurrentSlidePreviewPaneURL)); - nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2; - double Temp=nGap; - /// check whether RTL interface or not - if(AllSettings::GetLayoutRTL()) - Temp=aBox.Width - aCurrentSlideOuterBox.Width - nGap; - SetPanePosSizeAbsolute ( - PresenterPaneFactory::msCurrentSlidePreviewPaneURL, - Temp, - nSlidePreviewTop, - aCurrentSlideOuterBox.Width, - aCurrentSlideOuterBox.Height); - } - - // For the next slide view calculate the outer height from the outer - // width. This takes into account the slide aspect ratio and thus has to - // go over the inner pane size. - pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL); - if (pPane) - { - const awt::Size aNextSlideOuterBox (CalculatePaneSize( - aBox.Width - nHorizontalSlideDivide - 1.5*nGap, - PresenterPaneFactory::msNextSlidePreviewPaneURL)); - double Temp=aBox.Width - aNextSlideOuterBox.Width - nGap; - /// check whether RTL interface or not - if(AllSettings::GetLayoutRTL()) - Temp=nGap; - SetPanePosSizeAbsolute ( - PresenterPaneFactory::msNextSlidePreviewPaneURL, - Temp, - nSlidePreviewTop, - aNextSlideOuterBox.Width, - aNextSlideOuterBox.Height); - } - - LayoutToolBar(); -} - -void PresenterWindowManager::LayoutNotesMode() -{ - awt::Rectangle aBox = mxParentWindow->getPosSize(); - - const geometry::RealRectangle2D aToolBarBox (LayoutToolBar()); - - const double nGoldenRatio ((1 + sqrt(5.0)) / 2); - const double nGap (20); - const double nPrimaryWidth (aBox.Width / nGoldenRatio); - const double nSecondaryWidth (aBox.Width - nPrimaryWidth); - const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio); - double nSlidePreviewTop (0); - double nNotesViewBottom (aToolBarBox.Y1 - nGap); - /// check whether RTL interface or not - - - // The notes view has no fixed aspect ratio. - PresenterPaneContainer::SharedPaneDescriptor pPane ( - mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL)); - if (pPane) - { - const geometry::RealSize2D aNotesViewOuterSize( - nPrimaryWidth - 1.5*nGap + 0.5, - nNotesViewBottom); - nSlidePreviewTop = (aBox.Height - - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2; - /// check whether RTL interface or not - double Temp=aBox.Width - aNotesViewOuterSize.Width - nGap; - if(AllSettings::GetLayoutRTL()) - Temp=nGap; - SetPanePosSizeAbsolute ( - PresenterPaneFactory::msNotesPaneURL, - Temp, - nSlidePreviewTop, - aNotesViewOuterSize.Width, - aNotesViewOuterSize.Height); - nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height; - } - - // For the current slide view calculate the outer height from the outer - // width. This takes into account the slide aspect ratio and thus has to - // go over the inner pane size. - pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL); - if (pPane) - { - const awt::Size aCurrentSlideOuterBox(CalculatePaneSize( - nSecondaryWidth - 1.5*nGap, - PresenterPaneFactory::msCurrentSlidePreviewPaneURL)); - /// check whether RTL interface or not - double Temp=nGap; - if(AllSettings::GetLayoutRTL()) - Temp=aBox.Width - aCurrentSlideOuterBox.Width - nGap; - SetPanePosSizeAbsolute ( - PresenterPaneFactory::msCurrentSlidePreviewPaneURL, - Temp, - nSlidePreviewTop, - aCurrentSlideOuterBox.Width, - aCurrentSlideOuterBox.Height); - } - - // For the next slide view calculate the outer height from the outer - // width. This takes into account the slide aspect ratio and thus has to - // go over the inner pane size. - pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL); - if (!pPane) - return; - - const awt::Size aNextSlideOuterBox (CalculatePaneSize( - nTertiaryWidth, - PresenterPaneFactory::msNextSlidePreviewPaneURL)); - /// check whether RTL interface or not - double Temp=nGap; - if(AllSettings::GetLayoutRTL()) - Temp=aBox.Width - aNextSlideOuterBox.Width - nGap; - SetPanePosSizeAbsolute ( - PresenterPaneFactory::msNextSlidePreviewPaneURL, - Temp, - nNotesViewBottom - aNextSlideOuterBox.Height, - aNextSlideOuterBox.Width, - aNextSlideOuterBox.Height); - - -} - -void PresenterWindowManager::LayoutSlideSorterMode() -{ - const geometry::RealRectangle2D aToolBarBox (LayoutToolBar()); - - awt::Rectangle aWindowBox = mxParentWindow->getPosSize(); - const double nGap (20); - SetPanePosSizeAbsolute( - mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL), - nGap, - nGap, - aWindowBox.Width - 2*nGap, - aToolBarBox.Y1 - 2*nGap); -} - -void PresenterWindowManager::LayoutHelpMode() -{ - const geometry::RealRectangle2D aToolBarBox (LayoutToolBar()); - - awt::Rectangle aWindowBox = mxParentWindow->getPosSize(); - const double nGap (20); - const double nGoldenRatio ((1 + sqrt(5.0)) / 2); - const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio); - SetPanePosSizeAbsolute( - mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL), - (aWindowBox.Width - nWidth)/2, - nGap, - nWidth, - aToolBarBox.Y1 - 2*nGap); -} - -geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar() -{ - double nToolBarWidth (400); - double nToolBarHeight (80); - - // Get access to the tool bar. - PresenterPaneContainer::SharedPaneDescriptor pDescriptor( - mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL)); - if (pDescriptor) - { - PresenterToolBarView* pToolBarView - = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get()); - if (pToolBarView != nullptr && pToolBarView->GetPresenterToolBar().is()) - { - geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize()); - - if (mpPaneBorderPainter.is()) - { - const awt::Rectangle aBox (mpPaneBorderPainter->addBorder ( - PresenterPaneFactory::msToolBarPaneURL, - awt::Rectangle( - 0, - 0, - PresenterGeometryHelper::Round(aSize.Width), - PresenterGeometryHelper::Round(aSize.Height)), - css::drawing::framework::BorderType_TOTAL_BORDER)); - - nToolBarWidth = aBox.Width; - nToolBarHeight = aBox.Height; - } - else - { - nToolBarWidth = aSize.Width + 20; - nToolBarHeight = aSize.Height + 10; - } - } - } - - const awt::Rectangle aBox = mxParentWindow->getPosSize(); - const double nToolBarX ((aBox.Width - nToolBarWidth) / 2); - const double nToolBarY (aBox.Height - nToolBarHeight); - SetPanePosSizeAbsolute( - PresenterPaneFactory::msToolBarPaneURL, - nToolBarX, - nToolBarY, - nToolBarWidth, - nToolBarHeight); - - return geometry::RealRectangle2D( - nToolBarX, - nToolBarY, - nToolBarX + nToolBarWidth - 1, - nToolBarY + nToolBarHeight - 1); -} - -awt::Size PresenterWindowManager::CalculatePaneSize ( - const double nOuterWidth, - const OUString& rsPaneURL) -{ - // Calculate the inner width by removing the pane border. - awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder ( - rsPaneURL, - awt::Rectangle(0,0, - sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)), - drawing::framework::BorderType_TOTAL_BORDER)); - - // Calculate the inner height with the help of the slide aspect ratio. - const double nCurrentSlideInnerHeight ( - aInnerBox.Width / mpPresenterController->GetSlideAspectRatio()); - - // Add the pane border to get the outer box. - awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder ( - rsPaneURL, - awt::Rectangle(0,0, - aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)), - drawing::framework::BorderType_TOTAL_BORDER)); - - return awt::Size(aOuterBox.Width, aOuterBox.Height); -} - -void PresenterWindowManager::NotifyLayoutModeChange() -{ - document::EventObject aEvent; - aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this)); - - LayoutListenerContainer aContainerCopy (maLayoutListeners); - for (const auto& rxListener : aContainerCopy) - { - if (rxListener.is()) - { - try - { - rxListener->notifyEvent(aEvent); - } - catch (lang::DisposedException&) - { - RemoveLayoutListener(rxListener); - } - catch (RuntimeException&) - { - } - } - } -} - -void PresenterWindowManager::NotifyDisposing() -{ - lang::EventObject aEvent; - aEvent.Source = static_cast<XWeak*>(this); - - LayoutListenerContainer aContainer; - aContainer.swap(maLayoutListeners); - for (auto& rxListener : aContainer) - { - if (rxListener.is()) - { - try - { - rxListener->disposing(aEvent); - } - catch (lang::DisposedException&) - { - } - catch (RuntimeException&) - { - } - } - } -} - -void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow) -{ - PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( - mpPaneContainer->FindBorderWindow(rxBorderWindow)); - if (pDescriptor) - { - mxClipPolygon = nullptr; - - // ToTop is called last because it may invalidate the iterator. - if ( ! mbIsLayouting) - mpPaneContainer->ToTop(pDescriptor); - } -} - -void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox) -{ - if ( ! mxParentWindow.is()) - return; - - Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice()); - if ( ! xDevice.is()) - return; - - // Create a polygon for the background and for clipping. - Reference<rendering::XPolyPolygon2D> xBackgroundPolygon ( - PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice)); - if ( ! mxClipPolygon.is()) - mxClipPolygon = CreateClipPolyPolygon(); - - // Create View- and RenderState structs. - const rendering::ViewState aViewState( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice)); - rendering::RenderState aRenderState ( - geometry::AffineMatrix2D(1,0,0, 0,1,0), - mxClipPolygon, - Sequence<double>(4), - rendering::CompositeOperation::SOURCE); - - // Paint the background. - if (!mpBackgroundBitmap) - return; - - ProvideBackgroundBitmap(); - - if (mxScaledBackgroundBitmap.is()) - { - const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize()); - Sequence<rendering::Texture> aTextures - { - { - geometry::AffineMatrix2D( aBitmapSize.Width,0,0, 0,aBitmapSize.Height,0), - 1, - 0, - mxScaledBackgroundBitmap, - nullptr, - nullptr, - rendering::StrokeAttributes(), - rendering::TexturingMode::REPEAT, - rendering::TexturingMode::REPEAT - } - }; - - mxParentCanvas->fillTexturedPolyPolygon( - xBackgroundPolygon, - aViewState, - aRenderState, - aTextures); - } - else - { - const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor); - aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0; - aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0; - aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0; - aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0; - mxParentCanvas->fillPolyPolygon( - xBackgroundPolygon, - aViewState, - aRenderState); - } -} - -void PresenterWindowManager::ProvideBackgroundBitmap() -{ - if ( mxScaledBackgroundBitmap.is()) - return; - - Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap()); - if (!xBitmap.is()) - return; - - const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode - == PresenterBitmapDescriptor::Stretch); - const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode - == PresenterBitmapDescriptor::Stretch); - if (bStretchHorizontal || bStretchVertical) - { - geometry::RealSize2D aSize; - if (bStretchVertical) - aSize.Height = mxParentWindow->getPosSize().Height; - else - aSize.Height = xBitmap->getSize().Height; - if (bStretchHorizontal) - aSize.Width = mxParentWindow->getPosSize().Width; - else - aSize.Width = xBitmap->getSize().Width; - mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, false); - } - else - { - mxScaledBackgroundBitmap = xBitmap; - } -} - -Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon() const -{ - // Create a clip polygon that includes the whole update area but has the - // content windows as holes. - const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size()); - ::std::vector<awt::Rectangle> aRectangles; - aRectangles.reserve(1+nPaneCount); - aRectangles.push_back(mxParentWindow->getPosSize()); - for (const auto& pDescriptor : mpPaneContainer->maPanes) - { - if ( ! pDescriptor->mbIsActive) - continue; - if ( ! pDescriptor->mbIsOpaque) - continue; - if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is()) - continue; - Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY); - if (xWindow.is() && ! xWindow->isVisible()) - continue; - - const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize()); - awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize()); - aInnerBorderBox.X += aOuterBorderBox.X; - aInnerBorderBox.Y += aOuterBorderBox.Y; - aRectangles.push_back(aInnerBorderBox); - } - Reference<rendering::XPolyPolygon2D> xPolyPolygon ( - PresenterGeometryHelper::CreatePolygon( - aRectangles, - mxParentCanvas->getDevice())); - if (xPolyPolygon.is()) - xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD); - return xPolyPolygon; -} - -void PresenterWindowManager::Update() -{ - mxClipPolygon = nullptr; - mbIsLayoutPending = true; - - mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow); -} - -void PresenterWindowManager::ThrowIfDisposed() const -{ - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - throw lang::DisposedException ( - "PresenterWindowManager has already been disposed", - const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); - } -} - -} // end of namespace ::sdext::presenter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/PresenterWindowManager.hxx b/sdext/source/presenter/PresenterWindowManager.hxx deleted file mode 100644 index 9c032e6df433..000000000000 --- a/sdext/source/presenter/PresenterWindowManager.hxx +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERWINDOWMANAGER_HXX -#define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERWINDOWMANAGER_HXX - -#include "PresenterPaneContainer.hxx" -#include "PresenterTheme.hxx" -#include <com/sun/star/awt/Size.hpp> -#include <com/sun/star/awt/XFocusListener.hpp> -#include <com/sun/star/awt/XPaintListener.hpp> -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/document/XEventListener.hpp> -#include <com/sun/star/drawing/framework/XPane.hpp> -#include <com/sun/star/rendering/XBitmap.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> -#include <rtl/ref.hxx> -#include <memory> - -namespace sdext::presenter { - -class PresenterController; -class PresenterPaneBorderPainter; -class PresenterTheme; - -typedef ::cppu::WeakComponentImplHelper< - css::awt::XWindowListener, - css::awt::XPaintListener, - css::awt::XMouseListener, - css::awt::XFocusListener -> PresenterWindowManagerInterfaceBase; - -/** A simple manager of the positions of the panes of the presenter screen. - Uses relative coordinates of the four sides of each pane. Allows panes - to be moved or resized with the mouse. -*/ -class PresenterWindowManager - : protected ::cppu::BaseMutex, - public PresenterWindowManagerInterfaceBase -{ -public: - PresenterWindowManager ( - const css::uno::Reference<css::uno::XComponentContext>& rxContext, - const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer, - const ::rtl::Reference<PresenterController>& rpPresenterController); - virtual ~PresenterWindowManager() override; - PresenterWindowManager(const PresenterWindowManager&) = delete; - PresenterWindowManager& operator=(const PresenterWindowManager&) = delete; - - void SAL_CALL disposing() override; - - void SetParentPane (const css::uno::Reference<css::drawing::framework::XPane>& rxPane); - void SetTheme (const std::shared_ptr<PresenterTheme>& rpTheme); - void NotifyViewCreation (const css::uno::Reference<css::drawing::framework::XView>& rxView); - void SetPanePosSizeAbsolute ( - const OUString& rsPaneURL, - const double nX, - const double nY, - const double nWidth, - const double nHeight); - void SetPaneBorderPainter (const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter); - void Update(); - void Layout(); - - void SetSlideSorterState (bool bIsActive); - void SetHelpViewState (bool bIsActive); - void SetPauseState (bool bIsPaused); - - enum LayoutMode { LM_Standard, LM_Notes, LM_Generic }; -private: - void SetLayoutMode (const LayoutMode eMode); - -public: - enum ViewMode { VM_Standard, VM_Notes, VM_SlideOverview, VM_Help }; - /** The high-level method to switch the view mode. Use this instead of - SetLayoutMode and Set(Help|SlideSorter)State when possible. - */ - void SetViewMode (const ViewMode eMode); - - ViewMode GetViewMode() const; - - /** Restore the layout mode (or slide sorter state) from the - configuration. - */ - void RestoreViewMode(); - - void AddLayoutListener ( - const css::uno::Reference<css::document::XEventListener>& rxListener); - void RemoveLayoutListener ( - const css::uno::Reference<css::document::XEventListener>& rxListener); - - // XWindowListener - - virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) override; - - virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) override; - - virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) override; - - // XPaintListener - - virtual void SAL_CALL windowPaint (const css::awt::PaintEvent& rEvent) override; - - // XMouseListener - - virtual void SAL_CALL mousePressed (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseReleased (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseEntered (const css::awt::MouseEvent& rEvent) override; - - virtual void SAL_CALL mouseExited (const css::awt::MouseEvent& rEvent) override; - - // XFocusListener - - virtual void SAL_CALL focusGained (const css::awt::FocusEvent& rEvent) override; - - virtual void SAL_CALL focusLost (const css::awt::FocusEvent& rEvent) override; - - // XEventListener - - virtual void SAL_CALL disposing ( - const css::lang::EventObject& rEvent) override; - -private: - css::uno::Reference<css::uno::XComponentContext> mxComponentContext; - ::rtl::Reference<PresenterController> mpPresenterController; - css::uno::Reference<css::awt::XWindow> mxParentWindow; - css::uno::Reference<css::rendering::XCanvas> mxParentCanvas; - css::uno::Reference<css::uno::XInterface> mxPaneBorderManager; - ::rtl::Reference<PresenterPaneBorderPainter> mpPaneBorderPainter; - ::rtl::Reference<PresenterPaneContainer> mpPaneContainer; - bool mbIsLayoutPending; - /** This flag is set to <TRUE/> while the Layout() method is being - executed. Prevents windowMoved() and windowResized() from changing - the window sizes. - */ - bool mbIsLayouting; - std::shared_ptr<PresenterTheme> mpTheme; - SharedBitmapDescriptor mpBackgroundBitmap; - css::uno::Reference<css::rendering::XBitmap> mxScaledBackgroundBitmap; - css::uno::Reference<css::rendering::XPolyPolygon2D> mxClipPolygon; - LayoutMode meLayoutMode; - bool mbIsSlideSorterActive; - bool mbIsHelpViewActive; - bool mbisPaused; - typedef ::std::vector<css::uno::Reference<css::document::XEventListener> > - LayoutListenerContainer; - LayoutListenerContainer maLayoutListeners; - bool mbIsMouseClickPending; - - void PaintChildren (const css::awt::PaintEvent& rEvent) const; - void UpdateWindowSize (const css::uno::Reference<css::awt::XWindow>& rxBorderWindow); - void PaintBackground (const css::awt::Rectangle& rUpdateBox); - void ProvideBackgroundBitmap(); - css::uno::Reference<css::rendering::XPolyPolygon2D> CreateClipPolyPolygon() const; - - void StoreViewMode (const ViewMode eViewMode); - - void LayoutStandardMode(); - void LayoutNotesMode(); - void LayoutSlideSorterMode(); - void LayoutHelpMode(); - - /** Layout the tool bar and return its outer bounding box. - */ - css::geometry::RealRectangle2D LayoutToolBar(); - - css::awt::Size CalculatePaneSize ( - const double nOuterWidth, - const OUString& rsPaneURL); - - /** Notify changes of the layout mode and of the slide sorter state. - */ - void NotifyLayoutModeChange(); - - void NotifyDisposing(); - - /// @throws css::lang::DisposedException - void ThrowIfDisposed() const; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/presenter/presenter.component b/sdext/source/presenter/presenter.component deleted file mode 100644 index 01e18b38eca0..000000000000 --- a/sdext/source/presenter/presenter.component +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * ---> -<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@" - xmlns="http://openoffice.org/2010/uno-components"> - <implementation name="org.libreoffice.comp.PresenterScreenJob" - constructor="sdext_PresenterScreenJob_get_implementation" /> - <implementation name="org.libreoffice.comp.PresenterScreenProtocolHandler" - constructor="sdext_PresenterProtocolHandler_get_implementation"> - <service name="com.sun.star.frame.ProtocolHandler"/> - </implementation> -</component> |