xref: /trunk/main/svx/source/table/tablerow.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <com/sun/star/lang/DisposedException.hpp>
32 
33 #include "cell.hxx"
34 #include "tablerow.hxx"
35 #include "tableundo.hxx"
36 #include "svx/svdmodel.hxx"
37 #include "svx/svdotable.hxx"
38 
39 // -----------------------------------------------------------------------------
40 
41 using ::rtl::OUString;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::lang;
44 using namespace ::com::sun::star::container;
45 using namespace ::com::sun::star::table;
46 using namespace ::com::sun::star::beans;
47 
48 // -----------------------------------------------------------------------------
49 
50 namespace sdr { namespace table {
51 
52 const sal_Int32 Property_Height = 0;
53 const sal_Int32 Property_OptimalHeight = 1;
54 const sal_Int32 Property_IsVisible = 2;
55 const sal_Int32 Property_IsStartOfNewPage = 3;
56 
57 // -----------------------------------------------------------------------------
58 // TableRow
59 // -----------------------------------------------------------------------------
60 
61 TableRow::TableRow( const TableModelRef& xTableModel, sal_Int32 nRow, sal_Int32 nColumns )
62 : TableRowBase( getStaticPropertySetInfo() )
63 , mxTableModel( xTableModel )
64 , mnRow( nRow )
65 , mnHeight( 0 )
66 , mbOptimalHeight( sal_True )
67 , mbIsVisible( sal_True )
68 , mbIsStartOfNewPage( sal_False )
69 {
70 	if( nColumns < 20 )
71 		maCells.reserve( 20 );
72 
73 	if( nColumns )
74 	{
75 		maCells.resize( nColumns );
76 		while( nColumns-- )
77 			maCells[ nColumns ] = mxTableModel->createCell();
78 	}
79 }
80 
81 // -----------------------------------------------------------------------------
82 
83 TableRow::~TableRow()
84 {
85 }
86 
87 // -----------------------------------------------------------------------------
88 
89 void TableRow::dispose()
90 {
91 	mxTableModel.clear();
92 	if( !maCells.empty() )
93 	{
94 		CellVector::iterator aIter( maCells.begin() );
95 		while( aIter != maCells.end() )
96 			(*aIter++)->dispose();
97 		CellVector().swap(maCells);
98 	}
99 }
100 
101 // -----------------------------------------------------------------------------
102 
103 void TableRow::throwIfDisposed() const throw (::com::sun::star::uno::RuntimeException)
104 {
105 	if( !mxTableModel.is() )
106 		throw DisposedException();
107 }
108 
109 // -----------------------------------------------------------------------------
110 
111 TableRow& TableRow::operator=( const TableRow& r )
112 {
113 	mnHeight = r.mnHeight;
114 	mbOptimalHeight = r.mbOptimalHeight;
115 	mbIsVisible = r.mbIsVisible;
116 	mbIsStartOfNewPage = r.mbIsStartOfNewPage;
117 	maName = r.maName;
118 
119 	return *this;
120 }
121 
122 // -----------------------------------------------------------------------------
123 
124 void TableRow::insertColumns( sal_Int32 nIndex, sal_Int32 nCount, CellVector::iterator* pIter /* = 0 */  )
125 {
126 	throwIfDisposed();
127 	if( nCount )
128 	{
129 		if( nIndex >= static_cast< sal_Int32 >( maCells.size() ) )
130 			nIndex = static_cast< sal_Int32 >( maCells.size() );
131 		if ( pIter )
132 			maCells.insert( maCells.begin() + nIndex, *pIter, (*pIter) + nCount );
133 		else
134 		{
135 			maCells.reserve( maCells.size() + nCount );
136 			for ( sal_Int32 i = 0; i < nCount; i++ )
137 				maCells.insert( maCells.begin() + nIndex + i, mxTableModel->createCell() );
138 		}
139 	}
140 }
141 
142 // -----------------------------------------------------------------------------
143 
144 void TableRow::removeColumns( sal_Int32 nIndex, sal_Int32 nCount )
145 {
146 	throwIfDisposed();
147 	if( (nCount >= 0) && ( nIndex >= 0) )
148 	{
149 		if( (nIndex + nCount) < static_cast< sal_Int32 >( maCells.size() ) )
150 		{
151 			CellVector::iterator aBegin( maCells.begin() );
152 			while( nIndex-- && (aBegin != maCells.end()) )
153 				aBegin++;
154 
155 			if( nCount > 1 )
156 			{
157 				CellVector::iterator aEnd( aBegin );
158 				while( nCount-- && (aEnd != maCells.end()) )
159 					aEnd++;
160 				maCells.erase( aBegin, aEnd );
161 			}
162 			else
163 			{
164 				maCells.erase( aBegin );
165 			}
166 		}
167 		else
168 		{
169 			maCells.resize( nIndex );
170 		}
171 	}
172 }
173 
174 // -----------------------------------------------------------------------------
175 // XCellRange
176 // -----------------------------------------------------------------------------
177 
178 Reference< XCell > SAL_CALL TableRow::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
179 {
180 	throwIfDisposed();
181 	if( nRow != 0 )
182 		throw IndexOutOfBoundsException();
183 
184 	return mxTableModel->getCellByPosition( nColumn, mnRow );
185 }
186 
187 // -----------------------------------------------------------------------------
188 
189 Reference< XCellRange > SAL_CALL TableRow::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException)
190 {
191 	throwIfDisposed();
192 	if( (nLeft >= 0 ) && (nTop == 0) && (nRight >= nLeft) && (nBottom == 0)  )
193 	{
194 		return mxTableModel->getCellRangeByPosition( nLeft, mnRow, nRight, mnRow );
195 	}
196 	throw IndexOutOfBoundsException();
197 }
198 
199 // -----------------------------------------------------------------------------
200 
201 Reference< XCellRange > SAL_CALL TableRow::getCellRangeByName( const OUString& /*aRange*/ ) throw (RuntimeException)
202 {
203 	throwIfDisposed();
204 	return Reference< XCellRange >();
205 }
206 
207 // -----------------------------------------------------------------------------
208 // XNamed
209 // -----------------------------------------------------------------------------
210 
211 OUString SAL_CALL TableRow::getName() throw (RuntimeException)
212 {
213 	return maName;
214 }
215 
216 // -----------------------------------------------------------------------------
217 
218 void SAL_CALL TableRow::setName( const OUString& aName ) throw (RuntimeException)
219 {
220 	maName = aName;
221 }
222 
223 // -----------------------------------------------------------------------------
224 // XFastPropertySet
225 // -----------------------------------------------------------------------------
226 
227 void SAL_CALL TableRow::setFastPropertyValue( sal_Int32 nHandle, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, RuntimeException)
228 {
229 	bool bOk = false;
230 	bool bChange = false;
231 
232 	TableRowUndo* pUndo = 0;
233 
234 	SdrModel* pModel = mxTableModel->getSdrTableObj()->GetModel();
235 
236 	const bool bUndo = mxTableModel.is() && mxTableModel->getSdrTableObj() && mxTableModel->getSdrTableObj()->IsInserted() && pModel && pModel->IsUndoEnabled();
237 
238 	if( bUndo )
239 	{
240 		TableRowRef xThis( this );
241 		pUndo = new TableRowUndo( xThis );
242 	}
243 
244 	switch( nHandle )
245 	{
246 	case Property_Height:
247 		{
248 			sal_Int32 nHeight = mnHeight;
249 			bOk = aValue >>= nHeight;
250 			if( bOk && (mnHeight != nHeight) )
251 			{
252 				mnHeight = nHeight;
253 				mbOptimalHeight = mnHeight == 0;
254 				bChange = true;
255 			}
256 			break;
257 		}
258 
259 	case Property_OptimalHeight:
260 		{
261 			sal_Bool bOptimalHeight = mbOptimalHeight;
262 			bOk = aValue >>= bOptimalHeight;
263 			if( bOk && (mbOptimalHeight != bOptimalHeight) )
264 			{
265 				mbOptimalHeight = bOptimalHeight;
266 				if( bOptimalHeight )
267 					mnHeight = 0;
268 				bChange = true;
269 			}
270 			break;
271 		}
272 	case Property_IsVisible:
273 		{
274 			sal_Bool bIsVisible = mbIsVisible;
275 			bOk = aValue >>= bIsVisible;
276 			if( bOk && (mbIsVisible != bIsVisible) )
277 			{
278 				mbIsVisible = bIsVisible;
279 				bChange = true;
280 			}
281 			break;
282 		}
283 
284 	case Property_IsStartOfNewPage:
285 		{
286 			sal_Bool bIsStartOfNewPage = mbIsStartOfNewPage;
287 			bOk = aValue >>= bIsStartOfNewPage;
288 			if( bOk && (mbIsStartOfNewPage != bIsStartOfNewPage) )
289 			{
290 				mbIsStartOfNewPage = bIsStartOfNewPage;
291 				bChange = true;
292 			}
293 			break;
294 		}
295 	default:
296 		throw UnknownPropertyException();
297 	}
298 	if( !bOk )
299 		throw IllegalArgumentException();
300 
301 	if( bChange )
302 	{
303 		if( pUndo )
304 		{
305 			pModel->AddUndo( pUndo );
306 			pUndo = 0;
307 		}
308 		mxTableModel->setModified(sal_True);
309 	}
310 
311 	if( pUndo )
312 		delete pUndo;
313 }
314 
315 // -----------------------------------------------------------------------------
316 
317 Any SAL_CALL TableRow::getFastPropertyValue( sal_Int32 nHandle ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
318 {
319 	switch( nHandle )
320 	{
321 	case Property_Height:			return Any( mnHeight );
322 	case Property_OptimalHeight:	return Any( mbOptimalHeight );
323 	case Property_IsVisible:		return Any( mbIsVisible );
324 	case Property_IsStartOfNewPage:	return Any( mbIsStartOfNewPage );
325 	default:						throw UnknownPropertyException();
326 	}
327 }
328 
329 // -----------------------------------------------------------------------------
330 
331 rtl::Reference< ::comphelper::FastPropertySetInfo > TableRow::getStaticPropertySetInfo()
332 {
333 	static rtl::Reference< ::comphelper::FastPropertySetInfo > xInfo;
334 	if( !xInfo.is() )
335 	{
336         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
337 		if( !xInfo.is() )
338 		{
339 			comphelper::PropertyVector aProperties(6);
340 
341 			aProperties[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
342 			aProperties[0].Handle = Property_Height;
343 			aProperties[0].Type = ::getCppuType((const sal_Int32*)0);
344 			aProperties[0].Attributes = 0;
345 
346 			aProperties[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OptimalHeight" ) );
347 			aProperties[1].Handle = Property_OptimalHeight;
348 			aProperties[1].Type = ::getBooleanCppuType();
349 			aProperties[1].Attributes = 0;
350 
351 			aProperties[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) );
352 			aProperties[2].Handle = Property_IsVisible;
353 			aProperties[2].Type = ::getBooleanCppuType();
354 			aProperties[2].Attributes = 0;
355 
356 			aProperties[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" ) );
357 			aProperties[3].Handle = Property_IsStartOfNewPage;
358 			aProperties[3].Type = ::getBooleanCppuType();
359 			aProperties[3].Attributes = 0;
360 
361 			aProperties[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
362 			aProperties[4].Handle = Property_Height;
363 			aProperties[4].Type = ::getCppuType((const sal_Int32*)0);
364 			aProperties[4].Attributes = 0;
365 
366 			aProperties[5].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OptimalSize" ) );
367 			aProperties[5].Handle = Property_OptimalHeight;
368 			aProperties[5].Type = ::getBooleanCppuType();
369 			aProperties[5].Attributes = 0;
370 
371 			xInfo.set( new ::comphelper::FastPropertySetInfo(aProperties) );
372 		}
373 	}
374 
375 	return xInfo;
376 }
377 
378 // -----------------------------------------------------------------------------
379 
380 
381 } }
382