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 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_svtools.hxx"
29 
30 #include "unogridcolumnfacade.hxx"
31 #include "unocontroltablemodel.hxx"
32 
33 #include "svtools/table/defaultinputhandler.hxx"
34 #include "svtools/table/gridtablerenderer.hxx"
35 #include "svtools/table/tablecontrol.hxx"
36 
37 /** === begin UNO includes === **/
38 #include <com/sun/star/awt/grid/XGridColumn.hpp>
39 #include <com/sun/star/view/SelectionType.hpp>
40 #include <com/sun/star/awt/grid/XGridColumnListener.hpp>
41 /** === end UNO includes === **/
42 
43 #include <comphelper/stlunosequence.hxx>
44 #include <tools/debug.hxx>
45 #include <tools/diagnose_ex.h>
46 #include <vcl/svapp.hxx>
47 #include <vos/mutex.hxx>
48 
49 // .....................................................................................................................
50 namespace svt { namespace table
51 {
52 // .....................................................................................................................
53 
54     /** === begin UNO using === **/
55     using ::com::sun::star::uno::Reference;
56     using ::com::sun::star::uno::RuntimeException;
57     using ::com::sun::star::uno::Sequence;
58     using ::com::sun::star::uno::UNO_QUERY_THROW;
59     using ::com::sun::star::uno::UNO_QUERY;
60     using ::com::sun::star::awt::grid::XGridColumn;
61     using ::com::sun::star::uno::XInterface;
62     using ::com::sun::star::uno::Exception;
63     using ::com::sun::star::awt::grid::XGridColumnListener;
64     using ::com::sun::star::lang::EventObject;
65     using ::com::sun::star::awt::grid::GridColumnEvent;
66     using ::com::sun::star::uno::Any;
67     using ::com::sun::star::style::HorizontalAlignment_LEFT;
68     using ::com::sun::star::style::HorizontalAlignment;
69     /** === end UNO using === **/
70 
71     //------------------------------------------------------------------------------------------------------------------
72     namespace
73     {
74         template< class ATTRIBUTE_TYPE >
75         void lcl_set( Reference< XGridColumn > const & i_column, void ( SAL_CALL XGridColumn::*i_setter )( ATTRIBUTE_TYPE ),
76             ATTRIBUTE_TYPE i_value )
77         {
78             try
79             {
80                 (i_column.get()->*i_setter) ( i_value );
81             }
82             catch( const Exception& )
83             {
84             	DBG_UNHANDLED_EXCEPTION();
85             }
86         }
87 
88         template< class ATTRIBUTE_TYPE >
89         ATTRIBUTE_TYPE lcl_get( Reference< XGridColumn > const & i_column, ATTRIBUTE_TYPE ( SAL_CALL XGridColumn::*i_getter )() )
90         {
91             ATTRIBUTE_TYPE value = ATTRIBUTE_TYPE();
92             try
93             {
94                 value = (i_column.get()->*i_getter)();
95             }
96             catch( const Exception& )
97             {
98             	DBG_UNHANDLED_EXCEPTION();
99             }
100             return value;
101         }
102     }
103 
104 	//==================================================================================================================
105 	//= ColumnChangeMultiplexer
106 	//==================================================================================================================
107     typedef ::cppu::WeakImplHelper1 <   XGridColumnListener
108                                     >   ColumnChangeMultiplexer_Base;
109     class ColumnChangeMultiplexer   :public ColumnChangeMultiplexer_Base
110                                     ,public ::boost::noncopyable
111     {
112     public:
113         ColumnChangeMultiplexer( UnoGridColumnFacade& i_colImpl );
114 
115         void dispose();
116 
117     protected:
118         ~ColumnChangeMultiplexer();
119 
120         // XGridColumnListener
121         virtual void SAL_CALL columnChanged( const GridColumnEvent& i_event ) throw (RuntimeException);
122 
123         // XEventListener
124         virtual void SAL_CALL disposing( const EventObject& i_event ) throw (RuntimeException);
125 
126     private:
127         UnoGridColumnFacade* m_pColumnImplementation;
128     };
129 
130     //------------------------------------------------------------------------------------------------------------------
131     ColumnChangeMultiplexer::ColumnChangeMultiplexer( UnoGridColumnFacade& i_colImpl )
132         :m_pColumnImplementation( &i_colImpl )
133     {
134     }
135 
136     //------------------------------------------------------------------------------------------------------------------
137     ColumnChangeMultiplexer::~ColumnChangeMultiplexer()
138     {
139     }
140 
141     //------------------------------------------------------------------------------------------------------------------
142     void ColumnChangeMultiplexer::dispose()
143     {
144         DBG_TESTSOLARMUTEX();
145         m_pColumnImplementation = NULL;
146     }
147 
148     //------------------------------------------------------------------------------------------------------------------
149     void SAL_CALL ColumnChangeMultiplexer::columnChanged( const GridColumnEvent& i_event ) throw (RuntimeException)
150     {
151         if ( i_event.AttributeName.equalsAscii( "DataColumnIndex" ) )
152         {
153             ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
154             if ( m_pColumnImplementation != NULL )
155                 m_pColumnImplementation->dataColumnIndexChanged();
156             return;
157         }
158 
159         ColumnAttributeGroup nChangedAttributes( COL_ATTRS_NONE );
160 
161         if ( i_event.AttributeName.equalsAscii( "HorizontalAlign" ) )
162             nChangedAttributes |= COL_ATTRS_APPEARANCE;
163 
164         if  (   i_event.AttributeName.equalsAscii( "ColumnWidth" )
165             ||  i_event.AttributeName.equalsAscii( "MaxWidth" )
166             ||  i_event.AttributeName.equalsAscii( "MinWidth" )
167             ||  i_event.AttributeName.equalsAscii( "PreferredWidth" )
168             ||  i_event.AttributeName.equalsAscii( "Resizeable" )
169             ||  i_event.AttributeName.equalsAscii( "Flexibility" )
170             )
171             nChangedAttributes |= COL_ATTRS_WIDTH;
172 
173         OSL_ENSURE( nChangedAttributes != COL_ATTRS_NONE,
174             "ColumnChangeMultiplexer::columnChanged: unknown column attributed changed!" );
175 
176         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
177         if ( m_pColumnImplementation != NULL )
178             m_pColumnImplementation->columnChanged( nChangedAttributes );
179     }
180 
181     //------------------------------------------------------------------------------------------------------------------
182     void SAL_CALL ColumnChangeMultiplexer::disposing( const EventObject& i_event ) throw (RuntimeException)
183     {
184         OSL_UNUSED( i_event );
185     }
186 
187 	//==================================================================================================================
188 	//= UnoGridColumnFacade
189 	//==================================================================================================================
190     //------------------------------------------------------------------------------------------------------------------
191     UnoGridColumnFacade::UnoGridColumnFacade( UnoControlTableModel const & i_owner, Reference< XGridColumn > const & i_gridColumn )
192         :m_pOwner( &i_owner )
193         ,m_nDataColumnIndex( -1 )
194         ,m_xGridColumn( i_gridColumn, UNO_QUERY_THROW )
195         ,m_pChangeMultiplexer( new ColumnChangeMultiplexer( *this ) )
196     {
197         m_xGridColumn->addGridColumnListener( m_pChangeMultiplexer.get() );
198         impl_updateDataColumnIndex_nothrow();
199     }
200 
201     //------------------------------------------------------------------------------------------------------------------
202     UnoGridColumnFacade::~UnoGridColumnFacade()
203     {
204     }
205 
206     //------------------------------------------------------------------------------------------------------------------
207     void UnoGridColumnFacade::dispose()
208     {
209         DBG_TESTSOLARMUTEX();
210         ENSURE_OR_RETURN_VOID( m_pOwner != NULL, "UnoGridColumnFacade::dispose: already disposed!" );
211 
212         m_xGridColumn->removeGridColumnListener( m_pChangeMultiplexer.get() );
213         m_pChangeMultiplexer->dispose();
214         m_pChangeMultiplexer.clear();
215         m_xGridColumn.clear();
216         m_pOwner = NULL;
217     }
218 
219     //------------------------------------------------------------------------------------------------------------------
220     void UnoGridColumnFacade::impl_updateDataColumnIndex_nothrow()
221     {
222         m_nDataColumnIndex = -1;
223         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
224         try
225         {
226             m_nDataColumnIndex = m_xGridColumn->getDataColumnIndex();
227         }
228         catch( const Exception& )
229         {
230         	DBG_UNHANDLED_EXCEPTION();
231         }
232     }
233 
234     //------------------------------------------------------------------------------------------------------------------
235     void UnoGridColumnFacade::dataColumnIndexChanged()
236     {
237         DBG_TESTSOLARMUTEX();
238         impl_updateDataColumnIndex_nothrow();
239         if ( m_pOwner != NULL )
240             m_pOwner->notifyAllDataChanged();
241     }
242 
243     //------------------------------------------------------------------------------------------------------------------
244     void UnoGridColumnFacade::columnChanged( ColumnAttributeGroup const i_attributeGroup )
245     {
246         DBG_TESTSOLARMUTEX();
247         if ( m_pOwner != NULL )
248             m_pOwner->notifyColumnChange( m_pOwner->getColumnPos( *this ), i_attributeGroup );
249     }
250 
251     //------------------------------------------------------------------------------------------------------------------
252     Any UnoGridColumnFacade::getID() const
253     {
254         Any aID;
255         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", aID );
256         try
257         {
258             aID = m_xGridColumn->getIdentifier();
259         }
260         catch( const Exception& )
261         {
262         	DBG_UNHANDLED_EXCEPTION();
263         }
264         return aID;
265     }
266 
267     //------------------------------------------------------------------------------------------------------------------
268     void UnoGridColumnFacade::setID( const Any& i_ID )
269     {
270         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
271         try
272         {
273             m_xGridColumn->setIdentifier( i_ID );
274         }
275         catch( const Exception& )
276         {
277         	DBG_UNHANDLED_EXCEPTION();
278         }
279     }
280 
281     //------------------------------------------------------------------------------------------------------------------
282     String UnoGridColumnFacade::getName() const
283     {
284         ::rtl::OUString sName;
285         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", sName );
286         try
287         {
288             sName = m_xGridColumn->getTitle();
289         }
290         catch( const Exception& )
291         {
292         	DBG_UNHANDLED_EXCEPTION();
293         }
294         return sName;
295     }
296 
297     //------------------------------------------------------------------------------------------------------------------
298     void UnoGridColumnFacade::setName( const String& _rName )
299     {
300         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
301         try
302         {
303             m_xGridColumn->setTitle( _rName );
304         }
305         catch( const Exception& )
306         {
307         	DBG_UNHANDLED_EXCEPTION();
308         }
309     }
310 
311     //------------------------------------------------------------------------------------------------------------------
312     String UnoGridColumnFacade::getHelpText() const
313     {
314         ::rtl::OUString sHelpText;
315         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", sHelpText );
316         try
317         {
318             sHelpText = m_xGridColumn->getHelpText();
319         }
320         catch( const Exception& )
321         {
322         	DBG_UNHANDLED_EXCEPTION();
323         }
324         return sHelpText;
325     }
326 
327     //------------------------------------------------------------------------------------------------------------------
328     void UnoGridColumnFacade::setHelpText( const String& i_helpText )
329     {
330         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
331         try
332         {
333             m_xGridColumn->setHelpText( i_helpText );
334         }
335         catch( const Exception& )
336         {
337         	DBG_UNHANDLED_EXCEPTION();
338         }
339     }
340 
341     //------------------------------------------------------------------------------------------------------------------
342     bool UnoGridColumnFacade::isResizable() const
343     {
344         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", false );
345         return lcl_get( m_xGridColumn, &XGridColumn::getResizeable );
346     }
347 
348     //------------------------------------------------------------------------------------------------------------------
349     void UnoGridColumnFacade::setResizable( bool i_resizable )
350     {
351         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
352         lcl_set( m_xGridColumn, &XGridColumn::setResizeable, sal_Bool( i_resizable ) );
353     }
354 
355     //------------------------------------------------------------------------------------------------------------------
356     sal_Int32 UnoGridColumnFacade::getFlexibility() const
357     {
358         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 1 );
359         return lcl_get( m_xGridColumn, &XGridColumn::getFlexibility );
360     }
361 
362 	//------------------------------------------------------------------------------------------------------------------
363     void UnoGridColumnFacade::setFlexibility( sal_Int32 const i_flexibility )
364     {
365         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
366         lcl_set( m_xGridColumn, &XGridColumn::setFlexibility, i_flexibility );
367     }
368 
369     //------------------------------------------------------------------------------------------------------------------
370     TableMetrics UnoGridColumnFacade::getWidth() const
371     {
372         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 );
373         return lcl_get( m_xGridColumn, &XGridColumn::getColumnWidth );
374     }
375 
376     //------------------------------------------------------------------------------------------------------------------
377     void UnoGridColumnFacade::setWidth( TableMetrics _nWidth )
378     {
379         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
380         lcl_set( m_xGridColumn, &XGridColumn::setColumnWidth, _nWidth );
381     }
382 
383     //------------------------------------------------------------------------------------------------------------------
384     TableMetrics UnoGridColumnFacade::getMinWidth() const
385     {
386         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 );
387         return lcl_get( m_xGridColumn, &XGridColumn::getMinWidth );
388     }
389 
390     //------------------------------------------------------------------------------------------------------------------
391     void UnoGridColumnFacade::setMinWidth( TableMetrics _nMinWidth )
392     {
393         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
394         lcl_set( m_xGridColumn, &XGridColumn::setMinWidth, _nMinWidth );
395     }
396 
397     //------------------------------------------------------------------------------------------------------------------
398     TableMetrics UnoGridColumnFacade::getMaxWidth() const
399     {
400         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 );
401         return lcl_get( m_xGridColumn, &XGridColumn::getMaxWidth );
402     }
403 
404     //------------------------------------------------------------------------------------------------------------------
405     void UnoGridColumnFacade::setMaxWidth( TableMetrics _nMaxWidth )
406     {
407         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
408         lcl_set( m_xGridColumn, &XGridColumn::setMinWidth, _nMaxWidth );
409     }
410 
411 	//------------------------------------------------------------------------------------------------------------------
412 	::com::sun::star::style::HorizontalAlignment UnoGridColumnFacade::getHorizontalAlign()
413     {
414         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", HorizontalAlignment_LEFT );
415         return lcl_get( m_xGridColumn, &XGridColumn::getHorizontalAlign );
416     }
417 
418     //------------------------------------------------------------------------------------------------------------------
419 	void UnoGridColumnFacade::setHorizontalAlign( com::sun::star::style::HorizontalAlignment _align )
420     {
421         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
422         lcl_set( m_xGridColumn, &XGridColumn::setHorizontalAlign, _align );
423     }
424 
425 // .....................................................................................................................
426 } } // svt::table
427 // .....................................................................................................................
428