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 #include "precompiled_reportdesign.hxx"
24 #include "SectionView.hxx"
25 #include "DesignView.hxx"
26 #include <RptPage.hxx>
27 #include <RptObject.hxx>
28 #include <RptDef.hxx>
29 #include <svx/svxids.hrc>
30 #include <svx/svddrgmt.hxx>
31 #include <vcl/scrbar.hxx>
32 #include "ReportSection.hxx"
33 #include "ReportWindow.hxx"
34 #include "uistrings.hrc"
35 #include <tools/debug.hxx>
36 #include <tools/diagnose_ex.h>
37 
38 namespace rptui
39 {
40     using namespace ::com::sun::star;
41 TYPEINIT1( OSectionView, SdrView );
42 
43 //----------------------------------------------------------------------------
44 DBG_NAME( rpt_OSectionView )
45 OSectionView::OSectionView( SdrModel* pModel, OReportSection* _pSectionWindow, OReportWindow* pEditor )
46 	:SdrView( pModel, _pSectionWindow )
47 	,m_pReportWindow( pEditor )
48 	,m_pSectionWindow(_pSectionWindow)
49 {
50 	DBG_CTOR( rpt_OSectionView,NULL);
51     // SetPagePaintingAllowed(false);
52     SetBufferedOutputAllowed(true);
53     SetBufferedOverlayAllowed(true);
54     SetPageBorderVisible(false);
55     SetBordVisible();
56     SetQuickTextEditMode(sal_False);
57 }
58 
59 //----------------------------------------------------------------------------
60 
61 OSectionView::~OSectionView()
62 {
63 	DBG_DTOR( rpt_OSectionView,NULL);
64 }
65 
66 //----------------------------------------------------------------------------
67 
68 void OSectionView::MarkListHasChanged()
69 {
70 	DBG_CHKTHIS( rpt_OSectionView,NULL);
71 	SdrView::MarkListHasChanged();
72 
73 	if ( m_pReportWindow && m_pSectionWindow && !m_pSectionWindow->getPage()->getSpecialMode() )
74     {
75 		//m_pReportWindow->unmarkAllObjects(this); // WHY
76 		DlgEdHint aHint( RPTUI_HINT_SELECTIONCHANGED );
77 		m_pReportWindow->getReportView()->Broadcast( aHint );
78         m_pReportWindow->getReportView()->UpdatePropertyBrowserDelayed(*this);
79     }
80 }
81 
82 //----------------------------------------------------------------------------
83 
84 void OSectionView::MakeVisible( const Rectangle& rRect, Window& rWin )
85 {
86 	DBG_CHKTHIS( rpt_OSectionView,NULL);
87 	// visible area
88 	MapMode aMap( rWin.GetMapMode() );
89 	const Point aOrg( aMap.GetOrigin() );
90 	const Size aVisSize( rWin.GetOutputSize() );
91 	const Rectangle aVisRect( Point(-aOrg.X(),-aOrg.Y()), aVisSize );
92 
93 	// check, if rectangle is inside visible area
94 	if ( !aVisRect.IsInside( rRect ) )
95 	{
96 		// calculate scroll distance; the rectangle must be inside the visible area
97 		sal_Int32 nScrollX = 0, nScrollY = 0;
98 
99 		const sal_Int32 nVisLeft   = aVisRect.Left();
100 		const sal_Int32 nVisRight  = aVisRect.Right();
101 		const sal_Int32 nVisTop    = aVisRect.Top();
102 		const sal_Int32 nVisBottom = aVisRect.Bottom();
103 
104 		// don't scroll beyond the page size
105 		Size aPageSize = m_pSectionWindow->getPage()->GetSize();
106 		const sal_Int32 nPageWidth  = aPageSize.Width();
107 		const sal_Int32 nPageHeight = aPageSize.Height();
108 
109 		if ( nVisRight + nScrollX > nPageWidth )
110 			nScrollX = nPageWidth - nVisRight;
111 
112 		if ( nVisLeft + nScrollX < 0 )
113 			nScrollX = -nVisLeft;
114 
115 		if ( nVisBottom + nScrollY > nPageHeight )
116 			nScrollY = nPageHeight - nVisBottom;
117 
118 		if ( nVisTop + nScrollY < 0 )
119 			nScrollY = -nVisTop;
120 
121 		// scroll window
122 		rWin.Update();
123 		rWin.Scroll( -nScrollX, -nScrollY );
124 		aMap.SetOrigin( Point( aOrg.X() - nScrollX, aOrg.Y() - nScrollY ) );
125 		rWin.SetMapMode( aMap );
126 		rWin.Update();
127         rWin.Invalidate();
128 
129 		if ( m_pReportWindow )
130         {
131             const DlgEdHint aHint( RPTUI_HINT_WINDOWSCROLLED );
132 			m_pReportWindow->getReportView()->Broadcast( aHint );
133         }
134 	}
135     else
136     {
137         rWin.Invalidate(INVALIDATE_NOERASE);
138     }
139 }
140 //------------------------------------------------------------------------------
141 void OSectionView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
142 {
143 	DBG_CHKTHIS( rpt_OSectionView,NULL);
144     SdrView::Notify(rBC,rHint);
145     if ( rHint.ISA(SdrHint) )
146     {
147         const SdrObject* pObj = ((SdrHint&)rHint).GetObject();
148         const SdrHintKind eKind = ((SdrHint&)rHint).GetKind();
149         // check for change of selected object
150         if(HINT_OBJCHG == eKind && pObj && IsObjMarked(const_cast<SdrObject*>(pObj)))
151             AdjustMarkHdl();
152 	    else if ( eKind == HINT_OBJREMOVED )
153 		    ObjectRemovedInAliveMode(pObj);
154     }
155 }
156 
157 //------------------------------------------------------------------------------
158 void OSectionView::ObjectRemovedInAliveMode( const SdrObject* _pObject )
159 {
160 	DBG_CHKTHIS( rpt_OSectionView,NULL);
161     const SdrMarkList& rMarkedList = GetMarkedObjectList();
162 	const sal_uLong nMark = rMarkedList.GetMarkCount();
163 
164 	for( sal_uLong i = 0; i < nMark; i++ )
165 	{
166 		SdrObject* pSdrObj = rMarkedList.GetMark(i)->GetMarkedSdrObj();
167 		if (_pObject == pSdrObj)
168 		{
169 			SdrPageView*    pPgView = GetSdrPageView();
170 			BrkAction();
171 			MarkObj( pSdrObj, pPgView, sal_True );
172 			break;
173 		}
174 	}
175 }
176 
177 // -----------------------------------------------------------------------------
178 void OSectionView::SetMarkedToLayer( SdrLayerID _nLayerNo )
179 {
180 	if (AreObjectsMarked())
181 	{
182 		//	#i11702# use SdrUndoObjectLayerChange for undo
183 		//	STR_UNDO_SELATTR is "Attributes" - should use a different text later
184 		BegUndo( );
185 
186 		const SdrMarkList& rMark = GetMarkedObjectList();
187 		sal_uLong nCount = rMark.GetMarkCount();
188 		for (sal_uLong i=0; i<nCount; i++)
189 		{
190 			SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
191 			if ( pObj->ISA(OCustomShape) )
192 			{
193 				AddUndo( new SdrUndoObjectLayerChange( *pObj, pObj->GetLayer(), _nLayerNo) );
194 				pObj->SetLayer( _nLayerNo );
195                 OObjectBase* pBaseObj = dynamic_cast<OObjectBase*>(pObj);
196                 try
197                 {
198                     pBaseObj->getReportComponent()->setPropertyValue(PROPERTY_OPAQUE,uno::makeAny(_nLayerNo == RPT_LAYER_FRONT));
199                 }
200                 catch(const uno::Exception&)
201                 {
202                     DBG_UNHANDLED_EXCEPTION();
203                 }
204 			}
205 		}
206 
207 		EndUndo();
208 
209 		//	#84073# check mark list now instead of later in a timer
210 		CheckMarked();
211 		MarkListHasChanged();
212 	}
213 }
214 // -----------------------------------------------------------------------------
215 bool OSectionView::OnlyShapesMarked() const
216 {
217     const SdrMarkList& rMark = GetMarkedObjectList();
218 	const sal_uLong nCount = rMark.GetMarkCount();
219     if ( !nCount )
220         return false;
221     sal_uLong i=0;
222 	for (; i<nCount; i++)
223 	{
224 		SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
225 		if ( !pObj->ISA(OCustomShape) )
226         {
227             break;
228         }
229     } // for (sal_uLong i=0; i<nCount; i++)
230     return i == nCount;
231 }
232 
233 bool OSectionView::IsDragResize() const
234 {
235     const SdrDragMethod* pDragMethod = GetDragMethod();
236     if (pDragMethod)
237     {
238         bool bMoveOnly = pDragMethod->getMoveOnly();
239         if (bMoveOnly == false)
240         {
241             // current marked components will be resized
242             return true;
243         }
244     }
245     return false;
246 }
247 
248 // -----------------------------------------------------------------------------
249 short OSectionView::GetLayerIdOfMarkedObjects() const
250 {
251 	short nRet = SHRT_MAX;
252 	const SdrMarkList &rMrkList = GetMarkedObjectList();
253 	for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
254 	{
255 		const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
256 		if ( nRet == SHRT_MAX )
257 			nRet = pObj->GetLayer();
258 		else if ( nRet != pObj->GetLayer() )
259 		{
260 			nRet = -1;
261 			break;
262 		}
263 	}
264 	if ( nRet == SHRT_MAX )
265 		nRet = -1;
266 	return nRet;
267 }
268 
269 //============================================================================
270 } // rptui
271 //============================================================================
272