summaryrefslogtreecommitdiffstats
path: root/avmedia/source/viewer
diff options
context:
space:
mode:
Diffstat (limited to 'avmedia/source/viewer')
-rw-r--r--avmedia/source/viewer/mediaevent_impl.cxx173
-rw-r--r--avmedia/source/viewer/mediaevent_impl.hxx78
-rw-r--r--avmedia/source/viewer/mediawindow.cxx404
-rw-r--r--avmedia/source/viewer/mediawindow_impl.cxx671
-rw-r--r--avmedia/source/viewer/mediawindow_impl.hxx157
5 files changed, 1483 insertions, 0 deletions
diff --git a/avmedia/source/viewer/mediaevent_impl.cxx b/avmedia/source/viewer/mediaevent_impl.cxx
new file mode 100644
index 000000000..9fbaceea1
--- /dev/null
+++ b/avmedia/source/viewer/mediaevent_impl.cxx
@@ -0,0 +1,173 @@
+/* -*- 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 "mediaevent_impl.hxx"
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/event.hxx>
+
+using namespace ::com::sun::star;
+
+namespace avmedia::priv {
+
+MediaEventListenersImpl::MediaEventListenersImpl( vcl::Window& rEventWindow ) :
+ mpNotifyWindow( &rEventWindow )
+{
+}
+
+
+MediaEventListenersImpl::~MediaEventListenersImpl()
+{
+}
+
+
+void MediaEventListenersImpl::cleanUp()
+{
+ Application::RemoveMouseAndKeyEvents( reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ) );
+ mpNotifyWindow = nullptr;
+}
+
+
+void SAL_CALL MediaEventListenersImpl::disposing( const css::lang::EventObject& )
+{
+}
+
+
+void SAL_CALL MediaEventListenersImpl::keyPressed( const css::awt::KeyEvent& e )
+{
+ const ::osl::MutexGuard aGuard( maMutex );
+ const SolarMutexGuard aAppGuard;
+
+ if( mpNotifyWindow )
+ {
+ vcl::KeyCode aVCLKeyCode( e.KeyCode,
+ ( ( e.Modifiers & 1 ) ? KEY_SHIFT : 0 ) |
+ ( ( e.Modifiers & 2 ) ? KEY_MOD1 : 0 ) |
+ ( ( e.Modifiers & 4 ) ? KEY_MOD2 : 0 ) );
+ KeyEvent aVCLKeyEvt( e.KeyChar, aVCLKeyCode );
+
+ Application::PostKeyEvent( VclEventId::WindowKeyInput, reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ), &aVCLKeyEvt );
+ }
+}
+
+
+void SAL_CALL MediaEventListenersImpl::keyReleased( const css::awt::KeyEvent& e )
+{
+ const ::osl::MutexGuard aGuard( maMutex );
+ const SolarMutexGuard aAppGuard;
+
+ if( mpNotifyWindow )
+ {
+ vcl::KeyCode aVCLKeyCode( e.KeyCode,
+ ( ( e.Modifiers & 1 ) ? KEY_SHIFT : 0 ) |
+ ( ( e.Modifiers & 2 ) ? KEY_MOD1 : 0 ) |
+ ( ( e.Modifiers & 4 ) ? KEY_MOD2 : 0 ) );
+ KeyEvent aVCLKeyEvt( e.KeyChar, aVCLKeyCode );
+ Application::PostKeyEvent( VclEventId::WindowKeyUp, reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ), &aVCLKeyEvt );
+ }
+}
+
+
+void SAL_CALL MediaEventListenersImpl::mousePressed( const css::awt::MouseEvent& e )
+{
+ const ::osl::MutexGuard aGuard( maMutex );
+ const SolarMutexGuard aAppGuard;
+
+ if( mpNotifyWindow )
+ {
+ MouseEvent aVCLMouseEvt( Point( e.X, e.Y ),
+ sal::static_int_cast< sal_uInt16 >(e.ClickCount),
+ MouseEventModifiers::NONE,
+ ( ( e.Buttons & 1 ) ? MOUSE_LEFT : 0 ) |
+ ( ( e.Buttons & 2 ) ? MOUSE_RIGHT : 0 ) |
+ ( ( e.Buttons & 4 ) ? MOUSE_MIDDLE : 0 ),
+ e.Modifiers );
+ Application::PostMouseEvent( VclEventId::WindowMouseButtonDown, reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ), &aVCLMouseEvt );
+ }
+}
+
+
+void SAL_CALL MediaEventListenersImpl::mouseReleased( const css::awt::MouseEvent& e )
+{
+ const ::osl::MutexGuard aGuard( maMutex );
+ const SolarMutexGuard aAppGuard;
+
+ if( mpNotifyWindow )
+ {
+ MouseEvent aVCLMouseEvt( Point( e.X, e.Y ),
+ sal::static_int_cast< sal_uInt16 >(e.ClickCount),
+ MouseEventModifiers::NONE,
+ ( ( e.Buttons & 1 ) ? MOUSE_LEFT : 0 ) |
+ ( ( e.Buttons & 2 ) ? MOUSE_RIGHT : 0 ) |
+ ( ( e.Buttons & 4 ) ? MOUSE_MIDDLE : 0 ),
+ e.Modifiers );
+ Application::PostMouseEvent( VclEventId::WindowMouseButtonUp, reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ), &aVCLMouseEvt );
+ }
+}
+
+
+void SAL_CALL MediaEventListenersImpl::mouseEntered( const css::awt::MouseEvent& )
+{
+}
+
+
+void SAL_CALL MediaEventListenersImpl::mouseExited( const css::awt::MouseEvent& )
+{
+}
+
+
+void SAL_CALL MediaEventListenersImpl::mouseDragged( const css::awt::MouseEvent& e )
+{
+ const ::osl::MutexGuard aGuard( maMutex );
+ const SolarMutexGuard aAppGuard;
+
+ if( mpNotifyWindow )
+ {
+ MouseEvent aVCLMouseEvt( Point( e.X, e.Y ), 0, MouseEventModifiers::NONE, e.Buttons, e.Modifiers );
+ Application::PostMouseEvent( VclEventId::WindowMouseMove, reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ), &aVCLMouseEvt );
+ }
+}
+
+
+void SAL_CALL MediaEventListenersImpl::mouseMoved( const css::awt::MouseEvent& e )
+{
+ const ::osl::MutexGuard aGuard( maMutex );
+ const SolarMutexGuard aAppGuard;
+
+ if( mpNotifyWindow )
+ {
+ MouseEvent aVCLMouseEvt( Point( e.X, e.Y ), 0, MouseEventModifiers::NONE, e.Buttons, e.Modifiers );
+ Application::PostMouseEvent( VclEventId::WindowMouseMove, reinterpret_cast< vcl::Window* >( mpNotifyWindow.get() ), &aVCLMouseEvt );
+ }
+}
+
+
+void SAL_CALL MediaEventListenersImpl::focusGained( const css::awt::FocusEvent& )
+{
+}
+
+
+void SAL_CALL MediaEventListenersImpl::focusLost( const css::awt::FocusEvent& )
+{
+}
+
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/avmedia/source/viewer/mediaevent_impl.hxx b/avmedia/source/viewer/mediaevent_impl.hxx
new file mode 100644
index 000000000..9c864ecff
--- /dev/null
+++ b/avmedia/source/viewer/mediaevent_impl.hxx
@@ -0,0 +1,78 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <avmedia/mediawindow.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <vcl/vclptr.hxx>
+
+namespace avmedia
+{
+ namespace priv
+ {
+
+ // - MediaEventListenersImpl -
+
+ class MediaEventListenersImpl : public ::cppu::WeakImplHelper< css::awt::XKeyListener,
+ css::awt::XMouseListener,
+ css::awt::XMouseMotionListener,
+ css::awt::XFocusListener >
+ {
+ public:
+
+ explicit MediaEventListenersImpl( vcl::Window& rNotifyWindow );
+ virtual ~MediaEventListenersImpl() override;
+
+ void cleanUp();
+
+ protected:
+
+ // XKeyListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+ virtual void SAL_CALL keyPressed( const css::awt::KeyEvent& e ) override;
+ virtual void SAL_CALL keyReleased( const css::awt::KeyEvent& e ) override;
+
+ // XMouseListener
+ virtual void SAL_CALL mousePressed( const css::awt::MouseEvent& e ) override;
+ virtual void SAL_CALL mouseReleased( const css::awt::MouseEvent& e ) override;
+ virtual void SAL_CALL mouseEntered( const css::awt::MouseEvent& e ) override;
+ virtual void SAL_CALL mouseExited( const css::awt::MouseEvent& e ) override;
+
+ // XMouseMotionListener
+ virtual void SAL_CALL mouseDragged( const css::awt::MouseEvent& e ) override;
+ virtual void SAL_CALL mouseMoved( const css::awt::MouseEvent& e ) override;
+
+ // XFocusListener
+ virtual void SAL_CALL focusGained( const css::awt::FocusEvent& e ) override;
+ virtual void SAL_CALL focusLost( const css::awt::FocusEvent& e ) override;
+
+ private:
+
+ VclPtr<vcl::Window> mpNotifyWindow;
+ mutable ::osl::Mutex maMutex;
+ };
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/avmedia/source/viewer/mediawindow.cxx b/avmedia/source/viewer/mediawindow.cxx
new file mode 100644
index 000000000..e823c2e8d
--- /dev/null
+++ b/avmedia/source/viewer/mediawindow.cxx
@@ -0,0 +1,404 @@
+/* -*- 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 <avmedia/mediawindow.hxx>
+#include "mediawindow_impl.hxx"
+#include <mediamisc.hxx>
+#include <bitmaps.hlst>
+#include <strings.hrc>
+#include <tools/urlobj.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/media/XPlayer.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <memory>
+#include <sal/log.hxx>
+
+#define AVMEDIA_FRAMEGRABBER_DEFAULTFRAME_MEDIATIME 3.0
+
+using namespace ::com::sun::star;
+
+namespace avmedia {
+
+MediaWindow::MediaWindow( vcl::Window* parent, bool bInternalMediaControl ) :
+ mpImpl( VclPtr<priv::MediaWindowImpl>::Create( parent, this, bInternalMediaControl ) )
+{
+ mpImpl->Show();
+}
+
+
+MediaWindow::~MediaWindow()
+{
+ mpImpl.disposeAndClear();
+}
+
+
+void MediaWindow::setURL( const OUString& rURL, const OUString& rReferer )
+{
+ mpImpl->setURL( rURL, OUString(), rReferer );
+}
+
+
+const OUString& MediaWindow::getURL() const
+{
+ return mpImpl->getURL();
+}
+
+
+bool MediaWindow::isValid() const
+{
+ return mpImpl->isValid();
+}
+
+
+void MediaWindow::MouseMove( const MouseEvent& )
+{
+}
+
+
+void MediaWindow::MouseButtonDown( const MouseEvent& )
+{
+}
+
+
+void MediaWindow::MouseButtonUp( const MouseEvent& )
+{
+}
+
+
+void MediaWindow::KeyInput( const KeyEvent& )
+{
+}
+
+
+void MediaWindow::KeyUp( const KeyEvent& )
+{
+}
+
+void MediaWindow::Command( const CommandEvent& )
+{
+}
+
+
+sal_Int8 MediaWindow::AcceptDrop( const AcceptDropEvent& )
+{
+ return 0;
+}
+
+
+sal_Int8 MediaWindow::ExecuteDrop( const ExecuteDropEvent& )
+{
+ return 0;
+}
+
+
+void MediaWindow::StartDrag( sal_Int8, const Point& )
+{
+}
+
+
+Size MediaWindow::getPreferredSize() const
+{
+ return mpImpl->getPreferredSize();
+}
+
+
+void MediaWindow::setPosSize( const tools::Rectangle& rNewRect )
+{
+ mpImpl->setPosSize( rNewRect );
+}
+
+
+void MediaWindow::setPointer( PointerStyle nPointer )
+{
+ mpImpl->setPointer( nPointer );
+}
+
+
+bool MediaWindow::start()
+{
+ return mpImpl->start();
+}
+
+
+void MediaWindow::updateMediaItem( MediaItem& rItem ) const
+{
+ mpImpl->updateMediaItem( rItem );
+}
+
+
+void MediaWindow::executeMediaItem( const MediaItem& rItem )
+{
+ mpImpl->executeMediaItem( rItem );
+}
+
+
+void MediaWindow::show()
+{
+ mpImpl->Show();
+}
+
+
+void MediaWindow::hide()
+{
+ mpImpl->Hide();
+}
+
+
+vcl::Window* MediaWindow::getWindow() const
+{
+ return mpImpl.get();
+}
+
+
+FilterNameVector MediaWindow::getMediaFilters()
+{
+ return {{"Advanced Audio Coding", "aac"},
+ {"AIF Audio", "aif;aiff"},
+ {"Advanced Systems Format", "asf;wma;wmv"},
+ {"AU Audio", "au"},
+ {"AC3 Audio", "ac3"},
+ {"AVI", "avi"},
+ {"CD Audio", "cda"},
+ {"Digital Video", "dv"},
+ {"FLAC Audio", "flac"},
+ {"Flash Video", "flv"},
+ {"Matroska Media", "mkv"},
+ {"MIDI Audio", "mid;midi"},
+ {"MPEG Audio", "mp2;mp3;mpa;m4a"},
+ {"MPEG Video", "mpg;mpeg;mpv;mp4;m4v"},
+ {"Ogg Audio", "ogg;oga;opus"},
+ {"Ogg Video", "ogv;ogx"},
+ {"Real Audio", "ra"},
+ {"Real Media", "rm"},
+ {"RMI MIDI Audio", "rmi"},
+ {"SND (SouND) Audio", "snd"},
+ {"Quicktime Video", "mov"},
+ {"Vivo Video", "viv"},
+ {"WAVE Audio", "wav"},
+ {"WebM Video", "webm"},
+ {"Windows Media Audio", "wma"},
+ {"Windows Media Video", "wmv"}};
+}
+
+
+bool MediaWindow::executeMediaURLDialog(weld::Window* pParent, OUString& rURL, bool *const o_pbLink)
+{
+ ::sfx2::FileDialogHelper aDlg(o_pbLink != nullptr
+ ? ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
+ : ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, pParent);
+ static const char aWildcard[] = "*.";
+ FilterNameVector aFilters = getMediaFilters();
+ static const char aSeparator[] = ";";
+ OUStringBuffer aAllTypes;
+
+ aDlg.SetTitle( AvmResId( o_pbLink != nullptr
+ ? AVMEDIA_STR_INSERTMEDIA_DLG : AVMEDIA_STR_OPENMEDIA_DLG ) );
+
+ for( FilterNameVector::size_type i = 0; i < aFilters.size(); ++i )
+ {
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ if( !aAllTypes.isEmpty() )
+ aAllTypes.append(aSeparator);
+
+ aAllTypes.append(aWildcard).append(aFilters[ i ].second.getToken( 0, ';', nIndex ));
+ }
+ }
+
+ // add filter for all media types
+ aDlg.AddFilter( AvmResId( AVMEDIA_STR_ALL_MEDIAFILES ), aAllTypes.makeStringAndClear() );
+
+ for( FilterNameVector::size_type i = 0; i < aFilters.size(); ++i )
+ {
+ OUStringBuffer aTypes;
+
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ if( !aTypes.isEmpty() )
+ aTypes.append(aSeparator);
+
+ aTypes.append(aWildcard).append(aFilters[ i ].second.getToken( 0, ';', nIndex ));
+ }
+
+ // add single filters
+ aDlg.AddFilter( aFilters[ i ].first, aTypes.makeStringAndClear() );
+ }
+
+ // add filter for all types
+ aDlg.AddFilter( AvmResId( AVMEDIA_STR_ALL_FILES ), "*.*" );
+
+ uno::Reference<ui::dialogs::XFilePicker3> const xFP(aDlg.GetFilePicker());
+ uno::Reference<ui::dialogs::XFilePickerControlAccess> const xCtrlAcc(xFP,
+ uno::UNO_QUERY_THROW);
+ if (o_pbLink != nullptr)
+ {
+ // for video link should be the default
+ xCtrlAcc->setValue(
+ ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0,
+ uno::Any(true) );
+ // disabled for now: TODO: preview?
+ xCtrlAcc->enableControl(
+ ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW,
+ false);
+ }
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ const INetURLObject aURL( aDlg.GetPath() );
+ rURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
+
+ if (o_pbLink != nullptr)
+ {
+ uno::Any const any = xCtrlAcc->getValue(
+ ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0);
+ if (!(any >>= *o_pbLink))
+ {
+ SAL_WARN("avmedia", "invalid link property");
+ *o_pbLink = true;
+ }
+ }
+ }
+ else if( !rURL.isEmpty() )
+ rURL.clear();
+
+ return !rURL.isEmpty();
+}
+
+void MediaWindow::executeFormatErrorBox(weld::Window* pParent)
+{
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
+ VclMessageType::Warning, VclButtonsType::Ok, AvmResId(AVMEDIA_STR_ERR_URL)));
+ xBox->run();
+}
+
+bool MediaWindow::isMediaURL( const OUString& rURL, const OUString& rReferer, bool bDeep, Size* pPreferredSizePixel )
+{
+ const INetURLObject aURL( rURL );
+
+ if( aURL.GetProtocol() != INetProtocol::NotValid )
+ {
+ if( bDeep || pPreferredSizePixel )
+ {
+ try
+ {
+ uno::Reference< media::XPlayer > xPlayer( priv::MediaWindowImpl::createPlayer(
+ aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ),
+ rReferer, nullptr ) );
+
+ if( xPlayer.is() )
+ {
+ if( pPreferredSizePixel )
+ {
+ const awt::Size aAwtSize( xPlayer->getPreferredPlayerWindowSize() );
+
+ pPreferredSizePixel->setWidth( aAwtSize.Width );
+ pPreferredSizePixel->setHeight( aAwtSize.Height );
+ }
+
+ return true;
+ }
+ }
+ catch( ... )
+ {
+ }
+ }
+ else
+ {
+ FilterNameVector aFilters = getMediaFilters();
+ const OUString aExt( aURL.getExtension() );
+
+ for( FilterNameVector::size_type i = 0; i < aFilters.size(); ++i )
+ {
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ if( aExt.equalsIgnoreAsciiCase( aFilters[ i ].second.getToken( 0, ';', nIndex ) ) )
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
+uno::Reference< media::XPlayer > MediaWindow::createPlayer( const OUString& rURL, const OUString& rReferer, const OUString* pMimeType )
+{
+ return priv::MediaWindowImpl::createPlayer( rURL, rReferer, pMimeType );
+}
+
+
+uno::Reference< graphic::XGraphic > MediaWindow::grabFrame( const OUString& rURL,
+ const OUString& rReferer,
+ const OUString& sMimeType )
+{
+ uno::Reference< media::XPlayer > xPlayer( createPlayer( rURL, rReferer, &sMimeType ) );
+ uno::Reference< graphic::XGraphic > xRet;
+ std::unique_ptr< Graphic > xGraphic;
+
+ if( xPlayer.is() )
+ {
+ uno::Reference< media::XFrameGrabber > xGrabber( xPlayer->createFrameGrabber() );
+
+ if( xGrabber.is() )
+ {
+ double fMediaTime = AVMEDIA_FRAMEGRABBER_DEFAULTFRAME_MEDIATIME;
+
+ if( fMediaTime >= xPlayer->getDuration() )
+ fMediaTime = ( xPlayer->getDuration() * 0.5 );
+
+ xRet = xGrabber->grabFrame( fMediaTime );
+ }
+
+ if( !xRet.is() )
+ {
+ awt::Size aPrefSize( xPlayer->getPreferredPlayerWindowSize() );
+
+ if( !aPrefSize.Width && !aPrefSize.Height )
+ {
+ const BitmapEx aBmpEx(AVMEDIA_BMP_AUDIOLOGO);
+ xGraphic.reset( new Graphic( aBmpEx ) );
+ }
+ }
+ }
+
+ if (!xRet.is() && !xGraphic)
+ {
+ const BitmapEx aBmpEx(AVMEDIA_BMP_EMPTYLOGO);
+ xGraphic.reset( new Graphic( aBmpEx ) );
+ }
+
+ if (xGraphic)
+ xRet = xGraphic->GetXGraphic();
+
+ return xRet;
+}
+
+
+} // namespace avmedia
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx
new file mode 100644
index 000000000..98f867e4e
--- /dev/null
+++ b/avmedia/source/viewer/mediawindow_impl.cxx
@@ -0,0 +1,671 @@
+/* -*- 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 <iostream>
+#include "mediawindow_impl.hxx"
+#include "mediaevent_impl.hxx"
+#include <mediamisc.hxx>
+#include <bitmaps.hlst>
+#include <helpids.h>
+
+#include <algorithm>
+
+#include <sal/log.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+#include <unotools/securityoptions.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/event.hxx>
+#include <vcl/ptrstyle.hxx>
+
+#include <com/sun/star/awt/SystemPointer.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/media/XManager.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+using namespace ::com::sun::star;
+
+namespace avmedia::priv {
+
+MediaWindowControl::MediaWindowControl(vcl::Window* pParent)
+ : MediaControl(pParent, MEDIACONTROLSTYLE_MULTILINE)
+{
+}
+
+void MediaWindowControl::update()
+{
+ MediaItem aItem;
+
+ static_cast< MediaWindowImpl* >( GetParent() )->updateMediaItem( aItem );
+ setState(aItem);
+}
+
+void MediaWindowControl::execute(const MediaItem& rItem)
+{
+ static_cast<MediaWindowImpl*>(GetParent())->executeMediaItem(rItem);
+}
+
+MediaChildWindow::MediaChildWindow(vcl::Window* pParent)
+ : SystemChildWindow(pParent, WB_CLIPCHILDREN)
+{
+}
+
+void MediaChildWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
+ rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
+
+ SystemChildWindow::MouseMove( rMEvt );
+ GetParent()->MouseMove( aTransformedEvent );
+}
+
+void MediaChildWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
+ rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
+
+ SystemChildWindow::MouseButtonDown( rMEvt );
+ GetParent()->MouseButtonDown( aTransformedEvent );
+}
+
+void MediaChildWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
+ rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
+
+ SystemChildWindow::MouseButtonUp( rMEvt );
+ GetParent()->MouseButtonUp( aTransformedEvent );
+}
+
+void MediaChildWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ SystemChildWindow::KeyInput( rKEvt );
+ GetParent()->KeyInput( rKEvt );
+}
+
+void MediaChildWindow::KeyUp( const KeyEvent& rKEvt )
+{
+ SystemChildWindow::KeyUp( rKEvt );
+ GetParent()->KeyUp( rKEvt );
+}
+
+void MediaChildWindow::Command( const CommandEvent& rCEvt )
+{
+ const CommandEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ),
+ rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetEventData() );
+
+ SystemChildWindow::Command( rCEvt );
+ GetParent()->Command( aTransformedEvent );
+}
+
+MediaWindowImpl::MediaWindowImpl(vcl::Window* pParent, MediaWindow* pMediaWindow, bool bInternalMediaControl)
+ : Control(pParent)
+ , DropTargetHelper(this)
+ , DragSourceHelper(this)
+ , mpMediaWindow(pMediaWindow)
+ , mpMediaWindowControl(bInternalMediaControl ? VclPtr<MediaWindowControl>::Create(this) : nullptr)
+{
+ if (mpMediaWindowControl)
+ {
+ mpMediaWindowControl->SetSizePixel(mpMediaWindowControl->GetOptimalSize());
+ mpMediaWindowControl->Show();
+ }
+}
+
+MediaWindowImpl::~MediaWindowImpl()
+{
+ disposeOnce();
+}
+
+void MediaWindowImpl::dispose()
+{
+ if (mxEvents.is())
+ mxEvents->cleanUp();
+
+ if (mxPlayerWindow.is())
+ {
+ auto pEventsIf = static_cast<cppu::OWeakObject*>(mxEvents.get());
+ mxPlayerWindow->removeKeyListener( uno::Reference< awt::XKeyListener >( pEventsIf, uno::UNO_QUERY ) );
+ mxPlayerWindow->removeMouseListener( uno::Reference< awt::XMouseListener >( pEventsIf, uno::UNO_QUERY ) );
+ mxPlayerWindow->removeMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( pEventsIf, uno::UNO_QUERY ) );
+ mxPlayerWindow->dispose();
+ mxPlayerWindow.clear();
+ }
+
+ uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
+ if (xComponent.is()) // this stops the player
+ xComponent->dispose();
+
+ mxPlayer.clear();
+
+ mpMediaWindow = nullptr;
+
+ mpEmptyBmpEx.reset();
+ mpAudioBmpEx.reset();
+ mpMediaWindowControl.disposeAndClear();
+ mpChildWindow.disposeAndClear();
+
+ Control::dispose();
+}
+
+uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rURL, const OUString& rReferer, const OUString* pMimeType)
+{
+ uno::Reference<media::XPlayer> xPlayer;
+
+ if( rURL.isEmpty() )
+ return xPlayer;
+
+ if (SvtSecurityOptions().isUntrustedReferer(rReferer))
+ {
+ return xPlayer;
+ }
+
+ if (!pMimeType || *pMimeType == AVMEDIA_MIMETYPE_COMMON)
+ {
+ uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
+
+ static OUStringLiteral aServiceManagers[] =
+ {
+ AVMEDIA_MANAGER_SERVICE_PREFERRED,
+ AVMEDIA_MANAGER_SERVICE_NAME,
+ };
+
+ for (const auto& rServiceName : aServiceManagers)
+ {
+ xPlayer = createPlayer(rURL, rServiceName, xContext);
+ if (xPlayer)
+ break;
+ }
+ }
+
+ return xPlayer;
+}
+
+uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer(
+ const OUString& rURL, const OUString& rManagerServName,
+ const uno::Reference< uno::XComponentContext >& xContext)
+{
+ uno::Reference< media::XPlayer > xPlayer;
+ try
+ {
+ uno::Reference< media::XManager > xManager (
+ xContext->getServiceManager()->createInstanceWithContext(rManagerServName, xContext),
+ uno::UNO_QUERY );
+ if( xManager.is() )
+ xPlayer = xManager->createPlayer( rURL );
+ else
+ SAL_INFO( "avmedia", "failed to create media player service " << rManagerServName );
+ } catch ( const uno::Exception & )
+ {
+ TOOLS_WARN_EXCEPTION( "avmedia", "couldn't create media player " << rManagerServName);
+ }
+ return xPlayer;
+}
+
+void MediaWindowImpl::setURL( const OUString& rURL,
+ OUString const& rTempURL, OUString const& rReferer)
+{
+ maReferer = rReferer;
+ if( rURL == getURL() )
+ return;
+
+ if( mxPlayer.is() )
+ mxPlayer->stop();
+
+ if( mxPlayerWindow.is() )
+ {
+ mxPlayerWindow->setVisible( false );
+ mxPlayerWindow.clear();
+ }
+
+ mxPlayer.clear();
+ mTempFileURL.clear();
+
+ if (!rTempURL.isEmpty())
+ {
+ maFileURL = rURL;
+ mTempFileURL = rTempURL;
+ }
+ else
+ {
+ INetURLObject aURL( rURL );
+
+ if (aURL.GetProtocol() != INetProtocol::NotValid)
+ maFileURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous);
+ else
+ maFileURL = rURL;
+ }
+
+ mxPlayer = createPlayer((!mTempFileURL.isEmpty()) ? mTempFileURL : maFileURL, rReferer, &m_sMimeType );
+ onURLChanged();
+}
+
+const OUString& MediaWindowImpl::getURL() const
+{
+ return maFileURL;
+}
+
+bool MediaWindowImpl::isValid() const
+{
+ return mxPlayer.is();
+}
+
+Size MediaWindowImpl::getPreferredSize() const
+{
+ Size aRet(480, 360);
+
+ if( mxPlayer.is() )
+ {
+ awt::Size aPrefSize( mxPlayer->getPreferredPlayerWindowSize() );
+
+ aRet.setWidth( aPrefSize.Width );
+ aRet.setHeight( aPrefSize.Height );
+ }
+
+ return aRet;
+}
+
+bool MediaWindowImpl::start()
+{
+ return mxPlayer.is() && ( mxPlayer->start(), true );
+}
+
+void MediaWindowImpl::updateMediaItem( MediaItem& rItem ) const
+{
+ if( isPlaying() )
+ rItem.setState( MediaState::Play );
+ else
+ rItem.setState( ( getMediaTime() == 0.0 ) ? MediaState::Stop : MediaState::Pause );
+
+ rItem.setDuration( getDuration() );
+ rItem.setTime( getMediaTime() );
+ rItem.setLoop( mxPlayer.is() && mxPlayer->isPlaybackLoop() );
+ rItem.setMute( mxPlayer.is() && mxPlayer->isMute() );
+ rItem.setVolumeDB( mxPlayer.is() ? mxPlayer->getVolumeDB() : 0 );
+ rItem.setZoom( mxPlayerWindow.is() ? mxPlayerWindow->getZoomLevel() : media::ZoomLevel_NOT_AVAILABLE );
+ rItem.setURL( getURL(), mTempFileURL, maReferer );
+}
+
+void MediaWindowImpl::executeMediaItem( const MediaItem& rItem )
+{
+ const AVMediaSetMask nMaskSet = rItem.getMaskSet();
+
+ // set URL first
+ if (nMaskSet & AVMediaSetMask::URL)
+ {
+ m_sMimeType = rItem.getMimeType();
+ setURL(rItem.getURL(), rItem.getTempURL(), rItem.getReferer());
+ }
+
+ // set different states next
+ if (nMaskSet & AVMediaSetMask::TIME)
+ setMediaTime(std::min(rItem.getTime(), getDuration()));
+
+ if (nMaskSet & AVMediaSetMask::LOOP && mxPlayer.is() )
+ mxPlayer->setPlaybackLoop( rItem.isLoop() );
+
+ if (nMaskSet & AVMediaSetMask::MUTE && mxPlayer.is() )
+ mxPlayer->setMute( rItem.isMute() );
+
+ if (nMaskSet & AVMediaSetMask::VOLUMEDB && mxPlayer.is() )
+ mxPlayer->setVolumeDB( rItem.getVolumeDB() );
+
+ if (nMaskSet & AVMediaSetMask::ZOOM && mxPlayerWindow.is() )
+ mxPlayerWindow->setZoomLevel( rItem.getZoom() );
+
+ // set play state at last
+ if (!(nMaskSet & AVMediaSetMask::STATE))
+ return;
+
+ switch (rItem.getState())
+ {
+ case MediaState::Play:
+ {
+ if (!isPlaying())
+ start();
+ }
+ break;
+
+ case MediaState::Pause:
+ {
+ if (isPlaying())
+ stop();
+ }
+ break;
+
+ case MediaState::Stop:
+ {
+ if (isPlaying())
+ {
+ setMediaTime( 0.0 );
+ stop();
+ setMediaTime( 0.0 );
+ }
+ }
+ break;
+ }
+}
+
+void MediaWindowImpl::stop()
+{
+ if( mxPlayer.is() )
+ mxPlayer->stop();
+}
+
+bool MediaWindowImpl::isPlaying() const
+{
+ return( mxPlayer.is() && mxPlayer->isPlaying() );
+}
+
+double MediaWindowImpl::getDuration() const
+{
+ return( mxPlayer.is() ? mxPlayer->getDuration() : 0.0 );
+}
+
+void MediaWindowImpl::setMediaTime( double fTime )
+{
+ if( mxPlayer.is() )
+ mxPlayer->setMediaTime( fTime );
+}
+
+double MediaWindowImpl::getMediaTime() const
+{
+ return( mxPlayer.is() ? mxPlayer->getMediaTime() : 0.0 );
+}
+
+void MediaWindowImpl::stopPlayingInternal(bool bStop)
+{
+ if (isPlaying())
+ {
+ bStop ? mxPlayer->stop() : mxPlayer->start();
+ }
+}
+
+void MediaWindowImpl::onURLChanged()
+{
+ if (m_sMimeType == AVMEDIA_MIMETYPE_COMMON)
+ {
+ mpChildWindow.disposeAndClear();
+ mpChildWindow.reset(VclPtr<MediaChildWindow>::Create(this));
+ }
+ if (!mpChildWindow)
+ return;
+ mpChildWindow->SetHelpId(HID_AVMEDIA_PLAYERWINDOW);
+ mxEvents = new MediaEventListenersImpl(*mpChildWindow);
+
+ if (mxPlayer.is())
+ {
+ Resize();
+ uno::Sequence<uno::Any> aArgs( 3 );
+ uno::Reference<media::XPlayerWindow> xPlayerWindow;
+ const Point aPoint;
+ const Size aSize(mpChildWindow->GetSizePixel());
+
+ aArgs[0] <<= mpChildWindow->GetParentWindowHandle();
+ aArgs[1] <<= awt::Rectangle(aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height());
+ aArgs[2] <<= reinterpret_cast<sal_IntPtr>(mpChildWindow.get());
+
+ try
+ {
+ xPlayerWindow = mxPlayer->createPlayerWindow( aArgs );
+ }
+ catch( const uno::RuntimeException& )
+ {
+ // happens eg, on MacOSX where Java frames cannot be created from X11 window handles
+ }
+
+ mxPlayerWindow = xPlayerWindow;
+
+ if( xPlayerWindow.is() )
+ {
+ auto pEventsIf = static_cast<cppu::OWeakObject*>(mxEvents.get());
+ xPlayerWindow->addKeyListener( uno::Reference< awt::XKeyListener >( pEventsIf, uno::UNO_QUERY ) );
+ xPlayerWindow->addMouseListener( uno::Reference< awt::XMouseListener >( pEventsIf, uno::UNO_QUERY ) );
+ xPlayerWindow->addMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( pEventsIf, uno::UNO_QUERY ) );
+ xPlayerWindow->addFocusListener( uno::Reference< awt::XFocusListener >( pEventsIf, uno::UNO_QUERY ) );
+ }
+ }
+ else
+ mxPlayerWindow.clear();
+
+ if( mxPlayerWindow.is() )
+ mpChildWindow->Show();
+ else
+ mpChildWindow->Hide();
+
+ if( mpMediaWindowControl )
+ {
+ MediaItem aItem;
+
+ updateMediaItem( aItem );
+ mpMediaWindowControl->setState( aItem );
+ }
+}
+
+void MediaWindowImpl::setPosSize(const tools::Rectangle& rRect)
+{
+ SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
+}
+
+void MediaWindowImpl::setPointer(PointerStyle aPointer)
+{
+ SetPointer(aPointer);
+
+ if (mpChildWindow)
+ mpChildWindow->SetPointer(aPointer);
+
+ if (!mxPlayerWindow.is())
+ return;
+
+ long nPointer;
+
+ switch (aPointer)
+ {
+ case PointerStyle::Cross:
+ nPointer = awt::SystemPointer::CROSS;
+ break;
+ case PointerStyle::Hand:
+ nPointer = awt::SystemPointer::HAND;
+ break;
+ case PointerStyle::Move:
+ nPointer = awt::SystemPointer::MOVE;
+ break;
+ case PointerStyle::Wait:
+ nPointer = awt::SystemPointer::WAIT;
+ break;
+ default:
+ nPointer = awt::SystemPointer::ARROW;
+ break;
+ }
+
+ mxPlayerWindow->setPointerType(nPointer);
+}
+
+void MediaWindowImpl::Resize()
+{
+ const Size aCurSize(GetOutputSizePixel());
+ const sal_Int32 nOffset(mpMediaWindowControl ? AVMEDIA_CONTROLOFFSET : 0);
+
+ Size aPlayerWindowSize(aCurSize.Width() - (nOffset << 1),
+ aCurSize.Height() - (nOffset << 1));
+
+ if (mpMediaWindowControl)
+ {
+ const sal_Int32 nControlHeight = mpMediaWindowControl->GetSizePixel().Height();
+ const sal_Int32 nControlY = std::max(aCurSize.Height() - nControlHeight - nOffset, 0L);
+
+ aPlayerWindowSize.setHeight( nControlY - (nOffset << 1) );
+ mpMediaWindowControl->SetPosSizePixel(Point(nOffset, nControlY ), Size(aCurSize.Width() - (nOffset << 1), nControlHeight));
+ }
+ if (mpChildWindow)
+ mpChildWindow->SetPosSizePixel(Point(0, 0), aPlayerWindowSize);
+
+ if (mxPlayerWindow.is())
+ mxPlayerWindow->setPosSize(0, 0, aPlayerWindowSize.Width(), aPlayerWindowSize.Height(), 0);
+}
+
+void MediaWindowImpl::StateChanged(StateChangedType eType)
+{
+ if (!mxPlayerWindow.is())
+ return;
+
+ // stop playing when going disabled or hidden
+ switch (eType)
+ {
+ case StateChangedType::Visible:
+ {
+ stopPlayingInternal(!IsVisible());
+ mxPlayerWindow->setVisible(IsVisible());
+ }
+ break;
+
+ case StateChangedType::Enable:
+ {
+ stopPlayingInternal(!IsEnabled());
+ mxPlayerWindow->setEnable(IsEnabled());
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void MediaWindowImpl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ if (mxPlayerWindow.is())
+ mxPlayerWindow->update();
+
+ BitmapEx* pLogo = nullptr;
+
+ if (!mxPlayer.is())
+ {
+ if (!mpEmptyBmpEx)
+ mpEmptyBmpEx.reset(new BitmapEx(AVMEDIA_BMP_EMPTYLOGO));
+
+ pLogo = mpEmptyBmpEx.get();
+ }
+ else if (!mxPlayerWindow.is())
+ {
+ if (!mpAudioBmpEx)
+ mpAudioBmpEx.reset(new BitmapEx(AVMEDIA_BMP_AUDIOLOGO));
+
+ pLogo = mpAudioBmpEx.get();
+ }
+
+ if (!mpChildWindow)
+ return;
+
+ const Point aBasePos(mpChildWindow->GetPosPixel());
+ const tools::Rectangle aVideoRect(aBasePos, mpChildWindow->GetSizePixel());
+
+ if (!(pLogo && !pLogo->IsEmpty() && !aVideoRect.IsEmpty()))
+ return;
+
+ Size aLogoSize(pLogo->GetSizePixel());
+ const Color aBackgroundColor(67, 67, 67);
+
+ rRenderContext.SetLineColor(aBackgroundColor);
+ rRenderContext.SetFillColor(aBackgroundColor);
+ rRenderContext.DrawRect(aVideoRect);
+
+ if ((aLogoSize.Width() > aVideoRect.GetWidth() || aLogoSize.Height() > aVideoRect.GetHeight() ) &&
+ (aLogoSize.Height() > 0))
+ {
+ const double fLogoWH = double(aLogoSize.Width()) / aLogoSize.Height();
+
+ if (fLogoWH < (double(aVideoRect.GetWidth()) / aVideoRect.GetHeight()))
+ {
+ aLogoSize.setWidth( long(aVideoRect.GetHeight() * fLogoWH) );
+ aLogoSize.setHeight( aVideoRect.GetHeight() );
+ }
+ else
+ {
+ aLogoSize.setWidth( aVideoRect.GetWidth() );
+ aLogoSize.setHeight( long(aVideoRect.GetWidth() / fLogoWH) );
+ }
+ }
+
+ Point aPoint(aBasePos.X() + ((aVideoRect.GetWidth() - aLogoSize.Width()) >> 1),
+ aBasePos.Y() + ((aVideoRect.GetHeight() - aLogoSize.Height()) >> 1));
+
+ rRenderContext.DrawBitmapEx(aPoint, aLogoSize, *pLogo);
+}
+
+void MediaWindowImpl::GetFocus()
+{
+}
+
+void MediaWindowImpl::MouseMove(const MouseEvent& rMEvt)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->MouseMove(rMEvt);
+}
+
+void MediaWindowImpl::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->MouseButtonDown(rMEvt);
+}
+
+void MediaWindowImpl::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->MouseButtonUp(rMEvt);
+}
+
+void MediaWindowImpl::KeyInput(const KeyEvent& rKEvt)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->KeyInput(rKEvt);
+}
+
+void MediaWindowImpl::KeyUp(const KeyEvent& rKEvt)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->KeyUp(rKEvt);
+}
+
+void MediaWindowImpl::Command(const CommandEvent& rCEvt)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->Command(rCEvt);
+}
+
+sal_Int8 MediaWindowImpl::AcceptDrop(const AcceptDropEvent& rEvt)
+{
+ return (mpMediaWindow ? mpMediaWindow->AcceptDrop(rEvt) : 0);
+}
+
+sal_Int8 MediaWindowImpl::ExecuteDrop(const ExecuteDropEvent& rEvt)
+{
+ return (mpMediaWindow ? mpMediaWindow->ExecuteDrop(rEvt) : 0);
+}
+
+void MediaWindowImpl::StartDrag(sal_Int8 nAction, const Point& rPosPixel)
+{
+ if (mpMediaWindow)
+ mpMediaWindow->StartDrag(nAction, rPosPixel);
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/avmedia/source/viewer/mediawindow_impl.hxx b/avmedia/source/viewer/mediawindow_impl.hxx
new file mode 100644
index 000000000..8bceebb08
--- /dev/null
+++ b/avmedia/source/viewer/mediawindow_impl.hxx
@@ -0,0 +1,157 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/transfer.hxx>
+#include <vcl/syschild.hxx>
+
+#include <mediacontrol.hxx>
+
+namespace com::sun::star::media {
+ class XPlayer;
+ class XPlayerWindow;
+}
+
+namespace com::sun::star::uno {
+ class XComponentContext;
+}
+
+class BitmapEx;
+
+namespace avmedia
+{
+
+class MediaWindow;
+
+namespace priv
+{
+
+class MediaWindowControl : public MediaControl
+{
+public:
+
+ explicit MediaWindowControl( vcl::Window* pParent );
+
+protected:
+
+ void update() override;
+ void execute( const MediaItem& rItem ) override;
+};
+
+class MediaChildWindow : public SystemChildWindow
+{
+public:
+
+ explicit MediaChildWindow( vcl::Window* pParent );
+
+protected:
+
+ virtual void MouseMove( const MouseEvent& rMEvt ) override;
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
+ virtual void KeyInput( const KeyEvent& rKEvt ) override;
+ virtual void KeyUp( const KeyEvent& rKEvt ) override;
+ virtual void Command( const CommandEvent& rCEvt ) override;
+};
+
+class MediaEventListenersImpl;
+
+class MediaWindowImpl : public Control, public DropTargetHelper, public DragSourceHelper
+{
+public:
+ MediaWindowImpl(vcl::Window* parent, MediaWindow* pMediaWindow, bool bInternalMediaControl);
+ virtual ~MediaWindowImpl() override;
+
+ virtual void dispose() override;
+
+ static css::uno::Reference<css::media::XPlayer> createPlayer(const OUString& rURL, const OUString& rReferer, const OUString* pMimeType);
+
+ void setURL(const OUString& rURL, OUString const& rTempURL, OUString const& rReferer);
+
+ const OUString& getURL() const;
+
+ bool isValid() const;
+
+ Size getPreferredSize() const;
+
+ bool start();
+
+ void updateMediaItem( MediaItem& rItem ) const;
+ void executeMediaItem( const MediaItem& rItem );
+
+ void setPosSize( const tools::Rectangle& rRect );
+
+ void setPointer( PointerStyle nPointer );
+
+private:
+
+ // Window
+ virtual void MouseMove( const MouseEvent& rMEvt ) override;
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
+ virtual void KeyInput( const KeyEvent& rKEvt ) override;
+ virtual void KeyUp( const KeyEvent& rKEvt ) override;
+ virtual void Command( const CommandEvent& rCEvt ) override;
+ virtual void Resize() override;
+ virtual void StateChanged( StateChangedType ) override;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override; // const
+ virtual void GetFocus() override;
+
+ // DropTargetHelper
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
+
+ // DragSourceHelper
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override;
+
+ void stop();
+
+ bool isPlaying() const;
+
+ double getDuration() const;
+
+ void setMediaTime( double fTime );
+ double getMediaTime() const;
+
+ void stopPlayingInternal( bool );
+
+ void onURLChanged();
+
+ static css::uno::Reference<css::media::XPlayer> createPlayer(const OUString& rURL, const OUString& rManagerServName,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext);
+
+ OUString maFileURL;
+ OUString mTempFileURL;
+ OUString maReferer;
+ OUString m_sMimeType;
+ css::uno::Reference<css::media::XPlayer> mxPlayer;
+ css::uno::Reference<css::media::XPlayerWindow> mxPlayerWindow;
+ MediaWindow* mpMediaWindow;
+
+ rtl::Reference<MediaEventListenersImpl> mxEvents;
+ VclPtr<MediaChildWindow> mpChildWindow;
+ VclPtr<MediaWindowControl> mpMediaWindowControl;
+ std::unique_ptr<BitmapEx> mpEmptyBmpEx;
+ std::unique_ptr<BitmapEx> mpAudioBmpEx;
+};
+
+}} // end namespace avmedia::priv
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */