Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sc/source/ui/app/client.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 <com/sun/star/embed/XEmbeddedObject.hpp>
21
22
#include <toolkit/helper/vclunohelper.hxx>
23
#include <comphelper/diagnose_ex.hxx>
24
#include <sfx2/objsh.hxx>
25
#include <svx/svditer.hxx>
26
#include <svx/svdobj.hxx>
27
#include <svx/svdmodel.hxx>
28
#include <svx/svdpage.hxx>
29
#include <svx/svdoole2.hxx>
30
31
#include <client.hxx>
32
#include <tabvwsh.hxx>
33
#include <docsh.hxx>
34
#include <gridwin.hxx>
35
36
using namespace com::sun::star;
37
38
ScClient::ScClient( ScTabViewShell* pViewShell, vcl::Window* pDraw, SdrModel* pSdrModel, const SdrOle2Obj* pObj ) :
39
0
    SfxInPlaceClient( pViewShell, pDraw, pObj->GetAspect() ),
40
0
    pModel( pSdrModel )
41
0
{
42
0
    SetObject( pObj->GetObjRef() );
43
0
}
44
45
ScClient::~ScClient()
46
0
{
47
0
}
48
49
SdrOle2Obj* ScClient::GetDrawObj()
50
0
{
51
0
    uno::Reference < embed::XEmbeddedObject > xObj = GetObject();
52
0
    SdrOle2Obj* pOle2Obj = nullptr;
53
0
    OUString aName = GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
54
55
0
    sal_uInt16 nPages = pModel->GetPageCount();
56
0
    for (sal_uInt16 nPNr=0; nPNr<nPages && !pOle2Obj; nPNr++)
57
0
    {
58
0
        SdrPage* pPage = pModel->GetPage(nPNr);
59
0
        SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups );
60
0
        SdrObject* pObject = aIter.Next();
61
0
        while (pObject && !pOle2Obj)
62
0
        {
63
0
            if ( pObject->GetObjIdentifier() == SdrObjKind::OLE2 )
64
0
            {
65
                // name from InfoObject is PersistName
66
0
                if ( static_cast<SdrOle2Obj*>(pObject)->GetPersistName() == aName )
67
0
                    pOle2Obj = static_cast<SdrOle2Obj*>(pObject);
68
0
            }
69
0
            pObject = aIter.Next();
70
0
        }
71
0
    }
72
0
    return pOle2Obj;
73
0
}
74
75
void ScClient::RequestNewObjectArea( tools::Rectangle& aLogicRect )
76
0
{
77
0
    SfxViewShell* pSfxViewSh = GetViewShell();
78
0
    ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( pSfxViewSh  );
79
0
    if (!pViewSh)
80
0
    {
81
0
        OSL_FAIL("Wrong ViewShell");
82
0
        return;
83
0
    }
84
85
0
    tools::Rectangle aOldRect = GetObjArea();
86
0
    SdrOle2Obj*  pDrawObj = GetDrawObj();
87
0
    if ( pDrawObj )
88
0
    {
89
0
        if ( pDrawObj->IsResizeProtect() )
90
0
            aLogicRect.SetSize( aOldRect.GetSize() );
91
92
0
        if ( pDrawObj->IsMoveProtect() )
93
0
            aLogicRect.SetPos( aOldRect.TopLeft() );
94
0
    }
95
96
0
    sal_uInt16 nTab = pViewSh->GetViewData().GetTabNo();
97
0
    SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
98
0
    if ( !(pPage && aLogicRect != aOldRect) )
99
0
        return;
100
101
0
    Point aPos;
102
0
    Size aSize = pPage->GetSize();
103
0
    if ( aSize.Width() < 0 )
104
0
    {
105
0
        aPos.setX( aSize.Width() + 1 );       // negative
106
0
        aSize.setWidth( -aSize.Width() );     // positive
107
0
    }
108
0
    tools::Rectangle aPageRect( aPos, aSize );
109
110
0
    if (aLogicRect.Right() > aPageRect.Right())
111
0
    {
112
0
        tools::Long nDiff = aLogicRect.Right() - aPageRect.Right();
113
0
        aLogicRect.AdjustLeft( -nDiff );
114
0
        aLogicRect.AdjustRight( -nDiff );
115
0
    }
116
0
    if (aLogicRect.Bottom() > aPageRect.Bottom())
117
0
    {
118
0
        tools::Long nDiff = aLogicRect.Bottom() - aPageRect.Bottom();
119
0
        aLogicRect.AdjustTop( -nDiff );
120
0
        aLogicRect.AdjustBottom( -nDiff );
121
0
    }
122
123
0
    if (aLogicRect.Left() < aPageRect.Left())
124
0
    {
125
0
        tools::Long nDiff = aLogicRect.Left() - aPageRect.Left();
126
0
        aLogicRect.AdjustRight( -nDiff );
127
0
        aLogicRect.AdjustLeft( -nDiff );
128
0
    }
129
0
    if (aLogicRect.Top() < aPageRect.Top())
130
0
    {
131
0
        tools::Long nDiff = aLogicRect.Top() - aPageRect.Top();
132
0
        aLogicRect.AdjustBottom( -nDiff );
133
0
        aLogicRect.AdjustTop( -nDiff );
134
0
    }
135
0
}
136
137
void ScClient::ObjectAreaChanged()
138
0
{
139
0
    SfxViewShell* pSfxViewSh = GetViewShell();
140
0
    ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( pSfxViewSh  );
141
0
    if (!pViewSh)
142
0
    {
143
0
        OSL_FAIL("Wrong ViewShell");
144
0
        return;
145
0
    }
146
147
    // Take over position and size into document
148
0
    SdrOle2Obj* pDrawObj = GetDrawObj();
149
0
    if (!pDrawObj)
150
0
        return;
151
152
0
    tools::Rectangle aNewRectangle(GetScaledObjArea());
153
154
    // #i118524# if sheared/rotated, center to non-rotated LogicRect
155
0
    pDrawObj->setSuppressSetVisAreaSize(true);
156
157
0
    if(pDrawObj->GetGeoStat().m_nRotationAngle || pDrawObj->GetGeoStat().m_nShearAngle)
158
0
    {
159
0
        pDrawObj->SetLogicRect( aNewRectangle );
160
161
0
        const tools::Rectangle& rBoundRect = pDrawObj->GetCurrentBoundRect();
162
0
        const Point aDelta(aNewRectangle.Center() - rBoundRect.Center());
163
164
0
        aNewRectangle.Move(aDelta.X(), aDelta.Y());
165
0
    }
166
167
0
    pDrawObj->SetLogicRect( aNewRectangle );
168
0
    pDrawObj->setSuppressSetVisAreaSize(false);
169
170
    //  set document modified (SdrModel::SetChanged is not used)
171
0
    pViewSh->GetViewData().GetDocShell().SetDrawModified();
172
0
    pViewSh->ScrollToObject(pDrawObj);
173
0
}
174
175
void ScClient::ViewChanged()
176
0
{
177
0
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
178
0
    {
179
        // the iconified object seems not to need such a scaling handling
180
        // since the replacement image and the size a completely controlled by the container
181
        // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here
182
183
0
        return;
184
0
    }
185
186
0
    uno::Reference < embed::XEmbeddedObject > xObj = GetObject();
187
0
    if (!xObj.is())
188
0
        return;
189
190
    // TODO/LEAN: working with Visual Area can switch object to running state
191
0
    awt::Size aSz;
192
0
    try {
193
0
        aSz = xObj->getVisualAreaSize( GetAspect() );
194
0
    } catch (const uno::Exception&) {
195
0
        TOOLS_WARN_EXCEPTION("sc", "The visual area size must be available!");
196
0
        return; // leave it unchanged on failure
197
0
    }
198
199
0
    MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( GetAspect() ) );
200
0
    Size aVisSize = OutputDevice::LogicToLogic(Size(aSz.Width, aSz.Height), MapMode(aMapUnit), MapMode(MapUnit::Map100thMM));
201
202
    // Take over position and size into document
203
0
    SdrOle2Obj* pDrawObj = GetDrawObj();
204
0
    if (!pDrawObj)
205
0
        return;
206
207
0
    if (!IsObjectInPlaceActive())
208
0
    {
209
0
        pDrawObj->ActionChanged();
210
0
        return;
211
0
    }
212
213
0
    tools::Rectangle aLogicRect = pDrawObj->GetLogicRect();
214
0
    Fraction aFractX = GetScaleWidth() * aVisSize.Width();
215
0
    Fraction aFractY = GetScaleHeight() * aVisSize.Height();
216
0
    aVisSize = Size( static_cast<tools::Long>(aFractX), static_cast<tools::Long>(aFractY) ); // Scaled for Draw model
217
218
    //  pClientData->SetObjArea before pDrawObj->SetLogicRect, so that we don't
219
    //  calculate wrong scalings:
220
    //Rectangle aObjArea = aLogicRect;
221
    //aObjArea.SetSize( aVisSize );          // Document size from the server
222
    //SetObjArea( aObjArea );
223
224
0
    SfxViewShell* pSfxViewSh = GetViewShell();
225
0
    ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( pSfxViewSh  );
226
0
    if ( pViewSh )
227
0
    {
228
0
        vcl::Window* pWin = pViewSh->GetActiveWin();
229
0
        if ( pWin->LogicToPixel( aVisSize ) != pWin->LogicToPixel( aLogicRect.GetSize() ) )
230
0
        {
231
0
            aLogicRect.SetSize( aVisSize );
232
0
            pDrawObj->SetLogicRect( aLogicRect );
233
234
            // set document modified (SdrModel::SetChanged is not used)
235
0
            pViewSh->GetViewData().GetDocShell().SetDrawModified();
236
0
        }
237
0
    }
238
0
}
239
240
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */