xref: /trunk/main/extensions/source/dbpilots/controlwizard.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include "controlwizard.hxx"
31 #include <tools/debug.hxx>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
34 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
35 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
36 #include <com/sun/star/container/XChild.hpp>
37 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
38 #include <com/sun/star/frame/XModel.hpp>
39 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
40 #include <com/sun/star/drawing/XDrawView.hpp>
41 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
42 #include <com/sun/star/sdb/CommandType.hpp>
43 #include <com/sun/star/sdbc/SQLWarning.hpp>
44 #include <com/sun/star/sdb/SQLContext.hpp>
45 #include <comphelper/types.hxx>
46 #include <connectivity/dbtools.hxx>
47 #include <vcl/msgbox.hxx>
48 #include <comphelper/interaction.hxx>
49 #include <vcl/stdtext.hxx>
50 #include <svtools/localresaccess.hxx>
51 #include <connectivity/conncleanup.hxx>
52 #include <com/sun/star/sdbc/DataType.hpp>
53 #include <tools/urlobj.hxx>
54 
55 //.........................................................................
56 namespace dbp
57 {
58 //.........................................................................
59 
60     using namespace ::com::sun::star::uno;
61     using namespace ::com::sun::star::awt;
62     using namespace ::com::sun::star::lang;
63     using namespace ::com::sun::star::sdb;
64     using namespace ::com::sun::star::sdbc;
65     using namespace ::com::sun::star::sdbcx;
66     using namespace ::com::sun::star::beans;
67     using namespace ::com::sun::star::container;
68     using namespace ::com::sun::star::drawing;
69     using namespace ::com::sun::star::frame;
70     using namespace ::com::sun::star::sheet;
71     using namespace ::com::sun::star::form;
72     using namespace ::com::sun::star::task;
73     using namespace ::svt;
74     using namespace ::comphelper;
75     using namespace ::dbtools;
76 
77     //=====================================================================
78     //= OAccessRegulator
79     //=====================================================================
80     struct OAccessRegulator
81     {
82         friend class OControlWizardPage;
83 
84     protected:
85         OAccessRegulator() { }
86     };
87 
88     //=====================================================================
89     //= OControlWizardPage
90     //=====================================================================
91     //---------------------------------------------------------------------
92     OControlWizardPage::OControlWizardPage( OControlWizard* _pParent, const ResId& _rResId )
93         :OControlWizardPage_Base( _pParent, _rResId )
94         ,m_pFormSettingsSeparator(NULL)
95         ,m_pFormDatasourceLabel(NULL)
96         ,m_pFormDatasource(NULL)
97         ,m_pFormContentTypeLabel(NULL)
98         ,m_pFormContentType(NULL)
99         ,m_pFormTableLabel(NULL)
100         ,m_pFormTable(NULL)
101     {
102     }
103 
104     //---------------------------------------------------------------------
105     OControlWizardPage::~OControlWizardPage()
106     {
107         delete m_pFormSettingsSeparator;
108         delete m_pFormDatasourceLabel;
109         delete m_pFormDatasource;
110         delete m_pFormContentTypeLabel;
111         delete m_pFormContentType;
112         delete m_pFormTableLabel;
113         delete m_pFormTable;
114     }
115 
116     //---------------------------------------------------------------------
117     OControlWizard* OControlWizardPage::getDialog()
118     {
119         return static_cast< OControlWizard* >(GetParent());
120     }
121 
122     //---------------------------------------------------------------------
123     const OControlWizard* OControlWizardPage::getDialog() const
124     {
125         return static_cast< OControlWizard* >(GetParent());
126     }
127 
128     //---------------------------------------------------------------------
129     sal_Bool OControlWizardPage::updateContext()
130     {
131         return getDialog()->updateContext(OAccessRegulator());
132     }
133 
134     //---------------------------------------------------------------------
135     Reference< XConnection > OControlWizardPage::getFormConnection() const
136     {
137         return getDialog()->getFormConnection(OAccessRegulator());
138     }
139 
140     //---------------------------------------------------------------------
141     void OControlWizardPage::setFormConnection( const Reference< XConnection >& _rxConn, sal_Bool _bAutoDispose )
142     {
143         getDialog()->setFormConnection( OAccessRegulator(), _rxConn, _bAutoDispose );
144     }
145 
146     //---------------------------------------------------------------------
147     const OControlWizardContext& OControlWizardPage::getContext()
148     {
149         return getDialog()->getContext();
150     }
151 
152     //---------------------------------------------------------------------
153     void OControlWizardPage::fillListBox(ListBox& _rList, const Sequence< ::rtl::OUString >& _rItems, sal_Bool _bClear)
154     {
155         if (_bClear)
156             _rList.Clear();
157         const ::rtl::OUString* pItems = _rItems.getConstArray();
158         const ::rtl::OUString* pEnd = pItems + _rItems.getLength();
159         ::svt::WizardTypes::WizardState nPos;
160         sal_Int32 nIndex = 0;
161         for (;pItems < pEnd; ++pItems, ++nIndex)
162         {
163             nPos = _rList.InsertEntry(*pItems);
164             _rList.SetEntryData(nPos, reinterpret_cast<void*>(nIndex));
165         }
166     }
167 
168     //---------------------------------------------------------------------
169     void OControlWizardPage::fillListBox(ComboBox& _rList, const Sequence< ::rtl::OUString >& _rItems, sal_Bool _bClear)
170     {
171         if (_bClear)
172             _rList.Clear();
173         const ::rtl::OUString* pItems = _rItems.getConstArray();
174         const ::rtl::OUString* pEnd = pItems + _rItems.getLength();
175         ::svt::WizardTypes::WizardState nPos;
176         sal_Int32 nIndex = 0;
177         for (;pItems < pEnd; ++pItems)
178         {
179             nPos = _rList.InsertEntry(*pItems);
180             _rList.SetEntryData(nPos, reinterpret_cast<void*>(nIndex));
181         }
182     }
183 
184     //---------------------------------------------------------------------
185     void OControlWizardPage::enableFormDatasourceDisplay()
186     {
187         if (m_pFormSettingsSeparator)
188             // nothing to do
189             return;
190 
191         ModuleRes aModuleRes(RID_PAGE_FORM_DATASOURCE_STATUS);
192         OLocalResourceAccess aLocalControls(aModuleRes, RSC_TABPAGE);
193 
194         m_pFormSettingsSeparator    = new FixedLine(this,  ModuleRes(FL_FORMSETINGS));
195         m_pFormDatasourceLabel      = new FixedText(this,  ModuleRes(FT_FORMDATASOURCELABEL));
196         m_pFormDatasource           = new FixedText(this,  ModuleRes(FT_FORMDATASOURCE));
197         m_pFormContentTypeLabel     = new FixedText(this,  ModuleRes(FT_FORMCONTENTTYPELABEL));
198         m_pFormContentType          = new FixedText(this,  ModuleRes(FT_FORMCONTENTTYPE));
199         m_pFormTableLabel           = new FixedText(this,  ModuleRes(FT_FORMTABLELABEL));
200         m_pFormTable                = new FixedText(this,  ModuleRes(FT_FORMTABLE));
201 
202         const OControlWizardContext& rContext = getContext();
203         if ( rContext.bEmbedded )
204         {
205             m_pFormDatasourceLabel->Hide();
206             m_pFormDatasource->Hide();
207             m_pFormContentTypeLabel->SetPosPixel(m_pFormDatasourceLabel->GetPosPixel());
208             m_pFormContentType->SetPosPixel(m_pFormDatasource->GetPosPixel());
209             m_pFormTableLabel->SetPosPixel(::Point(m_pFormDatasourceLabel->GetPosPixel().X(),m_pFormTableLabel->GetPosPixel().Y()));
210             m_pFormTable->SetPosPixel(::Point(m_pFormDatasource->GetPosPixel().X(),m_pFormTable->GetPosPixel().Y()));
211         }
212     }
213 
214     //---------------------------------------------------------------------
215     void OControlWizardPage::adjustControlForNoDSDisplay(Control* _pControl, sal_Bool _bConstLowerDistance)
216     {
217         ::Size aDistanceToMove = LogicToPixel( ::Size( 0, 37 ), MAP_APPFONT );
218 
219         ::Point aPos = _pControl->GetPosPixel();
220         aPos.Y() -= aDistanceToMove.Height();
221         _pControl->SetPosPixel(aPos);
222 
223         if (_bConstLowerDistance)
224         {
225             ::Size aSize = _pControl->GetSizePixel();
226             aSize.Height() += aDistanceToMove.Height();
227             _pControl->SetSizePixel(aSize);
228         }
229     }
230 
231     //---------------------------------------------------------------------
232     void OControlWizardPage::initializePage()
233     {
234         if (m_pFormDatasource && m_pFormContentTypeLabel && m_pFormTable)
235         {
236             const OControlWizardContext& rContext = getContext();
237             ::rtl::OUString sDataSource;
238             ::rtl::OUString sCommand;
239             sal_Int32 nCommandType = CommandType::COMMAND;
240             try
241             {
242                 rContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("DataSourceName")) >>= sDataSource;
243                 rContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("Command")) >>= sCommand;
244                 rContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("CommandType")) >>= nCommandType;
245             }
246             catch(const Exception&)
247             {
248                 DBG_ERROR("OControlWizardPage::initializePage: caught an exception!");
249             }
250 
251             INetURLObject aURL( sDataSource );
252             if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
253                 sDataSource = aURL.GetName(INetURLObject::DECODE_WITH_CHARSET);
254             m_pFormDatasource->SetText(sDataSource);
255             m_pFormTable->SetText(sCommand);
256 
257             ::svt::WizardTypes::WizardState nCommandTypeResourceId = 0;
258             switch (nCommandType)
259             {
260                 case CommandType::TABLE:
261                     nCommandTypeResourceId = RID_STR_TYPE_TABLE;
262                     break;
263 
264                 case CommandType::QUERY:
265                     nCommandTypeResourceId = RID_STR_TYPE_QUERY;
266                     break;
267 
268                 default:
269                     nCommandTypeResourceId = RID_STR_TYPE_COMMAND;
270                     break;
271             }
272             m_pFormContentType->SetText(String(ModuleRes(nCommandTypeResourceId)));
273         }
274 
275         OControlWizardPage_Base::initializePage();
276     }
277 
278     //=====================================================================
279     //= OControlWizard
280     //=====================================================================
281     //---------------------------------------------------------------------
282     OControlWizard::OControlWizard( Window* _pParent, const ResId& _rId,
283             const Reference< XPropertySet >& _rxObjectModel, const Reference< XMultiServiceFactory >& _rxORB )
284         :OWizardMachine(_pParent, _rId, WZB_CANCEL | WZB_PREVIOUS | WZB_NEXT | WZB_FINISH)
285         ,m_xORB(_rxORB)
286     {
287         m_aContext.xObjectModel = _rxObjectModel;
288         initContext();
289 
290         SetPageSizePixel(LogicToPixel(::Size(WINDOW_SIZE_X, WINDOW_SIZE_Y), MAP_APPFONT));
291         ShowButtonFixedLine(sal_True);
292         defaultButton(WZB_NEXT);
293         enableButtons(WZB_FINISH, sal_False);
294     }
295 
296     //---------------------------------------------------------------------
297     OControlWizard::~OControlWizard()
298     {
299     }
300 
301     //---------------------------------------------------------------------
302     short OControlWizard::Execute()
303     {
304         // get the class id of the control we're dealing with
305         sal_Int16 nClassId = FormComponentType::CONTROL;
306         try
307         {
308             getContext().xObjectModel->getPropertyValue(::rtl::OUString::createFromAscii("ClassId")) >>= nClassId;
309         }
310         catch(Exception&)
311         {
312             DBG_ERROR("OControlWizard::activate: could not obtain the class id!");
313         }
314         if (!approveControl(nClassId))
315         {
316             // TODO: MessageBox or exception
317             return RET_CANCEL;
318         }
319 
320         ActivatePage();
321 
322         return OControlWizard_Base::Execute();
323     }
324 
325     //---------------------------------------------------------------------
326     void OControlWizard::ActivatePage()
327     {
328         OControlWizard_Base::ActivatePage();
329     }
330 
331     //---------------------------------------------------------------------
332     void OControlWizard::implDetermineShape()
333     {
334         Reference< XIndexAccess > xPageObjects(m_aContext.xDrawPage, UNO_QUERY);
335         DBG_ASSERT(xPageObjects.is(), "OControlWizard::implDetermineShape: invalid page!");
336 
337         // for comparing the model
338         Reference< XControlModel > xModelCompare(m_aContext.xObjectModel, UNO_QUERY);
339 
340         if (xPageObjects.is())
341         {
342             // loop through all objects of the page
343             sal_Int32 nObjects = xPageObjects->getCount();
344             Reference< XControlShape > xControlShape;
345             Reference< XControlModel > xControlModel;
346             for (sal_Int32 i=0; i<nObjects; ++i)
347             {
348                 if (xPageObjects->getByIndex(i) >>= xControlShape)
349                 {   // it _is_ a control shape
350                     xControlModel = xControlShape->getControl();
351                     DBG_ASSERT(xControlModel.is(), "OControlWizard::implDetermineShape: control shape without model!");
352                     if (xModelCompare.get() == xControlModel.get())
353                     {
354                         m_aContext.xObjectShape = xControlShape;
355                         break;
356                     }
357                 }
358             }
359         }
360     }
361 
362     //---------------------------------------------------------------------
363     void OControlWizard::implDetermineForm()
364     {
365         Reference< XChild > xModelAsChild(m_aContext.xObjectModel, UNO_QUERY);
366         Reference< XInterface > xControlParent;
367         if (xModelAsChild.is())
368             xControlParent = xModelAsChild->getParent();
369 
370         m_aContext.xForm = Reference< XPropertySet >(xControlParent, UNO_QUERY);
371         m_aContext.xRowSet = Reference< XRowSet >(xControlParent, UNO_QUERY);
372         DBG_ASSERT(m_aContext.xForm.is() && m_aContext.xRowSet.is(),
373             "OControlWizard::implDetermineForm: missing some interfaces of the control parent!");
374 
375     }
376 
377     //---------------------------------------------------------------------
378     void OControlWizard::implDeterminePage()
379     {
380         try
381         {
382             // get the document model
383             Reference< XChild > xControlAsChild(m_aContext.xObjectModel, UNO_QUERY);
384             Reference< XChild > xModelSearch(xControlAsChild->getParent(), UNO_QUERY);
385 
386             Reference< XModel > xModel(xModelSearch, UNO_QUERY);
387             while (xModelSearch.is() && !xModel.is())
388             {
389                 xModelSearch = Reference< XChild >(xModelSearch->getParent(), UNO_QUERY);
390                 xModel = Reference< XModel >(xModelSearch, UNO_QUERY);
391             }
392 
393             Reference< XDrawPage > xPage;
394             if (xModel.is())
395             {
396                 m_aContext.xDocumentModel = xModel;
397 
398                 Reference< XDrawPageSupplier > xPageSupp(xModel, UNO_QUERY);
399                 if (xPageSupp.is())
400                 {   // it's a document with only one page -> Writer
401                     xPage = xPageSupp->getDrawPage();
402                 }
403                 else
404                 {
405                     // get the controller currently working on this model
406                     Reference< XController > xController = xModel->getCurrentController();
407                     DBG_ASSERT(xController.is(), "OControlWizard::implDeterminePage: no current controller!");
408 
409                     // maybe it's a spredsheet
410                     Reference< XSpreadsheetView > xView(xController, UNO_QUERY);
411                     if (xView.is())
412                     {   // okay, it is one
413                         Reference< XSpreadsheet > xSheet = xView->getActiveSheet();
414                         xPageSupp = Reference< XDrawPageSupplier >(xSheet, UNO_QUERY);
415                         DBG_ASSERT(xPageSupp.is(), "OControlWizard::implDeterminePage: a spreadsheet which is no page supplier!");
416                         if (xPageSupp.is())
417                             xPage = xPageSupp->getDrawPage();
418                     }
419                     else
420                     {   // can be a draw/impress doc only
421                         Reference< XDrawView > xDrawView(xController, UNO_QUERY);
422                         DBG_ASSERT(xDrawView.is(), "OControlWizard::implDeterminePage: no alternatives left ... can't determine the page!");
423                         if (xDrawView.is())
424                             xPage = xDrawView->getCurrentPage();
425                     }
426                 }
427             }
428             else
429             {
430                 DBG_ASSERT(xPage.is(), "OControlWizard::implDeterminePage: can't determine the page (no model)!");
431             }
432             m_aContext.xDrawPage = xPage;
433         }
434         catch(Exception&)
435         {
436             DBG_ERROR("OControlWizard::implDeterminePage: caught an exception!");
437         }
438     }
439 
440     //---------------------------------------------------------------------
441     void OControlWizard::implGetDSContext()
442     {
443         Reference< XMultiServiceFactory > xORB = getServiceFactory();
444         try
445         {
446             DBG_ASSERT(xORB.is(), "OControlWizard::implGetDSContext: invalid service factory!");
447 
448             Reference< XInterface > xContext;
449             if (xORB.is())
450                 xContext = xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.sdb.DatabaseContext"));
451             DBG_ASSERT(xContext.is(), "OControlWizard::implGetDSContext: invalid database context!");
452 
453             m_aContext.xDatasourceContext = Reference< XNameAccess >(xContext, UNO_QUERY);
454             DBG_ASSERT(m_aContext.xDatasourceContext.is() || !xContext.is(), "OControlWizard::implGetDSContext: invalid database context (missing the XNameAccess)!");
455         }
456         catch(Exception&)
457         {
458             DBG_ERROR("OControlWizard::implGetDSContext: invalid database context!");
459         }
460     }
461 
462     //---------------------------------------------------------------------
463     Reference< XConnection > OControlWizard::getFormConnection(const OAccessRegulator&) const
464     {
465         return getFormConnection();
466     }
467     //---------------------------------------------------------------------
468     Reference< XConnection > OControlWizard::getFormConnection() const
469     {
470         Reference< XConnection > xConn;
471         try
472         {
473             if ( !::dbtools::isEmbeddedInDatabase(m_aContext.xForm,xConn) )
474                 m_aContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("ActiveConnection")) >>= xConn;
475         }
476         catch(const Exception&)
477         {
478             DBG_ERROR("OControlWizard::getFormConnection: caught an exception!");
479         }
480         return xConn;
481     }
482 
483     //---------------------------------------------------------------------
484     void OControlWizard::setFormConnection( const OAccessRegulator& _rAccess, const Reference< XConnection >& _rxConn, sal_Bool _bAutoDispose )
485     {
486         try
487         {
488             Reference< XConnection > xOldConn = getFormConnection(_rAccess);
489             if (xOldConn.get() == _rxConn.get())
490                 return;
491 
492             disposeComponent(xOldConn);
493 
494             // set the new connection
495             if ( _bAutoDispose )
496             {
497                 // for this, use a AutoDisposer (so the conn is cleaned up when the form dies or get's another connection)
498                 Reference< XRowSet > xFormRowSet( m_aContext.xForm, UNO_QUERY );
499                 OAutoConnectionDisposer* pAutoDispose = new OAutoConnectionDisposer( xFormRowSet, _rxConn );
500                 Reference< XPropertyChangeListener > xEnsureDelete( pAutoDispose );
501             }
502             else
503             {
504                 m_aContext.xForm->setPropertyValue( ::rtl::OUString::createFromAscii("ActiveConnection"), makeAny( _rxConn ) );
505             }
506         }
507         catch(const Exception&)
508         {
509             DBG_ERROR("OControlWizard::setFormConnection: caught an exception!");
510         }
511     }
512 
513     //---------------------------------------------------------------------
514     sal_Bool OControlWizard::updateContext(const OAccessRegulator&)
515     {
516         return initContext();
517     }
518     //---------------------------------------------------------------------
519     Reference< XInteractionHandler > OControlWizard::getInteractionHandler(Window* _pWindow) const
520     {
521         const ::rtl::OUString sInteractionHandlerServiceName = ::rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler");
522         Reference< XInteractionHandler > xHandler;
523         try
524         {
525             if (getServiceFactory().is())
526                 xHandler = Reference< XInteractionHandler >(getServiceFactory()->createInstance(sInteractionHandlerServiceName), UNO_QUERY);
527         }
528         catch(Exception&) { }
529         if (!xHandler.is())
530             ShowServiceNotAvailableError(_pWindow, sInteractionHandlerServiceName, sal_True);
531         return xHandler;
532     }
533     //---------------------------------------------------------------------
534     sal_Bool OControlWizard::initContext()
535     {
536         DBG_ASSERT(m_aContext.xObjectModel.is(), "OGroupBoxWizard::initContext: have no control model to work with!");
537         if (!m_aContext.xObjectModel.is())
538             return sal_False;
539 
540         // reset the context
541         m_aContext.xForm.clear();
542         m_aContext.xRowSet.clear();
543         m_aContext.xDocumentModel.clear();
544         m_aContext.xDrawPage.clear();
545         m_aContext.xObjectShape.clear();
546         m_aContext.aFieldNames.realloc(0);
547 
548         m_aContext.xObjectContainer.clear();
549         m_aContext.aTypes.clear();
550         m_aContext.bEmbedded = sal_False;
551 
552         Any aSQLException;
553         Reference< XPreparedStatement >  xStatement;
554         try
555         {
556             // get the datasource context
557             implGetDSContext();
558 
559             // first, determine the form the control belongs to
560             implDetermineForm();
561 
562             // need the page, too
563             implDeterminePage();
564 
565             // the shape of the control
566             implDetermineShape();
567 
568             // get the columns of the object the settins refer to
569             Reference< XNameAccess >  xColumns;
570 
571             if (m_aContext.xForm.is())
572             {
573                 // collect some properties of the form
574                 ::rtl::OUString sObjectName = ::comphelper::getString(m_aContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("Command")));
575                 sal_Int32 nObjectType = ::comphelper::getINT32(m_aContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("CommandType")));
576 
577                 // calculate the connection the rowset is working with
578                 Reference< XConnection > xConnection;
579                 m_aContext.bEmbedded = ::dbtools::isEmbeddedInDatabase( m_aContext.xForm, xConnection );
580                 if ( !m_aContext.bEmbedded )
581                     xConnection = ::dbtools::connectRowset( m_aContext.xRowSet, getServiceFactory(), sal_True );
582 
583                 // get the fields
584                 if (xConnection.is())
585                 {
586                     switch (nObjectType)
587                     {
588                         case 0:
589                         {
590                             Reference< XTablesSupplier >  xSupplyTables(xConnection, UNO_QUERY);
591                             if (xSupplyTables.is() && xSupplyTables->getTables().is() && xSupplyTables->getTables()->hasByName(sObjectName))
592                             {
593                                 Reference< XColumnsSupplier >  xSupplyColumns;
594                                 m_aContext.xObjectContainer = xSupplyTables->getTables();
595                                 m_aContext.xObjectContainer->getByName(sObjectName) >>= xSupplyColumns;
596                                 DBG_ASSERT(xSupplyColumns.is(), "OControlWizard::initContext: invalid table columns!");
597                                 xColumns = xSupplyColumns->getColumns();
598                             }
599                         }
600                         break;
601                         case 1:
602                         {
603                             Reference< XQueriesSupplier >  xSupplyQueries(xConnection, UNO_QUERY);
604                             if (xSupplyQueries.is() && xSupplyQueries->getQueries().is() && xSupplyQueries->getQueries()->hasByName(sObjectName))
605                             {
606                                 Reference< XColumnsSupplier >  xSupplyColumns;
607                                 m_aContext.xObjectContainer = xSupplyQueries->getQueries();
608                                 m_aContext.xObjectContainer->getByName(sObjectName) >>= xSupplyColumns;
609                                 DBG_ASSERT(xSupplyColumns.is(), "OControlWizard::initContext: invalid query columns!");
610                                 xColumns  = xSupplyColumns->getColumns();
611                             }
612                         }
613                         break;
614                         default:
615                         {
616                             xStatement = xConnection->prepareStatement(sObjectName);
617 
618                             // not interested in any results, only in the fields
619                             Reference< XPropertySet > xStatementProps(xStatement, UNO_QUERY);
620                             xStatementProps->setPropertyValue(::rtl::OUString::createFromAscii("MaxRows"), makeAny(sal_Int32(0)));
621 
622                             // TODO: think about handling local SQLExceptions here ...
623                             Reference< XColumnsSupplier >  xSupplyCols(xStatement->executeQuery(), UNO_QUERY);
624                             if (xSupplyCols.is())
625                                 xColumns = xSupplyCols->getColumns();
626                         }
627                     }
628                 }
629             }
630 
631             if (xColumns.is())
632             {
633                 m_aContext.aFieldNames = xColumns->getElementNames();
634                 static const ::rtl::OUString s_sFieldTypeProperty   = ::rtl::OUString::createFromAscii("Type");
635                 const ::rtl::OUString* pBegin = m_aContext.aFieldNames.getConstArray();
636                 const ::rtl::OUString* pEnd   = pBegin + m_aContext.aFieldNames.getLength();
637                 for(;pBegin != pEnd;++pBegin)
638                 {
639                     sal_Int32 nFieldType = DataType::OTHER;
640                     try
641                     {
642                         Reference< XPropertySet > xColumn;
643                         xColumns->getByName(*pBegin) >>= xColumn;
644                         xColumn->getPropertyValue(s_sFieldTypeProperty) >>= nFieldType;
645                     }
646                     catch(Exception&)
647                     {
648                         DBG_ERROR("OControlWizard::initContext: unexpected exception while gathering column information!");
649                     }
650                     m_aContext.aTypes.insert(OControlWizardContext::TNameTypeMap::value_type(*pBegin,nFieldType));
651                 }
652             }
653         }
654         catch(SQLContext& e) { aSQLException <<= e; }
655         catch(SQLWarning& e) { aSQLException <<= e; }
656         catch(SQLException& e) { aSQLException <<= e; }
657         catch(Exception&)
658         {
659             DBG_ERROR("OControlWizard::initContext: could not retrieve the control context (caught an exception)!");
660         }
661 
662         ::comphelper::disposeComponent(xStatement);
663 
664         if (aSQLException.hasValue())
665         {   // an SQLException (or derivee) was thrown ...
666 
667             // prepend an extra SQLContext explaining what we were doing
668             SQLContext aContext;
669             aContext.Message = String(ModuleRes(RID_STR_COULDNOTOPENTABLE));
670             aContext.NextException = aSQLException;
671 
672             // create an interaction handler to display this exception
673             Reference< XInteractionHandler > xHandler = getInteractionHandler(this);
674             if ( !xHandler.is() )
675                 return sal_False;
676 
677             Reference< XInteractionRequest > xRequest = new OInteractionRequest(makeAny(aContext));
678             try
679             {
680                 xHandler->handle(xRequest);
681             }
682             catch(Exception&) { }
683             return sal_False;
684         }
685 
686         return 0 != m_aContext.aFieldNames.getLength();
687     }
688 
689     //---------------------------------------------------------------------
690     void OControlWizard::commitControlSettings(OControlWizardSettings* _pSettings)
691     {
692         DBG_ASSERT(m_aContext.xObjectModel.is(), "OControlWizard::commitControlSettings: have no control model to work with!");
693         if (!m_aContext.xObjectModel.is())
694             return;
695 
696         // the only thing we have at the moment is the label
697         try
698         {
699             ::rtl::OUString sLabelPropertyName = ::rtl::OUString::createFromAscii("Label");
700             Reference< XPropertySetInfo > xInfo = m_aContext.xObjectModel->getPropertySetInfo();
701             if (xInfo.is() && xInfo->hasPropertyByName(sLabelPropertyName))
702             {
703                 ::rtl::OUString sControlLabel(_pSettings->sControlLabel);
704                 m_aContext.xObjectModel->setPropertyValue(
705                     ::rtl::OUString::createFromAscii("Label"),
706                     makeAny(sControlLabel)
707                 );
708             }
709         }
710         catch(Exception&)
711         {
712             DBG_ERROR("OControlWizard::commitControlSettings: could not commit the basic control settings!");
713         }
714     }
715 
716     //---------------------------------------------------------------------
717     void OControlWizard::initControlSettings(OControlWizardSettings* _pSettings)
718     {
719         DBG_ASSERT(m_aContext.xObjectModel.is(), "OControlWizard::initControlSettings: have no control model to work with!");
720         if (!m_aContext.xObjectModel.is())
721             return;
722 
723         // initialize some settings from the control model give
724         try
725         {
726             ::rtl::OUString sLabelPropertyName = ::rtl::OUString::createFromAscii("Label");
727             Reference< XPropertySetInfo > xInfo = m_aContext.xObjectModel->getPropertySetInfo();
728             if (xInfo.is() && xInfo->hasPropertyByName(sLabelPropertyName))
729             {
730                 ::rtl::OUString sControlLabel;
731                 m_aContext.xObjectModel->getPropertyValue(sLabelPropertyName) >>= sControlLabel;
732                 _pSettings->sControlLabel = sControlLabel;
733             }
734         }
735         catch(Exception&)
736         {
737             DBG_ERROR("OControlWizard::initControlSettings: could not retrieve the basic control settings!");
738         }
739     }
740 
741     //---------------------------------------------------------------------
742     sal_Bool OControlWizard::needDatasourceSelection()
743     {
744         // lemme see ...
745         return (0 == getContext().aFieldNames.getLength());
746             // if we got fields, the data source is valid ...
747 //      try
748 //      {
749 //          // first, we need a valid data source name
750 //          ::rtl::OUString sDataSourceName;
751 //          m_aContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("DataSourceName")) >>= sDataSourceName;
752 //          if (m_aContext.xDatasourceContext.is() && m_aContext.xDatasourceContext->hasByName(sDataSourceName))
753 //          {   // at least the data source name is valid ...
754 //              // then, a CommandType "table" would be nice ...
755 //              sal_Int32 nCommandType = CommandType::COMMAND;
756 //              m_aContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("CommandType")) >>= nCommandType;
757 //              if (CommandType::TABLE == nCommandType)
758 //              {   // okay ....
759 //                  // now the table itself should be valid
760 //                  ::rtl::OUString sTableName;
761 //                  m_aContext.xForm->getPropertyValue(::rtl::OUString::createFromAscii("Command")) >>= sTableName;
762 //                  if (m_aContext.xObjectContainer.is() && m_aContext.xObjectContainer->hasByName(sTableName))
763 //                      return sal_False;
764 //              }
765 //          }
766 //      }
767 //      catch(Exception&)
768 //      {
769 //          DBG_ERROR("OControlWizard::needDatasourceSelection: caught an exception while checking the form settings!");
770 //      }
771 //      return sal_True;
772     }
773 
774 //.........................................................................
775 }   // namespace dbp
776 //.........................................................................
777 
778