Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/chart2/source/controller/main/CommandDispatchContainer.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <CommandDispatchContainer.hxx>
21
#include <ControllerCommandDispatch.hxx>
22
#include "UndoCommandDispatch.hxx"
23
#include "StatusBarCommandDispatch.hxx"
24
#include <DisposeHelper.hxx>
25
#include "DrawCommandDispatch.hxx"
26
#include "ShapeController.hxx"
27
#include <ChartModel.hxx>
28
29
#include <com/sun/star/frame/XDispatchProvider.hpp>
30
#include <com/sun/star/view/XSelectionSupplier.hpp>
31
#include <osl/diagnose.h>
32
#include <rtl/ref.hxx>
33
34
#include <o3tl/sorted_vector.hxx>
35
36
using namespace ::com::sun::star;
37
38
using ::com::sun::star::uno::Reference;
39
using ::com::sun::star::uno::Sequence;
40
41
namespace chart
42
{
43
44
CommandDispatchContainer::CommandDispatchContainer(
45
    const Reference< uno::XComponentContext > & xContext )
46
0
        :m_xContext( xContext )
47
0
        ,m_pDrawCommandDispatch( nullptr )
48
0
        ,m_pShapeController( nullptr )
49
0
{
50
0
}
51
52
0
CommandDispatchContainer::~CommandDispatchContainer() = default;
53
54
void CommandDispatchContainer::setModel(
55
    const rtl::Reference<::chart::ChartModel> & xModel )
56
0
{
57
    // remove all existing dispatcher that base on the old model
58
0
    m_aCachedDispatches.clear();
59
0
    DisposeHelper::DisposeAllElements( m_aToBeDisposedDispatches );
60
0
    m_aToBeDisposedDispatches.clear();
61
0
    m_xModel = xModel.get();
62
0
}
63
64
void CommandDispatchContainer::setChartDispatch(
65
    const rtl::Reference< ControllerCommandDispatch >& rChartDispatch,
66
    const o3tl::sorted_vector< std::u16string_view > & rChartCommands )
67
0
{
68
0
    OSL_ENSURE(rChartDispatch.is(),"Invalid fall back dispatcher!");
69
0
    m_xChartDispatcher = rChartDispatch;
70
0
    m_aAdditionalChartCommands = rChartCommands;
71
0
    m_aToBeDisposedDispatches.push_back( m_xChartDispatcher );
72
0
}
73
74
Reference< frame::XDispatch > CommandDispatchContainer::getDispatchForURL(
75
    const util::URL & rURL )
76
0
{
77
0
    static const o3tl::sorted_vector< std::u16string_view >  s_aContainerDocumentCommands {
78
0
        u"AddDirect",    u"NewDoc",             u"Open",
79
0
        u"Save",         u"SaveAs",             u"SendMail",
80
0
        u"EditDoc",      u"ExportDirectToPDF",  u"PrintDefault",
81
0
        u"ChangeTheme", };
82
83
0
    if (auto aIt = m_aCachedDispatches.find(rURL.Complete); aIt != m_aCachedDispatches.end())
84
0
        return aIt->second;
85
86
0
    auto cacheIt = [this, url = rURL.Complete](const Reference<frame::XDispatch>& val)
87
0
    {
88
0
        m_aCachedDispatches[url].set(val);
89
0
        return val;
90
0
    };
91
92
0
    if (rtl::Reference<::chart::ChartModel> xModel{ m_xModel })
93
0
    {
94
0
        if (rURL.Path == "Undo" || rURL.Path == "Redo" ||
95
0
            rURL.Path == "GetUndoStrings" || rURL.Path == "GetRedoStrings")
96
0
        {
97
0
            rtl::Reference<CommandDispatch> pDispatch = new UndoCommandDispatch( m_xContext, xModel );
98
0
            pDispatch->initialize();
99
0
            m_aCachedDispatches[u".uno:Undo"_ustr].set(pDispatch);
100
0
            m_aCachedDispatches[u".uno:Redo"_ustr].set(pDispatch);
101
0
            m_aCachedDispatches[u".uno:GetUndoStrings"_ustr].set(pDispatch);
102
0
            m_aCachedDispatches[u".uno:GetRedoStrings"_ustr].set(pDispatch);
103
0
            m_aToBeDisposedDispatches.push_back(pDispatch);
104
0
            return pDispatch;
105
0
        }
106
0
        if (rURL.Path == "Context" || rURL.Path == "ModifiedStatus")
107
0
        {
108
0
            Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), uno::UNO_QUERY );
109
0
            rtl::Reference<CommandDispatch> pDispatch = new StatusBarCommandDispatch( m_xContext, xModel, xSelSupp );
110
0
            pDispatch->initialize();
111
0
            m_aCachedDispatches[u".uno:Context"_ustr].set(pDispatch);
112
0
            m_aCachedDispatches[u".uno:ModifiedStatus"_ustr].set(pDispatch);
113
0
            m_aToBeDisposedDispatches.push_back(pDispatch);
114
0
            return pDispatch;
115
0
        }
116
0
        if (s_aContainerDocumentCommands.contains(rURL.Path))
117
0
        {
118
            // ToDo: can those dispatches be cached?
119
0
            return cacheIt(getContainerDispatchForURL(xModel->getCurrentController(), rURL));
120
0
        }
121
0
    }
