Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / dbaccess / source / ui / misc / UITools.cxx
blob8027c7aed2b1a1ea20d0e5dba9f0b0806de5209f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
109 #include <memory>
111 namespace dbaui
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!");
160 return aInfo;
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!");
185 else
186 { // instantiate the default SDB interaction handler
187 Reference< XInteractionHandler > xHandler( InteractionHandler::createWithParent(_rxContext, nullptr), UNO_QUERY);
188 _rOUTConnection = xConnectionCompletion->connectWithCompletion(xHandler);
191 else
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!"); }
206 return aInfo;
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;
215 Any aError;
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();
235 else
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() )
248 return xDatasource;
250 if ( aSQLError.isValid() )
252 if ( _pErrorInfo )
254 *_pErrorInfo = aSQLError;
256 else
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();
272 if ( !xRet.is() )
274 Reference<XOfficeDatabaseDocument> xOfficeDoc(_xObject,UNO_QUERY);
275 if ( xOfficeDoc.is() )
276 xRet = xOfficeDoc->getDataSource();
279 return xRet;
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,
289 sal_Int32 _nType,
290 const OUString& _sTypeName,
291 const OUString& _sCreateParams,
292 sal_Int32 _nPrecision,
293 sal_Int32 _nScale,
294 bool _bAutoIncrement,
295 bool& _brForceToType)
297 TOTypeInfoSP pTypeInfo;
298 _brForceToType = false;
299 // search for type
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
307 #ifdef DBG_UTIL
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;
312 #endif
313 if ( (
314 _sTypeName.isEmpty()
315 || (aIter->second->aTypeName.equalsIgnoreAsciiCase(_sTypeName))
317 && (
319 !aIter->second->aCreateParams.getLength()
320 && _sCreateParams.isEmpty()
322 || (
323 (aIter->second->nPrecision >= _nPrecision)
324 && (aIter->second->nMaximumScale >= _nScale)
325 && ( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
329 break;
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).");
348 break;
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
356 // type id (nType)
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 )
367 break;
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)
381 break;
383 if ( aIter == aPair.second )
385 // try it without the auto increment flag
386 pTypeInfo = getTypeInfoFromType(_rTypeInfo,
387 _nType,
388 _sTypeName,
389 _sCreateParams,
390 _nPrecision,
391 _nScale,
392 false,
393 _brForceToType);
395 else
396 pTypeInfo = aIter->second;
398 else
400 pTypeInfo = aPair.first->second;
401 _brForceToType = true;
404 else
405 pTypeInfo = aIter->second;
407 else
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;
418 break;
423 OSL_ENSURE(pTypeInfo, "getTypeInfoFromType: no type info found for this type!");
424 return pTypeInfo;
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())
433 return;
434 Reference< XResultSet> xRs = _rxConnection->getMetaData ()->getTypeInfo ();
435 Reference< XRow> xRow(xRs,UNO_QUERY);
436 // Information for a single SQL type
437 if(xRs.is())
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
446 while (xRs->next())
448 TOTypeInfoSP pInfo(new OTypeInfo());
449 sal_Int32 nPos = 1;
450 if ( aTypes.empty() )
452 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
453 if ( nCount < 1 )
454 nCount = 18;
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;
467 ++nPos;
468 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
469 pInfo->nType = aValue;
470 ++nPos;
471 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
472 pInfo->nPrecision = aValue;
473 ++nPos;
474 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
475 pInfo->aLiteralPrefix = aValue;
476 ++nPos;
477 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
478 pInfo->aLiteralSuffix = aValue;
479 ++nPos;
480 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
481 pInfo->aCreateParams = aValue;
482 ++nPos;
483 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
484 pInfo->bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
485 ++nPos;
486 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
487 pInfo->bCaseSensitive = (bool)aValue;
488 ++nPos;
489 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
490 pInfo->nSearchType = aValue;
491 ++nPos;
492 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
493 pInfo->bUnsigned = (bool)aValue;
494 ++nPos;
495 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
496 pInfo->bCurrency = (bool)aValue;
497 ++nPos;
498 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
499 pInfo->bAutoIncrement = (bool)aValue;
500 ++nPos;
501 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
502 pInfo->aLocalTypeName = aValue;
503 ++nPos;
504 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
505 pInfo->nMinimumScale = aValue;
506 ++nPos;
507 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
508 pInfo->nMaximumScale = aValue;
509 assert(nPos == 15);
510 // 16 and 17 are unused
511 nPos = 18;
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;
525 OUString aName;
526 switch(pInfo->nType)
528 case DataType::CHAR:
529 aName = _rsTypeNames.getToken(TYPE_CHAR, ';');
530 break;
531 case DataType::VARCHAR:
532 aName = _rsTypeNames.getToken(TYPE_TEXT, ';');
533 break;
534 case DataType::DECIMAL:
535 aName = _rsTypeNames.getToken(TYPE_DECIMAL, ';');
536 break;
537 case DataType::NUMERIC:
538 aName = _rsTypeNames.getToken(TYPE_NUMERIC, ';');
539 break;
540 case DataType::BIGINT:
541 aName = _rsTypeNames.getToken(TYPE_BIGINT, ';');
542 break;
543 case DataType::FLOAT:
544 aName = _rsTypeNames.getToken(TYPE_FLOAT, ';');
545 break;
546 case DataType::DOUBLE:
547 aName = _rsTypeNames.getToken(TYPE_DOUBLE, ';');
548 break;
549 case DataType::LONGVARCHAR:
550 aName = _rsTypeNames.getToken(TYPE_MEMO, ';');
551 break;
552 case DataType::LONGVARBINARY:
553 aName = _rsTypeNames.getToken(TYPE_IMAGE, ';');
554 break;
555 case DataType::DATE:
556 aName = _rsTypeNames.getToken(TYPE_DATE, ';');
557 break;
558 case DataType::TIME:
559 aName = _rsTypeNames.getToken(TYPE_TIME, ';');
560 break;
561 case DataType::TIMESTAMP:
562 aName = _rsTypeNames.getToken(TYPE_DATETIME, ';');
563 break;
564 case DataType::BIT:
565 if ( !pInfo->aCreateParams.isEmpty() )
567 aName = _rsTypeNames.getToken(TYPE_BIT, ';');
568 break;
570 SAL_FALLTHROUGH;
571 case DataType::BOOLEAN:
572 aName = _rsTypeNames.getToken(TYPE_BOOL, ';');
573 break;
574 case DataType::TINYINT:
575 aName = _rsTypeNames.getToken(TYPE_TINYINT, ';');
576 break;
577 case DataType::SMALLINT:
578 aName = _rsTypeNames.getToken(TYPE_SMALLINT, ';');
579 break;
580 case DataType::INTEGER:
581 aName = _rsTypeNames.getToken(TYPE_INTEGER, ';');
582 break;
583 case DataType::REAL:
584 aName = _rsTypeNames.getToken(TYPE_REAL, ';');
585 break;
586 case DataType::BINARY:
587 aName = _rsTypeNames.getToken(TYPE_BINARY, ';');
588 break;
589 case DataType::VARBINARY:
590 aName = _rsTypeNames.getToken(TYPE_VARBINARY, ';');
591 break;
592 case DataType::SQLNULL:
593 aName = _rsTypeNames.getToken(TYPE_SQLNULL, ';');
594 break;
595 case DataType::OBJECT:
596 aName = _rsTypeNames.getToken(TYPE_OBJECT, ';');
597 break;
598 case DataType::DISTINCT:
599 aName = _rsTypeNames.getToken(TYPE_DISTINCT, ';');
600 break;
601 case DataType::STRUCT:
602 aName = _rsTypeNames.getToken(TYPE_STRUCT, ';');
603 break;
604 case DataType::ARRAY:
605 aName = _rsTypeNames.getToken(TYPE_ARRAY, ';');
606 break;
607 case DataType::BLOB:
608 aName = _rsTypeNames.getToken(TYPE_BLOB, ';');
609 break;
610 case DataType::CLOB:
611 aName = _rsTypeNames.getToken(TYPE_CLOB, ';');
612 break;
613 case DataType::REF:
614 aName = _rsTypeNames.getToken(TYPE_REF, ';');
615 break;
616 case DataType::OTHER:
617 aName = _rsTypeNames.getToken(TYPE_OTHER, ';');
618 break;
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();
675 if ( xCon.is() )
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);
684 if(!xRow->wasNull())
685 break;
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&)
703 return sDefaultName;
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);
710 if ( !bRet )
711 { // try if this one is a URL
714 bRet = xDataBaseContext->getByName(_sDataSourceName).hasValue();
716 catch(const Exception&)
720 return bRet;
723 sal_Int32 mapTextAllign(const SvxCellHorJustify& _eAlignment)
725 sal_Int32 nAlignment = css::awt::TextAlign::LEFT;
726 switch (_eAlignment)
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;
732 default:
733 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
735 return nAlignment;
738 SvxCellHorJustify mapTextJustify(sal_Int32 _nAlignment)
740 SvxCellHorJustify eJustify = SVX_HOR_JUSTIFY_LEFT;
741 switch (_nAlignment)
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;
746 default:
747 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
749 return eJustify;
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;
770 if ( bHasFormat )
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)));
776 if (bHasFormat)
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,
793 bool _bHasFormat)
795 bool bRet = false;
797 // UNO->ItemSet
798 static SfxItemInfo aItemInfos[] =
800 { 0, false },
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));
828 // fill it
829 pFormatDescriptor->Put(SvxHorJustifyItem(_eJustify, SBA_ATTR_ALIGN_HOR_JUSTIFY));
830 bool bText = false;
831 if (_bHasFormat)
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))
836 bText = true;
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));
846 if (!bText)
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())
857 // ItemSet->UNO
858 // UNO-properties
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();
868 // format key
869 if (_bHasFormat)
871 const SfxUInt32Item* pFormat = pSet->GetItem<SfxUInt32Item>(SBA_DEF_FMTVALUE);
872 _nFormatKey = (sal_Int32)pFormat->GetValue();
874 bRet = true;
876 // deleted formats
877 const SfxItemSet* pResult = aDlg->GetOutputItemSet();
878 if (pResult)
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)
895 delete pDefault;
897 return bRet;
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!");
904 return pFilter;
907 bool appendToFilter(const Reference<XConnection>& _xConnection,
908 const OUString& _sName,
909 const Reference< XComponentContext >& _rxContext,
910 vcl::Window* _pParent)
912 bool bRet = false;
913 Reference< XChild> xChild(_xConnection,UNO_QUERY);
914 if(xChild.is())
916 Reference< XPropertySet> xProp(xChild->getParent(),UNO_QUERY);
917 if(xProp.is())
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)
929 sal_Int32 nLen;
930 if((nLen = pBegin->lastIndexOf('.')) != -1 && !pBegin->compareTo(_sName,nLen))
931 bHasToInsert = false;
932 else if(pBegin->getLength() == 1)
933 bHasToInsert = false;
937 bRet = true;
938 if(bHasToInsert)
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();
944 bRet = false;
946 else
948 aFilter.realloc(aFilter.getLength()+1);
949 aFilter.getArray()[aFilter.getLength()-1] = _sName;
950 xProp->setPropertyValue(PROPERTY_TABLEFILTER,makeAny(aFilter));
955 return bRet;
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;
962 if ( pSystemWindow )
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();
1003 if ( -1 == nValue )
1004 { // default width
1005 nValue = _pBox->GetDefaultColumnWidth( _pBox->GetColumnTitle( _nColId ) );
1007 else
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);
1061 if(xChild.is())
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);
1085 return sName;
1088 void AppendConfigToken( OUString& _rURL, bool _bQuestionMark )
1090 // query part exists?
1091 if ( _bQuestionMark )
1092 // no, so start with '?'
1093 _rURL += "?";
1094 else
1095 // yes, so only append with '&'
1096 _rURL += "&";
1098 // set parameters
1099 _rURL += "Language=";
1100 _rURL += utl::ConfigManager::getLocale();
1101 _rURL += "&System=";
1102 _rURL += SvtHelpOptions().GetSystem();
1105 namespace
1108 bool GetHelpAnchor_Impl( const OUString& _rURL, OUString& _rAnchor )
1110 bool bRet = false;
1111 OUString sAnchor;
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() )
1123 _rAnchor = sAnchor;
1124 bRet = true;
1127 else
1129 SAL_WARN( "dbaccess.ui", "Property 'AnchorName' is missing" );
1132 catch( Exception& )
1136 return bRet;
1138 } // anonymous
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);
1146 OUString sAnchor;
1147 OUString sTempURL = aURL.Complete;
1148 AppendConfigToken( sTempURL, true );
1149 bool bHasAnchor = GetHelpAnchor_Impl( sTempURL, sAnchor );
1150 AppendConfigToken(aURL.Complete,true);
1151 if ( bHasAnchor )
1153 aURL.Complete += "#";
1154 aURL.Complete += sAnchor;
1156 return aURL;
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
1195 break;
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!");
1207 return pTypeInfo;
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;
1217 switch(_nDataType)
1219 case DataType::TINYINT:
1220 if( (pTypeInfo = queryTypeInfoByType(DataType::SMALLINT,_rTypeInfo) ) )
1221 break;
1222 SAL_FALLTHROUGH;
1223 case DataType::SMALLINT:
1224 if( (pTypeInfo = queryTypeInfoByType(DataType::INTEGER,_rTypeInfo) ) )
1225 break;
1226 SAL_FALLTHROUGH;
1227 case DataType::INTEGER:
1228 if( (pTypeInfo = queryTypeInfoByType(DataType::FLOAT,_rTypeInfo) ) )
1229 break;
1230 SAL_FALLTHROUGH;
1231 case DataType::FLOAT:
1232 if( (pTypeInfo = queryTypeInfoByType(DataType::REAL,_rTypeInfo) ) )
1233 break;
1234 SAL_FALLTHROUGH;
1235 case DataType::DATE:
1236 case DataType::TIME:
1237 if( DataType::DATE == _nDataType || DataType::TIME == _nDataType )
1239 if( (pTypeInfo = queryTypeInfoByType(DataType::TIMESTAMP,_rTypeInfo) ) )
1240 break;
1242 SAL_FALLTHROUGH;
1243 case DataType::TIMESTAMP:
1244 case DataType::REAL:
1245 case DataType::BIGINT:
1246 if ( (pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo) ) )
1247 break;
1248 SAL_FALLTHROUGH;
1249 case DataType::DOUBLE:
1250 if ( (pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo) ) )
1251 break;
1252 SAL_FALLTHROUGH;
1253 case DataType::NUMERIC:
1254 pTypeInfo = queryTypeInfoByType(DataType::DECIMAL,_rTypeInfo);
1255 break;
1256 case DataType::DECIMAL:
1257 if ( (pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo) ) )
1258 break;
1259 if ( (pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo) ) )
1260 break;
1261 break;
1262 case DataType::VARCHAR:
1263 if ( (pTypeInfo = queryTypeInfoByType(DataType::LONGVARCHAR,_rTypeInfo) ) )
1264 break;
1265 break;
1266 case DataType::LONGVARCHAR:
1267 if ( (pTypeInfo = queryTypeInfoByType(DataType::CLOB,_rTypeInfo) ) )
1268 break;
1269 break;
1270 default:
1273 if ( !pTypeInfo )
1275 OUString sTypeName;
1276 bool bForce = true;
1277 pTypeInfo = ::dbaui::getTypeInfoFromType(_rTypeInfo,DataType::VARCHAR,sTypeName,"x",50,0,false,bForce);
1279 OSL_ENSURE(pTypeInfo,"Wrong DataType supplied!");
1280 return pTypeInfo;
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);
1289 if ( _bAll )
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();
1297 namespace
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;
1322 if(xSup.is())
1323 xViews = xSup->getViews();
1324 Reference<XDataDescriptorFactory> xFact(xViews,UNO_QUERY);
1325 OSL_ENSURE(xFact.is(),"No XDataDescriptorFactory available!");
1326 if(!xFact.is())
1327 return nullptr;
1329 Reference<XPropertySet> xView = xFact->createDataDescriptor();
1330 if ( !xView.is() )
1331 return nullptr;
1333 OUString sCatalog,sSchema,sTable;
1334 ::dbtools::qualifiedNameComponents(_rxConnection->getMetaData(),
1335 _rName,
1336 sCatalog,
1337 sSchema,
1338 sTable,
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);
1348 if(xAppend.is())
1349 xAppend->appendByDescriptor(xView);
1351 xView = nullptr;
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;
1356 if ( xTabSup.is() )
1358 xTables = xTabSup->getTables();
1359 if ( xTables.is() && xTables->hasByName( _rName ) )
1360 xTables->getByName( _rName ) >>= xView;
1363 return xView;
1366 Reference<XPropertySet> createView( const OUString& _rName, const Reference< XConnection >& _rxConnection
1367 ,const Reference<XPropertySet>& _rxSourceObject)
1369 OUString sCommand;
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 );
1380 else
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,
1390 bool _bForm,
1391 bool _bCollection,
1392 const Reference<XContent>& _xContent,
1393 bool _bMove)
1395 OSL_ENSURE( _xNames.is(), "insertHierachyElement: illegal name container!" );
1396 if ( !_xNames.is() )
1397 return false;
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() )
1410 return false;
1412 OUString sNewName;
1413 Reference<XPropertySet> xProp(_xContent,UNO_QUERY);
1414 if ( xProp.is() )
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;
1424 else
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(
1433 _pParent,
1434 _rxContext,
1435 sTargetName,
1436 sLabel,
1437 aNameChecker,
1438 SAD_ADDITIONAL_DESCRIPTION | SAD_TITLE_PASTE_AS );
1439 if ( RET_OK != aAskForName->Execute() )
1440 // cancelled by the user
1441 return false;
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;
1458 // set as folder
1459 aValue.Name = "Name";
1460 aValue.Value <<= sNewName;
1461 aArguments[0] <<= aValue;
1462 //parent
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();
1484 return false;
1487 return true;
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();
1510 return xFormatter;
1513 } // dbaui
1515 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */