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 <vcl/commandevent.hxx>
21
22 #include <ViewShell.hxx>
23 #include <smarttag.hxx>
24 #include <Window.hxx>
25 #include <View.hxx>
26
27 namespace sd
28 {
29
SmartTag(::sd::View & rView)30 SmartTag::SmartTag( ::sd::View& rView )
31 : mrView( rView )
32 , mbSelected( false )
33 {
34 SmartTagReference xThis( this );
35 mrView.getSmartTags().add( xThis );
36 }
37
~SmartTag()38 SmartTag::~SmartTag()
39 {
40 }
41
MouseButtonDown(const MouseEvent &,SmartHdl &)42 bool SmartTag::MouseButtonDown( const MouseEvent&, SmartHdl& )
43 {
44 return false;
45 }
46
47 /** returns true if the SmartTag consumes this event. */
KeyInput(const KeyEvent &)48 bool SmartTag::KeyInput( const KeyEvent& /*rKEvt*/ )
49 {
50 return false;
51 }
52
53 /** returns true if the SmartTag consumes this event. */
Command(const CommandEvent &)54 bool SmartTag::Command( const CommandEvent& /*rCEvt*/ )
55 {
56 return false;
57 }
58
addCustomHandles(SdrHdlList &)59 void SmartTag::addCustomHandles( SdrHdlList& /*rHandlerList*/ )
60 {
61 }
62
select()63 void SmartTag::select()
64 {
65 mbSelected = true;
66 }
67
deselect()68 void SmartTag::deselect()
69 {
70 mbSelected = false;
71 }
72
disposing()73 void SmartTag::disposing()
74 {
75 SmartTagReference xThis( this );
76 mrView.getSmartTags().remove( xThis );
77 }
78
getContext(SdrViewContext &)79 bool SmartTag::getContext( SdrViewContext& /*rContext*/ )
80 {
81 return false;
82 }
83
GetMarkablePointCount() const84 sal_Int32 SmartTag::GetMarkablePointCount() const
85 {
86 return 0;
87 }
88
GetMarkedPointCount() const89 sal_Int32 SmartTag::GetMarkedPointCount() const
90 {
91 return 0;
92 }
93
MarkPoint(SdrHdl &,bool)94 bool SmartTag::MarkPoint(SdrHdl& /*rHdl*/, bool /*bUnmark*/ )
95 {
96 return false;
97 }
98
MarkPoints(const::tools::Rectangle *,bool)99 bool SmartTag::MarkPoints(const ::tools::Rectangle* /*pRect*/, bool /*bUnmark*/ )
100 {
101 return false;
102 }
103
CheckPossibilities()104 void SmartTag::CheckPossibilities()
105 {
106 }
107
SmartTagSet(View & rView)108 SmartTagSet::SmartTagSet( View& rView )
109 : mrView( rView )
110 {
111 }
112
~SmartTagSet()113 SmartTagSet::~SmartTagSet()
114 {
115 }
116
add(const SmartTagReference & xTag)117 void SmartTagSet::add( const SmartTagReference& xTag )
118 {
119 maSet.insert( xTag );
120 mrView.InvalidateAllWin();
121
122 if( xTag == mxMouseOverTag )
123 mxMouseOverTag.clear();
124
125 if( xTag == mxSelectedTag )
126 mxSelectedTag.clear();
127 }
128
remove(const SmartTagReference & xTag)129 void SmartTagSet::remove( const SmartTagReference& xTag )
130 {
131 std::set< SmartTagReference >::iterator aIter( maSet.find( xTag ) );
132 if( aIter != maSet.end() )
133 maSet.erase( aIter );
134 mrView.InvalidateAllWin();
135
136 if( xTag == mxMouseOverTag )
137 mxMouseOverTag.clear();
138
139 if( xTag == mxSelectedTag )
140 mxSelectedTag.clear();
141 }
142
Dispose()143 void SmartTagSet::Dispose()
144 {
145 std::set< SmartTagReference > aSet;
146 aSet.swap( maSet );
147 for( auto& rxItem : aSet )
148 rxItem->Dispose();
149 mrView.InvalidateAllWin();
150 mxMouseOverTag.clear();
151 mxSelectedTag.clear();
152 }
153
select(const SmartTagReference & xTag)154 void SmartTagSet::select( const SmartTagReference& xTag )
155 {
156 if( mxSelectedTag == xTag )
157 return;
158
159 if( mxSelectedTag.is() )
160 mxSelectedTag->deselect();
161
162 mxSelectedTag = xTag;
163 mxSelectedTag->select();
164 mrView.SetPossibilitiesDirty();
165 if( mrView.GetMarkedObjectCount() > 0 )
166 mrView.UnmarkAllObj();
167 else
168 mrView.updateHandles();
169 }
170
deselect()171 void SmartTagSet::deselect()
172 {
173 if( mxSelectedTag.is() )
174 {
175 mxSelectedTag->deselect();
176 mxSelectedTag.clear();
177 mrView.SetPossibilitiesDirty();
178 mrView.updateHandles();
179 }
180 }
181
MouseButtonDown(const MouseEvent & rMEvt)182 bool SmartTagSet::MouseButtonDown( const MouseEvent& rMEvt )
183 {
184 Point aMDPos( mrView.GetViewShell()->GetActiveWindow()->PixelToLogic( rMEvt.GetPosPixel() ) );
185 SdrHdl* pHdl = mrView.PickHandle(aMDPos);
186
187 // check if a smart tag is selected and no handle is hit
188 if( mxSelectedTag.is() && !pHdl )
189 {
190 // deselect smart tag
191 deselect();
192 return false;
193 }
194
195 // if a smart tag handle is hit, forward event to its smart tag
196 SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( pHdl );
197 if(pSmartHdl && pSmartHdl->getTag().is() )
198 {
199 SmartTagReference xTag( pSmartHdl->getTag() );
200 return xTag->MouseButtonDown( rMEvt, *pSmartHdl );
201 }
202
203 return false;
204 }
205
KeyInput(const KeyEvent & rKEvt)206 bool SmartTagSet::KeyInput( const KeyEvent& rKEvt )
207 {
208 if( mxSelectedTag.is() )
209 return mxSelectedTag->KeyInput( rKEvt );
210 else if( rKEvt.GetKeyCode().GetCode() == KEY_SPACE )
211 {
212 SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( mrView.GetHdlList().GetFocusHdl() );
213 if( pSmartHdl )
214 {
215 const_cast< SdrHdlList& >( mrView.GetHdlList() ).ResetFocusHdl();
216 const SmartTagReference& xTag( pSmartHdl->getTag() );
217 select( xTag );
218 return true;
219 }
220 }
221
222 return false;
223 }
224
225 /** returns true if the SmartTag consumes this event. */
Command(const CommandEvent & rCEvt)226 bool SmartTagSet::Command( const CommandEvent& rCEvt )
227 {
228 if( rCEvt.IsMouseEvent() )
229 {
230 Point aMDPos( mrView.GetViewShell()->GetActiveWindow()->PixelToLogic( rCEvt.GetMousePosPixel() ) );
231 SdrHdl* pHdl = mrView.PickHandle(aMDPos);
232
233 if( pHdl )
234 {
235 // if a smart tag handle is hit, forward event to its smart tag
236 SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( pHdl );
237 if(pSmartHdl && pSmartHdl->getTag().is() )
238 {
239 const SmartTagReference& xTag( pSmartHdl->getTag() );
240 return xTag->Command( rCEvt );
241 }
242 }
243 }
244 else
245 {
246 if( mxSelectedTag.is() )
247 return mxSelectedTag->Command( rCEvt );
248
249 }
250
251 return false;
252 }
253
addCustomHandles(SdrHdlList & rHandlerList)254 void SmartTagSet::addCustomHandles( SdrHdlList& rHandlerList )
255 {
256 for( auto& rxItem : maSet )
257 rxItem->addCustomHandles( rHandlerList );
258 }
259
260 /** returns true if the currently selected smart tag has
261 a special context, returned in rContext. */
getContext(SdrViewContext & rContext) const262 bool SmartTagSet::getContext( SdrViewContext& rContext ) const
263 {
264 if( mxSelectedTag.is() )
265 return mxSelectedTag->getContext( rContext );
266 else
267 return false;
268 }
269
270 // support point editing
271
HasMarkablePoints() const272 bool SmartTagSet::HasMarkablePoints() const
273 {
274 return GetMarkablePointCount() != 0;
275 }
276
GetMarkablePointCount() const277 sal_uLong SmartTagSet::GetMarkablePointCount() const
278 {
279 if( mxSelectedTag.is() )
280 return mxSelectedTag->GetMarkablePointCount();
281 return 0;
282 }
283
HasMarkedPoints() const284 bool SmartTagSet::HasMarkedPoints() const
285 {
286 return GetMarkedPointCount() != 0;
287 }
288
GetMarkedPointCount() const289 sal_uLong SmartTagSet::GetMarkedPointCount() const
290 {
291 if( mxSelectedTag.is() )
292 return mxSelectedTag->GetMarkedPointCount();
293 else
294 return 0;
295 }
296
MarkPoint(SdrHdl & rHdl,bool bUnmark)297 bool SmartTagSet::MarkPoint(SdrHdl& rHdl, bool bUnmark )
298 {
299 if( mxSelectedTag.is() )
300 return mxSelectedTag->MarkPoint( rHdl, bUnmark );
301
302 return false;
303 }
304
MarkPoints(const::tools::Rectangle * pRect,bool bUnmark)305 bool SmartTagSet::MarkPoints(const ::tools::Rectangle* pRect, bool bUnmark)
306 {
307 if( mxSelectedTag.is() )
308 return mxSelectedTag->MarkPoints( pRect, bUnmark );
309 return false;
310 }
311
CheckPossibilities()312 void SmartTagSet::CheckPossibilities()
313 {
314 if( mxSelectedTag.is() )
315 mxSelectedTag->CheckPossibilities();
316 }
317
SmartHdl(const SmartTagReference & xTag,SdrObject * pObject,const Point & rPnt,SdrHdlKind eNewKind)318 SmartHdl::SmartHdl( const SmartTagReference& xTag, SdrObject* pObject, const Point& rPnt, SdrHdlKind eNewKind /*=SdrHdlKind::Move*/ )
319 : SdrHdl( rPnt, eNewKind )
320 , mxSmartTag( xTag )
321 {
322 SetObj( pObject );
323 }
324
SmartHdl(const SmartTagReference & xTag,const Point & rPnt,SdrHdlKind eNewKind)325 SmartHdl::SmartHdl( const SmartTagReference& xTag, const Point& rPnt, SdrHdlKind eNewKind /*=SdrHdlKind::Move*/ )
326 : SdrHdl( rPnt, eNewKind )
327 , mxSmartTag( xTag )
328 {
329 }
330
331 } // end of namespace sd
332
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
334