122
123
0
    if (m_xChartDispatcher.is()
124
0
        && (m_xChartDispatcher->commandHandled(rURL.Complete)
125
0
            || m_aAdditionalChartCommands.contains(rURL.Path)))
126
0
        return cacheIt(m_xChartDispatcher);
127
128
    // #i12587# support for shapes in chart
129
    // Note, that the chart dispatcher must be queried first, because
130
    // the chart dispatcher is the default dispatcher for all context
131
    // sensitive commands.
132
0
    if (m_pDrawCommandDispatch && m_pDrawCommandDispatch->isFeatureSupported(rURL.Complete))
133
0
        return cacheIt(m_pDrawCommandDispatch);
134
135
0
    if (m_pShapeController && m_pShapeController->isFeatureSupported(rURL.Complete))
136
0
        return cacheIt(m_pShapeController);
137
138
0
    return {};
139
0
}
140
141
Sequence< Reference< frame::XDispatch > > CommandDispatchContainer::getDispatchesForURLs(
142
    const Sequence< frame::DispatchDescriptor > & aDescriptors )
143
0
{
144
0
    sal_Int32 nCount = aDescriptors.getLength();
145
0
    uno::Sequence< uno::Reference< frame::XDispatch > > aRet( nCount );
146
0
    auto aRetRange = asNonConstRange(aRet);
147
148
0
    for( sal_Int32 nPos = 0; nPos < nCount; ++nPos )
149
0
    {
150
0
        if (aDescriptors[nPos].FrameName.isEmpty() || aDescriptors[nPos].FrameName == "_self")
151
0
            aRetRange[ nPos ] = getDispatchForURL( aDescriptors[ nPos ].FeatureURL );
152
0
    }
153
0
    return aRet;
154
0
}
155
156
void CommandDispatchContainer::DisposeAndClear()
157
0
{
158
0
    m_aCachedDispatches.clear();
159
0
    DisposeHelper::DisposeAllElements( m_aToBeDisposedDispatches );
160
0
    m_aToBeDisposedDispatches.clear();
161
0
    m_xChartDispatcher.clear();
162
0
    m_aAdditionalChartCommands.clear();
163
0
    m_pDrawCommandDispatch = nullptr;
164
0
    m_pShapeController = nullptr;
165
0
}
166
167
Reference< frame::XDispatch > CommandDispatchContainer::getContainerDispatchForURL(
168
    const Reference< frame::XController > & xChartController,
169
    const util::URL & rURL )
170
0
{
171
0
    Reference< frame::XDispatch > xResult;
172
0
    if( xChartController.is())
173
0
    {
174
0
        Reference< frame::XFrame > xFrame( xChartController->getFrame());
175
0
        if( xFrame.is())
176
0
        {
177
0
            Reference< frame::XDispatchProvider > xDispProv( xFrame->getCreator(), uno::UNO_QUERY );
178
0
            if( xDispProv.is())
179
0
                xResult.set( xDispProv->queryDispatch( rURL, u"_self"_ustr, 0 ));
180
0
        }
181
0
    }
182
0
    return xResult;
183
0
}
184
185
void CommandDispatchContainer::setDrawCommandDispatch( DrawCommandDispatch* pDispatch )
186
0
{
187
0
    m_pDrawCommandDispatch = pDispatch;
188
0
    m_aToBeDisposedDispatches.emplace_back( pDispatch );
189
0
}
190
191
void CommandDispatchContainer::setShapeController( ShapeController* pController )
192
0
{
193
0
    m_pShapeController = pController;
194
0
    m_aToBeDisposedDispatches.emplace_back( pController );
195
0
}
196
197
} //  namespace chart
198
199
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */