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