1*2a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2a97ec55SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2a97ec55SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2a97ec55SAndrew Rist  * distributed with this work for additional information
6*2a97ec55SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2a97ec55SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2a97ec55SAndrew Rist  * "License"); you may not use this file except in compliance
9*2a97ec55SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2a97ec55SAndrew Rist  *
11*2a97ec55SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2a97ec55SAndrew Rist  *
13*2a97ec55SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2a97ec55SAndrew Rist  * software distributed under the License is distributed on an
15*2a97ec55SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2a97ec55SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2a97ec55SAndrew Rist  * specific language governing permissions and limitations
18*2a97ec55SAndrew Rist  * under the License.
19*2a97ec55SAndrew Rist  *
20*2a97ec55SAndrew Rist  *************************************************************/
21*2a97ec55SAndrew Rist 
22*2a97ec55SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_extensions.hxx"
26cdf0e10cSrcweir #include "pushbuttonnavigation.hxx"
27cdf0e10cSrcweir #include <com/sun/star/form/FormButtonType.hpp>
28cdf0e10cSrcweir #include <com/sun/star/beans/XPropertyState.hpp>
29cdf0e10cSrcweir #include "formstrings.hxx"
30cdf0e10cSrcweir #include <comphelper/extract.hxx>
31cdf0e10cSrcweir #include <comphelper/property.hxx>
32cdf0e10cSrcweir #include <osl/diagnose.h>
33cdf0e10cSrcweir #include <tools/diagnose_ex.h>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //............................................................................
36cdf0e10cSrcweir namespace pcr
37cdf0e10cSrcweir {
38cdf0e10cSrcweir //............................................................................
39cdf0e10cSrcweir 
40cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
41cdf0e10cSrcweir     using namespace ::com::sun::star::beans;
42cdf0e10cSrcweir     using namespace ::com::sun::star::form;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir     //------------------------------------------------------------------------
45cdf0e10cSrcweir     namespace
46cdf0e10cSrcweir     {
47cdf0e10cSrcweir         static const sal_Int32 s_nFirstVirtualButtonType = 1 + (sal_Int32)FormButtonType_URL;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir         static const sal_Char* pNavigationURLs[] =
50cdf0e10cSrcweir         {
51cdf0e10cSrcweir 	        ".uno:FormController/moveToFirst",
52cdf0e10cSrcweir 	        ".uno:FormController/moveToPrev",
53cdf0e10cSrcweir 	        ".uno:FormController/moveToNext",
54cdf0e10cSrcweir 	        ".uno:FormController/moveToLast",
55cdf0e10cSrcweir 	        ".uno:FormController/saveRecord",
56cdf0e10cSrcweir 	        ".uno:FormController/undoRecord",
57cdf0e10cSrcweir 	        ".uno:FormController/moveToNew",
58cdf0e10cSrcweir 	        ".uno:FormController/deleteRecord",
59cdf0e10cSrcweir 	        ".uno:FormController/refreshForm",
60cdf0e10cSrcweir             NULL
61cdf0e10cSrcweir         };
62cdf0e10cSrcweir 
lcl_getNavigationURLIndex(const::rtl::OUString & _rNavURL)63cdf0e10cSrcweir         static sal_Int32 lcl_getNavigationURLIndex( const ::rtl::OUString& _rNavURL )
64cdf0e10cSrcweir         {
65cdf0e10cSrcweir             const sal_Char** pLookup = pNavigationURLs;
66cdf0e10cSrcweir             while ( *pLookup )
67cdf0e10cSrcweir             {
68cdf0e10cSrcweir                 if ( _rNavURL.equalsAscii( *pLookup ) )
69cdf0e10cSrcweir                     return pLookup - pNavigationURLs;
70cdf0e10cSrcweir                 ++pLookup;
71cdf0e10cSrcweir             }
72cdf0e10cSrcweir             return -1;
73cdf0e10cSrcweir         }
74cdf0e10cSrcweir 
lcl_getNavigationURL(sal_Int32 _nButtonTypeIndex)75cdf0e10cSrcweir         static const sal_Char* lcl_getNavigationURL( sal_Int32 _nButtonTypeIndex )
76cdf0e10cSrcweir         {
77cdf0e10cSrcweir             const sal_Char** pLookup = pNavigationURLs;
78cdf0e10cSrcweir             while ( _nButtonTypeIndex-- && *pLookup++ )
79cdf0e10cSrcweir                 ;
80cdf0e10cSrcweir             OSL_ENSURE( *pLookup, "lcl_getNavigationURL: invalid index!" );
81cdf0e10cSrcweir             return *pLookup;
82cdf0e10cSrcweir         }
83cdf0e10cSrcweir     }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     //========================================================================
86cdf0e10cSrcweir     //= PushButtonNavigation
87cdf0e10cSrcweir     //========================================================================
88cdf0e10cSrcweir     //------------------------------------------------------------------------
PushButtonNavigation(const Reference<XPropertySet> & _rxControlModel)89cdf0e10cSrcweir     PushButtonNavigation::PushButtonNavigation( const Reference< XPropertySet >& _rxControlModel )
90cdf0e10cSrcweir         :m_xControlModel( _rxControlModel )
91cdf0e10cSrcweir         ,m_bIsPushButton( sal_False )
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         OSL_ENSURE( m_xControlModel.is(), "PushButtonNavigation::PushButtonNavigation: invalid control model!" );
94cdf0e10cSrcweir 
95cdf0e10cSrcweir         try
96cdf0e10cSrcweir         {
97cdf0e10cSrcweir 			m_bIsPushButton = ::comphelper::hasProperty( PROPERTY_BUTTONTYPE, m_xControlModel );
98cdf0e10cSrcweir         }
99cdf0e10cSrcweir         catch( const Exception& )
100cdf0e10cSrcweir         {
101cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::PushButtonNavigation: caught an exception!" );
102cdf0e10cSrcweir         }
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     //------------------------------------------------------------------------
implGetCurrentButtonType() const106cdf0e10cSrcweir     sal_Int32 PushButtonNavigation::implGetCurrentButtonType() const SAL_THROW((Exception))
107cdf0e10cSrcweir     {
108cdf0e10cSrcweir         sal_Int32 nButtonType = FormButtonType_PUSH;
109cdf0e10cSrcweir         if ( !m_xControlModel.is() )
110cdf0e10cSrcweir             return nButtonType;
111cdf0e10cSrcweir         OSL_VERIFY( ::cppu::enum2int( nButtonType, m_xControlModel->getPropertyValue( PROPERTY_BUTTONTYPE ) ) );
112cdf0e10cSrcweir 
113cdf0e10cSrcweir         if ( nButtonType == FormButtonType_URL )
114cdf0e10cSrcweir         {
115cdf0e10cSrcweir             // there's a chance that this is a "virtual" button type
116cdf0e10cSrcweir             // (which are realized by special URLs)
117cdf0e10cSrcweir             ::rtl::OUString sTargetURL;
118cdf0e10cSrcweir             m_xControlModel->getPropertyValue( PROPERTY_TARGET_URL ) >>= sTargetURL;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir             sal_Int32 nNavigationURLIndex = lcl_getNavigationURLIndex( sTargetURL );
121cdf0e10cSrcweir             if ( nNavigationURLIndex >= 0)
122cdf0e10cSrcweir                 // it actually *is* a virtual button type
123cdf0e10cSrcweir                 nButtonType = s_nFirstVirtualButtonType + nNavigationURLIndex;
124cdf0e10cSrcweir         }
125cdf0e10cSrcweir         return nButtonType;
126cdf0e10cSrcweir     }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir     //------------------------------------------------------------------------
getCurrentButtonType() const129cdf0e10cSrcweir     Any PushButtonNavigation::getCurrentButtonType() const SAL_THROW(())
130cdf0e10cSrcweir     {
131cdf0e10cSrcweir         OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::getCurrentButtonType: not expected to be called for forms!" );
132cdf0e10cSrcweir         Any aReturn;
133cdf0e10cSrcweir 
134cdf0e10cSrcweir         try
135cdf0e10cSrcweir         {
136cdf0e10cSrcweir             aReturn <<= implGetCurrentButtonType();
137cdf0e10cSrcweir         }
138cdf0e10cSrcweir         catch( const Exception& )
139cdf0e10cSrcweir         {
140cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentButtonType: caught an exception!" );
141cdf0e10cSrcweir         }
142cdf0e10cSrcweir         return aReturn;
143cdf0e10cSrcweir     }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir     //------------------------------------------------------------------------
setCurrentButtonType(const Any & _rValue) const146cdf0e10cSrcweir     void PushButtonNavigation::setCurrentButtonType( const Any& _rValue ) const SAL_THROW(())
147cdf0e10cSrcweir     {
148cdf0e10cSrcweir         OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::setCurrentButtonType: not expected to be called for forms!" );
149cdf0e10cSrcweir         if ( !m_xControlModel.is() )
150cdf0e10cSrcweir             return;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         try
153cdf0e10cSrcweir         {
154cdf0e10cSrcweir             sal_Int32 nButtonType = FormButtonType_PUSH;
155cdf0e10cSrcweir             OSL_VERIFY( ::cppu::enum2int( nButtonType, _rValue ) );
156cdf0e10cSrcweir             ::rtl::OUString sTargetURL;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir             bool bIsVirtualButtonType = nButtonType >= s_nFirstVirtualButtonType;
159cdf0e10cSrcweir             if ( bIsVirtualButtonType )
160cdf0e10cSrcweir             {
161cdf0e10cSrcweir                 const sal_Char* pURL = lcl_getNavigationURL( nButtonType - s_nFirstVirtualButtonType );
162cdf0e10cSrcweir                 sTargetURL = ::rtl::OUString::createFromAscii( pURL );
163cdf0e10cSrcweir 
164cdf0e10cSrcweir                 nButtonType = FormButtonType_URL;
165cdf0e10cSrcweir             }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir             m_xControlModel->setPropertyValue( PROPERTY_BUTTONTYPE, makeAny( static_cast< FormButtonType >( nButtonType ) ) );
168cdf0e10cSrcweir             m_xControlModel->setPropertyValue( PROPERTY_TARGET_URL, makeAny( sTargetURL ) );
169cdf0e10cSrcweir         }
170cdf0e10cSrcweir         catch( const Exception& )
171cdf0e10cSrcweir         {
172cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentButtonType: caught an exception!" );
173cdf0e10cSrcweir         }
174cdf0e10cSrcweir     }
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     //------------------------------------------------------------------------
getCurrentButtonTypeState() const177cdf0e10cSrcweir     PropertyState PushButtonNavigation::getCurrentButtonTypeState( ) const SAL_THROW(())
178cdf0e10cSrcweir     {
179cdf0e10cSrcweir         OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::getCurrentButtonTypeState: not expected to be called for forms!" );
180cdf0e10cSrcweir         PropertyState eState = PropertyState_DIRECT_VALUE;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir         try
183cdf0e10cSrcweir         {
184cdf0e10cSrcweir             Reference< XPropertyState > xStateAccess( m_xControlModel, UNO_QUERY );
185cdf0e10cSrcweir             if ( xStateAccess.is() )
186cdf0e10cSrcweir             {
187cdf0e10cSrcweir                 // let's see what the model says about the ButtonType property
188cdf0e10cSrcweir                 eState = xStateAccess->getPropertyState( PROPERTY_BUTTONTYPE );
189cdf0e10cSrcweir                 if ( eState == PropertyState_DIRECT_VALUE )
190cdf0e10cSrcweir                 {
191cdf0e10cSrcweir                     sal_Int32 nRealButtonType = FormButtonType_PUSH;
192cdf0e10cSrcweir                     OSL_VERIFY( ::cppu::enum2int( nRealButtonType, m_xControlModel->getPropertyValue( PROPERTY_BUTTONTYPE ) ) );
193cdf0e10cSrcweir                     // perhaps it's one of the virtual button types?
194cdf0e10cSrcweir                     if ( FormButtonType_URL == nRealButtonType )
195cdf0e10cSrcweir                     {
196cdf0e10cSrcweir                         // yes, it is -> rely on the state of the URL property
197cdf0e10cSrcweir                         eState = xStateAccess->getPropertyState( PROPERTY_TARGET_URL );
198cdf0e10cSrcweir                     }
199cdf0e10cSrcweir                 }
200cdf0e10cSrcweir             }
201cdf0e10cSrcweir         }
202cdf0e10cSrcweir         catch( const Exception& )
203cdf0e10cSrcweir         {
204cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentButtonTypeState: caught an exception!" );
205cdf0e10cSrcweir         }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         return eState;
208cdf0e10cSrcweir     }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir     //------------------------------------------------------------------------
getCurrentTargetURL() const211cdf0e10cSrcweir     Any PushButtonNavigation::getCurrentTargetURL() const SAL_THROW(())
212cdf0e10cSrcweir     {
213cdf0e10cSrcweir         Any aReturn;
214cdf0e10cSrcweir         if ( !m_xControlModel.is() )
215cdf0e10cSrcweir             return aReturn;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         try
218cdf0e10cSrcweir         {
219cdf0e10cSrcweir             aReturn = m_xControlModel->getPropertyValue( PROPERTY_TARGET_URL );
220cdf0e10cSrcweir             if ( m_bIsPushButton )
221cdf0e10cSrcweir             {
222cdf0e10cSrcweir                 sal_Int32 nCurrentButtonType = implGetCurrentButtonType();
223cdf0e10cSrcweir                 bool bIsVirtualButtonType = nCurrentButtonType >= s_nFirstVirtualButtonType;
224cdf0e10cSrcweir                 if ( bIsVirtualButtonType )
225cdf0e10cSrcweir                 {
226cdf0e10cSrcweir                     // pretend (to the user) that there's no URL set - since
227cdf0e10cSrcweir                     // virtual button types imply a special (technical) URL which
228cdf0e10cSrcweir                     // the user should not see
229cdf0e10cSrcweir                     aReturn <<= ::rtl::OUString();
230cdf0e10cSrcweir                 }
231cdf0e10cSrcweir             }
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir         catch( const Exception& )
234cdf0e10cSrcweir         {
235cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentTargetURL: caught an exception!" );
236cdf0e10cSrcweir         }
237cdf0e10cSrcweir         return aReturn;
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     //------------------------------------------------------------------------
setCurrentTargetURL(const Any & _rValue) const241cdf0e10cSrcweir     void PushButtonNavigation::setCurrentTargetURL( const Any& _rValue ) const SAL_THROW(())
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir         if ( !m_xControlModel.is() )
244cdf0e10cSrcweir             return;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir         try
247cdf0e10cSrcweir         {
248cdf0e10cSrcweir             m_xControlModel->setPropertyValue( PROPERTY_TARGET_URL, _rValue );
249cdf0e10cSrcweir         }
250cdf0e10cSrcweir         catch( const Exception& )
251cdf0e10cSrcweir         {
252cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentTargetURL: caught an exception!" );
253cdf0e10cSrcweir         }
254cdf0e10cSrcweir     }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     //------------------------------------------------------------------------
getCurrentTargetURLState() const257cdf0e10cSrcweir     PropertyState PushButtonNavigation::getCurrentTargetURLState( ) const SAL_THROW(())
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir         PropertyState eState = PropertyState_DIRECT_VALUE;
260cdf0e10cSrcweir 
261cdf0e10cSrcweir         try
262cdf0e10cSrcweir         {
263cdf0e10cSrcweir             Reference< XPropertyState > xStateAccess( m_xControlModel, UNO_QUERY );
264cdf0e10cSrcweir             if ( xStateAccess.is() )
265cdf0e10cSrcweir             {
266cdf0e10cSrcweir                 eState = xStateAccess->getPropertyState( PROPERTY_TARGET_URL );
267cdf0e10cSrcweir             }
268cdf0e10cSrcweir         }
269cdf0e10cSrcweir         catch( const Exception& )
270cdf0e10cSrcweir         {
271cdf0e10cSrcweir             OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentTargetURL: caught an exception!" );
272cdf0e10cSrcweir         }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir         return eState;
275cdf0e10cSrcweir     }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     //------------------------------------------------------------------------
currentButtonTypeIsOpenURL() const278cdf0e10cSrcweir     bool PushButtonNavigation::currentButtonTypeIsOpenURL() const
279cdf0e10cSrcweir     {
280cdf0e10cSrcweir         sal_Int32 nButtonType( FormButtonType_PUSH );
281cdf0e10cSrcweir         try
282cdf0e10cSrcweir         {
283cdf0e10cSrcweir             nButtonType = implGetCurrentButtonType();
284cdf0e10cSrcweir         }
285cdf0e10cSrcweir         catch( const Exception& )
286cdf0e10cSrcweir         {
287cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
288cdf0e10cSrcweir         }
289cdf0e10cSrcweir         return nButtonType == FormButtonType_URL;
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     //------------------------------------------------------------------------
hasNonEmptyCurrentTargetURL() const293cdf0e10cSrcweir     bool PushButtonNavigation::hasNonEmptyCurrentTargetURL() const
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir         ::rtl::OUString sTargetURL;
296cdf0e10cSrcweir         OSL_VERIFY( getCurrentTargetURL() >>= sTargetURL );
297cdf0e10cSrcweir         return sTargetURL.getLength() != 0;
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir //............................................................................
301cdf0e10cSrcweir }   // namespace pcr
302cdf0e10cSrcweir //............................................................................
303