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