1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "UITools.hxx"
21 #include <sfx2/docfilt.hxx>
22 #include "callbacks.hxx"
23 #include "dbustrings.hrc"
24 #include "dbu_resource.hrc"
25 #include "dlgsave.hxx"
26 #include "dbtreelistbox.hxx"
27 #include "defaultobjectnamecheck.hxx"
28 #include <comphelper/extract.hxx>
29 #include <com/sun/star/sdb/DatabaseContext.hpp>
30 #include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
31 #include <com/sun/star/sdb/XCompletedConnection.hpp>
32 #include <com/sun/star/sdbc/XDataSource.hpp>
33 #include <com/sun/star/sdb/SQLContext.hpp>
34 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
35 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
36 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
37 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
38 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
39 #include <com/sun/star/sdbcx/XAppend.hpp>
40 #include <com/sun/star/sdbc/XRow.hpp>
41 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
42 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
43 #include <com/sun/star/sdbc/ColumnValue.hpp>
44 #include <com/sun/star/task/InteractionHandler.hpp>
45 #include <com/sun/star/ucb/XContent.hpp>
46 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
47 #include <com/sun/star/beans/PropertyValue.hpp>
48 #include <com/sun/star/container/XIndexAccess.hpp>
49 #include <com/sun/star/container/XNameContainer.hpp>
50 #include <com/sun/star/ucb/InteractiveIOException.hpp>
51 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
52 #include <com/sun/star/ucb/IOErrorCode.hpp>
53 #include <toolkit/helper/vclunohelper.hxx>
54 #include <toolkit/awt/vclxwindow.hxx>
55 #include <vcl/stdtext.hxx>
56 #include <vcl/settings.hxx>
57 #include <com/sun/star/beans/XPropertySetInfo.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <com/sun/star/container/XNameAccess.hpp>
60 #include <com/sun/star/container/XContainer.hpp>
61 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
62 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
63 #include <com/sun/star/awt/TextAlign.hpp>
64 #include <com/sun/star/awt/FontDescriptor.hpp>
65 #include <com/sun/star/awt/FontWeight.hpp>
66 #include <com/sun/star/awt/FontRelief.hpp>
67 #include <com/sun/star/awt/FontWidth.hpp>
68 #include "TypeInfo.hxx"
69 #include "FieldDescriptions.hxx"
70 #include <comphelper/processfactory.hxx>
71 #include <comphelper/stl_types.hxx>
73 #include <svx/svxids.hrc>
75 #include <svl/itempool.hxx>
76 #include "dbaccess_helpid.hrc"
77 #include <svl/itemset.hxx>
78 #include "sbagrid.hrc"
79 #include <svl/rngitem.hxx>
80 #include <svl/intitem.hxx>
81 #include <svx/algitem.hxx>
82 #include <svx/numinf.hxx>
83 #include <svl/zforlist.hxx>
84 #include "dlgattr.hxx"
85 #include <vcl/msgbox.hxx>
86 #include <com/sun/star/container/XChild.hpp>
87 #include <com/sun/star/util/NumberFormatter.hpp>
88 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
89 #include <com/sun/star/util/XNumberFormatter.hpp>
90 #include "dbu_misc.hrc"
91 #include "sqlmessage.hxx"
92 #include <com/sun/star/util/NumberFormat.hpp>
93 #include <com/sun/star/util/URL.hpp>
94 #include <vcl/toolbox.hxx>
95 #include "dlgsize.hxx"
96 #include <svtools/editbrowsebox.hxx>
97 #include <unotools/configmgr.hxx>
98 #include <svtools/helpopt.hxx>
99 #include <ucbhelper/content.hxx>
100 #include <tools/urlobj.hxx>
101 #include <tools/diagnose_ex.h>
102 #include <svl/numuno.hxx>
103 #include <unotools/pathoptions.hxx>
104 #include <svl/filenotation.hxx>
105 #include <svtools/fileview.hxx>
106 #include <connectivity/FValue.hxx>
108 #include <editeng/justifyitem.hxx>
113 using namespace ::dbtools
;
114 using namespace ::comphelper
;
115 using namespace ::com::sun::star
;
116 using namespace ::com::sun::star::uno
;
117 using namespace ::com::sun::star::task
;
118 using namespace ::com::sun::star::sdbcx
;
119 using namespace ::com::sun::star::sdbc
;
120 using namespace ::com::sun::star::sdb
;
121 using namespace ::com::sun::star::util
;
122 using namespace ::com::sun::star::ucb
;
123 using namespace ::com::sun::star::beans
;
124 using namespace ::com::sun::star::container
;
125 using namespace ::com::sun::star::lang
;
126 using namespace ::com::sun::star::ui::dialogs
;
127 using namespace ::svt
;
128 using ::com::sun::star::ucb::InteractiveIOException
;
129 using ::com::sun::star::ucb::IOErrorCode_NO_FILE
;
130 using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING
;
132 SQLExceptionInfo
createConnection( const OUString
& _rsDataSourceName
,
133 const Reference
< css::container::XNameAccess
>& _xDatabaseContext
,
134 const Reference
< css::uno::XComponentContext
>& _rxContext
,
135 Reference
< css::lang::XEventListener
>& _rEvtLst
,
136 Reference
< css::sdbc::XConnection
>& _rOUTConnection
)
138 Reference
<XPropertySet
> xProp
;
141 xProp
.set(_xDatabaseContext
->getByName(_rsDataSourceName
),UNO_QUERY
);
143 catch(const Exception
&)
146 SQLExceptionInfo aInfo
;
148 return createConnection(xProp
,_rxContext
,_rEvtLst
,_rOUTConnection
);
151 SQLExceptionInfo
createConnection( const Reference
< css::beans::XPropertySet
>& _xDataSource
,
152 const Reference
< css::uno::XComponentContext
>& _rxContext
,
153 Reference
< css::lang::XEventListener
>& _rEvtLst
,
154 Reference
< css::sdbc::XConnection
>& _rOUTConnection
)
156 SQLExceptionInfo aInfo
;
157 if ( !_xDataSource
.is() )
159 SAL_WARN("dbaccess.ui", "createConnection: could not retrieve the data source!");
163 OUString sPwd
, sUser
;
164 bool bPwdReq
= false;
167 _xDataSource
->getPropertyValue(PROPERTY_PASSWORD
) >>= sPwd
;
168 bPwdReq
= ::cppu::any2bool(_xDataSource
->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED
));
169 _xDataSource
->getPropertyValue(PROPERTY_USER
) >>= sUser
;
171 catch(const Exception
&)
173 SAL_WARN("dbaccess.ui", "createConnection: error while retrieving data source properties!");
178 if(bPwdReq
&& sPwd
.isEmpty())
179 { // password required, but empty -> connect using an interaction handler
180 Reference
<XCompletedConnection
> xConnectionCompletion(_xDataSource
, UNO_QUERY
);
181 if (!xConnectionCompletion
.is())
183 SAL_WARN("dbaccess.ui", "createConnection: missing an interface ... need an error message here!");
186 { // instantiate the default SDB interaction handler
187 Reference
< XInteractionHandler
> xHandler( InteractionHandler::createWithParent(_rxContext
, nullptr), UNO_QUERY
);
188 _rOUTConnection
= xConnectionCompletion
->connectWithCompletion(xHandler
);
193 Reference
<XDataSource
> xDataSource(_xDataSource
,UNO_QUERY
);
194 _rOUTConnection
= xDataSource
->getConnection(sUser
, sPwd
);
196 // be notified when connection is in disposing
197 Reference
< XComponent
> xComponent(_rOUTConnection
, UNO_QUERY
);
198 if (xComponent
.is() && _rEvtLst
.is())
199 xComponent
->addEventListener(_rEvtLst
);
201 catch(const SQLContext
& e
) { aInfo
= SQLExceptionInfo(e
); }
202 catch(const SQLWarning
& e
) { aInfo
= SQLExceptionInfo(e
); }
203 catch(const SQLException
& e
) { aInfo
= SQLExceptionInfo(e
); }
204 catch(const Exception
&) { SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnExpandEntry: could not connect - unknown exception!"); }
209 Reference
< XDataSource
> getDataSourceByName( const OUString
& _rDataSourceName
,
210 vcl::Window
* _pErrorMessageParent
, const Reference
< XComponentContext
>& _rxContext
, ::dbtools::SQLExceptionInfo
* _pErrorInfo
)
212 Reference
< XDatabaseContext
> xDatabaseContext
= DatabaseContext::create(_rxContext
);
214 Reference
< XDataSource
> xDatasource
;
216 SQLExceptionInfo aSQLError
;
219 xDatabaseContext
->getByName( _rDataSourceName
) >>= xDatasource
;
221 catch(const WrappedTargetException
& e
)
223 InteractiveIOException aIOException
;
224 if ( ( e
.TargetException
>>= aIOException
)
225 && ( ( aIOException
.Code
== IOErrorCode_NO_FILE
)
226 || ( aIOException
.Code
== IOErrorCode_NOT_EXISTING
)
230 OUString
sErrorMessage( ModuleRes( STR_FILE_DOES_NOT_EXIST
) );
231 OFileNotation
aTransformer( e
.Message
);
232 sErrorMessage
= sErrorMessage
.replaceFirst( "$file$", aTransformer
.get( OFileNotation::N_SYSTEM
) );
233 aSQLError
= SQLExceptionInfo( sErrorMessage
).get();
237 aSQLError
= SQLExceptionInfo( e
.TargetException
);
238 if ( !aSQLError
.isValid() )
239 aError
= e
.TargetException
;
242 catch( const Exception
& )
244 DBG_UNHANDLED_EXCEPTION();
247 if ( xDatasource
.is() )
250 if ( aSQLError
.isValid() )
254 *_pErrorInfo
= aSQLError
;
258 showError( aSQLError
, _pErrorMessageParent
, _rxContext
);
262 return Reference
<XDataSource
>();
265 Reference
< XInterface
> getDataSourceOrModel(const Reference
< XInterface
>& _xObject
)
267 Reference
< XInterface
> xRet
;
268 Reference
<XDocumentDataSource
> xDocumentDataSource(_xObject
,UNO_QUERY
);
269 if ( xDocumentDataSource
.is() )
270 xRet
= xDocumentDataSource
->getDatabaseDocument();
274 Reference
<XOfficeDatabaseDocument
> xOfficeDoc(_xObject
,UNO_QUERY
);
275 if ( xOfficeDoc
.is() )
276 xRet
= xOfficeDoc
->getDataSource();
282 void showError(const SQLExceptionInfo
& _rInfo
, vcl::Window
* _pParent
,const Reference
< XComponentContext
>& _rxContext
)
284 OSL_ENSURE(_pParent
,"showError: Parent window must be NOT NULL!");
285 ::dbtools::showError(_rInfo
,VCLUnoHelper::GetInterface(_pParent
), _rxContext
);
288 TOTypeInfoSP
getTypeInfoFromType(const OTypeInfoMap
& _rTypeInfo
,
290 const OUString
& _sTypeName
,
291 const OUString
& _sCreateParams
,
292 sal_Int32 _nPrecision
,
294 bool _bAutoIncrement
,
295 bool& _brForceToType
)
297 TOTypeInfoSP pTypeInfo
;
298 _brForceToType
= false;
300 ::std::pair
<OTypeInfoMap::const_iterator
, OTypeInfoMap::const_iterator
> aPair
= _rTypeInfo
.equal_range(_nType
);
301 OTypeInfoMap::const_iterator aIter
= aPair
.first
;
302 if(aIter
!= _rTypeInfo
.end()) // compare with end is correct here
304 for(;aIter
!= aPair
.second
;++aIter
)
306 // search the best matching type
308 OUString sDBTypeName
= aIter
->second
->aTypeName
; (void)sDBTypeName
;
309 sal_Int32 nDBTypePrecision
= aIter
->second
->nPrecision
; (void)nDBTypePrecision
;
310 sal_Int32 nDBTypeScale
= aIter
->second
->nMaximumScale
; (void)nDBTypeScale
;
311 bool bDBAutoIncrement
= aIter
->second
->bAutoIncrement
; (void)bDBAutoIncrement
;
315 || (aIter
->second
->aTypeName
.equalsIgnoreAsciiCase(_sTypeName
))
319 !aIter
->second
->aCreateParams
.getLength()
320 && _sCreateParams
.isEmpty()
323 (aIter
->second
->nPrecision
>= _nPrecision
)
324 && (aIter
->second
->nMaximumScale
>= _nScale
)
325 && ( (_bAutoIncrement
&& aIter
->second
->bAutoIncrement
) || !_bAutoIncrement
)
332 if (aIter
== aPair
.second
)
334 for(aIter
= aPair
.first
; aIter
!= aPair
.second
; ++aIter
)
336 sal_Int32 nPrec
= aIter
->second
->nPrecision
;
337 sal_Int32 nScale
= aIter
->second
->nMaximumScale
;
338 // search the best matching type (now comparing the local names)
339 if ( (aIter
->second
->aLocalTypeName
.equalsIgnoreAsciiCase(_sTypeName
))
340 && (nPrec
>= _nPrecision
)
341 && (nScale
>= _nScale
)
342 && ( (_bAutoIncrement
&& aIter
->second
->bAutoIncrement
) || !_bAutoIncrement
)
345 SAL_WARN("dbaccess.ui", "getTypeInfoFromType: assuming column type " <<
346 aIter
->second
->aTypeName
<< "\" (expected type name " <<
347 _sTypeName
<< " matches the type's local name).");
353 if (aIter
== aPair
.second
)
354 { // no match for the names, no match for the local names
355 // -> drop the precision and the scale restriction, accept any type with the property
358 for(aIter
= aPair
.first
; aIter
!= aPair
.second
; ++aIter
)
360 // search the best matching type (now comparing the local names)
361 sal_Int32 nPrec
= aIter
->second
->nPrecision
;
362 sal_Int32 nScale
= aIter
->second
->nMaximumScale
;
363 if ( (nPrec
>= _nPrecision
)
364 && (nScale
>= _nScale
)
365 && ( (_bAutoIncrement
&& aIter
->second
->bAutoIncrement
) || !_bAutoIncrement
)
370 if (aIter
== aPair
.second
)
372 if ( _bAutoIncrement
)
374 for(aIter
= aPair
.first
; aIter
!= aPair
.second
; ++aIter
)
376 // search the best matching type (now comparing the local names)
377 sal_Int32 nScale
= aIter
->second
->nMaximumScale
;
378 if ( (nScale
>= _nScale
)
379 && (aIter
->second
->bAutoIncrement
== _bAutoIncrement
)
383 if ( aIter
== aPair
.second
)
385 // try it without the auto increment flag
386 pTypeInfo
= getTypeInfoFromType(_rTypeInfo
,
396 pTypeInfo
= aIter
->second
;
400 pTypeInfo
= aPair
.first
->second
;
401 _brForceToType
= true;
405 pTypeInfo
= aIter
->second
;
409 ::comphelper::UStringMixEqual
aCase(false);
410 // search for typeinfo where the typename is equal _sTypeName
411 OTypeInfoMap::const_iterator typeInfoLoop
= _rTypeInfo
.begin();
412 OTypeInfoMap::const_iterator typeInfoEnd
= _rTypeInfo
.end();
413 for (; typeInfoLoop
!= typeInfoEnd
; ++typeInfoLoop
)
415 if ( aCase( typeInfoLoop
->second
->getDBName() , _sTypeName
) )
417 pTypeInfo
= typeInfoLoop
->second
;
423 OSL_ENSURE(pTypeInfo
, "getTypeInfoFromType: no type info found for this type!");
427 void fillTypeInfo( const Reference
< css::sdbc::XConnection
>& _rxConnection
,
428 const OUString
& _rsTypeNames
,
429 OTypeInfoMap
& _rTypeInfoMap
,
430 ::std::vector
<OTypeInfoMap::iterator
>& _rTypeInfoIters
)
432 if(!_rxConnection
.is())
434 Reference
< XResultSet
> xRs
= _rxConnection
->getMetaData ()->getTypeInfo ();
435 Reference
< XRow
> xRow(xRs
,UNO_QUERY
);
436 // Information for a single SQL type
439 static const char aB1
[] = " [ ";
440 static const char aB2
[] = " ]";
441 Reference
<XResultSetMetaData
> xResultSetMetaData
= Reference
<XResultSetMetaDataSupplier
>(xRs
,UNO_QUERY
)->getMetaData();
442 ::connectivity::ORowSetValue aValue
;
443 ::std::vector
<sal_Int32
> aTypes
;
444 ::std::vector
<sal_Bool
> aNullable
;
445 // Loop on the result set until we reach end of file
448 TOTypeInfoSP
pInfo(new OTypeInfo());
450 if ( aTypes
.empty() )
452 sal_Int32 nCount
= xResultSetMetaData
->getColumnCount();
455 aTypes
.reserve(nCount
+1);
456 aTypes
.push_back(-1);
457 aNullable
.push_back(false);
458 for (sal_Int32 j
= 1; j
<= nCount
; ++j
)
460 aTypes
.push_back(xResultSetMetaData
->getColumnType(j
));
461 aNullable
.push_back(xResultSetMetaData
->isNullable(j
) != ColumnValue::NO_NULLS
);
465 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
466 pInfo
->aTypeName
= aValue
;
468 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
469 pInfo
->nType
= aValue
;
471 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
472 pInfo
->nPrecision
= aValue
;
474 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
475 pInfo
->aLiteralPrefix
= aValue
;
477 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
478 pInfo
->aLiteralSuffix
= aValue
;
480 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
481 pInfo
->aCreateParams
= aValue
;
483 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
484 pInfo
->bNullable
= (sal_Int32
)aValue
== ColumnValue::NULLABLE
;
486 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
487 pInfo
->bCaseSensitive
= (bool)aValue
;
489 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
490 pInfo
->nSearchType
= aValue
;
492 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
493 pInfo
->bUnsigned
= (bool)aValue
;
495 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
496 pInfo
->bCurrency
= (bool)aValue
;
498 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
499 pInfo
->bAutoIncrement
= (bool)aValue
;
501 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
502 pInfo
->aLocalTypeName
= aValue
;
504 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
505 pInfo
->nMinimumScale
= aValue
;
507 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
508 pInfo
->nMaximumScale
= aValue
;
510 // 16 and 17 are unused
512 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
513 pInfo
->nNumPrecRadix
= aValue
;
515 // check if values are less than zero like it happens in a oracle jdbc driver
516 if( pInfo
->nPrecision
< 0)
517 pInfo
->nPrecision
= 0;
518 if( pInfo
->nMinimumScale
< 0)
519 pInfo
->nMinimumScale
= 0;
520 if( pInfo
->nMaximumScale
< 0)
521 pInfo
->nMaximumScale
= 0;
522 if( pInfo
->nNumPrecRadix
<= 1)
523 pInfo
->nNumPrecRadix
= 10;
529 aName
= _rsTypeNames
.getToken(TYPE_CHAR
, ';');
531 case DataType::VARCHAR
:
532 aName
= _rsTypeNames
.getToken(TYPE_TEXT
, ';');
534 case DataType::DECIMAL
:
535 aName
= _rsTypeNames
.getToken(TYPE_DECIMAL
, ';');
537 case DataType::NUMERIC
:
538 aName
= _rsTypeNames
.getToken(TYPE_NUMERIC
, ';');
540 case DataType::BIGINT
:
541 aName
= _rsTypeNames
.getToken(TYPE_BIGINT
, ';');
543 case DataType::FLOAT
:
544 aName
= _rsTypeNames
.getToken(TYPE_FLOAT
, ';');
546 case DataType::DOUBLE
:
547 aName
= _rsTypeNames
.getToken(TYPE_DOUBLE
, ';');
549 case DataType::LONGVARCHAR
:
550 aName
= _rsTypeNames
.getToken(TYPE_MEMO
, ';');
552 case DataType::LONGVARBINARY
:
553 aName
= _rsTypeNames
.getToken(TYPE_IMAGE
, ';');
556 aName
= _rsTypeNames
.getToken(TYPE_DATE
, ';');
559 aName
= _rsTypeNames
.getToken(TYPE_TIME
, ';');
561 case DataType::TIMESTAMP
:
562 aName
= _rsTypeNames
.getToken(TYPE_DATETIME
, ';');
565 if ( !pInfo
->aCreateParams
.isEmpty() )
567 aName
= _rsTypeNames
.getToken(TYPE_BIT
, ';');
571 case DataType::BOOLEAN
:
572 aName
= _rsTypeNames
.getToken(TYPE_BOOL
, ';');
574 case DataType::TINYINT
:
575 aName
= _rsTypeNames
.getToken(TYPE_TINYINT
, ';');
577 case DataType::SMALLINT
:
578 aName
= _rsTypeNames
.getToken(TYPE_SMALLINT
, ';');
580 case DataType::INTEGER
:
581 aName
= _rsTypeNames
.getToken(TYPE_INTEGER
, ';');
584 aName
= _rsTypeNames
.getToken(TYPE_REAL
, ';');
586 case DataType::BINARY
:
587 aName
= _rsTypeNames
.getToken(TYPE_BINARY
, ';');
589 case DataType::VARBINARY
:
590 aName
= _rsTypeNames
.getToken(TYPE_VARBINARY
, ';');
592 case DataType::SQLNULL
:
593 aName
= _rsTypeNames
.getToken(TYPE_SQLNULL
, ';');
595 case DataType::OBJECT
:
596 aName
= _rsTypeNames
.getToken(TYPE_OBJECT
, ';');
598 case DataType::DISTINCT
:
599 aName
= _rsTypeNames
.getToken(TYPE_DISTINCT
, ';');
601 case DataType::STRUCT
:
602 aName
= _rsTypeNames
.getToken(TYPE_STRUCT
, ';');
604 case DataType::ARRAY
:
605 aName
= _rsTypeNames
.getToken(TYPE_ARRAY
, ';');
608 aName
= _rsTypeNames
.getToken(TYPE_BLOB
, ';');
611 aName
= _rsTypeNames
.getToken(TYPE_CLOB
, ';');
614 aName
= _rsTypeNames
.getToken(TYPE_REF
, ';');
616 case DataType::OTHER
:
617 aName
= _rsTypeNames
.getToken(TYPE_OTHER
, ';');
620 if ( !aName
.isEmpty() )
622 pInfo
->aUIName
= aName
;
623 pInfo
->aUIName
+= aB1
;
625 pInfo
->aUIName
+= pInfo
->aTypeName
;
626 if ( !aName
.isEmpty() )
627 pInfo
->aUIName
+= aB2
;
628 // Now that we have the type info, save it in the multimap
629 _rTypeInfoMap
.insert(OTypeInfoMap::value_type(pInfo
->nType
,pInfo
));
631 // for a faster index access
632 _rTypeInfoIters
.reserve(_rTypeInfoMap
.size());
634 OTypeInfoMap::iterator aIter
= _rTypeInfoMap
.begin();
635 OTypeInfoMap::const_iterator aEnd
= _rTypeInfoMap
.end();
636 for(;aIter
!= aEnd
;++aIter
)
637 _rTypeInfoIters
.push_back(aIter
);
639 // Close the result set/statement.
641 ::comphelper::disposeComponent(xRs
);
645 void setColumnProperties(const Reference
<XPropertySet
>& _rxColumn
,const OFieldDescription
* _pFieldDesc
)
647 _rxColumn
->setPropertyValue(PROPERTY_NAME
,makeAny(_pFieldDesc
->GetName()));
648 _rxColumn
->setPropertyValue(PROPERTY_TYPENAME
,makeAny(_pFieldDesc
->getTypeInfo()->aTypeName
));
649 _rxColumn
->setPropertyValue(PROPERTY_TYPE
,makeAny(_pFieldDesc
->GetType()));
650 _rxColumn
->setPropertyValue(PROPERTY_PRECISION
,makeAny(_pFieldDesc
->GetPrecision()));
651 _rxColumn
->setPropertyValue(PROPERTY_SCALE
,makeAny(_pFieldDesc
->GetScale()));
652 _rxColumn
->setPropertyValue(PROPERTY_ISNULLABLE
, makeAny(_pFieldDesc
->GetIsNullable()));
653 _rxColumn
->setPropertyValue(PROPERTY_ISAUTOINCREMENT
, css::uno::makeAny(_pFieldDesc
->IsAutoIncrement()));
654 _rxColumn
->setPropertyValue(PROPERTY_DESCRIPTION
,makeAny(_pFieldDesc
->GetDescription()));
655 if ( _rxColumn
->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISCURRENCY
) && _pFieldDesc
->IsCurrency() )
656 _rxColumn
->setPropertyValue(PROPERTY_ISCURRENCY
, css::uno::makeAny(_pFieldDesc
->IsCurrency()));
657 // set autoincrement value when available
658 // and only set when the entry is not empty, that lets the value in the column untouched
659 if ( _pFieldDesc
->IsAutoIncrement() && !_pFieldDesc
->GetAutoIncrementValue().isEmpty() && _rxColumn
->getPropertySetInfo()->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION
) )
660 _rxColumn
->setPropertyValue(PROPERTY_AUTOINCREMENTCREATION
,makeAny(_pFieldDesc
->GetAutoIncrementValue()));
663 OUString
createDefaultName(const Reference
< XDatabaseMetaData
>& _xMetaData
,const Reference
<XNameAccess
>& _xTables
,const OUString
& _sName
)
665 OSL_ENSURE(_xMetaData
.is(),"No MetaData!");
666 OUString sDefaultName
= _sName
;
669 OUString sCatalog
,sSchema
,sCompsedName
;
670 if(_xMetaData
->supportsCatalogsInTableDefinitions())
674 Reference
< XConnection
> xCon
= _xMetaData
->getConnection();
676 sCatalog
= xCon
->getCatalog();
677 if ( sCatalog
.isEmpty() )
679 Reference
<XResultSet
> xRes
= _xMetaData
->getCatalogs();
680 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
681 while(xRes
.is() && xRes
->next())
683 sCatalog
= xRow
->getString(1);
689 catch(const SQLException
&)
693 if(_xMetaData
->supportsSchemasInTableDefinitions())
695 sSchema
= _xMetaData
->getUserName();
697 sCompsedName
= ::dbtools::composeTableName( _xMetaData
, sCatalog
, sSchema
, _sName
, false, ::dbtools::EComposeRule::InDataManipulation
);
698 sDefaultName
= ::dbtools::createUniqueName(_xTables
,sCompsedName
);
700 catch(const SQLException
&)
706 bool checkDataSourceAvailable(const OUString
& _sDataSourceName
,const Reference
< css::uno::XComponentContext
>& _xContext
)
708 Reference
< XDatabaseContext
> xDataBaseContext
= DatabaseContext::create(_xContext
);
709 bool bRet
= xDataBaseContext
->hasByName(_sDataSourceName
);
711 { // try if this one is a URL
714 bRet
= xDataBaseContext
->getByName(_sDataSourceName
).hasValue();
716 catch(const Exception
&)
723 sal_Int32
mapTextAllign(const SvxCellHorJustify
& _eAlignment
)
725 sal_Int32 nAlignment
= css::awt::TextAlign::LEFT
;
728 case SVX_HOR_JUSTIFY_STANDARD
:
729 case SVX_HOR_JUSTIFY_LEFT
: nAlignment
= css::awt::TextAlign::LEFT
; break;
730 case SVX_HOR_JUSTIFY_CENTER
: nAlignment
= css::awt::TextAlign::CENTER
; break;
731 case SVX_HOR_JUSTIFY_RIGHT
: nAlignment
= css::awt::TextAlign::RIGHT
; break;
733 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
738 SvxCellHorJustify
mapTextJustify(sal_Int32 _nAlignment
)
740 SvxCellHorJustify eJustify
= SVX_HOR_JUSTIFY_LEFT
;
743 case css::awt::TextAlign::LEFT
: eJustify
= SVX_HOR_JUSTIFY_LEFT
; break;
744 case css::awt::TextAlign::CENTER
: eJustify
= SVX_HOR_JUSTIFY_CENTER
; break;
745 case css::awt::TextAlign::RIGHT
: eJustify
= SVX_HOR_JUSTIFY_RIGHT
; break;
747 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
752 void callColumnFormatDialog(const Reference
<XPropertySet
>& xAffectedCol
,
753 const Reference
<XPropertySet
>& xField
,
754 SvNumberFormatter
* _pFormatter
,
755 vcl::Window
* _pParent
)
757 if (xAffectedCol
.is() && xField
.is())
761 Reference
< XPropertySetInfo
> xInfo
= xAffectedCol
->getPropertySetInfo();
762 bool bHasFormat
= xInfo
->hasPropertyByName(PROPERTY_FORMATKEY
);
763 sal_Int32 nDataType
= ::comphelper::getINT32(xField
->getPropertyValue(PROPERTY_TYPE
));
765 SvxCellHorJustify
eJustify(SVX_HOR_JUSTIFY_STANDARD
);
766 Any aAlignment
= xAffectedCol
->getPropertyValue(PROPERTY_ALIGN
);
767 if (aAlignment
.hasValue())
768 eJustify
= dbaui::mapTextJustify(::comphelper::getINT16(aAlignment
));
769 sal_Int32 nFormatKey
= 0;
771 nFormatKey
= ::comphelper::getINT32(xAffectedCol
->getPropertyValue(PROPERTY_FORMATKEY
));
773 if(callColumnFormatDialog(_pParent
,_pFormatter
,nDataType
,nFormatKey
,eJustify
,bHasFormat
))
775 xAffectedCol
->setPropertyValue(PROPERTY_ALIGN
, makeAny((sal_Int16
)dbaui::mapTextAllign(eJustify
)));
777 xAffectedCol
->setPropertyValue(PROPERTY_FORMATKEY
, makeAny(nFormatKey
));
781 catch( const Exception
& )
783 DBG_UNHANDLED_EXCEPTION();
788 bool callColumnFormatDialog(vcl::Window
* _pParent
,
789 SvNumberFormatter
* _pFormatter
,
790 sal_Int32 _nDataType
,
791 sal_Int32
& _nFormatKey
,
792 SvxCellHorJustify
& _eJustify
,
798 static SfxItemInfo aItemInfos
[] =
801 { SID_ATTR_NUMBERFORMAT_VALUE
, true },
802 { SID_ATTR_ALIGN_HOR_JUSTIFY
, true },
803 { SID_ATTR_NUMBERFORMAT_ONE_AREA
, true },
804 { SID_ATTR_NUMBERFORMAT_INFO
, true }
806 static const sal_uInt16 aAttrMap
[] =
808 SBA_DEF_RANGEFORMAT
, SBA_ATTR_ALIGN_HOR_JUSTIFY
,
809 SID_ATTR_NUMBERFORMAT_ONE_AREA
, SID_ATTR_NUMBERFORMAT_ONE_AREA
,
810 SID_ATTR_NUMBERFORMAT_INFO
, SID_ATTR_NUMBERFORMAT_INFO
,
814 SfxPoolItem
* pDefaults
[] =
816 new SfxRangeItem(SBA_DEF_RANGEFORMAT
, SBA_DEF_FMTVALUE
, SBA_ATTR_ALIGN_HOR_JUSTIFY
),
817 new SfxUInt32Item(SBA_DEF_FMTVALUE
),
818 new SvxHorJustifyItem(SVX_HOR_JUSTIFY_STANDARD
, SBA_ATTR_ALIGN_HOR_JUSTIFY
),
819 new SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA
, false),
820 new SvxNumberInfoItem(SID_ATTR_NUMBERFORMAT_INFO
)
823 SfxItemPool
* pPool
= new SfxItemPool(OUString("GridBrowserProperties"), SBA_DEF_RANGEFORMAT
, SBA_ATTR_ALIGN_HOR_JUSTIFY
, aItemInfos
, pDefaults
);
824 pPool
->SetDefaultMetric( SFX_MAPUNIT_TWIP
); // ripped, don't understand why
825 pPool
->FreezeIdRanges(); // the same
827 std::unique_ptr
<SfxItemSet
> pFormatDescriptor(new SfxItemSet(*pPool
, aAttrMap
));
829 pFormatDescriptor
->Put(SvxHorJustifyItem(_eJustify
, SBA_ATTR_ALIGN_HOR_JUSTIFY
));
833 // if the col is bound to a text field we have to disallow all non-text formats
834 if ((DataType::CHAR
== _nDataType
) || (DataType::VARCHAR
== _nDataType
) || (DataType::LONGVARCHAR
== _nDataType
) || (DataType::CLOB
== _nDataType
))
837 pFormatDescriptor
->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA
, true));
838 if (!_pFormatter
->IsTextFormat(_nFormatKey
))
839 // text fields can only have text formats
840 _nFormatKey
= _pFormatter
->GetStandardFormat(css::util::NumberFormat::TEXT
,_pParent
->GetSettings().GetLanguageTag().getLanguageType());
843 pFormatDescriptor
->Put(SfxUInt32Item(SBA_DEF_FMTVALUE
, _nFormatKey
));
848 double dPreviewVal
= 1234.56789;
849 SvxNumberInfoItem
aFormatter(_pFormatter
, dPreviewVal
, SID_ATTR_NUMBERFORMAT_INFO
);
850 pFormatDescriptor
->Put(aFormatter
);
853 { // want the dialog to be destroyed before our set
854 ScopedVclPtrInstance
< SbaSbAttrDlg
> aDlg(_pParent
, pFormatDescriptor
.get(), _pFormatter
, _bHasFormat
);
855 if (RET_OK
== aDlg
->Execute())
859 const SfxItemSet
* pSet
= aDlg
->GetExampleSet();
860 // (of course we could put the modified items directly into the column, but then the UNO-model
861 // won't reflect these changes, and why do we have a model, then ?)
863 // horizontal justify
864 const SvxHorJustifyItem
* pHorJustify
= pSet
->GetItem
<SvxHorJustifyItem
>(SBA_ATTR_ALIGN_HOR_JUSTIFY
);
866 _eJustify
= (SvxCellHorJustify
)pHorJustify
->GetValue();
871 const SfxUInt32Item
* pFormat
= pSet
->GetItem
<SfxUInt32Item
>(SBA_DEF_FMTVALUE
);
872 _nFormatKey
= (sal_Int32
)pFormat
->GetValue();
877 const SfxItemSet
* pResult
= aDlg
->GetOutputItemSet();
880 const SfxPoolItem
* pItem
= pResult
->GetItem( SID_ATTR_NUMBERFORMAT_INFO
);
881 const SvxNumberInfoItem
* pInfoItem
= static_cast<const SvxNumberInfoItem
*>(pItem
);
882 if (pInfoItem
&& pInfoItem
->GetDelCount())
884 const sal_uInt32
* pDeletedKeys
= pInfoItem
->GetDelArray();
886 for (sal_uInt32 i
=0; i
< pInfoItem
->GetDelCount(); ++i
, ++pDeletedKeys
)
887 _pFormatter
->DeleteEntry(*pDeletedKeys
);
892 pFormatDescriptor
.reset();
893 SfxItemPool::Free(pPool
);
894 for (SfxPoolItem
* pDefault
: pDefaults
)
900 std::shared_ptr
<const SfxFilter
> getStandardDatabaseFilter()
902 std::shared_ptr
<const SfxFilter
> pFilter
= SfxFilter::GetFilterByName("StarOffice XML (Base)");
903 OSL_ENSURE(pFilter
,"Filter: StarOffice XML (Base) could not be found!");
907 bool appendToFilter(const Reference
<XConnection
>& _xConnection
,
908 const OUString
& _sName
,
909 const Reference
< XComponentContext
>& _rxContext
,
910 vcl::Window
* _pParent
)
913 Reference
< XChild
> xChild(_xConnection
,UNO_QUERY
);
916 Reference
< XPropertySet
> xProp(xChild
->getParent(),UNO_QUERY
);
919 Sequence
< OUString
> aFilter
;
920 xProp
->getPropertyValue(PROPERTY_TABLEFILTER
) >>= aFilter
;
921 // first check if we have something like SCHEMA.%
922 bool bHasToInsert
= true;
923 const OUString
* pBegin
= aFilter
.getConstArray();
924 const OUString
* pEnd
= pBegin
+ aFilter
.getLength();
925 for (;pBegin
!= pEnd
; ++pBegin
)
927 if(pBegin
->indexOf('%') != -1)
930 if((nLen
= pBegin
->lastIndexOf('.')) != -1 && !pBegin
->compareTo(_sName
,nLen
))
931 bHasToInsert
= false;
932 else if(pBegin
->getLength() == 1)
933 bHasToInsert
= false;
940 if(! ::dbaui::checkDataSourceAvailable(::comphelper::getString(xProp
->getPropertyValue(PROPERTY_NAME
)),_rxContext
))
942 OUString
aMessage(ModuleRes(STR_TABLEDESIGN_DATASOURCE_DELETED
));
943 ScopedVclPtrInstance
<OSQLWarningBox
>(_pParent
, aMessage
)->Execute();
948 aFilter
.realloc(aFilter
.getLength()+1);
949 aFilter
.getArray()[aFilter
.getLength()-1] = _sName
;
950 xProp
->setPropertyValue(PROPERTY_TABLEFILTER
,makeAny(aFilter
));
958 void notifySystemWindow(vcl::Window
* _pWindow
, vcl::Window
* _pToRegister
, const ::comphelper::mem_fun1_t
<TaskPaneList
,vcl::Window
*>& _rMemFunc
)
960 OSL_ENSURE(_pWindow
,"Window can not be null!");
961 SystemWindow
* pSystemWindow
= _pWindow
? _pWindow
->GetSystemWindow() : nullptr;
964 _rMemFunc( pSystemWindow
->GetTaskPaneList(), _pToRegister
);
968 void adjustToolBoxSize(ToolBox
* _pToolBox
)
970 // adjust the toolbox size, otherwise large bitmaps don't fit into
971 Size aOldSize
= _pToolBox
->GetSizePixel();
972 Size aSize
= _pToolBox
->CalcWindowSizePixel();
973 if ( !aSize
.Width() )
974 aSize
.Width() = aOldSize
.Width();
975 else if ( !aSize
.Height() )
976 aSize
.Height() = aOldSize
.Height();
978 Size aTbSize
= _pToolBox
->GetSizePixel();
979 if ( (aSize
.Width() && aSize
.Width() != aTbSize
.Width()) ||
980 (aSize
.Height() && aSize
.Height() != aTbSize
.Height()) )
982 _pToolBox
->SetPosSizePixel( _pToolBox
->GetPosPixel(), aSize
);
983 _pToolBox
->Invalidate();
987 void adjustBrowseBoxColumnWidth( ::svt::EditBrowseBox
* _pBox
, sal_uInt16 _nColId
)
989 sal_Int32 nColSize
= -1;
990 sal_uInt32 nDefaultWidth
= _pBox
->GetDefaultColumnWidth( _pBox
->GetColumnTitle( _nColId
) );
991 if ( nDefaultWidth
!= _pBox
->GetColumnWidth( _nColId
) )
993 Size aSizeMM
= _pBox
->PixelToLogic( Size( _pBox
->GetColumnWidth( _nColId
), 0 ), MapMode( MAP_MM
) );
994 nColSize
= aSizeMM
.Width() * 10;
997 Size aDefaultMM
= _pBox
->PixelToLogic( Size( nDefaultWidth
, 0 ), MapMode( MAP_MM
) );
999 ScopedVclPtrInstance
< DlgSize
> aColumnSizeDlg( _pBox
, nColSize
, false, aDefaultMM
.Width() * 10 );
1000 if ( aColumnSizeDlg
->Execute() )
1002 sal_Int32 nValue
= aColumnSizeDlg
->GetValue();
1005 nValue
= _pBox
->GetDefaultColumnWidth( _pBox
->GetColumnTitle( _nColId
) );
1009 Size
aSizeMM( nValue
/ 10, 0 );
1010 nValue
= _pBox
->LogicToPixel( aSizeMM
, MapMode( MAP_MM
) ).Width();
1012 _pBox
->SetColumnWidth( _nColId
, nValue
);
1016 // check if SQL92 name checking is enabled
1017 bool isSQL92CheckEnabled(const Reference
<XConnection
>& _xConnection
)
1019 return ::dbtools::getBooleanDataSourceSetting( _xConnection
, PROPERTY_ENABLESQL92CHECK
);
1022 bool isAppendTableAliasEnabled(const Reference
<XConnection
>& _xConnection
)
1024 return ::dbtools::getBooleanDataSourceSetting( _xConnection
, INFO_APPEND_TABLE_ALIAS
);
1027 bool generateAsBeforeTableAlias(const Reference
<XConnection
>& _xConnection
)
1029 return ::dbtools::getBooleanDataSourceSetting( _xConnection
, INFO_AS_BEFORE_CORRELATION_NAME
);
1032 void fillAutoIncrementValue(const Reference
<XPropertySet
>& _xDatasource
,
1033 bool& _rAutoIncrementValueEnabled
,
1034 OUString
& _rsAutoIncrementValue
)
1036 if ( _xDatasource
.is() )
1038 OSL_ENSURE(_xDatasource
->getPropertySetInfo()->hasPropertyByName(PROPERTY_INFO
),"NO datasource supplied!");
1039 Sequence
<PropertyValue
> aInfo
;
1040 _xDatasource
->getPropertyValue(PROPERTY_INFO
) >>= aInfo
;
1042 // search the right propertyvalue
1043 const PropertyValue
* pValue
=::std::find_if(aInfo
.getConstArray(),
1044 aInfo
.getConstArray() + aInfo
.getLength(),
1045 ::std::bind2nd(TPropertyValueEqualFunctor(),PROPERTY_AUTOINCREMENTCREATION
));
1046 if ( pValue
&& pValue
!= (aInfo
.getConstArray() + aInfo
.getLength()) )
1047 pValue
->Value
>>= _rsAutoIncrementValue
;
1048 pValue
=::std::find_if(aInfo
.getConstArray(),
1049 aInfo
.getConstArray() + aInfo
.getLength(),
1050 ::std::bind2nd(TPropertyValueEqualFunctor(),OUString("IsAutoRetrievingEnabled") ));
1051 if ( pValue
&& pValue
!= (aInfo
.getConstArray() + aInfo
.getLength()) )
1052 pValue
->Value
>>= _rAutoIncrementValueEnabled
;
1056 void fillAutoIncrementValue(const Reference
<XConnection
>& _xConnection
,
1057 bool& _rAutoIncrementValueEnabled
,
1058 OUString
& _rsAutoIncrementValue
)
1060 Reference
< XChild
> xChild(_xConnection
,UNO_QUERY
);
1063 Reference
< XPropertySet
> xProp(xChild
->getParent(),UNO_QUERY
);
1064 fillAutoIncrementValue(xProp
,_rAutoIncrementValueEnabled
,_rsAutoIncrementValue
);
1068 OUString
getStrippedDatabaseName(const Reference
<XPropertySet
>& _xDataSource
,OUString
& _rsDatabaseName
)
1070 if ( _rsDatabaseName
.isEmpty() && _xDataSource
.is() )
1074 _xDataSource
->getPropertyValue(PROPERTY_NAME
) >>= _rsDatabaseName
;
1076 catch(const Exception
& )
1078 DBG_UNHANDLED_EXCEPTION();
1081 OUString sName
= _rsDatabaseName
;
1082 INetURLObject
aURL(sName
);
1083 if ( aURL
.GetProtocol() != INetProtocol::NotValid
)
1084 sName
= aURL
.getBase(INetURLObject::LAST_SEGMENT
,true,INetURLObject::DECODE_UNAMBIGUOUS
);
1088 void AppendConfigToken( OUString
& _rURL
, bool _bQuestionMark
)
1090 // query part exists?
1091 if ( _bQuestionMark
)
1092 // no, so start with '?'
1095 // yes, so only append with '&'
1099 _rURL
+= "Language=";
1100 _rURL
+= utl::ConfigManager::getLocale();
1101 _rURL
+= "&System=";
1102 _rURL
+= SvtHelpOptions().GetSystem();
1108 bool GetHelpAnchor_Impl( const OUString
& _rURL
, OUString
& _rAnchor
)
1115 ::ucbhelper::Content
aCnt( INetURLObject( _rURL
).GetMainURL( INetURLObject::NO_DECODE
),
1116 Reference
< css::ucb::XCommandEnvironment
>(),
1117 comphelper::getProcessComponentContext() );
1118 if ( ( aCnt
.getPropertyValue("AnchorName") >>= sAnchor
) )
1121 if ( !sAnchor
.isEmpty() )
1129 SAL_WARN( "dbaccess.ui", "Property 'AnchorName' is missing" );
1140 css::util::URL
createHelpAgentURL(const OUString
& _sModuleName
, const OString
& sHelpId
)
1142 css::util::URL aURL
;
1143 aURL
.Complete
= "vnd.sun.star.help://" +
1144 _sModuleName
+ "/" + OStringToOUString(sHelpId
, RTL_TEXTENCODING_UTF8
);
1147 OUString sTempURL
= aURL
.Complete
;
1148 AppendConfigToken( sTempURL
, true );
1149 bool bHasAnchor
= GetHelpAnchor_Impl( sTempURL
, sAnchor
);
1150 AppendConfigToken(aURL
.Complete
,true);
1153 aURL
.Complete
+= "#";
1154 aURL
.Complete
+= sAnchor
;
1159 void setEvalDateFormatForFormatter(Reference
< css::util::XNumberFormatter
>& _rxFormatter
)
1161 OSL_ENSURE( _rxFormatter
.is(),"setEvalDateFormatForFormatter: Formatter is NULL!");
1162 if ( _rxFormatter
.is() )
1164 Reference
< css::util::XNumberFormatsSupplier
> xSupplier
= _rxFormatter
->getNumberFormatsSupplier();
1166 Reference
< XUnoTunnel
> xTunnel(xSupplier
,UNO_QUERY
);
1167 SvNumberFormatsSupplierObj
* pSupplierImpl
= reinterpret_cast<SvNumberFormatsSupplierObj
*>(xTunnel
->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1168 OSL_ENSURE(pSupplierImpl
,"No Supplier!");
1170 if ( pSupplierImpl
)
1172 SvNumberFormatter
* pFormatter
= pSupplierImpl
->GetNumberFormatter();
1173 pFormatter
->SetEvalDateFormat(NF_EVALDATEFORMAT_FORMAT
);
1178 TOTypeInfoSP
queryPrimaryKeyType(const OTypeInfoMap
& _rTypeInfo
)
1180 TOTypeInfoSP pTypeInfo
;
1181 // first we search for a type which supports autoIncrement
1182 OTypeInfoMap::const_iterator aIter
= _rTypeInfo
.begin();
1183 OTypeInfoMap::const_iterator aEnd
= _rTypeInfo
.end();
1184 for(;aIter
!= aEnd
;++aIter
)
1186 // OJ: we don't want to set an autoincrement column to be key
1187 // because we don't have the possibility to know how to create
1188 // such auto increment column later on
1189 // so until we know how to do it, we create a column without autoincrement
1190 // if ( !aIter->second->bAutoIncrement )
1191 { // therefore we have searched
1192 if ( aIter
->second
->nType
== DataType::INTEGER
)
1194 pTypeInfo
= aIter
->second
; // alternative
1197 else if ( !pTypeInfo
.get() && aIter
->second
->nType
== DataType::DOUBLE
)
1198 pTypeInfo
= aIter
->second
; // alternative
1199 else if ( !pTypeInfo
.get() && aIter
->second
->nType
== DataType::REAL
)
1200 pTypeInfo
= aIter
->second
; // alternative
1203 if ( !pTypeInfo
.get() ) // just a fallback
1204 pTypeInfo
= queryTypeInfoByType(DataType::VARCHAR
,_rTypeInfo
);
1206 OSL_ENSURE(pTypeInfo
.get(),"checkColumns: cann't find a type which is useable as a key!");
1210 TOTypeInfoSP
queryTypeInfoByType(sal_Int32 _nDataType
,const OTypeInfoMap
& _rTypeInfo
)
1212 OTypeInfoMap::const_iterator aIter
= _rTypeInfo
.find(_nDataType
);
1213 if(aIter
!= _rTypeInfo
.end())
1214 return aIter
->second
;
1215 // fall back if the type is unknown
1216 TOTypeInfoSP pTypeInfo
;
1219 case DataType::TINYINT
:
1220 if( (pTypeInfo
= queryTypeInfoByType(DataType::SMALLINT
,_rTypeInfo
) ) )
1223 case DataType::SMALLINT
:
1224 if( (pTypeInfo
= queryTypeInfoByType(DataType::INTEGER
,_rTypeInfo
) ) )
1227 case DataType::INTEGER
:
1228 if( (pTypeInfo
= queryTypeInfoByType(DataType::FLOAT
,_rTypeInfo
) ) )
1231 case DataType::FLOAT
:
1232 if( (pTypeInfo
= queryTypeInfoByType(DataType::REAL
,_rTypeInfo
) ) )
1235 case DataType::DATE
:
1236 case DataType::TIME
:
1237 if( DataType::DATE
== _nDataType
|| DataType::TIME
== _nDataType
)
1239 if( (pTypeInfo
= queryTypeInfoByType(DataType::TIMESTAMP
,_rTypeInfo
) ) )
1243 case DataType::TIMESTAMP
:
1244 case DataType::REAL
:
1245 case DataType::BIGINT
:
1246 if ( (pTypeInfo
= queryTypeInfoByType(DataType::DOUBLE
,_rTypeInfo
) ) )
1249 case DataType::DOUBLE
:
1250 if ( (pTypeInfo
= queryTypeInfoByType(DataType::NUMERIC
,_rTypeInfo
) ) )
1253 case DataType::NUMERIC
:
1254 pTypeInfo
= queryTypeInfoByType(DataType::DECIMAL
,_rTypeInfo
);
1256 case DataType::DECIMAL
:
1257 if ( (pTypeInfo
= queryTypeInfoByType(DataType::NUMERIC
,_rTypeInfo
) ) )
1259 if ( (pTypeInfo
= queryTypeInfoByType(DataType::DOUBLE
,_rTypeInfo
) ) )
1262 case DataType::VARCHAR
:
1263 if ( (pTypeInfo
= queryTypeInfoByType(DataType::LONGVARCHAR
,_rTypeInfo
) ) )
1266 case DataType::LONGVARCHAR
:
1267 if ( (pTypeInfo
= queryTypeInfoByType(DataType::CLOB
,_rTypeInfo
) ) )
1277 pTypeInfo
= ::dbaui::getTypeInfoFromType(_rTypeInfo
,DataType::VARCHAR
,sTypeName
,"x",50,0,false,bForce
);
1279 OSL_ENSURE(pTypeInfo
,"Wrong DataType supplied!");
1283 sal_Int32
askForUserAction(vcl::Window
* _pParent
,sal_uInt16 _nTitle
,sal_uInt16 _nText
,bool _bAll
,const OUString
& _sName
)
1285 SolarMutexGuard aGuard
;
1286 OUString aMsg
= ModuleRes(_nText
);
1287 aMsg
= aMsg
.replaceFirst("%1", _sName
);
1288 ScopedVclPtrInstance
< OSQLMessageBox
> aAsk(_pParent
, ModuleRes(_nTitle
), aMsg
,WB_YES_NO
| WB_DEF_YES
,OSQLMessageBox::Query
);
1291 aAsk
->AddButton(ModuleRes(STR_BUTTON_TEXT_ALL
), RET_ALL
);
1292 aAsk
->GetPushButton(RET_ALL
)->SetHelpId(HID_CONFIRM_DROP_BUTTON_ALL
);
1294 return aAsk
->Execute();
1299 OUString
lcl_createSDBCLevelStatement( const OUString
& _rStatement
, const Reference
< XConnection
>& _rxConnection
)
1301 OUString
sSDBCLevelStatement( _rStatement
);
1304 Reference
< XMultiServiceFactory
> xAnalyzerFactory( _rxConnection
, UNO_QUERY_THROW
);
1305 Reference
< XSingleSelectQueryAnalyzer
> xAnalyzer( xAnalyzerFactory
->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER
), UNO_QUERY_THROW
);
1306 xAnalyzer
->setQuery( _rStatement
);
1307 sSDBCLevelStatement
= xAnalyzer
->getQueryWithSubstitution();
1309 catch( const Exception
& )
1311 DBG_UNHANDLED_EXCEPTION();
1313 return sSDBCLevelStatement
;
1317 Reference
< XPropertySet
> createView( const OUString
& _rName
, const Reference
< XConnection
>& _rxConnection
,
1318 const OUString
& _rCommand
)
1320 Reference
<XViewsSupplier
> xSup(_rxConnection
,UNO_QUERY
);
1321 Reference
< XNameAccess
> xViews
;
1323 xViews
= xSup
->getViews();
1324 Reference
<XDataDescriptorFactory
> xFact(xViews
,UNO_QUERY
);
1325 OSL_ENSURE(xFact
.is(),"No XDataDescriptorFactory available!");
1329 Reference
<XPropertySet
> xView
= xFact
->createDataDescriptor();
1333 OUString sCatalog
,sSchema
,sTable
;
1334 ::dbtools::qualifiedNameComponents(_rxConnection
->getMetaData(),
1339 ::dbtools::EComposeRule::InDataManipulation
);
1341 xView
->setPropertyValue(PROPERTY_CATALOGNAME
,makeAny(sCatalog
));
1342 xView
->setPropertyValue(PROPERTY_SCHEMANAME
,makeAny(sSchema
));
1343 xView
->setPropertyValue(PROPERTY_NAME
,makeAny(sTable
));
1345 xView
->setPropertyValue( PROPERTY_COMMAND
, makeAny( _rCommand
) );
1347 Reference
<XAppend
> xAppend(xViews
,UNO_QUERY
);
1349 xAppend
->appendByDescriptor(xView
);
1352 // we need to reget the view because after appending it, it is no longer valid
1353 // but this time it isn't a view object it is a table object with type "VIEW"
1354 Reference
<XTablesSupplier
> xTabSup(_rxConnection
,UNO_QUERY
);
1355 Reference
< XNameAccess
> xTables
;
1358 xTables
= xTabSup
->getTables();
1359 if ( xTables
.is() && xTables
->hasByName( _rName
) )
1360 xTables
->getByName( _rName
) >>= xView
;
1366 Reference
<XPropertySet
> createView( const OUString
& _rName
, const Reference
< XConnection
>& _rxConnection
1367 ,const Reference
<XPropertySet
>& _rxSourceObject
)
1370 Reference
< XPropertySetInfo
> xPSI( _rxSourceObject
->getPropertySetInfo(), UNO_SET_THROW
);
1371 if ( xPSI
->hasPropertyByName( PROPERTY_COMMAND
) )
1373 _rxSourceObject
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
;
1375 bool bEscapeProcessing( false );
1376 OSL_VERIFY( _rxSourceObject
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bEscapeProcessing
);
1377 if ( bEscapeProcessing
)
1378 sCommand
= lcl_createSDBCLevelStatement( sCommand
, _rxConnection
);
1382 sCommand
= "SELECT * FROM " + composeTableNameForSelect( _rxConnection
, _rxSourceObject
);
1384 return createView( _rName
, _rxConnection
, sCommand
);
1387 bool insertHierachyElement( vcl::Window
* _pParent
, const Reference
< XComponentContext
>& _rxContext
,
1388 const Reference
<XHierarchicalNameContainer
>& _xNames
,
1389 const OUString
& _sParentFolder
,
1392 const Reference
<XContent
>& _xContent
,
1395 OSL_ENSURE( _xNames
.is(), "insertHierachyElement: illegal name container!" );
1396 if ( !_xNames
.is() )
1399 Reference
<XNameAccess
> xNameAccess( _xNames
, UNO_QUERY
);
1400 if ( _xNames
->hasByHierarchicalName(_sParentFolder
) )
1402 Reference
<XChild
> xChild(_xNames
->getByHierarchicalName(_sParentFolder
),UNO_QUERY
);
1403 xNameAccess
.set(xChild
,UNO_QUERY
);
1404 if ( !xNameAccess
.is() && xChild
.is() )
1405 xNameAccess
.set(xChild
->getParent(),UNO_QUERY
);
1408 OSL_ENSURE( xNameAccess
.is(), "insertHierachyElement: could not find the proper name container!" );
1409 if ( !xNameAccess
.is() )
1413 Reference
<XPropertySet
> xProp(_xContent
,UNO_QUERY
);
1415 xProp
->getPropertyValue(PROPERTY_NAME
) >>= sNewName
;
1417 if ( !_bMove
|| sNewName
.isEmpty() )
1419 OUString sTargetName
,sLabel
;
1420 if ( sNewName
.isEmpty() || xNameAccess
->hasByName(sNewName
) )
1422 if ( !sNewName
.isEmpty() )
1423 sTargetName
= sNewName
;
1425 sTargetName
= ModuleRes( _bCollection
? STR_NEW_FOLDER
: ((_bForm
) ? RID_STR_FORM
: RID_STR_REPORT
));
1426 sLabel
= ModuleRes( _bCollection
? STR_FOLDER_LABEL
: ((_bForm
) ? STR_FRM_LABEL
: STR_RPT_LABEL
));
1427 sTargetName
= ::dbtools::createUniqueName(xNameAccess
,sTargetName
);
1429 // here we have everything needed to create a new query object ...
1430 HierarchicalNameCheck
aNameChecker( _xNames
.get(), _sParentFolder
);
1431 // ... ehm, except a new name
1432 ScopedVclPtrInstance
<OSaveAsDlg
> aAskForName(
1438 SAD_ADDITIONAL_DESCRIPTION
| SAD_TITLE_PASTE_AS
);
1439 if ( RET_OK
!= aAskForName
->Execute() )
1440 // cancelled by the user
1443 sNewName
= aAskForName
->getName();
1446 else if ( xNameAccess
->hasByName(sNewName
) )
1448 OUString
sError(ModuleRes(STR_NAME_ALREADY_EXISTS
));
1449 sError
= sError
.replaceFirst("#",sNewName
);
1450 throw SQLException(sError
,nullptr,OUString("S1000") ,0,Any());
1455 Reference
<XMultiServiceFactory
> xORB( xNameAccess
, UNO_QUERY_THROW
);
1456 Sequence
< Any
> aArguments(3);
1457 PropertyValue aValue
;
1459 aValue
.Name
= "Name";
1460 aValue
.Value
<<= sNewName
;
1461 aArguments
[0] <<= aValue
;
1463 aValue
.Name
= "Parent";
1464 aValue
.Value
<<= xNameAccess
;
1465 aArguments
[1] <<= aValue
;
1467 aValue
.Name
= PROPERTY_EMBEDDEDOBJECT
;
1468 aValue
.Value
<<= _xContent
;
1469 aArguments
[2] <<= aValue
;
1471 OUString
sServiceName(_bCollection
? ((_bForm
) ? OUString(SERVICE_NAME_FORM_COLLECTION
) : OUString(SERVICE_NAME_REPORT_COLLECTION
)) : OUString(SERVICE_SDB_DOCUMENTDEFINITION
));
1473 Reference
<XContent
> xNew( xORB
->createInstanceWithArguments( sServiceName
, aArguments
), UNO_QUERY_THROW
);
1474 Reference
< XNameContainer
> xNameContainer( xNameAccess
, UNO_QUERY_THROW
);
1475 xNameContainer
->insertByName( sNewName
, makeAny( xNew
) );
1477 catch( const IllegalArgumentException
& e
)
1479 ::dbtools::throwGenericSQLException( e
.Message
, e
.Context
);
1481 catch( const Exception
& )
1483 DBG_UNHANDLED_EXCEPTION();
1490 Reference
< XNumberFormatter
> getNumberFormatter(const Reference
< XConnection
>& _rxConnection
, const Reference
< css::uno::XComponentContext
>& _rxContext
)
1492 // create a formatter working with the connections format supplier
1493 Reference
< XNumberFormatter
> xFormatter
;
1497 Reference
< css::util::XNumberFormatsSupplier
> xSupplier(::dbtools::getNumberFormats(_rxConnection
, true, _rxContext
));
1499 if ( xSupplier
.is() )
1501 // create a new formatter
1502 xFormatter
.set(util::NumberFormatter::create( _rxContext
), UNO_QUERY_THROW
);
1503 xFormatter
->attachNumberFormatsSupplier(xSupplier
);
1506 catch(const Exception
&)
1508 DBG_UNHANDLED_EXCEPTION();
1515 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */