Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/framework/source/layoutmanager/helpers.cxx
Line
Count
Source (jump to first uncovered line)
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 "helpers.hxx"
21
22
#include <com/sun/star/ui/DockingArea.hpp>
23
#include <com/sun/star/awt/Toolkit.hpp>
24
#include <com/sun/star/awt/XTopWindow.hpp>
25
#include <com/sun/star/frame/DispatchHelper.hpp>
26
#include <com/sun/star/awt/XDockableWindow.hpp>
27
#include <com/sun/star/awt/XDockableWindowListener.hpp>
28
#include <com/sun/star/awt/XWindowListener.hpp>
29
#include <com/sun/star/ui/XUIElement.hpp>
30
31
#include <comphelper/lok.hxx>
32
#include <comphelper/propertyvalue.hxx>
33
#include <unotools/mediadescriptor.hxx>
34
#include <vcl/svapp.hxx>
35
#include <o3tl/string_view.hxx>
36
#include <toolkit/helper/vclunohelper.hxx>
37
38
using namespace com::sun::star;
39
40
namespace framework
41
{
42
43
bool hasEmptySize( const css::awt::Size& rSize )
44
0
{
45
0
    return ( rSize.Width == 0 ) && ( rSize.Height == 0 );
46
0
}
47
48
bool hasDefaultPosValue( const css::awt::Point& rPos )
49
0
{
50
0
    return (( rPos.X == SAL_MAX_INT32 ) || ( rPos.Y == SAL_MAX_INT32 ));
51
0
}
52
53
bool isDefaultPos( const css::awt::Point& rPos )
54
0
{
55
0
    return (( rPos.X == SAL_MAX_INT32 ) && ( rPos.Y == SAL_MAX_INT32 ));
56
0
}
57
58
bool isReverseOrderDockingArea( const sal_Int32 nDockArea )
59
0
{
60
0
    ui::DockingArea eDockArea = static_cast< ui::DockingArea >( nDockArea );
61
0
    return (( eDockArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) ||
62
0
            ( eDockArea == ui::DockingArea_DOCKINGAREA_RIGHT ));
63
0
}
64
65
bool isToolboxHorizontalAligned( ToolBox const * pToolBox )
66
0
{
67
0
    if ( pToolBox )
68
0
        return (( pToolBox->GetAlign() == WindowAlign::Top ) || ( pToolBox->GetAlign() == WindowAlign::Bottom ));
69
0
    return false;
70
0
}
71
72
bool isHorizontalDockingArea( const ui::DockingArea& nDockingArea )
73
0
{
74
0
    return (( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ||
75
0
            ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ));
76
0
}
77
78
bool isHorizontalDockingArea( const sal_Int32 nDockArea )
79
0
{
80
0
  return isHorizontalDockingArea(static_cast< ui::DockingArea >( nDockArea ));
81
0
}
82
83
OUString retrieveToolbarNameFromHelpURL( vcl::Window* pWindow )
84
0
{
85
0
    OUString aToolbarName;
86
87
0
    if ( pWindow->GetType() == WindowType::TOOLBOX )
88
0
    {
89
0
        ToolBox* pToolBox = dynamic_cast<ToolBox *>( pWindow );
90
0
        if ( pToolBox )
91
0
        {
92
0
            aToolbarName = pToolBox->GetHelpId();
93
0
            sal_Int32 i = aToolbarName.lastIndexOf( ':' );
94
0
            if ( !aToolbarName.isEmpty() && ( i > 0 ) && (( i + 1 ) < aToolbarName.getLength() ))
95
0
                aToolbarName = aToolbarName.copy( i+1 ); // Remove ".HelpId:" protocol from toolbar name
96
0
            else
97
0
              aToolbarName.clear();
98
0
        }
99
0
    }
100
0
    return aToolbarName;
101
0
}
102
103
ToolBox* getToolboxPtr( vcl::Window* pWindow )
104
0
{
105
0
    ToolBox* pToolbox(nullptr);
106
0
    if ( pWindow->GetType() == WindowType::TOOLBOX )
107
0
        pToolbox = dynamic_cast<ToolBox*>( pWindow );
108
0
    return pToolbox;
109
0
}
110
111
vcl::Window* getWindowFromXUIElement( const uno::Reference< ui::XUIElement >& xUIElement )
112
0
{
113
0
    SolarMutexGuard aGuard;
114
0
    uno::Reference< awt::XWindow > xWindow;
115
0
    if ( xUIElement.is() )
116
0
        xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY );
117
0
    return VCLUnoHelper::GetWindow( xWindow );
118
0
}
119
120
SystemWindow* getTopSystemWindow( const uno::Reference< awt::XWindow >& xWindow )
121
29.6k
{
122
29.6k
    VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
123
29.6k
    while ( pWindow && !pWindow->IsSystemWindow() )
124
0
        pWindow = pWindow->GetParent();
125
126
29.6k
    if ( pWindow )
127
29.6k
        return static_cast<SystemWindow *>(pWindow.get());
128
0
    else
129
0
        return nullptr;
130
29.6k
}
131
132
// ATTENTION!
133
// This value is directly copied from the sfx2 project.
134
// You have to change BOTH values, see sfx2/inc/sfx2/sfxsids.hrc (SID_DOCKWIN_START)
135
const sal_Int32 DOCKWIN_ID_BASE = 9800;
136
137
bool lcl_checkUIElement(const uno::Reference< ui::XUIElement >& xUIElement, awt::Rectangle& _rPosSize, uno::Reference< awt::XWindow >& _xWindow)
138
0
{
139
0
    bool bRet = xUIElement.is();
140
0
    if ( bRet )
141
0
    {
142
0
        SolarMutexGuard aGuard;
143
0
        _xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY );
144
0
        _rPosSize = _xWindow->getPosSize();
145
146
0
        VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( _xWindow );
147
0
        if ( pWindow->GetType() == WindowType::TOOLBOX )
148
0
        {
149
0
            ::Size aSize = static_cast<ToolBox*>(pWindow.get())->CalcWindowSizePixel( 1 );
150
0
            _rPosSize.Width = aSize.Width();
151
0
            _rPosSize.Height = aSize.Height();
152
0
        }
153
0
    } // if ( xUIElement.is() )
154
0
    return bRet;
155
0
}
156
157
uno::Reference< awt::XVclWindowPeer > createToolkitWindow( const uno::Reference< uno::XComponentContext >& rxContext, const uno::Reference< awt::XVclWindowPeer >& rParent, const OUString& pService )
158
84.7k
{
159
84.7k
    uno::Reference< awt::XToolkit2 > xToolkit = awt::Toolkit::create( rxContext );
160
161
    // describe window properties.
162
84.7k
    css::awt::WindowDescriptor aDescriptor;
163
84.7k
    aDescriptor.Type                =   awt::WindowClass_SIMPLE;
164
84.7k
    aDescriptor.WindowServiceName   =   pService;
165
84.7k
    aDescriptor.ParentIndex         =   -1;
166
84.7k
    aDescriptor.Parent = rParent;
167
84.7k
    aDescriptor.Bounds              =   awt::Rectangle(0,0,0,0);
168
84.7k
    aDescriptor.WindowAttributes    =   0;
169
170
    // create an awt window
171
84.7k
    uno::Reference< awt::XWindowPeer > xPeer = xToolkit->createWindow( aDescriptor );
172
84.7k
    uno::Reference< awt::XVclWindowPeer > xVclPeer(xPeer, uno::UNO_QUERY);
173
84.7k
    assert(xVclPeer || !xPeer);
174
84.7k
    return xVclPeer;
175
84.7k
}
176
177
// convert alignment constant to vcl's WindowAlign type
178
WindowAlign ImplConvertAlignment( ui::DockingArea aAlignment )
179
0
{
180
0
    if ( aAlignment == ui::DockingArea_DOCKINGAREA_LEFT )
181
0
        return WindowAlign::Left;
182
0
    else if ( aAlignment == ui::DockingArea_DOCKINGAREA_RIGHT )
183
0
        return WindowAlign::Right;
184
0
    else if ( aAlignment == ui::DockingArea_DOCKINGAREA_TOP )
185
0
        return WindowAlign::Top;
186
0
    else
187
0
        return WindowAlign::Bottom;
188
0
}
189
190
std::u16string_view getElementTypeFromResourceURL( std::u16string_view aResourceURL )
191
0
{
192
0
    if ( o3tl::starts_with(aResourceURL, UIRESOURCE_URL ) )
193
0
    {
194
0
        sal_Int32 nIndex{ UIRESOURCE_URL.getLength() };
195
0
        return o3tl::getToken(aResourceURL,  1, '/', nIndex );
196
0
    }
197
198
0
    return std::u16string_view();
199
0
}
200
201
void parseResourceURL( std::u16string_view aResourceURL, OUString& aElementType, OUString& aElementName )
202
63.2k
{
203
63.2k
    if ( o3tl::starts_with(aResourceURL, UIRESOURCE_URL) )
204
63.2k
    {
205
63.2k
        sal_Int32 nIndex{ UIRESOURCE_URL.getLength() };
206
63.2k
        aElementType = o3tl::getToken(aResourceURL, 1, '/', nIndex );
207
63.2k
        aElementName = o3tl::getToken(aResourceURL, 0, '/', nIndex );
208
63.2k
    }
209
63.2k
}
210
211
css::awt::Rectangle putRectangleValueToAWT( const ::tools::Rectangle& rRect )
212
0
{
213
0
    css::awt::Rectangle aRect;
214
0
    aRect.X = rRect.Left();
215
0
    aRect.Y = rRect.Top();
216
0
    aRect.Width = rRect.Right();
217
0
    aRect.Height = rRect.Bottom();
218
219
0
    return aRect;
220
0
}
221
222
::tools::Rectangle putAWTToRectangle( const css::awt::Rectangle& rRect )
223
0
{
224
0
    ::tools::Rectangle aRect;
225
0
    aRect.SetLeft( rRect.X );
226
0
    aRect.SetTop( rRect.Y );
227
0
    aRect.SetRight( rRect.Width );
228
0
    aRect.SetBottom( rRect.Height );
229
230
0
    return aRect;
231
0
}
232
233
bool equalRectangles( const css::awt::Rectangle& rRect1,
234
                      const css::awt::Rectangle& rRect2 )
