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 <com/sun/star/frame/XModel.hpp>
69 #include "TypeInfo.hxx"
70 #include "FieldDescriptions.hxx"
71 #include <comphelper/processfactory.hxx>
72 #include <comphelper/stl_types.hxx>
74 #include <svx/svxids.hrc>
76 #include <svl/itempool.hxx>
77 #include "dbaccess_helpid.hrc"
78 #include <svl/itemset.hxx>
79 #include "sbagrid.hrc"
80 #include <svl/rngitem.hxx>
81 #include <svl/intitem.hxx>
82 #include <svx/algitem.hxx>
83 #include <svx/numinf.hxx>
84 #include <svl/zforlist.hxx>
85 #include "dlgattr.hxx"
86 #include <vcl/msgbox.hxx>
87 #include <com/sun/star/container/XChild.hpp>
88 #include <com/sun/star/util/NumberFormatter.hpp>
89 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
90 #include <com/sun/star/util/XNumberFormatter.hpp>
91 #include "dbu_misc.hrc"
92 #include "sqlmessage.hxx"
93 #include <com/sun/star/util/NumberFormat.hpp>
94 #include <com/sun/star/util/URL.hpp>
95 #include <vcl/toolbox.hxx>
96 #include "dlgsize.hxx"
97 #include <svtools/editbrowsebox.hxx>
98 #include <unotools/configmgr.hxx>
99 #include <svtools/helpopt.hxx>
100 #include <ucbhelper/content.hxx>
101 #include <tools/urlobj.hxx>
102 #include <tools/diagnose_ex.h>
103 #include <svl/numuno.hxx>
104 #include <unotools/pathoptions.hxx>
105 #include <svl/filenotation.hxx>
106 #include <svtools/fileview.hxx>
107 #include <connectivity/FValue.hxx>
109 #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
;
131 using ::com::sun::star::frame::XModel
;
133 SQLExceptionInfo
createConnection( const OUString
& _rsDataSourceName
,
134 const Reference
< ::com::sun::star::container::XNameAccess
>& _xDatabaseContext
,
135 const Reference
< ::com::sun::star::uno::XComponentContext
>& _rxContext
,
136 Reference
< ::com::sun::star::lang::XEventListener
>& _rEvtLst
,
137 Reference
< ::com::sun::star::sdbc::XConnection
>& _rOUTConnection
)
139 Reference
<XPropertySet
> xProp
;
142 xProp
.set(_xDatabaseContext
->getByName(_rsDataSourceName
),UNO_QUERY
);
144 catch(const Exception
&)
147 SQLExceptionInfo aInfo
;
149 return createConnection(xProp
,_rxContext
,_rEvtLst
,_rOUTConnection
);
152 SQLExceptionInfo
createConnection( const Reference
< ::com::sun::star::beans::XPropertySet
>& _xDataSource
,
153 const Reference
< ::com::sun::star::uno::XComponentContext
>& _rxContext
,
154 Reference
< ::com::sun::star::lang::XEventListener
>& _rEvtLst
,
155 Reference
< ::com::sun::star::sdbc::XConnection
>& _rOUTConnection
)
157 SQLExceptionInfo aInfo
;
158 if ( !_xDataSource
.is() )
160 SAL_WARN("dbaccess.ui", "createConnection: coult not retrieve the data source!");
164 OUString sPwd
, sUser
;
165 bool bPwdReq
= false;
168 _xDataSource
->getPropertyValue(PROPERTY_PASSWORD
) >>= sPwd
;
169 bPwdReq
= ::cppu::any2bool(_xDataSource
->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED
));
170 _xDataSource
->getPropertyValue(PROPERTY_USER
) >>= sUser
;
172 catch(const Exception
&)
174 SAL_WARN("dbaccess.ui", "createConnection: error while retrieving data source properties!");
179 if(bPwdReq
&& sPwd
.isEmpty())
180 { // password required, but empty -> connect using an interaction handler
181 Reference
<XCompletedConnection
> xConnectionCompletion(_xDataSource
, UNO_QUERY
);
182 if (!xConnectionCompletion
.is())
184 SAL_WARN("dbaccess.ui", "createConnection: missing an interface ... need an error message here!");
187 { // instantiate the default SDB interaction handler
188 Reference
< XInteractionHandler
> xHandler( InteractionHandler::createWithParent(_rxContext
, 0), UNO_QUERY
);
189 _rOUTConnection
= xConnectionCompletion
->connectWithCompletion(xHandler
);
194 Reference
<XDataSource
> xDataSource(_xDataSource
,UNO_QUERY
);
195 _rOUTConnection
= xDataSource
->getConnection(sUser
, sPwd
);
197 // be notified when connection is in disposing
198 Reference
< XComponent
> xComponent(_rOUTConnection
, UNO_QUERY
);
199 if (xComponent
.is() && _rEvtLst
.is())
200 xComponent
->addEventListener(_rEvtLst
);
202 catch(const SQLContext
& e
) { aInfo
= SQLExceptionInfo(e
); }
203 catch(const SQLWarning
& e
) { aInfo
= SQLExceptionInfo(e
); }
204 catch(const SQLException
& e
) { aInfo
= SQLExceptionInfo(e
); }
205 catch(const Exception
&) { SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnExpandEntry: could not connect - unknown exception!"); }
210 Reference
< XDataSource
> getDataSourceByName( const OUString
& _rDataSourceName
,
211 vcl::Window
* _pErrorMessageParent
, Reference
< XComponentContext
> _rxContext
, ::dbtools::SQLExceptionInfo
* _pErrorInfo
)
213 Reference
< XDatabaseContext
> xDatabaseContext
= DatabaseContext::create(_rxContext
);
215 Reference
< XDataSource
> xDatasource
;
217 SQLExceptionInfo aSQLError
;
220 xDatabaseContext
->getByName( _rDataSourceName
) >>= xDatasource
;
222 catch(const WrappedTargetException
& e
)
224 InteractiveIOException aIOException
;
225 if ( ( e
.TargetException
>>= aIOException
)
226 && ( ( aIOException
.Code
== IOErrorCode_NO_FILE
)
227 || ( aIOException
.Code
== IOErrorCode_NOT_EXISTING
)
231 OUString
sErrorMessage( ModuleRes( STR_FILE_DOES_NOT_EXIST
) );
232 OFileNotation
aTransformer( e
.Message
);
233 sErrorMessage
= sErrorMessage
.replaceFirst( "$file$", aTransformer
.get( OFileNotation::N_SYSTEM
) );
234 aSQLError
= SQLExceptionInfo( sErrorMessage
).get();
238 aSQLError
= SQLExceptionInfo( e
.TargetException
);
239 if ( !aSQLError
.isValid() )
240 aError
= e
.TargetException
;
243 catch( const Exception
& )
245 DBG_UNHANDLED_EXCEPTION();
248 if ( xDatasource
.is() )
251 if ( aSQLError
.isValid() )
255 *_pErrorInfo
= aSQLError
;
259 showError( aSQLError
, _pErrorMessageParent
, _rxContext
);
263 return Reference
<XDataSource
>();
266 Reference
< XInterface
> getDataSourceOrModel(const Reference
< XInterface
>& _xObject
)
268 Reference
< XInterface
> xRet
;
269 Reference
<XDocumentDataSource
> xDocumentDataSource(_xObject
,UNO_QUERY
);
270 if ( xDocumentDataSource
.is() )
271 xRet
= xDocumentDataSource
->getDatabaseDocument();
275 Reference
<XOfficeDatabaseDocument
> xOfficeDoc(_xObject
,UNO_QUERY
);
276 if ( xOfficeDoc
.is() )
277 xRet
= xOfficeDoc
->getDataSource();
283 void showError(const SQLExceptionInfo
& _rInfo
, vcl::Window
* _pParent
,const Reference
< XComponentContext
>& _rxContext
)
285 OSL_ENSURE(_pParent
,"showError: Parent window must be NOT NULL!");
286 ::dbtools::showError(_rInfo
,VCLUnoHelper::GetInterface(_pParent
), _rxContext
);
289 TOTypeInfoSP
getTypeInfoFromType(const OTypeInfoMap
& _rTypeInfo
,
291 const OUString
& _sTypeName
,
292 const OUString
& _sCreateParams
,
293 sal_Int32 _nPrecision
,
295 bool _bAutoIncrement
,
296 bool& _brForceToType
)
298 TOTypeInfoSP pTypeInfo
;
299 _brForceToType
= false;
301 ::std::pair
<OTypeInfoMap::const_iterator
, OTypeInfoMap::const_iterator
> aPair
= _rTypeInfo
.equal_range(_nType
);
302 OTypeInfoMap::const_iterator aIter
= aPair
.first
;
303 if(aIter
!= _rTypeInfo
.end()) // compare with end is correct here
305 for(;aIter
!= aPair
.second
;++aIter
)
307 // search the best matching type
309 OUString sDBTypeName
= aIter
->second
->aTypeName
; (void)sDBTypeName
;
310 sal_Int32 nDBTypePrecision
= aIter
->second
->nPrecision
; (void)nDBTypePrecision
;
311 sal_Int32 nDBTypeScale
= aIter
->second
->nMaximumScale
; (void)nDBTypeScale
;
312 bool bDBAutoIncrement
= aIter
->second
->bAutoIncrement
; (void)bDBAutoIncrement
;
316 || (aIter
->second
->aTypeName
.equalsIgnoreAsciiCase(_sTypeName
))
320 !aIter
->second
->aCreateParams
.getLength()
321 && _sCreateParams
.isEmpty()
324 (aIter
->second
->nPrecision
>= _nPrecision
)
325 && (aIter
->second
->nMaximumScale
>= _nScale
)
326 && ( (_bAutoIncrement
&& aIter
->second
->bAutoIncrement
) || !_bAutoIncrement
)
333 if (aIter
== aPair
.second
)
335 for(aIter
= aPair
.first
; aIter
!= aPair
.second
; ++aIter
)
337 sal_Int32 nPrec
= aIter
->second
->nPrecision
;
338 sal_Int32 nScale
= aIter
->second
->nMaximumScale
;
339 // search the best matching type (now comparing the local names)
340 if ( (aIter
->second
->aLocalTypeName
.equalsIgnoreAsciiCase(_sTypeName
))
341 && (nPrec
>= _nPrecision
)
342 && (nScale
>= _nScale
)
343 && ( (_bAutoIncrement
&& aIter
->second
->bAutoIncrement
) || !_bAutoIncrement
)
346 SAL_WARN("dbaccess.ui", "getTypeInfoFromType: assuming column type " <<
347 aIter
->second
->aTypeName
<< "\" (expected type name " <<
348 _sTypeName
<< " matches the type's local name).");
354 if (aIter
== aPair
.second
)
355 { // no match for the names, no match for the local names
356 // -> drop the precision and the scale restriction, accept any type with the property
359 for(aIter
= aPair
.first
; aIter
!= aPair
.second
; ++aIter
)
361 // search the best matching type (now comparing the local names)
362 sal_Int32 nPrec
= aIter
->second
->nPrecision
;
363 sal_Int32 nScale
= aIter
->second
->nMaximumScale
;
364 if ( (nPrec
>= _nPrecision
)
365 && (nScale
>= _nScale
)
366 && ( (_bAutoIncrement
&& aIter
->second
->bAutoIncrement
) || !_bAutoIncrement
)
371 if (aIter
== aPair
.second
)
373 if ( _bAutoIncrement
)
375 for(aIter
= aPair
.first
; aIter
!= aPair
.second
; ++aIter
)
377 // search the best matching type (now comparing the local names)
378 sal_Int32 nScale
= aIter
->second
->nMaximumScale
;
379 if ( (nScale
>= _nScale
)
380 && (aIter
->second
->bAutoIncrement
== _bAutoIncrement
)
384 if ( aIter
== aPair
.second
)
386 // try it without the auto increment flag
387 pTypeInfo
= getTypeInfoFromType(_rTypeInfo
,
397 pTypeInfo
= aIter
->second
;
401 pTypeInfo
= aPair
.first
->second
;
402 _brForceToType
= true;
406 pTypeInfo
= aIter
->second
;
410 ::comphelper::UStringMixEqual
aCase(false);
411 // search for typeinfo where the typename is equal _sTypeName
412 OTypeInfoMap::const_iterator typeInfoLoop
= _rTypeInfo
.begin();
413 OTypeInfoMap::const_iterator typeInfoEnd
= _rTypeInfo
.end();
414 for (; typeInfoLoop
!= typeInfoEnd
; ++typeInfoLoop
)
416 if ( aCase( typeInfoLoop
->second
->getDBName() , _sTypeName
) )
418 pTypeInfo
= typeInfoLoop
->second
;
424 OSL_ENSURE(pTypeInfo
, "getTypeInfoFromType: no type info found for this type!");
428 void fillTypeInfo( const Reference
< ::com::sun::star::sdbc::XConnection
>& _rxConnection
,
429 const OUString
& _rsTypeNames
,
430 OTypeInfoMap
& _rTypeInfoMap
,
431 ::std::vector
<OTypeInfoMap::iterator
>& _rTypeInfoIters
)
433 if(!_rxConnection
.is())
435 Reference
< XResultSet
> xRs
= _rxConnection
->getMetaData ()->getTypeInfo ();
436 Reference
< XRow
> xRow(xRs
,UNO_QUERY
);
437 // Information for a single SQL type
440 static const char aB1
[] = " [ ";
441 static const char aB2
[] = " ]";
442 Reference
<XResultSetMetaData
> xResultSetMetaData
= Reference
<XResultSetMetaDataSupplier
>(xRs
,UNO_QUERY
)->getMetaData();
443 ::connectivity::ORowSetValue aValue
;
444 ::std::vector
<sal_Int32
> aTypes
;
445 ::std::vector
<sal_Bool
> aNullable
;
446 // Loop on the result set until we reach end of file
449 TOTypeInfoSP
pInfo(new OTypeInfo());
451 if ( aTypes
.empty() )
453 sal_Int32 nCount
= xResultSetMetaData
->getColumnCount();
456 aTypes
.reserve(nCount
+1);
457 aTypes
.push_back(-1);
458 aNullable
.push_back(sal_False
);
459 for (sal_Int32 j
= 1; j
<= nCount
; ++j
)
461 aTypes
.push_back(xResultSetMetaData
->getColumnType(j
));
462 aNullable
.push_back(xResultSetMetaData
->isNullable(j
) != ColumnValue::NO_NULLS
);
466 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
467 pInfo
->aTypeName
= aValue
;
469 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
470 pInfo
->nType
= aValue
;
472 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
473 pInfo
->nPrecision
= aValue
;
475 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
476 pInfo
->aLiteralPrefix
= aValue
;
478 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
479 pInfo
->aLiteralSuffix
= aValue
;
481 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
482 pInfo
->aCreateParams
= aValue
;
484 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
485 pInfo
->bNullable
= (sal_Int32
)aValue
== ColumnValue::NULLABLE
;
487 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
488 pInfo
->bCaseSensitive
= (bool)aValue
;
490 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
491 pInfo
->nSearchType
= aValue
;
493 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
494 pInfo
->bUnsigned
= (bool)aValue
;
496 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
497 pInfo
->bCurrency
= (bool)aValue
;
499 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
500 pInfo
->bAutoIncrement
= (bool)aValue
;
502 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
503 pInfo
->aLocalTypeName
= aValue
;
505 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
506 pInfo
->nMinimumScale
= aValue
;
508 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
509 pInfo
->nMaximumScale
= aValue
;
511 // 16 and 17 are unused
513 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
514 pInfo
->nNumPrecRadix
= aValue
;
516 // check if values are less than zero like it happens in a oracle jdbc driver
517 if( pInfo
->nPrecision
< 0)
518 pInfo
->nPrecision
= 0;
519 if( pInfo
->nMinimumScale
< 0)
520 pInfo
->nMinimumScale
= 0;
521 if( pInfo
->nMaximumScale
< 0)
522 pInfo
->nMaximumScale
= 0;
523 if( pInfo
->nNumPrecRadix
<= 1)
524 pInfo
->nNumPrecRadix
= 10;
530 aName
= _rsTypeNames
.getToken(TYPE_CHAR
, ';');
532 case DataType::VARCHAR
:
533 aName
= _rsTypeNames
.getToken(TYPE_TEXT
, ';');
535 case DataType::DECIMAL
:
536 aName
= _rsTypeNames
.getToken(TYPE_DECIMAL
, ';');
538 case DataType::NUMERIC
:
539 aName
= _rsTypeNames
.getToken(TYPE_NUMERIC
, ';');
541 case DataType::BIGINT
:
542 aName
= _rsTypeNames
.getToken(TYPE_BIGINT
, ';');
544 case DataType::FLOAT
:
545 aName
= _rsTypeNames
.getToken(TYPE_FLOAT
, ';');
547 case DataType::DOUBLE
:
548 aName
= _rsTypeNames
.getToken(TYPE_DOUBLE
, ';');
550 case DataType::LONGVARCHAR
:
551 aName
= _rsTypeNames
.getToken(TYPE_MEMO
, ';');
553 case DataType::LONGVARBINARY
:
554 aName
= _rsTypeNames
.getToken(TYPE_IMAGE
, ';');
557 aName
= _rsTypeNames
.getToken(TYPE_DATE
, ';');
560 aName
= _rsTypeNames
.getToken(TYPE_TIME
, ';');
562 case DataType::TIMESTAMP
:
563 aName
= _rsTypeNames
.getToken(TYPE_DATETIME
, ';');
566 if ( !pInfo
->aCreateParams
.isEmpty() )
568 aName
= _rsTypeNames
.getToken(TYPE_BIT
, ';');
572 case DataType::BOOLEAN
:
573 aName
= _rsTypeNames
.getToken(TYPE_BOOL
, ';');
575 case DataType::TINYINT
:
576 aName
= _rsTypeNames
.getToken(TYPE_TINYINT
, ';');
578 case DataType::SMALLINT
:
579 aName
= _rsTypeNames
.getToken(TYPE_SMALLINT
, ';');
581 case DataType::INTEGER
:
582 aName
= _rsTypeNames
.getToken(TYPE_INTEGER
, ';');
585 aName
= _rsTypeNames
.getToken(TYPE_REAL
, ';');
587 case DataType::BINARY
:
588 aName
= _rsTypeNames
.getToken(TYPE_BINARY
, ';');
590 case DataType::VARBINARY
:
591 aName
= _rsTypeNames
.getToken(TYPE_VARBINARY
, ';');
593 case DataType::SQLNULL
:
594 aName
= _rsTypeNames
.getToken(TYPE_SQLNULL
, ';');
596 case DataType::OBJECT
:
597 aName
= _rsTypeNames
.getToken(TYPE_OBJECT
, ';');
599 case DataType::DISTINCT
:
600 aName
= _rsTypeNames
.getToken(TYPE_DISTINCT
, ';');
602 case DataType::STRUCT
:
603 aName
= _rsTypeNames
.getToken(TYPE_STRUCT
, ';');
605 case DataType::ARRAY
:
606 aName
= _rsTypeNames
.getToken(TYPE_ARRAY
, ';');
609 aName
= _rsTypeNames
.getToken(TYPE_BLOB
, ';');
612 aName
= _rsTypeNames
.getToken(TYPE_CLOB
, ';');
615 aName
= _rsTypeNames
.getToken(TYPE_REF
, ';');
617 case DataType::OTHER
:
618 aName
= _rsTypeNames
.getToken(TYPE_OTHER
, ';');
621 if ( !aName
.isEmpty() )
623 pInfo
->aUIName
= aName
;
624 pInfo
->aUIName
+= aB1
;
626 pInfo
->aUIName
+= pInfo
->aTypeName
;
627 if ( !aName
.isEmpty() )
628 pInfo
->aUIName
+= aB2
;
629 // Now that we have the type info, save it in the multimap
630 _rTypeInfoMap
.insert(OTypeInfoMap::value_type(pInfo
->nType
,pInfo
));
632 // for a faster index access
633 _rTypeInfoIters
.reserve(_rTypeInfoMap
.size());
635 OTypeInfoMap::iterator aIter
= _rTypeInfoMap
.begin();
636 OTypeInfoMap::iterator aEnd
= _rTypeInfoMap
.end();
637 for(;aIter
!= aEnd
;++aIter
)
638 _rTypeInfoIters
.push_back(aIter
);
640 // Close the result set/statement.
642 ::comphelper::disposeComponent(xRs
);
646 void setColumnProperties(const Reference
<XPropertySet
>& _rxColumn
,const OFieldDescription
* _pFieldDesc
)
648 _rxColumn
->setPropertyValue(PROPERTY_NAME
,makeAny(_pFieldDesc
->GetName()));
649 _rxColumn
->setPropertyValue(PROPERTY_TYPENAME
,makeAny(_pFieldDesc
->getTypeInfo()->aTypeName
));
650 _rxColumn
->setPropertyValue(PROPERTY_TYPE
,makeAny(_pFieldDesc
->GetType()));
651 _rxColumn
->setPropertyValue(PROPERTY_PRECISION
,makeAny(_pFieldDesc
->GetPrecision()));
652 _rxColumn
->setPropertyValue(PROPERTY_SCALE
,makeAny(_pFieldDesc
->GetScale()));
653 _rxColumn
->setPropertyValue(PROPERTY_ISNULLABLE
, makeAny(_pFieldDesc
->GetIsNullable()));
654 _rxColumn
->setPropertyValue(PROPERTY_ISAUTOINCREMENT
, css::uno::makeAny(_pFieldDesc
->IsAutoIncrement()));
655 _rxColumn
->setPropertyValue(PROPERTY_DESCRIPTION
,makeAny(_pFieldDesc
->GetDescription()));
656 if ( _rxColumn
->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISCURRENCY
) && _pFieldDesc
->IsCurrency() )
657 _rxColumn
->setPropertyValue(PROPERTY_ISCURRENCY
, css::uno::makeAny(_pFieldDesc
->IsCurrency()));
658 // set autoincrement value when available
659 // and only set when the entry is not empty, that lets the value in the column untouched
660 if ( _pFieldDesc
->IsAutoIncrement() && !_pFieldDesc
->GetAutoIncrementValue().isEmpty() && _rxColumn
->getPropertySetInfo()->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION
) )
661 _rxColumn
->setPropertyValue(PROPERTY_AUTOINCREMENTCREATION
,makeAny(_pFieldDesc
->GetAutoIncrementValue()));
664 OUString
createDefaultName(const Reference
< XDatabaseMetaData
>& _xMetaData
,const Reference
<XNameAccess
>& _xTables
,const OUString
& _sName
)
666 OSL_ENSURE(_xMetaData
.is(),"No MetaData!");
667 OUString sDefaultName
= _sName
;
670 OUString sCatalog
,sSchema
,sCompsedName
;
671 if(_xMetaData
->supportsCatalogsInTableDefinitions())
675 Reference
< XConnection
> xCon
= _xMetaData
->getConnection();
677 sCatalog
= xCon
->getCatalog();
678 if ( sCatalog
.isEmpty() )
680 Reference
<XResultSet
> xRes
= _xMetaData
->getCatalogs();
681 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
682 while(xRes
.is() && xRes
->next())
684 sCatalog
= xRow
->getString(1);
690 catch(const SQLException
&)
694 if(_xMetaData
->supportsSchemasInTableDefinitions())
696 sSchema
= _xMetaData
->getUserName();
698 sCompsedName
= ::dbtools::composeTableName( _xMetaData
, sCatalog
, sSchema
, _sName
, false, ::dbtools::eInDataManipulation
);
699 sDefaultName
= ::dbtools::createUniqueName(_xTables
,sCompsedName
);
701 catch(const SQLException
&)
707 bool checkDataSourceAvailable(const OUString
& _sDataSourceName
,const Reference
< ::com::sun::star::uno::XComponentContext
>& _xContext
)
709 Reference
< XDatabaseContext
> xDataBaseContext
= DatabaseContext::create(_xContext
);
710 bool bRet
= xDataBaseContext
->hasByName(_sDataSourceName
);
712 { // try if this one is a URL
715 bRet
= xDataBaseContext
->getByName(_sDataSourceName
).hasValue();
717 catch(const Exception
&)
724 sal_Int32
mapTextAllign(const SvxCellHorJustify
& _eAlignment
)
726 sal_Int32 nAlignment
= com::sun::star::awt::TextAlign::LEFT
;
729 case SVX_HOR_JUSTIFY_STANDARD
:
730 case SVX_HOR_JUSTIFY_LEFT
: nAlignment
= ::com::sun::star::awt::TextAlign::LEFT
; break;
731 case SVX_HOR_JUSTIFY_CENTER
: nAlignment
= ::com::sun::star::awt::TextAlign::CENTER
; break;
732 case SVX_HOR_JUSTIFY_RIGHT
: nAlignment
= ::com::sun::star::awt::TextAlign::RIGHT
; break;
734 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
739 SvxCellHorJustify
mapTextJustify(const sal_Int32
& _nAlignment
)
741 SvxCellHorJustify eJustify
= SVX_HOR_JUSTIFY_LEFT
;
744 case ::com::sun::star::awt::TextAlign::LEFT
: eJustify
= SVX_HOR_JUSTIFY_LEFT
; break;
745 case ::com::sun::star::awt::TextAlign::CENTER
: eJustify
= SVX_HOR_JUSTIFY_CENTER
; break;
746 case ::com::sun::star::awt::TextAlign::RIGHT
: eJustify
= SVX_HOR_JUSTIFY_RIGHT
; break;
748 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
753 void callColumnFormatDialog(const Reference
<XPropertySet
>& xAffectedCol
,
754 const Reference
<XPropertySet
>& xField
,
755 SvNumberFormatter
* _pFormatter
,
756 vcl::Window
* _pParent
)
758 if (xAffectedCol
.is() && xField
.is())
762 Reference
< XPropertySetInfo
> xInfo
= xAffectedCol
->getPropertySetInfo();
763 bool bHasFormat
= xInfo
->hasPropertyByName(PROPERTY_FORMATKEY
);
764 sal_Int32 nDataType
= ::comphelper::getINT32(xField
->getPropertyValue(PROPERTY_TYPE
));
766 SvxCellHorJustify
eJustify(SVX_HOR_JUSTIFY_STANDARD
);
767 Any aAlignment
= xAffectedCol
->getPropertyValue(PROPERTY_ALIGN
);
768 if (aAlignment
.hasValue())
769 eJustify
= dbaui::mapTextJustify(::comphelper::getINT16(aAlignment
));
770 sal_Int32 nFormatKey
= 0;
772 nFormatKey
= ::comphelper::getINT32(xAffectedCol
->getPropertyValue(PROPERTY_FORMATKEY
));
774 if(callColumnFormatDialog(_pParent
,_pFormatter
,nDataType
,nFormatKey
,eJustify
,bHasFormat
))
776 xAffectedCol
->setPropertyValue(PROPERTY_ALIGN
, makeAny((sal_Int16
)dbaui::mapTextAllign(eJustify
)));
778 xAffectedCol
->setPropertyValue(PROPERTY_FORMATKEY
, makeAny(nFormatKey
));
782 catch( const Exception
& )
784 DBG_UNHANDLED_EXCEPTION();
789 bool callColumnFormatDialog(vcl::Window
* _pParent
,
790 SvNumberFormatter
* _pFormatter
,
791 sal_Int32 _nDataType
,
792 sal_Int32
& _nFormatKey
,
793 SvxCellHorJustify
& _eJustify
,
799 static SfxItemInfo aItemInfos
[] =
801 { 0, SfxItemPoolFlags::NONE
},
802 { SID_ATTR_NUMBERFORMAT_VALUE
, SfxItemPoolFlags::POOLABLE
},
803 { SID_ATTR_ALIGN_HOR_JUSTIFY
, SfxItemPoolFlags::POOLABLE
},
804 { SID_ATTR_NUMBERFORMAT_ONE_AREA
, SfxItemPoolFlags::POOLABLE
},
805 { SID_ATTR_NUMBERFORMAT_INFO
, SfxItemPoolFlags::POOLABLE
}
807 static const sal_uInt16 aAttrMap
[] =
809 SBA_DEF_RANGEFORMAT
, SBA_ATTR_ALIGN_HOR_JUSTIFY
,
810 SID_ATTR_NUMBERFORMAT_ONE_AREA
, SID_ATTR_NUMBERFORMAT_ONE_AREA
,
811 SID_ATTR_NUMBERFORMAT_INFO
, SID_ATTR_NUMBERFORMAT_INFO
,
815 SfxPoolItem
* pDefaults
[] =
817 new SfxRangeItem(SBA_DEF_RANGEFORMAT
, SBA_DEF_FMTVALUE
, SBA_ATTR_ALIGN_HOR_JUSTIFY
),
818 new SfxUInt32Item(SBA_DEF_FMTVALUE
),
819 new SvxHorJustifyItem(SVX_HOR_JUSTIFY_STANDARD
, SBA_ATTR_ALIGN_HOR_JUSTIFY
),
820 new SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA
, false),
821 new SvxNumberInfoItem(SID_ATTR_NUMBERFORMAT_INFO
)
824 SfxItemPool
* pPool
= new SfxItemPool(OUString("GridBrowserProperties"), SBA_DEF_RANGEFORMAT
, SBA_ATTR_ALIGN_HOR_JUSTIFY
, aItemInfos
, pDefaults
);
825 pPool
->SetDefaultMetric( SFX_MAPUNIT_TWIP
); // ripped, don't understand why
826 pPool
->FreezeIdRanges(); // the same
828 SfxItemSet
* pFormatDescriptor
= new SfxItemSet(*pPool
, aAttrMap
);
830 pFormatDescriptor
->Put(SvxHorJustifyItem(_eJustify
, SBA_ATTR_ALIGN_HOR_JUSTIFY
));
834 // if the col is bound to a text field we have to disallow all non-text formats
835 if ((DataType::CHAR
== _nDataType
) || (DataType::VARCHAR
== _nDataType
) || (DataType::LONGVARCHAR
== _nDataType
) || (DataType::CLOB
== _nDataType
))
838 pFormatDescriptor
->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA
, true));
839 if (!_pFormatter
->IsTextFormat(_nFormatKey
))
840 // text fields can only have text formats
841 _nFormatKey
= _pFormatter
->GetStandardFormat(css::util::NumberFormat::TEXT
,_pParent
->GetSettings().GetLanguageTag().getLanguageType());
844 pFormatDescriptor
->Put(SfxUInt32Item(SBA_DEF_FMTVALUE
, _nFormatKey
));
849 double dPreviewVal
= 1234.56789;
850 SvxNumberInfoItem
aFormatter(_pFormatter
, dPreviewVal
, SID_ATTR_NUMBERFORMAT_INFO
);
851 pFormatDescriptor
->Put(aFormatter
);
854 { // want the dialog to be destroyed before our set
855 ScopedVclPtrInstance
< SbaSbAttrDlg
> aDlg(_pParent
, pFormatDescriptor
, _pFormatter
, _bHasFormat
);
856 if (RET_OK
== aDlg
->Execute())
860 const SfxItemSet
* pSet
= aDlg
->GetExampleSet();
861 // (of course we could put the modified items directly into the column, but then the UNO-model
862 // won't reflect these changes, and why do we have a model, then ?)
864 // horizontal justify
865 SFX_ITEMSET_GET(*pSet
, pHorJustify
, SvxHorJustifyItem
, SBA_ATTR_ALIGN_HOR_JUSTIFY
, true);
867 _eJustify
= (SvxCellHorJustify
)pHorJustify
->GetValue();
872 SFX_ITEMSET_GET(*pSet
, pFormat
, SfxUInt32Item
, SBA_DEF_FMTVALUE
, true);
873 _nFormatKey
= (sal_Int32
)pFormat
->GetValue();
878 const SfxItemSet
* pResult
= aDlg
->GetOutputItemSet();
881 const SfxPoolItem
* pItem
= pResult
->GetItem( SID_ATTR_NUMBERFORMAT_INFO
);
882 const SvxNumberInfoItem
* pInfoItem
= static_cast<const SvxNumberInfoItem
*>(pItem
);
883 if (pInfoItem
&& pInfoItem
->GetDelCount())
885 const sal_uInt32
* pDeletedKeys
= pInfoItem
->GetDelArray();
887 for (sal_uInt16 i
=0; i
< pInfoItem
->GetDelCount(); ++i
, ++pDeletedKeys
)
888 _pFormatter
->DeleteEntry(*pDeletedKeys
);
893 delete pFormatDescriptor
;
894 SfxItemPool::Free(pPool
);
895 for (sal_uInt16 i
=0; i
<sizeof(pDefaults
)/sizeof(pDefaults
[0]); ++i
)
901 const SfxFilter
* getStandardDatabaseFilter()
903 const SfxFilter
* pFilter
= SfxFilter::GetFilterByName(OUString("StarOffice XML (Base)"));
904 OSL_ENSURE(pFilter
,"Filter: StarOffice XML (Base) could not be found!");
908 bool appendToFilter(const Reference
<XConnection
>& _xConnection
,
909 const OUString
& _sName
,
910 const Reference
< XComponentContext
>& _rxContext
,
911 vcl::Window
* _pParent
)
914 Reference
< XChild
> xChild(_xConnection
,UNO_QUERY
);
917 Reference
< XPropertySet
> xProp(xChild
->getParent(),UNO_QUERY
);
920 Sequence
< OUString
> aFilter
;
921 xProp
->getPropertyValue(PROPERTY_TABLEFILTER
) >>= aFilter
;
922 // first check if we have something like SCHEMA.%
923 bool bHasToInsert
= true;
924 const OUString
* pBegin
= aFilter
.getConstArray();
925 const OUString
* pEnd
= pBegin
+ aFilter
.getLength();
926 for (;pBegin
!= pEnd
; ++pBegin
)
928 if(pBegin
->indexOf('%') != -1)
931 if((nLen
= pBegin
->lastIndexOf('.')) != -1 && !pBegin
->compareTo(_sName
,nLen
))
932 bHasToInsert
= false;
933 else if(pBegin
->getLength() == 1)
934 bHasToInsert
= false;
941 if(! ::dbaui::checkDataSourceAvailable(::comphelper::getString(xProp
->getPropertyValue(PROPERTY_NAME
)),_rxContext
))
943 OUString
aMessage(ModuleRes(STR_TABLEDESIGN_DATASOURCE_DELETED
));
944 ScopedVclPtr
<OSQLWarningBox
>::Create( _pParent
, aMessage
)->Execute();
949 aFilter
.realloc(aFilter
.getLength()+1);
950 aFilter
.getArray()[aFilter
.getLength()-1] = _sName
;
951 xProp
->setPropertyValue(PROPERTY_TABLEFILTER
,makeAny(aFilter
));
959 void notifySystemWindow(vcl::Window
* _pWindow
, vcl::Window
* _pToRegister
, const ::comphelper::mem_fun1_t
<TaskPaneList
,vcl::Window
*>& _rMemFunc
)
961 OSL_ENSURE(_pWindow
,"Window can not be null!");
962 SystemWindow
* pSystemWindow
= _pWindow
? _pWindow
->GetSystemWindow() : NULL
;
965 _rMemFunc( pSystemWindow
->GetTaskPaneList(), _pToRegister
);
969 void adjustToolBoxSize(ToolBox
* _pToolBox
)
971 // adjust the toolbox size, otherwise large bitmaps don't fit into
972 Size aOldSize
= _pToolBox
->GetSizePixel();
973 Size aSize
= _pToolBox
->CalcWindowSizePixel();
974 if ( !aSize
.Width() )
975 aSize
.Width() = aOldSize
.Width();
976 else if ( !aSize
.Height() )
977 aSize
.Height() = aOldSize
.Height();
979 Size aTbSize
= _pToolBox
->GetSizePixel();
980 if ( (aSize
.Width() && aSize
.Width() != aTbSize
.Width()) ||
981 (aSize
.Height() && aSize
.Height() != aTbSize
.Height()) )
983 _pToolBox
->SetPosSizePixel( _pToolBox
->GetPosPixel(), aSize
);
984 _pToolBox
->Invalidate();
988 void adjustBrowseBoxColumnWidth( ::svt::EditBrowseBox
* _pBox
, sal_uInt16 _nColId
)
990 sal_Int32 nColSize
= -1;
991 sal_uInt32 nDefaultWidth
= _pBox
->GetDefaultColumnWidth( _pBox
->GetColumnTitle( _nColId
) );
992 if ( nDefaultWidth
!= _pBox
->GetColumnWidth( _nColId
) )
994 Size aSizeMM
= _pBox
->PixelToLogic( Size( _pBox
->GetColumnWidth( _nColId
), 0 ), MapMode( MAP_MM
) );
995 nColSize
= aSizeMM
.Width() * 10;
998 Size aDefaultMM
= _pBox
->PixelToLogic( Size( nDefaultWidth
, 0 ), MapMode( MAP_MM
) );
1000 ScopedVclPtrInstance
< DlgSize
> aColumnSizeDlg( _pBox
, nColSize
, false, aDefaultMM
.Width() * 10 );
1001 if ( aColumnSizeDlg
->Execute() )
1003 sal_Int32 nValue
= aColumnSizeDlg
->GetValue();
1006 nValue
= _pBox
->GetDefaultColumnWidth( _pBox
->GetColumnTitle( _nColId
) );
1010 Size
aSizeMM( nValue
/ 10, 0 );
1011 nValue
= _pBox
->LogicToPixel( aSizeMM
, MapMode( MAP_MM
) ).Width();
1013 _pBox
->SetColumnWidth( _nColId
, nValue
);
1017 // check if SQL92 name checking is enabled
1018 bool isSQL92CheckEnabled(const Reference
<XConnection
>& _xConnection
)
1020 return ::dbtools::getBooleanDataSourceSetting( _xConnection
, PROPERTY_ENABLESQL92CHECK
);
1023 bool isAppendTableAliasEnabled(const Reference
<XConnection
>& _xConnection
)
1025 return ::dbtools::getBooleanDataSourceSetting( _xConnection
, INFO_APPEND_TABLE_ALIAS
);
1028 bool generateAsBeforeTableAlias(const Reference
<XConnection
>& _xConnection
)
1030 return ::dbtools::getBooleanDataSourceSetting( _xConnection
, INFO_AS_BEFORE_CORRELATION_NAME
);
1033 void fillAutoIncrementValue(const Reference
<XPropertySet
>& _xDatasource
,
1034 bool& _rAutoIncrementValueEnabled
,
1035 OUString
& _rsAutoIncrementValue
)
1037 if ( _xDatasource
.is() )
1039 OSL_ENSURE(_xDatasource
->getPropertySetInfo()->hasPropertyByName(PROPERTY_INFO
),"NO datasource supplied!");
1040 Sequence
<PropertyValue
> aInfo
;
1041 _xDatasource
->getPropertyValue(PROPERTY_INFO
) >>= aInfo
;
1043 // search the right propertyvalue
1044 const PropertyValue
* pValue
=::std::find_if(aInfo
.getConstArray(),
1045 aInfo
.getConstArray() + aInfo
.getLength(),
1046 ::std::bind2nd(TPropertyValueEqualFunctor(),PROPERTY_AUTOINCREMENTCREATION
));
1047 if ( pValue
&& pValue
!= (aInfo
.getConstArray() + aInfo
.getLength()) )
1048 pValue
->Value
>>= _rsAutoIncrementValue
;
1049 pValue
=::std::find_if(aInfo
.getConstArray(),
1050 aInfo
.getConstArray() + aInfo
.getLength(),
1051 ::std::bind2nd(TPropertyValueEqualFunctor(),OUString("IsAutoRetrievingEnabled") ));
1052 if ( pValue
&& pValue
!= (aInfo
.getConstArray() + aInfo
.getLength()) )
1053 pValue
->Value
>>= _rAutoIncrementValueEnabled
;
1057 void fillAutoIncrementValue(const Reference
<XConnection
>& _xConnection
,
1058 bool& _rAutoIncrementValueEnabled
,
1059 OUString
& _rsAutoIncrementValue
)
1061 Reference
< XChild
> xChild(_xConnection
,UNO_QUERY
);
1064 Reference
< XPropertySet
> xProp(xChild
->getParent(),UNO_QUERY
);
1065 fillAutoIncrementValue(xProp
,_rAutoIncrementValueEnabled
,_rsAutoIncrementValue
);
1069 OUString
getStrippedDatabaseName(const Reference
<XPropertySet
>& _xDataSource
,OUString
& _rsDatabaseName
)
1071 if ( _rsDatabaseName
.isEmpty() && _xDataSource
.is() )
1075 _xDataSource
->getPropertyValue(PROPERTY_NAME
) >>= _rsDatabaseName
;
1077 catch(const Exception
& )
1079 DBG_UNHANDLED_EXCEPTION();
1082 OUString sName
= _rsDatabaseName
;
1083 INetURLObject
aURL(sName
);
1084 if ( aURL
.GetProtocol() != INetProtocol::NotValid
)
1085 sName
= aURL
.getBase(INetURLObject::LAST_SEGMENT
,true,INetURLObject::DECODE_UNAMBIGUOUS
);
1089 void AppendConfigToken( OUString
& _rURL
, bool _bQuestionMark
)
1091 // query part exists?
1092 if ( _bQuestionMark
)
1093 // no, so start with '?'
1096 // yes, so only append with '&'
1100 _rURL
+= "Language=";
1101 _rURL
+= utl::ConfigManager::getLocale();
1102 _rURL
+= "&System=";
1103 _rURL
+= SvtHelpOptions().GetSystem();
1109 bool GetHelpAnchor_Impl( const OUString
& _rURL
, OUString
& _rAnchor
)
1116 ::ucbhelper::Content
aCnt( INetURLObject( _rURL
).GetMainURL( INetURLObject::NO_DECODE
),
1117 Reference
< ::com::sun::star::ucb::XCommandEnvironment
>(),
1118 comphelper::getProcessComponentContext() );
1119 if ( ( aCnt
.getPropertyValue("AnchorName") >>= sAnchor
) )
1122 if ( !sAnchor
.isEmpty() )
1130 SAL_WARN( "dbaccess.ui", "Property 'AnchorName' is missing" );
1141 ::com::sun::star::util::URL
createHelpAgentURL(const OUString
& _sModuleName
, const OString
& sHelpId
)
1143 ::com::sun::star::util::URL aURL
;
1144 aURL
.Complete
= "vnd.sun.star.help://" +
1145 _sModuleName
+ "/" + OStringToOUString(sHelpId
, RTL_TEXTENCODING_UTF8
);
1148 OUString sTempURL
= aURL
.Complete
;
1149 AppendConfigToken( sTempURL
, true );
1150 bool bHasAnchor
= GetHelpAnchor_Impl( sTempURL
, sAnchor
);
1151 AppendConfigToken(aURL
.Complete
,true);
1154 aURL
.Complete
+= "#";
1155 aURL
.Complete
+= sAnchor
;
1160 void setEvalDateFormatForFormatter(Reference
< ::com::sun::star::util::XNumberFormatter
>& _rxFormatter
)
1162 OSL_ENSURE( _rxFormatter
.is(),"setEvalDateFormatForFormatter: Formatter is NULL!");
1163 if ( _rxFormatter
.is() )
1165 Reference
< ::com::sun::star::util::XNumberFormatsSupplier
> xSupplier
= _rxFormatter
->getNumberFormatsSupplier();
1167 Reference
< XUnoTunnel
> xTunnel(xSupplier
,UNO_QUERY
);
1168 SvNumberFormatsSupplierObj
* pSupplierImpl
= reinterpret_cast<SvNumberFormatsSupplierObj
*>(xTunnel
->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1169 OSL_ENSURE(pSupplierImpl
,"No Supplier!");
1171 if ( pSupplierImpl
)
1173 SvNumberFormatter
* pFormatter
= pSupplierImpl
->GetNumberFormatter();
1174 pFormatter
->SetEvalDateFormat(NF_EVALDATEFORMAT_FORMAT
);
1179 TOTypeInfoSP
queryPrimaryKeyType(const OTypeInfoMap
& _rTypeInfo
)
1181 TOTypeInfoSP pTypeInfo
;
1182 // first we search for a type which supports autoIncrement
1183 OTypeInfoMap::const_iterator aIter
= _rTypeInfo
.begin();
1184 OTypeInfoMap::const_iterator aEnd
= _rTypeInfo
.end();
1185 for(;aIter
!= aEnd
;++aIter
)
1187 // OJ: we don't want to set an autoincrement column to be key
1188 // because we don't have the possibility to know how to create
1189 // such auto increment column later on
1190 // so until we know how to do it, we create a column without autoincrement
1191 // if ( !aIter->second->bAutoIncrement )
1192 { // therefore we have searched
1193 if ( aIter
->second
->nType
== DataType::INTEGER
)
1195 pTypeInfo
= aIter
->second
; // alternative
1198 else if ( !pTypeInfo
.get() && aIter
->second
->nType
== DataType::DOUBLE
)
1199 pTypeInfo
= aIter
->second
; // alternative
1200 else if ( !pTypeInfo
.get() && aIter
->second
->nType
== DataType::REAL
)
1201 pTypeInfo
= aIter
->second
; // alternative
1204 if ( !pTypeInfo
.get() ) // just a fallback
1205 pTypeInfo
= queryTypeInfoByType(DataType::VARCHAR
,_rTypeInfo
);
1207 OSL_ENSURE(pTypeInfo
.get(),"checkColumns: cann't find a type which is useable as a key!");
1211 TOTypeInfoSP
queryTypeInfoByType(sal_Int32 _nDataType
,const OTypeInfoMap
& _rTypeInfo
)
1213 OTypeInfoMap::const_iterator aIter
= _rTypeInfo
.find(_nDataType
);
1214 if(aIter
!= _rTypeInfo
.end())
1215 return aIter
->second
;
1216 // fall back if the type is unknown
1217 TOTypeInfoSP pTypeInfo
;
1220 case DataType::TINYINT
:
1221 if( (pTypeInfo
= queryTypeInfoByType(DataType::SMALLINT
,_rTypeInfo
) ) )
1224 case DataType::SMALLINT
:
1225 if( (pTypeInfo
= queryTypeInfoByType(DataType::INTEGER
,_rTypeInfo
) ) )
1228 case DataType::INTEGER
:
1229 if( (pTypeInfo
= queryTypeInfoByType(DataType::FLOAT
,_rTypeInfo
) ) )
1232 case DataType::FLOAT
:
1233 if( (pTypeInfo
= queryTypeInfoByType(DataType::REAL
,_rTypeInfo
) ) )
1236 case DataType::DATE
:
1237 case DataType::TIME
:
1238 if( DataType::DATE
== _nDataType
|| DataType::TIME
== _nDataType
)
1240 if( (pTypeInfo
= queryTypeInfoByType(DataType::TIMESTAMP
,_rTypeInfo
) ) )
1244 case DataType::TIMESTAMP
:
1245 case DataType::REAL
:
1246 case DataType::BIGINT
:
1247 if ( (pTypeInfo
= queryTypeInfoByType(DataType::DOUBLE
,_rTypeInfo
) ) )
1250 case DataType::DOUBLE
:
1251 if ( (pTypeInfo
= queryTypeInfoByType(DataType::NUMERIC
,_rTypeInfo
) ) )
1254 case DataType::NUMERIC
:
1255 pTypeInfo
= queryTypeInfoByType(DataType::DECIMAL
,_rTypeInfo
);
1257 case DataType::DECIMAL
:
1258 if ( (pTypeInfo
= queryTypeInfoByType(DataType::NUMERIC
,_rTypeInfo
) ) )
1260 if ( (pTypeInfo
= queryTypeInfoByType(DataType::DOUBLE
,_rTypeInfo
) ) )
1263 case DataType::VARCHAR
:
1264 if ( (pTypeInfo
= queryTypeInfoByType(DataType::LONGVARCHAR
,_rTypeInfo
) ) )
1267 case DataType::LONGVARCHAR
:
1268 if ( (pTypeInfo
= queryTypeInfoByType(DataType::CLOB
,_rTypeInfo
) ) )
1276 OUString
sCreate("x"),sTypeName
;
1278 pTypeInfo
= ::dbaui::getTypeInfoFromType(_rTypeInfo
,DataType::VARCHAR
,sTypeName
,sCreate
,50,0,false,bForce
);
1280 OSL_ENSURE(pTypeInfo
,"Wrong DataType supplied!");
1284 sal_Int32
askForUserAction(vcl::Window
* _pParent
,sal_uInt16 _nTitle
,sal_uInt16 _nText
,bool _bAll
,const OUString
& _sName
)
1286 SolarMutexGuard aGuard
;
1287 OUString aMsg
= ModuleRes(_nText
);
1288 aMsg
= aMsg
.replaceFirst("%1", _sName
);
1289 ScopedVclPtrInstance
< OSQLMessageBox
> aAsk(_pParent
, ModuleRes(_nTitle
), aMsg
,WB_YES_NO
| WB_DEF_YES
,OSQLMessageBox::Query
);
1292 aAsk
->AddButton(ModuleRes(STR_BUTTON_TEXT_ALL
), RET_ALL
);
1293 aAsk
->GetPushButton(RET_ALL
)->SetHelpId(HID_CONFIRM_DROP_BUTTON_ALL
);
1295 return aAsk
->Execute();
1300 static OUString
lcl_createSDBCLevelStatement( const OUString
& _rStatement
, const Reference
< XConnection
>& _rxConnection
)
1302 OUString
sSDBCLevelStatement( _rStatement
);
1305 Reference
< XMultiServiceFactory
> xAnalyzerFactory( _rxConnection
, UNO_QUERY_THROW
);
1306 Reference
< XSingleSelectQueryAnalyzer
> xAnalyzer( xAnalyzerFactory
->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER
), UNO_QUERY_THROW
);
1307 xAnalyzer
->setQuery( _rStatement
);
1308 sSDBCLevelStatement
= xAnalyzer
->getQueryWithSubstitution();
1310 catch( const Exception
& )
1312 DBG_UNHANDLED_EXCEPTION();
1314 return sSDBCLevelStatement
;
1318 Reference
< XPropertySet
> createView( const OUString
& _rName
, const Reference
< XConnection
>& _rxConnection
,
1319 const OUString
& _rCommand
)
1321 Reference
<XViewsSupplier
> xSup(_rxConnection
,UNO_QUERY
);
1322 Reference
< XNameAccess
> xViews
;
1324 xViews
= xSup
->getViews();
1325 Reference
<XDataDescriptorFactory
> xFact(xViews
,UNO_QUERY
);
1326 OSL_ENSURE(xFact
.is(),"No XDataDescriptorFactory available!");
1330 Reference
<XPropertySet
> xView
= xFact
->createDataDescriptor();
1334 OUString sCatalog
,sSchema
,sTable
;
1335 ::dbtools::qualifiedNameComponents(_rxConnection
->getMetaData(),
1340 ::dbtools::eInDataManipulation
);
1342 xView
->setPropertyValue(PROPERTY_CATALOGNAME
,makeAny(sCatalog
));
1343 xView
->setPropertyValue(PROPERTY_SCHEMANAME
,makeAny(sSchema
));
1344 xView
->setPropertyValue(PROPERTY_NAME
,makeAny(sTable
));
1346 xView
->setPropertyValue( PROPERTY_COMMAND
, makeAny( _rCommand
) );
1348 Reference
<XAppend
> xAppend(xViews
,UNO_QUERY
);
1350 xAppend
->appendByDescriptor(xView
);
1353 // we need to reget the view because after appending it, it is no longer valid
1354 // but this time it isn't a view object it is a table object with type "VIEW"
1355 Reference
<XTablesSupplier
> xTabSup(_rxConnection
,UNO_QUERY
);
1356 Reference
< XNameAccess
> xTables
;
1359 xTables
= xTabSup
->getTables();
1360 if ( xTables
.is() && xTables
->hasByName( _rName
) )
1361 xTables
->getByName( _rName
) >>= xView
;
1367 Reference
<XPropertySet
> createView( const OUString
& _rName
, const Reference
< XConnection
>& _rxConnection
1368 ,const Reference
<XPropertySet
>& _rxSourceObject
)
1371 Reference
< XPropertySetInfo
> xPSI( _rxSourceObject
->getPropertySetInfo(), UNO_SET_THROW
);
1372 if ( xPSI
->hasPropertyByName( PROPERTY_COMMAND
) )
1374 _rxSourceObject
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
;
1376 bool bEscapeProcessing( false );
1377 OSL_VERIFY( _rxSourceObject
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bEscapeProcessing
);
1378 if ( bEscapeProcessing
)
1379 sCommand
= lcl_createSDBCLevelStatement( sCommand
, _rxConnection
);
1383 sCommand
= "SELECT * FROM " + composeTableNameForSelect( _rxConnection
, _rxSourceObject
);
1385 return createView( _rName
, _rxConnection
, sCommand
);
1388 bool insertHierachyElement( vcl::Window
* _pParent
, const Reference
< XComponentContext
>& _rxContext
,
1389 const Reference
<XHierarchicalNameContainer
>& _xNames
,
1390 const OUString
& _sParentFolder
,
1393 const Reference
<XContent
>& _xContent
,
1396 OSL_ENSURE( _xNames
.is(), "insertHierachyElement: illegal name container!" );
1397 if ( !_xNames
.is() )
1400 Reference
<XNameAccess
> xNameAccess( _xNames
, UNO_QUERY
);
1401 OUString sName
= _sParentFolder
;
1402 if ( _xNames
->hasByHierarchicalName(sName
) )
1404 Reference
<XChild
> xChild(_xNames
->getByHierarchicalName(sName
),UNO_QUERY
);
1405 xNameAccess
.set(xChild
,UNO_QUERY
);
1406 if ( !xNameAccess
.is() && xChild
.is() )
1407 xNameAccess
.set(xChild
->getParent(),UNO_QUERY
);
1410 OSL_ENSURE( xNameAccess
.is(), "insertHierachyElement: could not find the proper name container!" );
1411 if ( !xNameAccess
.is() )
1415 Reference
<XPropertySet
> xProp(_xContent
,UNO_QUERY
);
1417 xProp
->getPropertyValue(PROPERTY_NAME
) >>= sNewName
;
1419 if ( !_bMove
|| sNewName
.isEmpty() )
1421 OUString sTargetName
,sLabel
;
1422 if ( sNewName
.isEmpty() || xNameAccess
->hasByName(sNewName
) )
1424 if ( !sNewName
.isEmpty() )
1425 sTargetName
= sNewName
;
1427 sTargetName
= ModuleRes( _bCollection
? STR_NEW_FOLDER
: ((_bForm
) ? RID_STR_FORM
: RID_STR_REPORT
));
1428 sLabel
= ModuleRes( _bCollection
? STR_FOLDER_LABEL
: ((_bForm
) ? STR_FRM_LABEL
: STR_RPT_LABEL
));
1429 sTargetName
= ::dbtools::createUniqueName(xNameAccess
,sTargetName
);
1431 // here we have everything needed to create a new query object ...
1432 HierarchicalNameCheck
aNameChecker( _xNames
.get(), sName
);
1433 // ... ehm, except a new name
1434 ScopedVclPtrInstance
<OSaveAsDlg
> aAskForName(
1440 SAD_ADDITIONAL_DESCRIPTION
| SAD_TITLE_PASTE_AS
);
1441 if ( RET_OK
!= aAskForName
->Execute() )
1442 // cancelled by the user
1445 sNewName
= aAskForName
->getName();
1448 else if ( xNameAccess
->hasByName(sNewName
) )
1450 OUString
sError(ModuleRes(STR_NAME_ALREADY_EXISTS
));
1451 sError
= sError
.replaceFirst("#",sNewName
);
1452 throw SQLException(sError
,NULL
,OUString("S1000") ,0,Any());
1457 Reference
<XMultiServiceFactory
> xORB( xNameAccess
, UNO_QUERY_THROW
);
1458 Sequence
< Any
> aArguments(3);
1459 PropertyValue aValue
;
1461 aValue
.Name
= "Name";
1462 aValue
.Value
<<= sNewName
;
1463 aArguments
[0] <<= aValue
;
1465 aValue
.Name
= "Parent";
1466 aValue
.Value
<<= xNameAccess
;
1467 aArguments
[1] <<= aValue
;
1469 aValue
.Name
= PROPERTY_EMBEDDEDOBJECT
;
1470 aValue
.Value
<<= _xContent
;
1471 aArguments
[2] <<= aValue
;
1473 OUString
sServiceName(_bCollection
? ((_bForm
) ? OUString(SERVICE_NAME_FORM_COLLECTION
) : OUString(SERVICE_NAME_REPORT_COLLECTION
)) : OUString(SERVICE_SDB_DOCUMENTDEFINITION
));
1475 Reference
<XContent
> xNew( xORB
->createInstanceWithArguments( sServiceName
, aArguments
), UNO_QUERY_THROW
);
1476 Reference
< XNameContainer
> xNameContainer( xNameAccess
, UNO_QUERY_THROW
);
1477 xNameContainer
->insertByName( sNewName
, makeAny( xNew
) );
1479 catch( const IllegalArgumentException
& e
)
1481 ::dbtools::throwGenericSQLException( e
.Message
, e
.Context
);
1483 catch( const Exception
& )
1485 DBG_UNHANDLED_EXCEPTION();
1492 Reference
< XNumberFormatter
> getNumberFormatter(const Reference
< XConnection
>& _rxConnection
, const Reference
< ::com::sun::star::uno::XComponentContext
>& _rxContext
)
1494 // create a formatter working with the connections format supplier
1495 Reference
< XNumberFormatter
> xFormatter
;
1499 Reference
< ::com::sun::star::util::XNumberFormatsSupplier
> xSupplier(::dbtools::getNumberFormats(_rxConnection
, true, _rxContext
));
1501 if ( xSupplier
.is() )
1503 // create a new formatter
1504 xFormatter
= Reference
< util::XNumberFormatter
> (
1505 util::NumberFormatter::create( _rxContext
), UNO_QUERY_THROW
);
1506 xFormatter
->attachNumberFormatsSupplier(xSupplier
);
1509 catch(const Exception
&)
1511 DBG_UNHANDLED_EXCEPTION();
1518 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */