1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 #include <editeng/unoedhlp.hxx>
27 #include <svx/svdoutl.hxx>
28 
29 #ifndef SD_ACCESSIBILITY_ACCESSIBLE_OUTLINE_EDIT_SOURCE_HXX
30 #include <AccessibleOutlineEditSource.hxx>
31 #endif
32 #include "OutlineView.hxx"
33 #include <svx/sdrpaintwindow.hxx>
34 
35 namespace accessibility
36 {
37 
38     AccessibleOutlineEditSource::AccessibleOutlineEditSource(
39         SdrOutliner& 	rOutliner,
40         SdrView& 		rView,
41         OutlinerView& rOutlView,
42         const ::Window& rViewWindow )
43         : mrView( rView ),
44           mrWindow( rViewWindow ),
45           mpOutliner( &rOutliner ),
46           mpOutlinerView( &rOutlView ),
47           mTextForwarder( rOutliner, 0 ),
48           mViewForwarder( rOutlView )
49     {
50         // register as listener - need to broadcast state change messages
51 		// Moved to ::GetTextForwarder()
52         //rOutliner.SetNotifyHdl( LINK(this, AccessibleOutlineEditSource, NotifyHdl) );
53         StartListening(rOutliner);
54     }
55 
56     AccessibleOutlineEditSource::~AccessibleOutlineEditSource()
57     {
58         if( mpOutliner )
59             mpOutliner->SetNotifyHdl( Link() );
60         Broadcast( TextHint( SFX_HINT_DYING ) );
61     }
62 
63     SvxEditSource* AccessibleOutlineEditSource::Clone() const
64     {
65         /*return NULL;*/
66 		return new AccessibleOutlineEditSource(*mpOutliner, mrView, *mpOutlinerView, mrWindow);
67     }
68 
69     SvxTextForwarder* AccessibleOutlineEditSource::GetTextForwarder()
70     {
71         // TODO: maybe suboptimal
72         if( IsValid() )
73 		{
74 			// Moved here to make sure that
75 			// the NotifyHandler was set on the current object.
76 			mpOutliner->SetNotifyHdl( LINK(this, AccessibleOutlineEditSource, NotifyHdl) );
77             return &mTextForwarder;
78 		}
79         else
80             return NULL;
81     }
82 
83     SvxViewForwarder* AccessibleOutlineEditSource::GetViewForwarder()
84     {
85         // TODO: maybe suboptimal
86         if( IsValid() )
87             return this;
88         else
89             return NULL;
90     }
91 
92     SvxEditViewForwarder* AccessibleOutlineEditSource::GetEditViewForwarder( sal_Bool )
93     {
94         // TODO: maybe suboptimal
95         if( IsValid() )
96         {
97             // ignore parameter, we're always in edit mode here
98             return &mViewForwarder;
99         }
100         else
101             return NULL;
102     }
103 
104     void AccessibleOutlineEditSource::UpdateData()
105     {
106         // NOOP, since we're always working on the 'real' outliner,
107         // i.e. changes are immediately reflected on the screen
108     }
109 
110     SfxBroadcaster& AccessibleOutlineEditSource::GetBroadcaster() const
111     {
112         return *( const_cast< AccessibleOutlineEditSource* > (this) );
113     }
114 
115 	sal_Bool AccessibleOutlineEditSource::IsValid() const
116     {
117         if( mpOutliner && mpOutlinerView )
118         {
119             // Our view still on outliner?
120             sal_uLong nCurrView, nViews;
121 
122             for( nCurrView=0, nViews=mpOutliner->GetViewCount(); nCurrView<nViews; ++nCurrView )
123             {
124                 if( mpOutliner->GetView(nCurrView) == mpOutlinerView )
125                     return sal_True;
126             }
127         }
128 
129         return sal_False;
130     }
131 
132     Rectangle AccessibleOutlineEditSource::GetVisArea() const
133     {
134         if( IsValid() )
135         {
136 			SdrPaintWindow* pPaintWindow = mrView.FindPaintWindow(mrWindow);
137 			Rectangle aVisArea;
138 
139 			if(pPaintWindow)
140 			{
141 				aVisArea = pPaintWindow->GetVisibleArea();
142 			}
143 
144             MapMode aMapMode(mrWindow.GetMapMode());
145             aMapMode.SetOrigin(Point());
146             return mrWindow.LogicToPixel( aVisArea, aMapMode );
147         }
148 
149         return Rectangle();
150     }
151 
152     Point AccessibleOutlineEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
153     {
154         if( IsValid() && mrView.GetModel() )
155         {
156             Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
157                                                       MapMode(mrView.GetModel()->GetScaleUnit()) ) );
158             MapMode aMapMode(mrWindow.GetMapMode());
159             aMapMode.SetOrigin(Point());
160             return mrWindow.LogicToPixel( aPoint, aMapMode );
161         }
162 
163         return Point();
164     }
165 
166     Point AccessibleOutlineEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
167     {
168         if( IsValid() && mrView.GetModel() )
169         {
170             MapMode aMapMode(mrWindow.GetMapMode());
171             aMapMode.SetOrigin(Point());
172             Point aPoint( mrWindow.PixelToLogic( rPoint, aMapMode ) );
173             return OutputDevice::LogicToLogic( aPoint,
174                                                MapMode(mrView.GetModel()->GetScaleUnit()),
175                                                rMapMode );
176         }
177 
178         return Point();
179     }
180 
181     void AccessibleOutlineEditSource::Notify( SfxBroadcaster& rBroadcaster, const SfxHint& rHint )
182     {
183         bool bDispose = false;
184 
185         if( &rBroadcaster == mpOutliner )
186         {
187             const SfxSimpleHint* pHint = dynamic_cast< const SfxSimpleHint * >( &rHint );
188             if( pHint && (pHint->GetId() == SFX_HINT_DYING) )
189             {
190                 bDispose = true;
191                 mpOutliner = NULL;
192             }
193         }
194         else
195         {
196             const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
197 
198             if( pSdrHint && ( pSdrHint->GetKind() == HINT_MODELCLEARED ) )
199 		    {
200 			    // model is dying under us, going defunc
201                 bDispose = true;
202             }
203         }
204 
205         if( bDispose )
206         {
207 		    if( mpOutliner )
208     		    mpOutliner->SetNotifyHdl( Link() );
209 		    mpOutliner = NULL;
210 		    mpOutlinerView = NULL;
211 		    Broadcast( TextHint( SFX_HINT_DYING ) );
212         }
213     }
214 
215     IMPL_LINK(AccessibleOutlineEditSource, NotifyHdl, EENotify*, aNotify)
216     {
217         if( aNotify )
218         {
219             ::std::auto_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( aNotify) );
220 
221             if( aHint.get() )
222                 Broadcast( *aHint.get() );
223         }
224 
225         return 0;
226     }
227 
228 } // end of namespace accessibility
229