xref: /AOO41X/main/dbaccess/source/ui/browser/exsrcbrw.cxx (revision 24c56ab9f1bd1305754aa2f564704f38ff57627e)
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 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 
27 #ifndef _SBA_EXTCTRLR_HXX
28 #include "exsrcbrw.hxx"
29 #endif
30 #ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_
31 #include <com/sun/star/form/FormComponentType.hpp>
32 #endif
33 #ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
34 #include <com/sun/star/util/XURLTransformer.hpp>
35 #endif
36 #ifndef _COM_SUN_STAR_FORM_XGRIDCOLUMNFACTORY_HPP_
37 #include <com/sun/star/form/XGridColumnFactory.hpp>
38 #endif
39 #ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_
40 #include <com/sun/star/form/XLoadable.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
43 #include <com/sun/star/frame/FrameSearchFlag.hpp>
44 #endif
45 #ifndef _SBA_FORMADAPTER_HXX
46 #include "formadapter.hxx"
47 #endif
48 #ifndef _COMPHELPER_PROCESSFACTORY_HXX_
49 #include <comphelper/processfactory.hxx>
50 #endif
51 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
52 #include "dbustrings.hrc"
53 #endif
54 #ifndef _DBU_REGHELPER_HXX_
55 #include "dbu_reghelper.hxx"
56 #endif
57 #ifndef TOOLS_DIAGNOSE_EX_H
58 #include <tools/diagnose_ex.h>
59 #endif
60 
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::sdb;
63 using namespace ::com::sun::star::sdbc;
64 using namespace ::com::sun::star::sdbcx;
65 using namespace ::com::sun::star::beans;
66 using namespace ::com::sun::star::container;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::form;
69 using namespace ::com::sun::star::frame;
70 using namespace dbaui;
71 
72 //==============================================================================
73 //= SbaExternalSourceBrowser
74 //==============================================================================
createRegistryInfo_OFormGridView()75 extern "C" void SAL_CALL createRegistryInfo_OFormGridView()
76 {
77     static OMultiInstanceAutoRegistration< SbaExternalSourceBrowser > aAutoRegistration;
78 }
79 //------------------------------------------------------------------------------
queryInterface(const Type & _rType)80 Any SAL_CALL SbaExternalSourceBrowser::queryInterface(const Type& _rType) throw (RuntimeException)
81 {
82     Any aRet = SbaXDataBrowserController::queryInterface(_rType);
83     if(!aRet.hasValue())
84         aRet = ::cppu::queryInterface(_rType,
85                                 (::com::sun::star::util::XModifyBroadcaster*)this,
86                                 (::com::sun::star::form::XLoadListener*)this);
87 
88     return aRet;
89 }
DBG_NAME(SbaExternalSourceBrowser)90 DBG_NAME(SbaExternalSourceBrowser)
91 //------------------------------------------------------------------------------
92 SbaExternalSourceBrowser::SbaExternalSourceBrowser(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
93     :SbaXDataBrowserController(_rM)
94     ,m_aModifyListeners(getMutex())
95     ,m_pDataSourceImpl(NULL)
96     ,m_bInQueryDispatch( sal_False )
97 {
98     DBG_CTOR(SbaExternalSourceBrowser,NULL);
99 
100 }
101 
102 //------------------------------------------------------------------------------
~SbaExternalSourceBrowser()103 SbaExternalSourceBrowser::~SbaExternalSourceBrowser()
104 {
105 
106     DBG_DTOR(SbaExternalSourceBrowser,NULL);
107 }
108 
109 //-------------------------------------------------------------------------
getSupportedServiceNames()110 ::comphelper::StringSequence SAL_CALL SbaExternalSourceBrowser::getSupportedServiceNames() throw(RuntimeException)
111 {
112     return getSupportedServiceNames_Static();
113 }
114 // -------------------------------------------------------------------------
getImplementationName_Static()115 ::rtl::OUString SbaExternalSourceBrowser::getImplementationName_Static() throw(RuntimeException)
116 {
117     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.OFormGridView"));
118 }
119 //-------------------------------------------------------------------------
getSupportedServiceNames_Static()120 ::comphelper::StringSequence SbaExternalSourceBrowser::getSupportedServiceNames_Static() throw(RuntimeException)
121 {
122     ::comphelper::StringSequence aSupported(1);
123     aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.FormGridView"));
124     return aSupported;
125 }
126 //-------------------------------------------------------------------------
Create(const Reference<XMultiServiceFactory> & _rxFactory)127 Reference< XInterface > SAL_CALL SbaExternalSourceBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory)
128 {
129     return *(new SbaExternalSourceBrowser(_rxFactory));
130 }
131 //-------------------------------------------------------------------------
getImplementationName()132 ::rtl::OUString SAL_CALL SbaExternalSourceBrowser::getImplementationName() throw(RuntimeException)
133 {
134     return getImplementationName_Static();
135 }
136 //------------------------------------------------------------------------------
CreateForm()137 Reference< XRowSet >  SbaExternalSourceBrowser::CreateForm()
138 {
139     m_pDataSourceImpl = new SbaXFormAdapter();
140     return m_pDataSourceImpl;
141 }
142 
143 //------------------------------------------------------------------------------
InitializeForm(const Reference<XPropertySet> &)144 sal_Bool SbaExternalSourceBrowser::InitializeForm(const Reference< XPropertySet > & /*i_formProperties*/)
145 {
146     return sal_True;
147 }
148 
149 //------------------------------------------------------------------
LoadForm()150 sal_Bool SbaExternalSourceBrowser::LoadForm()
151 {
152     // as we don't have a main form (yet), we have nothing to do
153     // we don't call FormLoaded, because this expects a working data source
154     return sal_True;
155 }
156 
157 
158 //------------------------------------------------------------------
modified(const::com::sun::star::lang::EventObject & aEvent)159 void SbaExternalSourceBrowser::modified(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException )
160 {
161     SbaXDataBrowserController::modified(aEvent);
162 
163     // multiplex this event to all my listeners
164     ::com::sun::star::lang::EventObject aEvt(*this);
165     ::cppu::OInterfaceIteratorHelper aIt(m_aModifyListeners);
166     while (aIt.hasMoreElements())
167         ((::com::sun::star::util::XModifyListener*)aIt.next())->modified(aEvt);
168 }
169 
170 //------------------------------------------------------------------
dispatch(const::com::sun::star::util::URL & aURL,const Sequence<::com::sun::star::beans::PropertyValue> & aArgs)171 void SAL_CALL SbaExternalSourceBrowser::dispatch(const ::com::sun::star::util::URL& aURL, const Sequence< ::com::sun::star::beans::PropertyValue>& aArgs) throw(::com::sun::star::uno::RuntimeException)
172 {
173     const ::com::sun::star::beans::PropertyValue* pArguments = aArgs.getConstArray();
174     if (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AddGridColumn")))
175     {
176         // search the argument describing the column to create
177         ::rtl::OUString sControlType;
178         sal_Int32 nControlPos = -1;
179         Sequence< ::com::sun::star::beans::PropertyValue> aControlProps;
180         sal_uInt16 i;
181         for ( i = 0; i < aArgs.getLength(); ++i, ++pArguments )
182         {
183             if (pArguments->Name.equals(::rtl::OUString::createFromAscii("ColumnType")))
184             {
185                 sal_Bool bCorrectType = pArguments->Value.getValueType().equals(::getCppuType((const ::rtl::OUString*)0));
186                 OSL_ENSURE(bCorrectType, "invalid type for argument \"ColumnType\" !");
187                 if (bCorrectType)
188                     sControlType = ::comphelper::getString(pArguments->Value);
189             }
190             else if (pArguments->Name.equals(::rtl::OUString::createFromAscii("ColumnPosition")))
191             {
192                 sal_Bool bCorrectType = pArguments->Value.getValueType().equals(::getCppuType((const sal_Int16*)0));
193                 OSL_ENSURE(bCorrectType, "invalid type for argument \"ColumnPosition\" !");
194                 if (bCorrectType)
195                     nControlPos = ::comphelper::getINT16(pArguments->Value);
196             }
197             else if (pArguments->Name.equals(::rtl::OUString::createFromAscii("ColumnProperties")))
198             {
199                 sal_Bool bCorrectType = pArguments->Value.getValueType().equals(::getCppuType((const Sequence< ::com::sun::star::beans::PropertyValue>*)0));
200                 OSL_ENSURE(bCorrectType, "invalid type for argument \"ColumnProperties\" !");
201                 if (bCorrectType)
202                     aControlProps = *(Sequence< ::com::sun::star::beans::PropertyValue>*)pArguments->Value.getValue();
203             }
204             else
205                 OSL_ENSURE(sal_False, ((ByteString("SbaExternalSourceBrowser::dispatch(AddGridColumn) : unknown argument (") += ByteString(pArguments->Name.getStr(), gsl_getSystemTextEncoding()).GetBuffer()) += ") !").GetBuffer());
206         }
207         if (!sControlType.getLength())
208         {
209             OSL_ENSURE(sal_False, "SbaExternalSourceBrowser::dispatch(AddGridColumn) : missing argument (ColumnType) !");
210             sControlType = ::rtl::OUString::createFromAscii("TextField");
211         }
212         OSL_ENSURE(aControlProps.getLength(), "SbaExternalSourceBrowser::dispatch(AddGridColumn) : missing argument (ColumnProperties) !");
213 
214         // create the col
215         Reference< ::com::sun::star::form::XGridColumnFactory >  xColFactory(getControlModel(), UNO_QUERY);
216         Reference< ::com::sun::star::beans::XPropertySet >  xNewCol = xColFactory->createColumn(sControlType);
217         Reference< XPropertySetInfo > xNewColProperties;
218         if (xNewCol.is())
219             xNewColProperties = xNewCol->getPropertySetInfo();
220         // set it's properties
221         if (xNewColProperties.is())
222         {
223             const ::com::sun::star::beans::PropertyValue* pControlProps = aControlProps.getConstArray();
224             for (i=0; i<aControlProps.getLength(); ++i, ++pControlProps)
225             {
226                 try
227                 {
228                     if (xNewColProperties->hasPropertyByName(pControlProps->Name))
229                         xNewCol->setPropertyValue(pControlProps->Name, pControlProps->Value);
230                 }
231                 catch(Exception&)
232                 {
233                     OSL_ENSURE(sal_False,
234                         (   ByteString("SbaExternalSourceBrowser::dispatch : could not set a column property (")
235                         +=  ByteString(pControlProps->Name.getStr(), (sal_uInt16)pControlProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US)
236                         +=  ByteString(")!")).GetBuffer());
237                 }
238             }
239         }
240 
241         // correct the position
242         Reference< ::com::sun::star::container::XIndexContainer >  xColContainer(getControlModel(), UNO_QUERY);
243 
244         if (nControlPos > xColContainer->getCount())
245             nControlPos = xColContainer->getCount();
246         if (nControlPos < 0)
247             nControlPos = 0;
248 
249         // append the column
250         xColContainer->insertByIndex(nControlPos, makeAny(xNewCol));
251     }
252     else if (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/ClearView")))
253     {
254         ClearView();
255     }
256     else if (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AttachToForm")))
257     {
258         if (!m_pDataSourceImpl)
259             return;
260 
261         Reference< XRowSet >  xMasterForm;
262         // search the arguments for he master form
263         for (sal_uInt16 i=0; i<aArgs.getLength(); ++i, ++pArguments)
264         {
265             if ((pArguments->Name.equals(::rtl::OUString::createFromAscii("MasterForm"))) && (pArguments->Value.getValueTypeClass() == TypeClass_INTERFACE))
266             {
267                 xMasterForm = Reference< XRowSet > (*(Reference< XInterface > *)pArguments->Value.getValue(), UNO_QUERY);
268                 break;
269             }
270         }
271         if (!xMasterForm.is())
272         {
273             OSL_ENSURE(sal_False, "SbaExternalSourceBrowser::dispatch(FormSlots/AttachToForm) : please specify a form to attach to as argument !");
274             return;
275         }
276 
277         Attach(xMasterForm);
278     }
279     else
280         SbaXDataBrowserController::dispatch(aURL, aArgs);
281 }
282 
283 //------------------------------------------------------------------
queryDispatch(const::com::sun::star::util::URL & aURL,const::rtl::OUString & aTargetFrameName,sal_Int32 nSearchFlags)284 Reference< ::com::sun::star::frame::XDispatch >  SAL_CALL SbaExternalSourceBrowser::queryDispatch(const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException )
285 {
286     Reference< ::com::sun::star::frame::XDispatch >  xReturn;
287     if (m_bInQueryDispatch)
288         return xReturn;
289 
290     m_bInQueryDispatch = sal_True;
291 
292     if  (   (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AttachToForm")))
293             // attach a new external form
294         ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AddGridColumn")))
295             // add a column to the grid
296         ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/ClearView")))
297             // clear the grid
298         )
299         xReturn = (::com::sun::star::frame::XDispatch*)this;
300 
301     if  (   !xReturn.is()
302         &&  (   (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToFirst")))
303             ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToPrev")))
304             ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToNext")))
305             ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToLast")))
306             ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToNew")))
307             ||  (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/undoRecord")))
308             )
309         )
310     {
311         OSL_ENSURE(aURL.Mark.getLength() == 0, "SbaExternalSourceBrowser::queryDispatch : the ::com::sun::star::util::URL shouldn't have a mark !");
312         ::com::sun::star::util::URL aNewUrl = aURL;
313 
314         // split the ::com::sun::star::util::URL
315         OSL_ENSURE( m_xUrlTransformer.is(), "SbaExternalSourceBrowser::queryDispatch : could not create an URLTransformer !" );
316         if ( m_xUrlTransformer.is() )
317             m_xUrlTransformer->parseStrict( aNewUrl );
318 
319         // set a new mark
320         aNewUrl.Mark = ::rtl::OUString::createFromAscii("DB/FormGridView");
321             // this controller is instantiated when somebody dispatches the ".component:DB/FormGridView" in any
322             // frame, so we use "FormGridView" as mark that a dispatch request came from this view
323 
324         if (m_xUrlTransformer.is())
325             m_xUrlTransformer->assemble(aNewUrl);
326 
327         Reference< XDispatchProvider >  xFrameDispatcher( getFrame(), UNO_QUERY );
328         if (xFrameDispatcher.is())
329             xReturn = xFrameDispatcher->queryDispatch(aNewUrl, aTargetFrameName, FrameSearchFlag::PARENT);
330 
331     }
332 
333     if (!xReturn.is())
334         xReturn = SbaXDataBrowserController::queryDispatch(aURL, aTargetFrameName, nSearchFlags);
335 
336     m_bInQueryDispatch = sal_False;
337     return xReturn;
338 }
339 
340 //------------------------------------------------------------------
disposing()341 void SAL_CALL SbaExternalSourceBrowser::disposing()
342 {
343     // say our modify listeners goodbye
344     ::com::sun::star::lang::EventObject aEvt;
345     aEvt.Source = (XWeak*) this;
346     m_aModifyListeners.disposeAndClear(aEvt);
347 
348     stopListening();
349 
350     SbaXDataBrowserController::disposing();
351 }
352 
353 //------------------------------------------------------------------
addModifyListener(const Reference<::com::sun::star::util::XModifyListener> & aListener)354 void SAL_CALL SbaExternalSourceBrowser::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener > & aListener) throw( RuntimeException )
355 {
356     m_aModifyListeners.addInterface(aListener);
357 }
358 
359 //------------------------------------------------------------------
removeModifyListener(const Reference<::com::sun::star::util::XModifyListener> & aListener)360 void SAL_CALL SbaExternalSourceBrowser::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener > & aListener) throw( RuntimeException )
361 {
362     m_aModifyListeners.removeInterface(aListener);
363 }
364 
365 //------------------------------------------------------------------
unloading(const::com::sun::star::lang::EventObject & aEvent)366 void SAL_CALL SbaExternalSourceBrowser::unloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException )
367 {
368     if (m_pDataSourceImpl && (m_pDataSourceImpl->getAttachedForm() == aEvent.Source))
369     {
370         ClearView();
371     }
372 
373     SbaXDataBrowserController::unloading(aEvent);
374 }
375 
376 //------------------------------------------------------------------
Attach(const Reference<XRowSet> & xMaster)377 void SbaExternalSourceBrowser::Attach(const Reference< XRowSet > & xMaster)
378 {
379     Any aOldPos;
380     sal_Bool bWasInsertRow = sal_False;
381     sal_Bool bBeforeFirst   = sal_True;
382     sal_Bool bAfterLast     = sal_True;
383     Reference< XResultSet > xResultSet(xMaster, UNO_QUERY);
384     Reference< XRowLocate > xCursor(xMaster, UNO_QUERY);
385     Reference< XPropertySet > xMasterProps(xMaster, UNO_QUERY);
386 
387     try
388     {
389         // switch the control to design mode
390         if (getBrowserView() && getBrowserView()->getGridControl().is())
391             getBrowserView()->getGridControl()->setDesignMode(sal_True);
392 
393         // the grid will move the form's cursor to the first record, but we want the form to remain unchanged
394         // restore the old position
395         if (xCursor.is() && xResultSet.is())
396         {
397             bBeforeFirst = xResultSet->isBeforeFirst();
398             bAfterLast   = xResultSet->isAfterLast();
399             if(!bBeforeFirst && !bAfterLast)
400                 aOldPos = xCursor->getBookmark();
401         }
402 
403         if (xMasterProps.is())
404             xMasterProps->getPropertyValue(PROPERTY_ISNEW) >>= bWasInsertRow;
405     }
406     catch( const Exception& )
407     {
408         DBG_UNHANDLED_EXCEPTION();
409     }
410 
411     onStartLoading( Reference< XLoadable >( xMaster, UNO_QUERY ) );
412 
413     stopListening();
414     m_pDataSourceImpl->AttachForm(xMaster);
415     startListening();
416 
417     if (xMaster.is())
418     {
419         // at this point we have to reset the formatter for the new form
420         initFormatter();
421         // assume that the master form is already loaded
422 #if OSL_DEBUG_LEVEL > 0
423         {
424             Reference< XLoadable > xLoadable( xMaster, UNO_QUERY );
425             OSL_ENSURE( xLoadable.is() && xLoadable->isLoaded(), "SbaExternalSourceBrowser::Attach: master is not loaded!" );
426         }
427 #endif
428 
429         LoadFinished(sal_True);
430 
431         Reference< XResultSetUpdate >  xUpdate(xMaster, UNO_QUERY);
432         try
433         {
434             if (bWasInsertRow && xUpdate.is())
435                 xUpdate->moveToInsertRow();
436             else if (xCursor.is() && aOldPos.hasValue())
437                 xCursor->moveToBookmark(aOldPos);
438             else if(bBeforeFirst && xResultSet.is())
439                 xResultSet->beforeFirst();
440             else if(bAfterLast && xResultSet.is())
441                 xResultSet->afterLast();
442         }
443         catch(Exception&)
444         {
445             OSL_ENSURE(sal_False, "SbaExternalSourceBrowser::Attach : couldn't restore the cursor position !");
446         }
447 
448     }
449 }
450 
451 //------------------------------------------------------------------
ClearView()452 void SbaExternalSourceBrowser::ClearView()
453 {
454     // set a new (empty) datasource
455     Attach(Reference< XRowSet > ());
456 
457 
458     // clear all cols in the grid
459     Reference< ::com::sun::star::container::XIndexContainer >  xColContainer(getControlModel(), UNO_QUERY);
460     while (xColContainer->getCount() > 0)
461         xColContainer->removeByIndex(0);
462 }
463 
464 //------------------------------------------------------------------
disposing(const::com::sun::star::lang::EventObject & Source)465 void SAL_CALL SbaExternalSourceBrowser::disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException )
466 {
467     if (m_pDataSourceImpl && (m_pDataSourceImpl->getAttachedForm() == Source.Source))
468     {
469         ClearView();
470     }
471 
472     SbaXDataBrowserController::disposing(Source);
473 }
474 
475 //------------------------------------------------------------------
startListening()476 void SbaExternalSourceBrowser::startListening()
477 {
478     if (m_pDataSourceImpl && m_pDataSourceImpl->getAttachedForm().is())
479     {
480         Reference< ::com::sun::star::form::XLoadable >  xLoadable(m_pDataSourceImpl->getAttachedForm(), UNO_QUERY);
481         xLoadable->addLoadListener((::com::sun::star::form::XLoadListener*)this);
482     }
483 }
484 
485 //------------------------------------------------------------------
stopListening()486 void SbaExternalSourceBrowser::stopListening()
487 {
488     if (m_pDataSourceImpl && m_pDataSourceImpl->getAttachedForm().is())
489     {
490         Reference< ::com::sun::star::form::XLoadable >  xLoadable(m_pDataSourceImpl->getAttachedForm(), UNO_QUERY);
491         xLoadable->removeLoadListener((::com::sun::star::form::XLoadListener*)this);
492     }
493 }
494 
495 //==================================================================
496 //==================================================================
497