235
0
{
236
0
    return (( rRect1.X == rRect2.X ) &&
237
0
            ( rRect1.Y == rRect2.Y ) &&
238
0
            ( rRect1.Width == rRect2.Width ) &&
239
0
            ( rRect1.Height == rRect2.Height ));
240
0
}
241
242
uno::Reference< frame::XModel > impl_getModelFromFrame( const uno::Reference< frame::XFrame >& rFrame )
243
21.1k
{
244
    // Query for the model to get check the context information
245
21.1k
    uno::Reference< frame::XModel > xModel;
246
21.1k
    if ( rFrame.is() )
247
8.47k
    {
248
8.47k
        uno::Reference< frame::XController > xController = rFrame->getController();
249
8.47k
        if ( xController.is() )
250
8.47k
            xModel = xController->getModel();
251
8.47k
    }
252
253
21.1k
    return xModel;
254
21.1k
}
255
256
bool implts_isPreviewModel( const uno::Reference< frame::XModel >& xModel )
257
12.7k
{
258
    // the cost in calc of calling getArgs for this property
259
    // includes measuring the entire sheet - which is extremely slow.
260
12.7k
    if (comphelper::LibreOfficeKit::isActive())
261
0
        return false;
262
263
12.7k
    if ( xModel.is() )
264
0
    {
265
0
        utl::MediaDescriptor aDesc( xModel->getArgs() );
266
0
        return aDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false);
267
0
    }
268
12.7k
    else
269
12.7k
        return false;
270
12.7k
}
271
272
bool implts_isFrameOrWindowTop( const uno::Reference< frame::XFrame >& xFrame )
273
21.0k
{
274
21.0k
    if (xFrame->isTop())
275
21.0k
        return true;
276
277
0
    uno::Reference< awt::XTopWindow > xWindowCheck(xFrame->getContainerWindow(), uno::UNO_QUERY); // don't use _THROW here ... it's a check only
278
0
    if (xWindowCheck.is())
279
0
    {
280
        // #i76867# top and system window is required.
281
0
        SolarMutexGuard aGuard;
282
0
        uno::Reference< awt::XWindow > xWindow( xWindowCheck, uno::UNO_QUERY );
283
0
        VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
284
0
        return pWindow && pWindow->IsSystemWindow();
285
0
    }
286
287
0
    return false;
288
0
}
289
290
void impl_setDockingWindowVisibility( const css::uno::Reference< css::uno::XComponentContext>& rxContext, const css::uno::Reference< css::frame::XFrame >& rFrame, std::u16string_view rDockingWindowName, bool bVisible )
291
0
{
292
0
    sal_Int32 nID    = o3tl::toInt32(rDockingWindowName);
293
0
    sal_Int32 nIndex = nID - DOCKWIN_ID_BASE;
294
295
0
    css::uno::Reference< css::frame::XDispatchProvider > xProvider(rFrame, css::uno::UNO_QUERY);
296
0
    if ( !(nIndex >= 0 && xProvider.is()) )
297
0
        return;
298
299
0
    OUString aDockWinArgName = "DockingWindow" + OUString::number( nIndex );
300
301
0
    css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
302
0
        aDockWinArgName, bVisible) };
303
304
0
    css::uno::Reference< css::frame::XDispatchHelper > xDispatcher = css::frame::DispatchHelper::create( rxContext );
305
306
0
    OUString aDockWinCommand = ".uno:" + aDockWinArgName;
307
0
    xDispatcher->executeDispatch(
308
0
        xProvider,
309
0
        aDockWinCommand,
310
0
        u"_self"_ustr,
311
0
        0,
312
0
        aArgs);
313
0
}
314
315
void impl_addWindowListeners(
316
    const css::uno::Reference< css::uno::XInterface >& xThis,
317
    const css::uno::Reference< css::ui::XUIElement >& xUIElement )
318
0
{
319
0
    css::uno::Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), css::uno::UNO_QUERY );
320
0
    css::uno::Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), css::uno::UNO_QUERY );
321
0
    if ( !(xDockWindow.is() && xWindow.is()) )
322
0
        return;
323
324
0
    try
325
0
    {
326
0
        xDockWindow->addDockableWindowListener(
327
0
            css::uno::Reference< css::awt::XDockableWindowListener >(
328
0
                xThis, css::uno::UNO_QUERY ));
329
0
        xWindow->addWindowListener(
330
0
            css::uno::Reference< css::awt::XWindowListener >(
331
0
                xThis, css::uno::UNO_QUERY ));
332
0
        xDockWindow->enableDocking( true );
333
0
    }
334
0
    catch ( const css::uno::Exception& )
335
0
    {
336
0
    }
337
0
}
338
339
} // namespace framework
340
341
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */