/* -*- 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 "CanvasUpdateRequester.hxx"
#include <vcl/svapp.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/rendering/XSpriteCanvas.hpp>
#include <cppuhelper/weakref.hxx>
#include <vector>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
namespace sd::presenter {
//===== CanvasUpdateRequester::Deleter ========================================
class CanvasUpdateRequester::Deleter
{
public:
void operator() (CanvasUpdateRequester* pObject) {
delete pObject; }
};
//===== CanvasUpdateRequester =================================================
std::shared_ptr<CanvasUpdateRequester> CanvasUpdateRequester::Instance (
const Reference<rendering::XSpriteCanvas>& rxSharedCanvas)
{
// this global must not own anything or we crash on shutdown
static std::vector<std::pair<
uno::WeakReference<rendering::XSpriteCanvas>,
std::weak_ptr<CanvasUpdateRequester>>> s_RequesterMap;
for (
auto it = s_RequesterMap.begin(); it != s_RequesterMap.end(); )
{
uno::Reference<rendering::XSpriteCanvas>
const xCanvas(it->first);
if (!xCanvas.is())
{
it = s_RequesterMap.erase(it);
// remove stale entry
}
else if (xCanvas == rxSharedCanvas)
{
std::shared_ptr<CanvasUpdateRequester> pRequester(it->second);
if (pRequester)
{
return pRequester;
}
else
{
std::shared_ptr<CanvasUpdateRequester>
const pNew(
new CanvasUpdateRequester(rxSharedCanvas), Deleter());
it->second = pNew;
return pNew;
}
}
else
{
++it;
}
}
// No requester for the given canvas found. Create a new one.
std::shared_ptr<CanvasUpdateRequester> pRequester (
new CanvasUpdateRequester(rxSharedCanvas), Deleter());
s_RequesterMap.emplace_back(rxSharedCanvas, pRequester);
return pRequester;
}
CanvasUpdateRequester::CanvasUpdateRequester (
const Reference<rendering::XSpriteCanvas>& rxCanvas)
: mxCanvas(rxCanvas)
, m_pUserEventId(nullptr)
, mbUpdateFlag(
false)
{
Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
if (xComponent.is())
{
//xComponent->addEventListener(this);
}
}
CanvasUpdateRequester::~CanvasUpdateRequester()
{
assert(m_pUserEventId == nullptr);
}
void CanvasUpdateRequester::RequestUpdate (
const bool bUpdateAll)
{
if (m_pUserEventId == nullptr)
{
m_pThis = shared_from_this();
// keep instance alive until dispatch
mbUpdateFlag = bUpdateAll;
m_pUserEventId = Application::PostUserEvent(LINK(
this, CanvasUpdateRequester, Callba
ck));
}
else
{
mbUpdateFlag |= bUpdateAll;
}
}
IMPL_LINK_NOARG(CanvasUpdateRequester, Callback, void*, void)
{
m_pUserEventId = nullptr;
if (mxCanvas.is())
{
mxCanvas->updateScreen(mbUpdateFlag);
mbUpdateFlag = false;
}
assert(m_pThis);
m_pThis.reset(); // possibly delete "this"
}
} // end of namespace ::sd::presenter
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */