avmedia/source/gtk/gtkplayer.cxx      |  130 ++++++++++++++++++++++++----------
 avmedia/source/gtk/gtkplayer.hxx      |   20 ++++-
 avmedia/source/viewer/mediawindow.cxx |  127 +++++++++++++++++++++++++++++----
 include/avmedia/mediawindow.hxx       |   47 ++++++++++--
 sc/source/ui/drawfunc/fuins1.cxx      |   57 ++++++++++----
 sd/source/ui/func/fuinsert.cxx        |   99 +++++++++++++++++--------
 sd/source/ui/inc/View.hxx             |    3 
 sd/source/ui/inc/fuinsert.hxx         |    5 +
 sd/source/ui/view/sdview.cxx          |    7 +
 sd/source/ui/view/sdview4.cxx         |   57 +++++++++-----
 sfx2/sdi/sfx.sdi                      |    6 +
 svx/source/svdraw/svdomedia.cxx       |   15 +++
 sw/source/uibase/shells/grfshex.cxx   |  118 ++++++++++++++++++------------
 13 files changed, 512 insertions(+), 179 deletions(-)

New commits:
commit 05db887bc226b85befe2c2b9e84b796020a6ca05
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Mon Feb 21 10:01:42 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Tue Mar 1 18:38:27 2022 +0100

    gtk4: media dimensions are only reliably available async
    
    this is also the case for the direct gstreamer use in gtk3 but
    more egregious when abstracted away from it in gtk4
    
    Change-Id: If90069308d67929585722c079c482cd4ad196e1f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130468
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/avmedia/source/gtk/gtkplayer.cxx b/avmedia/source/gtk/gtkplayer.cxx
index 7ce488f231ec..b988e7f19684 100644
--- a/avmedia/source/gtk/gtkplayer.cxx
+++ b/avmedia/source/gtk/gtkplayer.cxx
@@ -37,8 +37,12 @@ namespace avmedia::gtk
 {
 GtkPlayer::GtkPlayer()
     : GtkPlayer_BASE(m_aMutex)
+    , m_lListener(m_aMutex)
     , m_pStream(nullptr)
     , m_pVideo(nullptr)
+    , m_nNotifySignalId(0)
+    , m_nInvalidateSizeSignalId(0)
+    , m_nTimeoutId(0)
     , m_nUnmutedVolume(0)
 {
 }
@@ -61,6 +65,8 @@ void GtkPlayer::cleanup()
 
     if (m_pStream)
     {
+        uninstallNotify();
+
         // shouldn't have to attempt this unref on idle, but with gtk4-4.4.1 I 
get
         // intermittent "instance of invalid non-instantiatable type '(null)'"
         // on some mysterious gst dbus callback
@@ -81,6 +87,51 @@ void SAL_CALL GtkPlayer::disposing()
     cleanup();
 }
 
+static void do_notify(GtkPlayer* pThis)
+{
+    rtl::Reference<GtkPlayer> xThis(pThis);
+    xThis->notifyListeners();
+    xThis->uninstallNotify();
+}
+
+static void invalidate_size_cb(GdkPaintable* /*pPaintable*/, GtkPlayer* pThis) 
{ do_notify(pThis); }
+
+static void notify_cb(GtkMediaStream* /*pStream*/, GParamSpec* pspec, 
GtkPlayer* pThis)
+{
+    if (g_str_equal(pspec->name, "prepared") || g_str_equal(pspec->name, 
"error"))
+        do_notify(pThis);
+}
+
+static bool timeout_cb(GtkPlayer* pThis)
+{
+    do_notify(pThis);
+    return false;
+}
+
+void GtkPlayer::installNotify()
+{
+    if (m_nNotifySignalId)
+        return;
+    m_nNotifySignalId = g_signal_connect(m_pStream, "notify", 
G_CALLBACK(notify_cb), this);
+    // notify should be enough, but there is an upstream bug so also try 
"invalidate-size" and add a timeout for
+    // audio-only case where that won't happen, see: 
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4513
+    m_nInvalidateSizeSignalId
+        = g_signal_connect(m_pStream, "invalidate-size", 
G_CALLBACK(invalidate_size_cb), this);
+    m_nTimeoutId = g_timeout_add_seconds(10, G_SOURCE_FUNC(timeout_cb), this);
+}
+
+void GtkPlayer::uninstallNotify()
+{
+    if (!m_nNotifySignalId)
+        return;
+    g_signal_handler_disconnect(m_pStream, m_nNotifySignalId);
+    m_nNotifySignalId = 0;
+    g_signal_handler_disconnect(m_pStream, m_nInvalidateSizeSignalId);
+    m_nInvalidateSizeSignalId = 0;
+    g_source_remove(m_nTimeoutId);
+    m_nTimeoutId = 0;
+}
+
 bool GtkPlayer::create(const OUString& rURL)
 {
     bool bRet = false;
@@ -104,6 +155,25 @@ bool GtkPlayer::create(const OUString& rURL)
     return bRet;
 }
 
+void GtkPlayer::notifyListeners()
+{
+    comphelper::OInterfaceContainerHelper2* pContainer
+        = 
m_lListener.getContainer(cppu::UnoType<css::media::XPlayerListener>::get());
+    if (!pContainer)
+        return;
+
+    css::lang::EventObject aEvent;
+    aEvent.Source = static_cast<cppu::OWeakObject*>(this);
+
+    comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
+    while (pIterator.hasMoreElements())
+    {
+        css::uno::Reference<css::media::XPlayerListener> xListener(
+            static_cast<css::media::XPlayerListener*>(pIterator.next()));
+        xListener->preferredPlayerWindowSizeAvailable(aEvent);
+    }
+}
+
 void SAL_CALL GtkPlayer::start()
 {
     osl::MutexGuard aGuard(m_aMutex);
@@ -231,41 +301,6 @@ sal_Int16 SAL_CALL GtkPlayer::getVolumeDB()
     return m_nUnmutedVolume;
 }
 
-namespace
-{
-void invalidate_size(GdkPaintable* /*paintable*/, Timer* pTimer) { 
pTimer->Stop(); }
-
-Size GetPreferredPlayerWindowSize(GdkPaintable* pStream)
-{
-    Size aSize(gdk_paintable_get_intrinsic_width(pStream),
-               gdk_paintable_get_intrinsic_height(pStream));
-
-    // This is pretty nasty, maybe for the XFrameGrabber case it could be
-    // possible to implement an XGraphic which can be updated when the
-    // information becomes available rather than explicitly wait for it here,
-    // but the getPreferredPlayerWindowSize problem would remain.
-    if (aSize.Width() == 0 && aSize.Height() == 0)
-    {
-        Timer aTimer("gtkplayer waiting to find out size");
-        aTimer.SetTimeout(3000);
-
-        gulong nSignalId
-            = g_signal_connect(pStream, "invalidate-size", 
G_CALLBACK(invalidate_size), &aTimer);
-
-        aTimer.Start();
-        while (aTimer.IsActive())
-            Application::Yield();
-
-        g_signal_handler_disconnect(pStream, nSignalId);
-
-        aSize = Size(gdk_paintable_get_intrinsic_width(pStream),
-                     gdk_paintable_get_intrinsic_height(pStream));
-    }
-
-    return aSize;
-}
-}
-
 awt::Size SAL_CALL GtkPlayer::getPreferredPlayerWindowSize()
 {
     osl::MutexGuard aGuard(m_aMutex);
@@ -274,9 +309,8 @@ awt::Size SAL_CALL GtkPlayer::getPreferredPlayerWindowSize()
 
     if (m_pStream)
     {
-        Size aPrefSize = 
GetPreferredPlayerWindowSize(GDK_PAINTABLE(m_pStream));
-        aSize.Width = aPrefSize.Width();
-        aSize.Height = aPrefSize.Height();
+        aSize.Width = 
gdk_paintable_get_intrinsic_width(GDK_PAINTABLE(m_pStream));
+        aSize.Height = 
gdk_paintable_get_intrinsic_height(GDK_PAINTABLE(m_pStream));
     }
 
     return aSize;
@@ -325,6 +359,26 @@ uno::Reference<::media::XPlayerWindow>
     return xRet;
 }
 
+void SAL_CALL
+GtkPlayer::addPlayerListener(const 
css::uno::Reference<css::media::XPlayerListener>& rListener)
+{
+    
m_lListener.addInterface(cppu::UnoType<css::media::XPlayerListener>::get(), 
rListener);
+    if (gtk_media_stream_is_prepared(m_pStream))
+    {
+        css::lang::EventObject aEvent;
+        aEvent.Source = static_cast<cppu::OWeakObject*>(this);
+        rListener->preferredPlayerWindowSizeAvailable(aEvent);
+    }
+    else
+        installNotify();
+}
+
+void SAL_CALL
+GtkPlayer::removePlayerListener(const 
css::uno::Reference<css::media::XPlayerListener>& rListener)
+{
+    
m_lListener.removeInterface(cppu::UnoType<css::media::XPlayerListener>::get(), 
rListener);
+}
+
 namespace
 {
 class GtkFrameGrabber : public 
::cppu::WeakImplHelper<css::media::XFrameGrabber>
diff --git a/avmedia/source/gtk/gtkplayer.hxx b/avmedia/source/gtk/gtkplayer.hxx
index 89f9355c94ae..46e416e79e25 100644
--- a/avmedia/source/gtk/gtkplayer.hxx
+++ b/avmedia/source/gtk/gtkplayer.hxx
@@ -15,6 +15,8 @@
 
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/media/XPlayer.hpp>
+#include <com/sun/star/media/XPlayerNotifier.hpp>
+#include <comphelper/multicontainer2.hxx>
 #include <cppuhelper/compbase.hxx>
 #include <cppuhelper/basemutex.hxx>
 
@@ -23,7 +25,9 @@ typedef struct _GtkWidget GtkWidget;
 
 namespace avmedia::gtk
 {
-typedef cppu::WeakComponentImplHelper<css::media::XPlayer, 
css::lang::XServiceInfo> GtkPlayer_BASE;
+typedef cppu::WeakComponentImplHelper<css::media::XPlayer, 
css::media::XPlayerNotifier,
+                                      css::lang::XServiceInfo>
+    GtkPlayer_BASE;
 
 class GtkPlayer final : public cppu::BaseMutex, public GtkPlayer_BASE
 {
@@ -54,15 +58,29 @@ public:
     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 
override;
     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() 
override;
 
+    virtual void SAL_CALL
+    addPlayerListener(const css::uno::Reference<css::media::XPlayerListener>& 
rListener) override;
+    virtual void SAL_CALL removePlayerListener(
+        const css::uno::Reference<css::media::XPlayerListener>& rListener) 
override;
+
     virtual void SAL_CALL disposing() final override;
 
+    void notifyListeners();
+    void installNotify();
+    void uninstallNotify();
+
 private:
     void cleanup();
 
+    comphelper::OMultiTypeInterfaceContainerHelper2 m_lListener;
+
     OUString m_aURL;
     css::awt::Rectangle m_aArea; // Area of the player window.
     GtkMediaStream* m_pStream;
     GtkWidget* m_pVideo;
+    unsigned long m_nNotifySignalId;
+    unsigned long m_nInvalidateSizeSignalId;
+    unsigned long m_nTimeoutId;
     sal_Int16 m_nUnmutedVolume;
 };
 
diff --git a/avmedia/source/viewer/mediawindow.cxx 
b/avmedia/source/viewer/mediawindow.cxx
index c251f020225e..f3c034146f1d 100644
--- a/avmedia/source/viewer/mediawindow.cxx
+++ b/avmedia/source/viewer/mediawindow.cxx
@@ -28,11 +28,16 @@
 #include <vcl/weld.hxx>
 #include <sfx2/filedlghelper.hxx>
 #include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
 #include <com/sun/star/media/XPlayer.hpp>
+#include <com/sun/star/media/XPlayerNotifier.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 <com/sun/star/util/URLTransformer.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertysequence.hxx>
 #include <memory>
 #include <sal/log.hxx>
 
@@ -296,14 +301,14 @@ void MediaWindow::executeFormatErrorBox(weld::Window* 
pParent)
     xBox->run();
 }
 
-bool MediaWindow::isMediaURL( const OUString& rURL, const OUString& rReferer, 
bool bDeep, Size* pPreferredSizePixel )
+bool MediaWindow::isMediaURL(const OUString& rURL, const OUString& rReferer, 
bool bDeep, rtl::Reference<PlayerListener> xPreferredPixelSizeListener)
 {
     const INetURLObject aURL( rURL );
 
     if( aURL.GetProtocol() == INetProtocol::NotValid )
         return false;
 
-    if( bDeep || pPreferredSizePixel )
+    if (bDeep || xPreferredPixelSizeListener)
     {
         try
         {
@@ -313,14 +318,20 @@ bool MediaWindow::isMediaURL( const OUString& rURL, const 
OUString& rReferer, bo
 
             if( xPlayer.is() )
             {
-                if( pPreferredSizePixel )
+                if (xPreferredPixelSizeListener)
                 {
-                    const awt::Size aAwtSize( 
xPlayer->getPreferredPlayerWindowSize() );
-
-                    pPreferredSizePixel->setWidth( aAwtSize.Width );
-                    pPreferredSizePixel->setHeight( aAwtSize.Height );
+                    uno::Reference<media::XPlayerNotifier> 
xPlayerNotifier(xPlayer, css::uno::UNO_QUERY);
+                    if (xPlayerNotifier)
+                    {
+                        // wait until its possible to query this to get a 
sensible answer
+                        
xPreferredPixelSizeListener->startListening(xPlayerNotifier);
+                    }
+                    else
+                    {
+                        // assume the size is possible to query immediately
+                        
xPreferredPixelSizeListener->callPlayerWindowSizeAvailable(xPlayer);
+                    }
                 }
-
                 return true;
             }
         }
@@ -346,18 +357,13 @@ bool MediaWindow::isMediaURL( const OUString& rURL, const 
OUString& rReferer, bo
     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< graphic::XGraphic > MediaWindow::grabFrame(const 
css::uno::Reference<css::media::XPlayer>& xPlayer)
 {
-    uno::Reference< media::XPlayer >    xPlayer( createPlayer( rURL, rReferer, 
&sMimeType ) );
     uno::Reference< graphic::XGraphic > xRet;
     std::unique_ptr< Graphic > xGraphic;
 
@@ -399,6 +405,99 @@ uno::Reference< graphic::XGraphic > 
MediaWindow::grabFrame( const OUString& rURL
     return xRet;
 }
 
+uno::Reference< graphic::XGraphic > MediaWindow::grabFrame(const OUString& 
rURL,
+                                                           const OUString& 
rReferer,
+                                                           const OUString& 
sMimeType,
+                                                           
rtl::Reference<PlayerListener> xPreferredPixelSizeListener)
+{
+    uno::Reference<media::XPlayer> xPlayer(createPlayer(rURL, rReferer, 
&sMimeType));
+
+    if (xPreferredPixelSizeListener)
+    {
+        uno::Reference<media::XPlayerNotifier> xPlayerNotifier(xPlayer, 
css::uno::UNO_QUERY);
+        if (xPlayerNotifier)
+        {
+            // set a callback to call when a more sensible result is 
available, which
+            // might be called immediately if already available
+            xPreferredPixelSizeListener->startListening(xPlayerNotifier);
+        }
+        else
+        {
+            // assume the size is possible to query immediately
+            
xPreferredPixelSizeListener->callPlayerWindowSizeAvailable(xPlayer);
+        }
+
+        return nullptr;
+    }
+
+    return grabFrame(xPlayer);
+}
+
+void MediaWindow::dispatchInsertAVMedia(const 
css::uno::Reference<css::frame::XDispatchProvider>& rDispatchProvider,
+                                        const css::awt::Size& rSize, const 
OUString& rURL, bool bLink)
+{
+    util::URL aDispatchURL;
+    aDispatchURL.Complete = ".uno:InsertAVMedia";
+
+    css::uno::Reference<css::util::XURLTransformer> 
xTrans(css::util::URLTransformer::create(::comphelper::getProcessComponentContext()));
+    xTrans->parseStrict(aDispatchURL);
+
+    css::uno::Reference<css::frame::XDispatch> xDispatch = 
rDispatchProvider->queryDispatch(aDispatchURL, "", 0);
+    css::uno::Sequence<css::beans::PropertyValue> 
aArgs(comphelper::InitPropertySequence({
+        { "URL", css::uno::makeAny(rURL) },
+        { "Size.Width", uno::makeAny(rSize.Width)},
+        { "Size.Height", uno::makeAny(rSize.Height)},
+        { "IsLink", css::uno::makeAny(bLink) },
+    }));
+    xDispatch->dispatch(aDispatchURL, aArgs);
+}
+
+PlayerListener::PlayerListener(const std::function<void(const 
css::uno::Reference<css::media::XPlayer>&)> &rFn)
+    : PlayerListener_BASE(m_aMutex)
+    , m_aFn(rFn)
+{
+}
+
+void PlayerListener::dispose()
+{
+    stopListening();
+    PlayerListener_BASE::dispose();
+}
+
+void PlayerListener::startListening(const 
css::uno::Reference<media::XPlayerNotifier>& rNotifier)
+{
+    osl::MutexGuard aGuard(m_aMutex);
+
+    m_xNotifier = rNotifier;
+    m_xNotifier->addPlayerListener(this);
+}
+
+void PlayerListener::stopListening()
+{
+    osl::MutexGuard aGuard(m_aMutex);
+    if (!m_xNotifier)
+        return;
+    m_xNotifier->removePlayerListener(this);
+    m_xNotifier.clear();
+}
+
+void SAL_CALL PlayerListener::preferredPlayerWindowSizeAvailable(const 
css::lang::EventObject&)
+{
+    osl::MutexGuard aGuard(m_aMutex);
+
+    css::uno::Reference<media::XPlayer> xPlayer(m_xNotifier, 
css::uno::UNO_QUERY_THROW);
+    callPlayerWindowSizeAvailable(xPlayer);
+
+    stopListening();
+}
+
+void SAL_CALL PlayerListener::disposing(const css::lang::EventObject&)
+{
+}
+
+PlayerListener::~PlayerListener()
+{
+}
 
 } // namespace avmedia
 
diff --git a/include/avmedia/mediawindow.hxx b/include/avmedia/mediawindow.hxx
index d031f51adaf0..4954e04558bb 100644
--- a/include/avmedia/mediawindow.hxx
+++ b/include/avmedia/mediawindow.hxx
@@ -22,14 +22,22 @@
 
 #include <vector>
 #include <tools/gen.hxx>
+#include <com/sun/star/awt/Size.hpp>
 #include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/media/XPlayerListener.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/basemutex.hxx>
 #include <vcl/vclptr.hxx>
 #include <avmedia/avmediadllapi.h>
 
 #define AVMEDIA_FRAMEGRABBER_DEFAULTFRAME -1.0
 
+namespace com::sun::star::frame { class XDispatchProvider; }
 namespace com::sun::star::graphic { class XGraphic; }
-namespace com::sun::star::media { class XPlayer; }
+namespace com::sun::star::media {
+    class XPlayer;
+    class XPlayerNotifier;
+}
 
 namespace vcl { class Window; }
 namespace weld { class Window; }
@@ -40,7 +48,6 @@ struct AcceptDropEvent;
 struct ExecuteDropEvent;
 enum class PointerStyle;
 
-
 namespace avmedia
 {
     typedef ::std::vector< ::std::pair< OUString, OUString > > 
FilterNameVector;
@@ -49,6 +56,29 @@ namespace avmedia
 
     namespace priv { class MediaWindowImpl; }
 
+    typedef cppu::WeakComponentImplHelper<css::media::XPlayerListener> 
PlayerListener_BASE;
+
+    class AVMEDIA_DLLPUBLIC PlayerListener final : public cppu::BaseMutex, 
public PlayerListener_BASE
+    {
+    private:
+        css::uno::Reference<css::media::XPlayerNotifier> m_xNotifier;
+        std::function<void(const css::uno::Reference<css::media::XPlayer>&)> 
m_aFn;
+
+        using WeakComponentImplHelperBase::disposing;
+    public:
+        PlayerListener(const std::function<void(const 
css::uno::Reference<css::media::XPlayer>&)> &rFn);
+        virtual void SAL_CALL dispose() override;
+        virtual ~PlayerListener() override;
+
+        virtual void SAL_CALL preferredPlayerWindowSizeAvailable(const 
css::lang::EventObject& rSource) override;
+        virtual void SAL_CALL disposing(const css::lang::EventObject& rSource) 
override;
+
+        void startListening(const 
css::uno::Reference<css::media::XPlayerNotifier>& rNotifier);
+        void stopListening();
+
+        void callPlayerWindowSizeAvailable(const 
css::uno::Reference<css::media::XPlayer>& rPlayer) { m_aFn(rPlayer); }
+    };
+
     class AVMEDIA_DLLPUBLIC MediaWindow
     {
     public:
@@ -99,12 +129,18 @@ namespace avmedia
         ///                 checkbox and store its state in *o_pbLink
         static bool         executeMediaURLDialog(weld::Window* pParent, 
OUString& rURL, bool *const o_pbLink);
         static void         executeFormatErrorBox(weld::Window* pParent);
-        static bool         isMediaURL( const OUString& rURL, const OUString& 
rReferer, bool bDeep = false, Size* pPreferredSizePixel = nullptr );
+        static bool         isMediaURL(const OUString& rURL, const OUString& 
rReferer, bool bDeep = false,
+                                       rtl::Reference<PlayerListener> 
xPreferredPixelSizeListener = nullptr);
 
         static css::uno::Reference< css::media::XPlayer > createPlayer( const 
OUString& rURL, const OUString& rReferer, const OUString* pMimeType = nullptr );
 
-        static css::uno::Reference< css::graphic::XGraphic > grabFrame( const 
OUString& rURL, const OUString& rReferer,
-            const OUString& sMimeType );
+        static css::uno::Reference<css::graphic::XGraphic> grabFrame(const 
css::uno::Reference<css::media::XPlayer>& rPlayer);
+
+        static css::uno::Reference< css::graphic::XGraphic > grabFrame(const 
OUString& rURL, const OUString& rReferer,
+            const OUString& sMimeType, rtl::Reference<PlayerListener> 
xPreferredPixelSizeListener = nullptr);
+
+        static void dispatchInsertAVMedia(const 
css::uno::Reference<css::frame::XDispatchProvider>&,
+                                          const css::awt::Size& rSize, const 
OUString& rURL, bool bLink);
 
     private:
         MediaWindow(const MediaWindow&) = delete;
@@ -112,6 +148,7 @@ namespace avmedia
 
         VclPtr<priv::MediaWindowImpl>                 mpImpl;
     };
+
 }
 
 #endif // INCLUDED_AVMEDIA_MEDIAWINDOW_HXX
diff --git a/sc/source/ui/drawfunc/fuins1.cxx b/sc/source/ui/drawfunc/fuins1.cxx
index a447a56c6dca..cbc87373c467 100644
--- a/sc/source/ui/drawfunc/fuins1.cxx
+++ b/sc/source/ui/drawfunc/fuins1.cxx
@@ -20,8 +20,10 @@
 #include <config_features.h>
 
 #include <officecfg/Office/Common.hxx>
+#include <editeng/sizeitem.hxx>
 #include <sal/log.hxx>
 #include <sfx2/opengrf.hxx>
+#include <sfx2/viewfrm.hxx>
 #include <svx/svdograf.hxx>
 #include <svx/svdomedia.hxx>
 #include <svx/svdpage.hxx>
@@ -46,6 +48,8 @@
 #include <globstr.hrc>
 #include <comphelper/lok.hxx>
 
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/media/XPlayer.hpp>
 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
 #include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
@@ -372,10 +376,16 @@ FuInsertMedia::FuInsertMedia( ScTabViewShell&   rViewSh,
                               const SfxRequest& rReq ) :
     FuPoor(rViewSh, pWin, pViewP, pDoc, rReq)
 {
+#if HAVE_FEATURE_AVMEDIA
     OUString     aURL;
     const SfxItemSet*   pReqArgs = rReq.GetArgs();
     bool                bAPI = false;
 
+    const SvxSizeItem* pSizeItem = rReq.GetArg<SvxSizeItem>(FN_PARAM_1);
+    const SfxBoolItem* pLinkItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
+    const bool bSizeUnknown = !pSizeItem;
+    Size aPrefSize;
+
     if( pReqArgs )
     {
         const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>( 
&pReqArgs->Get( rReq.GetSlot() )  );
@@ -387,38 +397,49 @@ FuInsertMedia::FuInsertMedia( ScTabViewShell&   rViewSh,
         }
     }
 
-    bool bLink(true);
+    bool bLink(pLinkItem ? pLinkItem->GetValue() : true);
     bool bInsertMedia = bAPI;
-#if HAVE_FEATURE_AVMEDIA
     if (!bInsertMedia)
         bInsertMedia = ::avmedia::MediaWindow::executeMediaURLDialog(pWin ? 
pWin->GetFrameWeld() : nullptr, aURL, &bLink);
-#endif
     if (!bInsertMedia)
         return;
 
-    Size aPrefSize;
-
-    if( pWin )
-        pWin->EnterWait();
-
-#if HAVE_FEATURE_AVMEDIA
-    if( !::avmedia::MediaWindow::isMediaURL( aURL, ""/*TODO?*/, true, 
&aPrefSize ) )
+    if (!bSizeUnknown)
     {
-        if( pWin )
-            pWin->LeaveWait();
-
-        if( !bAPI )
-            ::avmedia::MediaWindow::executeFormatErrorBox(pWindow ? 
pWindow->GetFrameWeld() : nullptr);
+        aPrefSize = pSizeItem->GetSize();
     }
     else
-#endif
     {
-        lcl_InsertMedia( aURL, bAPI, &rViewSh, pWindow, pView, aPrefSize,
-                bLink );
+        if( pWin )
+            pWin->EnterWait();
+
+        css::uno::Reference<css::frame::XDispatchProvider> 
xDispatchProvider(rViewShell.GetViewFrame()->GetFrame().GetFrameInterface(), 
css::uno::UNO_QUERY);
+
+        rtl::Reference<avmedia::PlayerListener> xPlayerListener(new 
avmedia::PlayerListener(
+            [xDispatchProvider, aURL, bLink](const 
css::uno::Reference<css::media::XPlayer>& rPlayer){
+                css::awt::Size aSize = rPlayer->getPreferredPlayerWindowSize();
+                avmedia::MediaWindow::dispatchInsertAVMedia(xDispatchProvider, 
aSize, aURL, bLink);
+            }));
+
+        const bool bIsMediaURL = ::avmedia::MediaWindow::isMediaURL(aURL, 
""/*TODO?*/, true, xPlayerListener);
 
         if( pWin )
             pWin->LeaveWait();
+
+        if (!bIsMediaURL && !bAPI)
+            ::avmedia::MediaWindow::executeFormatErrorBox(pWindow ? 
pWindow->GetFrameWeld() : nullptr);
+
+        return;
     }
+
+    if (pWin)
+        pWin->EnterWait();
+
+    lcl_InsertMedia(aURL, bAPI, &rViewSh, pWindow, pView, aPrefSize, bLink);
+
+    if (pWin)
+        pWin->LeaveWait();
+#endif
 }
 
 FuInsertMedia::~FuInsertMedia()
diff --git a/sd/source/ui/func/fuinsert.cxx b/sd/source/ui/func/fuinsert.cxx
index 5d95335e48ca..d65e7c8b2ff2 100644
--- a/sd/source/ui/func/fuinsert.cxx
+++ b/sd/source/ui/func/fuinsert.cxx
@@ -21,16 +21,21 @@
 
 #include <fuinsert.hxx>
 #include <comphelper/storagehelper.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <editeng/sizeitem.hxx>
 #include <officecfg/Office/Common.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
 #include <svx/svxdlg.hxx>
+#include <com/sun/star/chart2/XChartDocument.hpp>
 #include <com/sun/star/embed/EmbedVerbs.hpp>
 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
 #include <com/sun/star/embed/Aspects.hpp>
 #include <com/sun/star/embed/XEmbeddedObject.hpp>
-#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/media/XPlayer.hpp>
 
 #include <svl/stritem.hxx>
+#include <sfx2/dispatch.hxx>
 #include <sfx2/msgpool.hxx>
 #include <sfx2/msg.hxx>
 #include <svtools/insdlg.hxx>
@@ -664,6 +669,11 @@ void FuInsertAVMedia::DoExecute( SfxRequest& rReq )
     const SfxItemSet*   pReqArgs = rReq.GetArgs();
     bool                bAPI = false;
 
+    const SvxSizeItem* pSizeItem = rReq.GetArg<SvxSizeItem>(FN_PARAM_1);
+    const SfxBoolItem* pLinkItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
+    const bool bSizeUnknown = !pSizeItem;
+    Size aPrefSize;
+
     if( pReqArgs )
     {
         const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>( 
&pReqArgs->Get( rReq.GetSlot() )  );
@@ -675,58 +685,83 @@ void FuInsertAVMedia::DoExecute( SfxRequest& rReq )
         }
     }
 
-    bool bLink(true);
+    bool bLink(pLinkItem ? pLinkItem->GetValue() : true);
     if (!(bAPI
         || ::avmedia::MediaWindow::executeMediaURLDialog(mpWindow ? 
mpWindow->GetFrameWeld() : nullptr, aURL, & bLink)
        ))
         return;
 
-    Size aPrefSize;
-
-    if( mpWindow )
-        mpWindow->EnterWait();
-
-    if( !::avmedia::MediaWindow::isMediaURL( aURL, "", true, &aPrefSize ) )
+    if (!bSizeUnknown)
     {
-        if( mpWindow )
-            mpWindow->LeaveWait();
-
-        if( !bAPI )
-            
::avmedia::MediaWindow::executeFormatErrorBox(mpWindow->GetFrameWeld());
+        aPrefSize = pSizeItem->GetSize();
     }
     else
     {
-        Point       aPos;
-        Size        aSize;
-        sal_Int8    nAction = DND_ACTION_COPY;
+        // If we don't have a size then try and find that out, the resulted 
might be deliver async, so dispatch a follow up
+        // effort to insert the video, this time with a size.
+        if( mpWindow )
+            mpWindow->EnterWait();
 
-        if( aPrefSize.Width() && aPrefSize.Height() )
-        {
-            if( mpWindow )
-                aSize = mpWindow->PixelToLogic(aPrefSize, 
MapMode(MapUnit::Map100thMM));
-            else
-                aSize = 
Application::GetDefaultDevice()->PixelToLogic(aPrefSize, 
MapMode(MapUnit::Map100thMM));
-        }
-        else
-            aSize = Size( 5000, 5000 );
+        css::uno::Reference<css::frame::XDispatchProvider> 
xDispatchProvider(mpViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), 
css::uno::UNO_QUERY);
 
-        if( mpWindow )
-        {
-            aPos = mpWindow->PixelToLogic( ::tools::Rectangle( aPos, 
mpWindow->GetOutputSizePixel() ).Center() );
-            aPos.AdjustX( -(aSize.Width() >> 1) );
-            aPos.AdjustY( -(aSize.Height() >> 1) );
-        }
+        rtl::Reference<avmedia::PlayerListener> xPlayerListener(new 
avmedia::PlayerListener(
+            [xDispatchProvider, aURL, bLink](const 
css::uno::Reference<css::media::XPlayer>& rPlayer){
+                css::awt::Size aSize = rPlayer->getPreferredPlayerWindowSize();
+                avmedia::MediaWindow::dispatchInsertAVMedia(xDispatchProvider, 
aSize, aURL, bLink);
+            }));
 
-        mpView->InsertMediaURL( aURL, nAction, aPos, aSize, bLink ) ;
+        const bool bIsMediaURL = ::avmedia::MediaWindow::isMediaURL(aURL, "", 
true, xPlayerListener);
 
         if( mpWindow )
             mpWindow->LeaveWait();
+
+        if (!bIsMediaURL && !bAPI)
+            
::avmedia::MediaWindow::executeFormatErrorBox(mpWindow->GetFrameWeld());
+
+        return;
     }
+
+    InsertMediaURL(aURL, aPrefSize, bLink);
+
 #else
     (void)rReq;
 #endif
 }
 
+#if HAVE_FEATURE_AVMEDIA
+void FuInsertAVMedia::InsertMediaURL(const OUString& rURL, const Size& 
rPrefSize, bool bLink)
+{
+    if( mpWindow )
+        mpWindow->EnterWait();
+
+    Point       aPos;
+    Size        aSize;
+    sal_Int8    nAction = DND_ACTION_COPY;
+
+    if (rPrefSize.Width() && rPrefSize.Height())
+    {
+        if( mpWindow )
+            aSize = mpWindow->PixelToLogic(rPrefSize, 
MapMode(MapUnit::Map100thMM));
+        else
+            aSize = Application::GetDefaultDevice()->PixelToLogic(rPrefSize, 
MapMode(MapUnit::Map100thMM));
+    }
+    else
+        aSize = Size( 5000, 5000 );
+
+    if( mpWindow )
+    {
+        aPos = mpWindow->PixelToLogic( ::tools::Rectangle( aPos, 
mpWindow->GetOutputSizePixel() ).Center() );
+        aPos.AdjustX( -(aSize.Width() >> 1) );
+        aPos.AdjustY( -(aSize.Height() >> 1) );
+    }
+
+    mpView->InsertMediaURL(rURL, nAction, aPos, aSize, bLink);
+
+    if( mpWindow )
+        mpWindow->LeaveWait();
+}
+#endif
+
 } // end of namespace sd
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx
index 8d211d0c3533..4e530e3f9227 100644
--- a/sd/source/ui/inc/View.hxx
+++ b/sd/source/ui/inc/View.hxx
@@ -40,6 +40,8 @@ class ImageMap;
 class Graphic;
 class SdrOutliner;
 
+namespace avmedia { class PlayerListener; }
+
 namespace sd {
 
 class DrawDocShell;
@@ -268,6 +270,7 @@ protected:
     sal_Int8                mnAction;
     Idle                    maDropErrorIdle;
     Idle                    maDropInsertFileIdle;
+    rtl::Reference<avmedia::PlayerListener> mxDropMediaSizeListener;
     sal_uInt16              mnLockRedrawSmph;
     bool                    mbIsDropAllowed;
 
diff --git a/sd/source/ui/inc/fuinsert.hxx b/sd/source/ui/inc/fuinsert.hxx
index 0ad622df36b8..a2b33596162d 100644
--- a/sd/source/ui/inc/fuinsert.hxx
+++ b/sd/source/ui/inc/fuinsert.hxx
@@ -19,6 +19,7 @@
 
 #pragma once
 
+#include <config_features.h>
 #include "fupoor.hxx"
 
 namespace sd {
@@ -101,6 +102,10 @@ private:
         ::sd::View* pView,
         SdDrawDocument* pDoc,
         SfxRequest& rReq);
+
+#if HAVE_FEATURE_AVMEDIA
+    void InsertMediaURL(const OUString& rURL, const Size& rPrefSize, bool 
bLink);
+#endif
 };
 } // end of namespace sd
 
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index b1ddd90c95cf..100374ae8205 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -22,6 +22,7 @@
 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
 
 #include <View.hxx>
+#include <avmedia/mediawindow.hxx>
 #include <editeng/outlobj.hxx>
 #include <editeng/unolingu.hxx>
 #include <o3tl/deleter.hxx>
@@ -142,6 +143,12 @@ View::~View()
     // release content of selection clipboard, if we own the content
     ClearSelectionClipboard();
 
+    if (mxDropMediaSizeListener)
+    {
+        mxDropMediaSizeListener->dispose();
+        mxDropMediaSizeListener.clear();
+    }
+
     maDropErrorIdle.Stop();
     maDropInsertFileIdle.Stop();
 
diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx
index 2b08a5a041f8..7a3c7c2267a5 100644
--- a/sd/source/ui/view/sdview4.cxx
+++ b/sd/source/ui/view/sdview4.cxx
@@ -61,6 +61,7 @@
 #include <com/sun/star/embed/Aspects.hpp>
 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
 #include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/media/XPlayer.hpp>
 #include <svtools/soerr.hxx>
 #include <sfx2/ipclient.hxx>
 #include <tools/debug.hxx>
@@ -425,7 +426,7 @@ IMPL_LINK_NOARG(View, DropInsertFileHdl, Timer *, void)
     {
         OUString aCurrentDropFile( *aIter );
         INetURLObject   aURL( aCurrentDropFile );
-        bool            bOK = false;
+        bool bHandled = false;
 
         if( aURL.GetProtocol() == INetProtocol::NotValid )
         {
@@ -458,9 +459,9 @@ IMPL_LINK_NOARG(View, DropInsertFileHdl, Timer *, void)
                 if( aIter == maDropFileVector.begin() )
                     mnAction = nTempAction;
 
-                bOK = true;
+                bHandled = true;
             }
-            if( !bOK )
+            if (!bHandled)
             {
                 std::shared_ptr<const SfxFilter> pFoundFilter;
                 SfxMedium               aSfxMedium( aCurrentDropFile, 
StreamMode::READ | StreamMode::SHARE_DENYNONE );
@@ -493,36 +494,48 @@ IMPL_LINK_NOARG(View, DropInsertFileHdl, Timer *, void)
                         aReq.AppendItem( aItem1 );
                         aReq.AppendItem( aItem2 );
                         FuInsertFile::Create( mpViewSh, pWin, this, &mrDoc, 
aReq );
-                        bOK = true;
+                        bHandled = true;
                     }
                 }
             }
         }
 
-        if( !bOK )
-        {
 #if HAVE_FEATURE_AVMEDIA
-            Size aPrefSize;
-
-            if( ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile, 
""/*TODO?*/ ) &&
-                ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile, 
""/*TODO?*/, true, &aPrefSize ) )
+        if (!bHandled)
+        {
+            bool bShallowDetect = 
::avmedia::MediaWindow::isMediaURL(aCurrentDropFile, ""/*TODO?*/);
+            if (bShallowDetect)
             {
-                if( aPrefSize.Width() && aPrefSize.Height() )
-                {
-                    ::sd::Window* pWin = mpViewSh->GetActiveWindow();
+                mxDropMediaSizeListener.set(new avmedia::PlayerListener(
+                    [this, aCurrentDropFile](const 
css::uno::Reference<css::media::XPlayer>& rPlayer){
+                        SolarMutexGuard g;
 
-                    if( pWin )
-                        aPrefSize = pWin->PixelToLogic(aPrefSize, 
MapMode(MapUnit::Map100thMM));
-                    else
-                        aPrefSize = 
Application::GetDefaultDevice()->PixelToLogic(aPrefSize, 
MapMode(MapUnit::Map100thMM));
-                }
-                else
-                    aPrefSize  = Size( 5000, 5000 );
+                        css::awt::Size aSize = 
rPlayer->getPreferredPlayerWindowSize();
+                        Size aPrefSize(aSize.Width, aSize.Height);
+
+                        if (aPrefSize.Width() && aPrefSize.Height())
+                        {
+                            ::sd::Window* pWin = mpViewSh->GetActiveWindow();
 
-                InsertMediaURL( aCurrentDropFile, mnAction, maDropPos, 
aPrefSize, true ) ;
+                            if( pWin )
+                                aPrefSize = pWin->PixelToLogic(aPrefSize, 
MapMode(MapUnit::Map100thMM));
+                            else
+                                aPrefSize = 
Application::GetDefaultDevice()->PixelToLogic(aPrefSize, 
MapMode(MapUnit::Map100thMM));
+                        }
+                        else
+                            aPrefSize  = Size( 5000, 5000 );
+
+                        InsertMediaURL(aCurrentDropFile, mnAction, maDropPos, 
aPrefSize, true);
+
+                        mxDropMediaSizeListener.clear();
+                    }));
             }
-            else
+            bHandled = bShallowDetect && 
::avmedia::MediaWindow::isMediaURL(aCurrentDropFile, ""/*TODO?*/, true, 
mxDropMediaSizeListener);
+        }
 #endif
+
+        if (!bHandled)
+        {
             if( mnAction & DND_ACTION_LINK )
                 static_cast< DrawViewShell* >( mpViewSh )->InsertURLButton( 
aCurrentDropFile, aCurrentDropFile, OUString(), &maDropPos );
             else
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index 8ef53ebaedc5..5115dec907c0 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -5387,7 +5387,11 @@ SfxVoidItem AVMediaPlayer SID_AVMEDIA_PLAYER
 ]
 
 SfxVoidItem InsertAVMedia SID_INSERT_AVMEDIA
-()
+(
+    SfxStringItem URL SID_INSERT_AVMEDIA,
+    SvxSizeItem Size FN_PARAM_1,
+    SfxBoolItem IsLink FN_PARAM_2
+)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx
index b40a0644aa15..62b2f9e8213f 100644
--- a/svx/source/svdraw/svdomedia.cxx
+++ b/svx/source/svdraw/svdomedia.cxx
@@ -51,6 +51,7 @@ struct SdrMediaObj::Impl
     std::shared_ptr< ::avmedia::MediaTempFile >  m_pTempFile;
 #endif
     uno::Reference< graphic::XGraphic >   m_xCachedSnapshot;
+    rtl::Reference<avmedia::PlayerListener> m_xPlayerListener;
     OUString m_LastFailedPkgURL;
 };
 
