1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "unogridcolumnfacade.hxx"
21 #include "unocontroltablemodel.hxx"
22 
23 #include <com/sun/star/awt/grid/XGridColumn.hpp>
24 #include <com/sun/star/awt/grid/XGridColumnListener.hpp>
25 
26 #include <tools/debug.hxx>
27 #include <tools/diagnose_ex.h>
28 #include <vcl/svapp.hxx>
29 #include <cppuhelper/implbase.hxx>
30 
31 
32 namespace svt { namespace table
33 {
34 
35 
36     using css::uno::Reference;
37     using css::uno::RuntimeException;
38     using css::uno::UNO_QUERY_THROW;
39     using css::awt::grid::XGridColumn;
40     using css::uno::Exception;
41     using css::awt::grid::XGridColumnListener;
42     using css::lang::EventObject;
43     using css::awt::grid::GridColumnEvent;
44     using css::style::HorizontalAlignment_LEFT;
45     using css::style::HorizontalAlignment;
46 
47 
48     namespace
49     {
50         template< class T1, class T2 >
lcl_set(Reference<XGridColumn> const & i_column,void (SAL_CALL XGridColumn::* i_setter)(T1),T2 i_value)51         void lcl_set( Reference< XGridColumn > const & i_column, void ( SAL_CALL XGridColumn::*i_setter )( T1 ),
52             T2 i_value )
53         {
54             try
55             {
56                 (i_column.get()->*i_setter) ( i_value );
57             }
58             catch( const Exception& )
59             {
60                 DBG_UNHANDLED_EXCEPTION("svtools.uno");
61             }
62         }
63 
64         template< class ATTRIBUTE_TYPE >
lcl_get(Reference<XGridColumn> const & i_column,ATTRIBUTE_TYPE (SAL_CALL XGridColumn::* i_getter)())65         ATTRIBUTE_TYPE lcl_get( Reference< XGridColumn > const & i_column, ATTRIBUTE_TYPE ( SAL_CALL XGridColumn::*i_getter )() )
66         {
67             ATTRIBUTE_TYPE value = ATTRIBUTE_TYPE();
68             try
69             {
70                 value = (i_column.get()->*i_getter)();
71             }
72             catch( const Exception& )
73             {
74                 DBG_UNHANDLED_EXCEPTION("svtools.uno");
75             }
76             return value;
77         }
78     }
79 
80 
81     //= ColumnChangeMultiplexer
82 
83     typedef ::cppu::WeakImplHelper <   XGridColumnListener
84                                     >   ColumnChangeMultiplexer_Base;
85     class ColumnChangeMultiplexer   :public ColumnChangeMultiplexer_Base
86     {
87     public:
88         explicit ColumnChangeMultiplexer( UnoGridColumnFacade& i_colImpl );
89         ColumnChangeMultiplexer(const ColumnChangeMultiplexer&) = delete;
90         ColumnChangeMultiplexer& operator=(const ColumnChangeMultiplexer&) = delete;
91 
92         void dispose();
93 
94     protected:
95         virtual ~ColumnChangeMultiplexer() override;
96 
97         // XGridColumnListener
98         virtual void SAL_CALL columnChanged( const GridColumnEvent& i_event ) override;
99 
100         // XEventListener
101         virtual void SAL_CALL disposing( const EventObject& i_event ) override;
102 
103     private:
104         UnoGridColumnFacade* m_pColumnImplementation;
105     };
106 
107 
ColumnChangeMultiplexer(UnoGridColumnFacade & i_colImpl)108     ColumnChangeMultiplexer::ColumnChangeMultiplexer( UnoGridColumnFacade& i_colImpl )
109         :m_pColumnImplementation( &i_colImpl )
110     {
111     }
112 
113 
~ColumnChangeMultiplexer()114     ColumnChangeMultiplexer::~ColumnChangeMultiplexer()
115     {
116     }
117 
118 
dispose()119     void ColumnChangeMultiplexer::dispose()
120     {
121         DBG_TESTSOLARMUTEX();
122         m_pColumnImplementation = nullptr;
123     }
124 
125 
columnChanged(const GridColumnEvent & i_event)126     void SAL_CALL ColumnChangeMultiplexer::columnChanged( const GridColumnEvent& i_event )
127     {
128         if ( i_event.AttributeName == "DataColumnIndex" )
129         {
130             SolarMutexGuard aGuard;
131             if ( m_pColumnImplementation != nullptr )
132                 m_pColumnImplementation->dataColumnIndexChanged();
133             return;
134         }
135 
136         ColumnAttributeGroup nChangedAttributes( ColumnAttributeGroup::NONE );
137 
138         if ( i_event.AttributeName == "HorizontalAlign" )
139             nChangedAttributes |= ColumnAttributeGroup::APPEARANCE;
140 
141         if  (   i_event.AttributeName == "ColumnWidth"
142             ||  i_event.AttributeName == "MaxWidth"
143             ||  i_event.AttributeName == "MinWidth"
144             ||  i_event.AttributeName == "PreferredWidth"
145             ||  i_event.AttributeName == "Resizeable"
146             ||  i_event.AttributeName == "Flexibility"
147             )
148             nChangedAttributes |= ColumnAttributeGroup::WIDTH;
149 
150         OSL_ENSURE( nChangedAttributes != ColumnAttributeGroup::NONE,
151             "ColumnChangeMultiplexer::columnChanged: unknown column attributed changed!" );
152 
153         SolarMutexGuard aGuard;
154         if ( m_pColumnImplementation != nullptr )
155             m_pColumnImplementation->columnChanged( nChangedAttributes );
156     }
157 
158 
disposing(const EventObject &)159     void SAL_CALL ColumnChangeMultiplexer::disposing( const EventObject& )
160     {
161     }
162 
163 
164     //= UnoGridColumnFacade
165 
166 
UnoGridColumnFacade(UnoControlTableModel const & i_owner,Reference<XGridColumn> const & i_gridColumn)167     UnoGridColumnFacade::UnoGridColumnFacade( UnoControlTableModel const & i_owner, Reference< XGridColumn > const & i_gridColumn )
168         :m_pOwner( &i_owner )
169         ,m_nDataColumnIndex( -1 )
170         ,m_xGridColumn( i_gridColumn, css::uno::UNO_SET_THROW )
171         ,m_pChangeMultiplexer( new ColumnChangeMultiplexer( *this ) )
172     {
173         m_xGridColumn->addGridColumnListener( m_pChangeMultiplexer.get() );
174         impl_updateDataColumnIndex_nothrow();
175     }
176 
177 
~UnoGridColumnFacade()178     UnoGridColumnFacade::~UnoGridColumnFacade()
179     {
180     }
181 
182 
dispose()183     void UnoGridColumnFacade::dispose()
184     {
185         DBG_TESTSOLARMUTEX();
186         ENSURE_OR_RETURN_VOID( m_pOwner != nullptr, "UnoGridColumnFacade::dispose: already disposed!" );
187 
188         m_xGridColumn->removeGridColumnListener( m_pChangeMultiplexer.get() );
189         m_pChangeMultiplexer->dispose();
190         m_pChangeMultiplexer.clear();
191         m_xGridColumn.clear();
192         m_pOwner = nullptr;
193     }
194 
195 
impl_updateDataColumnIndex_nothrow()196     void UnoGridColumnFacade::impl_updateDataColumnIndex_nothrow()
197     {
198         m_nDataColumnIndex = -1;
199         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
200         try
201         {
202             m_nDataColumnIndex = m_xGridColumn->getDataColumnIndex();
203         }
204         catch( const Exception& )
205         {
206             DBG_UNHANDLED_EXCEPTION("svtools.uno");
207         }
208     }
209 
210 
dataColumnIndexChanged()211     void UnoGridColumnFacade::dataColumnIndexChanged()
212     {
213         DBG_TESTSOLARMUTEX();
214         impl_updateDataColumnIndex_nothrow();
215         if ( m_pOwner != nullptr )
216             m_pOwner->notifyAllDataChanged();
217     }
218 
219 
columnChanged(ColumnAttributeGroup const i_attributeGroup)220     void UnoGridColumnFacade::columnChanged( ColumnAttributeGroup const i_attributeGroup )
221     {
222         DBG_TESTSOLARMUTEX();
223         if ( m_pOwner != nullptr )
224             m_pOwner->notifyColumnChange( m_pOwner->getColumnPos( *this ), i_attributeGroup );
225     }
226 
227 
getName() const228     OUString UnoGridColumnFacade::getName() const
229     {
230         OUString sName;
231         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", sName );
232         try
233         {
234             sName = m_xGridColumn->getTitle();
235         }
236         catch( const Exception& )
237         {
238             DBG_UNHANDLED_EXCEPTION("svtools.uno");
239         }
240         return sName;
241     }
242 
243 
getHelpText() const244     OUString UnoGridColumnFacade::getHelpText() const
245     {
246         OUString sHelpText;
247         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", sHelpText );
248         try
249         {
250             sHelpText = m_xGridColumn->getHelpText();
251         }
252         catch( const Exception& )
253         {
254             DBG_UNHANDLED_EXCEPTION("svtools.uno");
255         }
256         return sHelpText;
257     }
258 
259 
isResizable() const260     bool UnoGridColumnFacade::isResizable() const
261     {
262         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", false );
263         return lcl_get( m_xGridColumn, &XGridColumn::getResizeable );
264     }
265 
266 
getFlexibility() const267     sal_Int32 UnoGridColumnFacade::getFlexibility() const
268     {
269         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 1 );
270         return lcl_get( m_xGridColumn, &XGridColumn::getFlexibility );
271     }
272 
273 
getWidth() const274     TableMetrics UnoGridColumnFacade::getWidth() const
275     {
276         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 );
277         return lcl_get( m_xGridColumn, &XGridColumn::getColumnWidth );
278     }
279 
280 
setWidth(TableMetrics _nWidth)281     void UnoGridColumnFacade::setWidth( TableMetrics _nWidth )
282     {
283         ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" );
284         lcl_set( m_xGridColumn, &XGridColumn::setColumnWidth, _nWidth );
285     }
286 
287 
getMinWidth() const288     TableMetrics UnoGridColumnFacade::getMinWidth() const
289     {
290         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 );
291         return lcl_get( m_xGridColumn, &XGridColumn::getMinWidth );
292     }
293 
294 
getMaxWidth() const295     TableMetrics UnoGridColumnFacade::getMaxWidth() const
296     {
297         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 );
298         return lcl_get( m_xGridColumn, &XGridColumn::getMaxWidth );
299     }
300 
301 
getHorizontalAlign()302     css::style::HorizontalAlignment UnoGridColumnFacade::getHorizontalAlign()
303     {
304         ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", HorizontalAlignment_LEFT );
305         return lcl_get( m_xGridColumn, &XGridColumn::getHorizontalAlign );
306     }
307 
308 
309 } } // svt::table
310 
311 
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
313