LibreOffice Module svx (master) 1
viewcontact.cxx
Go to the documentation of this file.
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
27#include <osl/diagnose.h>
28#include <tools/debug.hxx>
29
30namespace sdr::contact
31{
32// Create an Object-Specific ViewObjectContact, set ViewContact and
33// ObjectContact. Always needs to return something. Default is to create
34// a standard ViewObjectContact containing the given ObjectContact and *this
36{
37 return *(new ViewObjectContact(rObjectContact, *this));
38}
39
41
43
45{
46 // get rid of all VOCs
47 // #i84257# To avoid that each 'delete pCandidate' again uses
48 // the local RemoveViewObjectContact with a search and removal in the
49 // vector, simply copy and clear local vector.
50 std::vector<ViewObjectContact*> aLocalVOCList;
51 aLocalVOCList.swap(maViewObjectContactVector);
52
53 for (const auto& pCandidate : aLocalVOCList)
54 // ViewObjectContacts only make sense with View and Object contacts.
55 // When the contact to the SdrObject is deleted like in this case,
56 // all ViewObjectContacts can be deleted, too.
57 delete pCandidate;
58
59 // assert when there were new entries added during deletion
60 DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList in VC (!)");
61}
62
63// get an Object-specific ViewObjectContact for a specific
64// ObjectContact (->View). Always needs to return something.
66{
67 ViewObjectContact* pRetval = nullptr;
68 const sal_uInt32 nCount(maViewObjectContactVector.size());
69
70 // first search if there exists a VOC for the given OC
71 for (sal_uInt32 a(0); !pRetval && a < nCount; a++)
72 {
74 DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");
75
76 if (&(pCandidate->GetObjectContact()) == &rObjectContact)
77 {
78 pRetval = pCandidate;
79 }
80 }
81
82 if (!pRetval)
83 {
84 // create a new one. It's inserted to the local list from the
85 // ViewObjectContact constructor via AddViewObjectContact()
86 pRetval = &CreateObjectSpecificViewObjectContact(rObjectContact);
87 }
88
89 return *pRetval;
90}
91
92// A new ViewObjectContact was created and shall be remembered.
94{
95 maViewObjectContactVector.push_back(&rVOContact);
96}
97
98// A ViewObjectContact was deleted and shall be forgotten.
100{
101 std::vector<ViewObjectContact*>::iterator aFindResult = std::find(
102 maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact);
103
104 if (aFindResult != maViewObjectContactVector.end())
105 {
106 maViewObjectContactVector.erase(aFindResult);
107 }
108}
109
110// Test if this ViewContact has ViewObjectContacts at all. This can
111// be used to test if this ViewContact is visualized ATM or not
113{
114 const sal_uInt32 nCount(maViewObjectContactVector.size());
115
116 for (sal_uInt32 a(0); a < nCount; a++)
117 {
118 if (!maViewObjectContactVector[a]->GetObjectContact().IsPreviewRenderer())
119 {
120 return true;
121 }
122 }
123 return false;
124}
125
126// Test if this ViewContact has ViewObjectContacts at all. This can
127// be used to test if this ViewContact is visualized ATM or not
129{
130 const sal_uInt32 nCount(maViewObjectContactVector.size());
131
132 for (sal_uInt32 a(0); a < nCount; a++)
133 {
134 if (maViewObjectContactVector[a]->isAnimated())
135 {
136 return true;
137 }
138 }
139
140 return false;
141}
142
143// Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L
144// and GetViewContact default pops up an assert since it's an error if
145// GetObjectCount has a result != 0 and it's not overridden.
147{
148 // no sub-objects
149 return 0;
150}
151
152ViewContact& ViewContact::GetViewContact(sal_uInt32 /*nIndex*/) const
153{
154 // This is the default implementation; call would be an error
155 OSL_FAIL("ViewContact::GetViewContact: This call needs to be overridden when GetObjectCount() "
156 "can return results != 0 (!)");
157 return const_cast<ViewContact&>(*this);
158}
159
161{
162 // default has no parent
163 return nullptr;
164}
165
167{
168 // propagate change to all existing visualisations which
169 // will force a VOC for the new child and invalidate its range
170 const sal_uInt32 nCount(maViewObjectContactVector.size());
171
172 for (sal_uInt32 a(0); a < nCount; a++)
173 {
175 DBG_ASSERT(pCandidate,
176 "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
177
178 // take action at all VOCs. At the VOCs ObjectContact the initial
179 // rectangle will be invalidated at the associated OutputDevice.
180 pCandidate->ActionChildInserted(rChild);
181 }
182}
183
184// React on changes of the object of this ViewContact
186{
187 // propagate change to all existing VOCs. This will invalidate
188 // all drawn visualisations in all known views
189 const sal_uInt32 nCount(maViewObjectContactVector.size());
190
191 for (sal_uInt32 a(0); a < nCount; a++)
192 {
194 DBG_ASSERT(pCandidate,
195 "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
196
197 if (pCandidate)
198 {
199 pCandidate->ActionChanged();
200 }
201 }
202}
203
204// access to SdrObject and/or SdrPage. May return 0L like the default
205// implementations do. Override as needed.
206SdrObject* ViewContact::TryToGetSdrObject() const { return nullptr; }
207
208// primitive stuff
209
212{
213 // This is the default implementation and should never be called (see header). If this is called,
214 // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by
215 // providing a sequence of primitives -> which cannot be correct.
216 // Since we have no access to any known model data here, the default implementation creates a yellow placeholder
217 // hairline polygon with a default size of (1000, 1000, 5000, 3000)
218 OSL_FAIL("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback "
219 "base implementation, this is always an error (!)");
220 basegfx::B2DPolygon aOutline(
221 basegfx::utils::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0)));
222 const basegfx::BColor aYellow(1.0, 1.0, 0.0);
224 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(std::move(aOutline), aYellow));
225
226 rVisitor.visit(xReference);
227}
228
231{
232 /* Local up-to-date checks. Create new list and compare.
233 We cannot just always use the new data because the old data has cached bitmaps in it e.g. see the document in tdf#146108.
234 */
237
238 if (!xNew.empty())
239 {
240 // allow evtl. embedding in object-specific infos, e.g. Name, Title, Description
241 xNew = embedToObjectSpecificInformation(std::move(xNew));
242 }
243
245 {
246 // has changed, copy content
247 const_cast<ViewContact*>(this)->mxViewIndependentPrimitive2DSequence = std::move(xNew);
248 }
249
250 // return current Primitive2DContainer
252}
253
254// add Gluepoints (if available)
257{
258 // default returns empty reference
260}
261
264{
265 // nothing to do for default
266 return aSource;
267}
268
271{
272 // Return empty range.
273 return basegfx::B2DRange();
274}
275
277{
278 if (bWithHierarchy)
279 {
280 // flush DrawingLayer hierarchy
281 const sal_uInt32 nCount(GetObjectCount());
282
283 for (sal_uInt32 a(0); a < nCount; a++)
284 {
285 ViewContact& rChild = GetViewContact(a);
286 rChild.flushViewObjectContacts(bWithHierarchy);
287 }
288 }
289
290 // delete local VOCs
292}
293}
294
295/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Abstract DrawObject.
Definition: svdobj.hxx:260
virtual void visit(const Primitive2DReference &)=0
virtual drawinglayer::primitive2d::Primitive2DContainer createGluePointPrimitive2DSequence() const
friend class ViewObjectContact
Definition: viewcontact.hxx:41
virtual ViewContact & GetViewContact(sal_uInt32 nIndex) const
virtual void createViewIndependentPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
void ActionChildInserted(ViewContact &rChild)
virtual SdrObject * TryToGetSdrObject() const
void flushViewObjectContacts(bool bWithHierarchy=true)
void RemoveViewObjectContact(ViewObjectContact &rVOContact)
Definition: viewcontact.cxx:99
virtual sal_uInt32 GetObjectCount() const
virtual drawinglayer::primitive2d::Primitive2DContainer embedToObjectSpecificInformation(drawinglayer::primitive2d::Primitive2DContainer rSource) const
bool HasViewObjectContacts() const
void AddViewObjectContact(ViewObjectContact &rVOContact)
Definition: viewcontact.cxx:93
ViewObjectContact & GetViewObjectContact(ObjectContact &rObjectContact)
Definition: viewcontact.cxx:65
bool isAnimatedInAnyViewObjectContact() const
virtual ViewContact * GetParentContact() const
drawinglayer::primitive2d::Primitive2DContainer mxViewIndependentPrimitive2DSequence
Definition: viewcontact.hxx:52
virtual void ActionChanged()
virtual ViewObjectContact & CreateObjectSpecificViewObjectContact(ObjectContact &rObjectContact)
Definition: viewcontact.cxx:35
std::vector< ViewObjectContact * > maViewObjectContactVector
Definition: viewcontact.hxx:47
virtual basegfx::B2DRange getRange(const drawinglayer::geometry::ViewInformation2D &rViewInfo2D) const
void getViewIndependentPrimitive2DContainer(drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
ObjectContact & GetObjectContact() const
void ActionChildInserted(ViewContact &rChild)
int nCount
#define DBG_ASSERT(sCon, aError)
uno_Any a
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)