@@ -150,7 +151,18 @@ uno::Reference< graphic::XGraphic > const & 
SdrMediaObj::getSnapshot() const
         OUString aRealURL = m_xImpl->m_MediaProperties.getTempURL();
         if( aRealURL.isEmpty() )
             aRealURL = m_xImpl->m_MediaProperties.getURL();
-        m_xImpl->m_xCachedSnapshot = avmedia::MediaWindow::grabFrame( 
aRealURL, m_xImpl->m_MediaProperties.getReferer(), 
m_xImpl->m_MediaProperties.getMimeType());
+        OUString sReferer = m_xImpl->m_MediaProperties.getReferer();
+        OUString sMimeType = m_xImpl->m_MediaProperties.getMimeType();
+        uno::Reference<graphic::XGraphic> xCachedSnapshot = 
m_xImpl->m_xCachedSnapshot;
+
+        m_xImpl->m_xPlayerListener.set(new avmedia::PlayerListener(
+            [this, xCachedSnapshot, aRealURL, sReferer, sMimeType](const 
css::uno::Reference<css::media::XPlayer>& rPlayer){
+                SolarMutexGuard g;
+                m_xImpl->m_xCachedSnapshot = 
avmedia::MediaWindow::grabFrame(rPlayer);
+                ActionChanged();
+            }));
+
+        avmedia::MediaWindow::grabFrame(aRealURL, sReferer, sMimeType, 
m_xImpl->m_xPlayerListener);
     }
 #endif
     return m_xImpl->m_xCachedSnapshot;
@@ -341,6 +353,7 @@ void SdrMediaObj::mediaPropertiesChanged( const 
::avmedia::MediaItem& rNewProper
         ( rNewProperties.getURL() != getURL() ))
     {
         m_xImpl->m_xCachedSnapshot.clear();
+        m_xImpl->m_xPlayerListener.clear();
         OUString const& url(rNewProperties.getURL());
         if (url.startsWithIgnoreAsciiCase("vnd.sun.star.Package:"))
         {
diff --git a/sw/source/uibase/shells/grfshex.cxx 
b/sw/source/uibase/shells/grfshex.cxx
index 2fe098dba3a2..2f6ad40a36e5 100644
--- a/sw/source/uibase/shells/grfshex.cxx
+++ b/sw/source/uibase/shells/grfshex.cxx
@@ -25,12 +25,14 @@
 #include <doc.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <docsh.hxx>
-#include <svx/svdomedia.hxx>
-
+#include <avmedia/mediawindow.hxx>
+#include <editeng/sizeitem.hxx>
 #include <sfx2/request.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <svl/stritem.hxx>
-#include <avmedia/mediawindow.hxx>
+#include <svx/svdomedia.hxx>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/media/XPlayer.hpp>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -49,6 +51,10 @@ bool SwTextShell::InsertMediaDlg( SfxRequest const & rReq )
     vcl::Window&        rWindow = GetView().GetViewFrame()->GetWindow();
     bool bAPI = false;
 
+    const SvxSizeItem* pSizeItem = rReq.GetArg<SvxSizeItem>(FN_PARAM_1);
+    const SfxBoolItem* pLinkItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
+    const bool bSizeUnknown = !pSizeItem;
+
     if( pReqArgs )
     {
         const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>( 
&pReqArgs->Get( rReq.GetSlot() )  );
@@ -59,67 +65,85 @@ bool SwTextShell::InsertMediaDlg( SfxRequest const & rReq )
         }
     }
 
-    bool bLink(true);
+    bool bLink(pLinkItem ? pLinkItem->GetValue() : true);
+
     if (bAPI || 
::avmedia::MediaWindow::executeMediaURLDialog(rWindow.GetFrameWeld(), aURL, & 
bLink))
     {
         Size aPrefSize;
 
-        rWindow.EnterWait();
-
-        if( !::avmedia::MediaWindow::isMediaURL( aURL, "", true, &aPrefSize ) )
-        {
-            rWindow.LeaveWait();
-
-            if( !bAPI )
-                
::avmedia::MediaWindow::executeFormatErrorBox(rWindow.GetFrameWeld());
-        }
+        if (!bSizeUnknown)
+            aPrefSize = pSizeItem->GetSize();
         else
         {
-            SwWrtShell& rSh = GetShell();
+            rWindow.EnterWait();
 
-            if( !rSh.HasDrawView() )
-                rSh.MakeDrawView();
+            css::uno::Reference<css::frame::XDispatchProvider> 
xDispatchProvider(GetView().GetViewFrame()->GetFrame().GetFrameInterface(), 
css::uno::UNO_QUERY);
 
-            Size            aDocSz( rSh.GetDocSize() );
-            const SwRect&   rVisArea = rSh.VisArea();
-            Point           aPos( rVisArea.Center() );
-            Size            aSize;
+            rtl::Reference<avmedia::PlayerListener> xPlayerListener(new 
avmedia::PlayerListener(
+                [xDispatchProvider, aURL, bLink](const 
css::uno::Reference<css::media::XPlayer>& rPlayer){
+                    css::awt::Size aSize = 
rPlayer->getPreferredPlayerWindowSize();
+                    
avmedia::MediaWindow::dispatchInsertAVMedia(xDispatchProvider, aSize, aURL, 
bLink);
+                }));
 
-            if( rVisArea.Width() > aDocSz.Width())
-                aPos.setX( aDocSz.Width() / 2 + rVisArea.Left() );
+            const bool bIsMediaURL = ::avmedia::MediaWindow::isMediaURL(aURL, 
"", true, xPlayerListener);
 
-            if(rVisArea.Height() > aDocSz.Height())
-                aPos.setY( aDocSz.Height() / 2 + rVisArea.Top() );
-
-            if( aPrefSize.Width() && aPrefSize.Height() )
-                aSize = rWindow.PixelToLogic(aPrefSize, 
MapMode(MapUnit::MapTwip));
-            else
-                aSize = Size( 2835, 2835 );
+            rWindow.LeaveWait();
 
-            OUString realURL;
-            if (bLink)
-            {
-                realURL = aURL;
-            }
-            else
+            if (!bIsMediaURL)
             {
-                uno::Reference<frame::XModel> const xModel(
-                        rSh.GetDoc()->GetDocShell()->GetModel());
-                bRet = ::avmedia::EmbedMedia(xModel, aURL, realURL);
-                if (!bRet) { return bRet; }
+                if( !bAPI )
+                    
::avmedia::MediaWindow::executeFormatErrorBox(rWindow.GetFrameWeld());
+
+                return bRet;
             }
+        }
 
-            SdrMediaObj* pObj = new SdrMediaObj(
-                *rSh.GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(),
-                tools::Rectangle(aPos, aSize));
+        rWindow.EnterWait();
 
-            pObj->setURL( realURL, "" );
-            rSh.EnterStdMode();
-            rSh.SwFEShell::InsertDrawObj( *pObj, aPos );
-            bRet = true;
+        SwWrtShell& rSh = GetShell();
 
-            rWindow.LeaveWait();
+        if( !rSh.HasDrawView() )
+            rSh.MakeDrawView();
+
+        Size            aDocSz( rSh.GetDocSize() );
+        const SwRect&   rVisArea = rSh.VisArea();
+        Point           aPos( rVisArea.Center() );
+        Size            aSize;
+
+        if( rVisArea.Width() > aDocSz.Width())
+            aPos.setX( aDocSz.Width() / 2 + rVisArea.Left() );
+
+        if(rVisArea.Height() > aDocSz.Height())
+            aPos.setY( aDocSz.Height() / 2 + rVisArea.Top() );
+
+        if( aPrefSize.Width() && aPrefSize.Height() )
+            aSize = rWindow.PixelToLogic(aPrefSize, MapMode(MapUnit::MapTwip));
+        else
+            aSize = Size( 2835, 2835 );
+
+        OUString realURL;
+        if (bLink)
+        {
+            realURL = aURL;
+        }
+        else
+        {
+            uno::Reference<frame::XModel> const xModel(
+                    rSh.GetDoc()->GetDocShell()->GetModel());
+            bRet = ::avmedia::EmbedMedia(xModel, aURL, realURL);
+            if (!bRet) { return bRet; }
         }
+
+        SdrMediaObj* pObj = new SdrMediaObj(
+            *rSh.GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(),
+            tools::Rectangle(aPos, aSize));
+
+        pObj->setURL( realURL, "" );
+        rSh.EnterStdMode();
+        rSh.SwFEShell::InsertDrawObj( *pObj, aPos );
+        bRet = true;
+
+        rWindow.LeaveWait();
     }
 #endif
 

Reply via email to