Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / misc / UITools.cxx
blobc207e30087fb3fabd1580243d1b5079125ac7022
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 <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>
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;
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!");
161 return aInfo;
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!");
186 else
187 { // instantiate the default SDB interaction handler
188 Reference< XInteractionHandler > xHandler( InteractionHandler::createWithParent(_rxContext, 0), UNO_QUERY);
189 _rOUTConnection = xConnectionCompletion->connectWithCompletion(xHandler);
192 else
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!"); }
207 return aInfo;
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;
216 Any aError;
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();
236 else
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() )
249 return xDatasource;
251 if ( aSQLError.isValid() )
253 if ( _pErrorInfo )
255 *_pErrorInfo = aSQLError;
257 else
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();
273 if ( !xRet.is() )
275 Reference<XOfficeDatabaseDocument> xOfficeDoc(_xObject,UNO_QUERY);
276 if ( xOfficeDoc.is() )
277 xRet = xOfficeDoc->getDataSource();
280 return xRet;
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,
290 sal_Int32 _nType,
291 const OUString& _sTypeName,
292 const OUString& _sCreateParams,
293 sal_Int32 _nPrecision,
294 sal_Int32 _nScale,
295 bool _bAutoIncrement,
296 bool& _brForceToType)
298 TOTypeInfoSP pTypeInfo;
299 _brForceToType = false;
300 // search for type
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
308 #ifdef DBG_UTIL
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;
313 #endif
314 if ( (
315 _sTypeName.isEmpty()
316 || (aIter->second->aTypeName.equalsIgnoreAsciiCase(_sTypeName))
318 && (
320 !aIter->second->aCreateParams.getLength()
321 && _sCreateParams.isEmpty()
323 || (
324 (aIter->second->nPrecision >= _nPrecision)
325 && (aIter->second->nMaximumScale >= _nScale)
326 && ( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
330 break;
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).");
349 break;
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
357 // type id (nType)
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 )
368 break;
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)
382 break;
384 if ( aIter == aPair.second )
386 // try it without the auto increment flag
387 pTypeInfo = getTypeInfoFromType(_rTypeInfo,
388 _nType,
389 _sTypeName,
390 _sCreateParams,
391 _nPrecision,
392 _nScale,
393 false,
394 _brForceToType);
396 else
397 pTypeInfo = aIter->second;
399 else
401 pTypeInfo = aPair.first->second;
402 _brForceToType = true;
405 else
406 pTypeInfo = aIter->second;
408 else
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;
419 break;
424 OSL_ENSURE(pTypeInfo, "getTypeInfoFromType: no type info found for this type!");
425 return pTypeInfo;
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())
434 return;
435 Reference< XResultSet> xRs = _rxConnection->getMetaData ()->getTypeInfo ();
436 Reference< XRow> xRow(xRs,UNO_QUERY);
437 // Information for a single SQL type
438 if(xRs.is())
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
447 while (xRs->next())
449 TOTypeInfoSP pInfo(new OTypeInfo());
450 sal_Int32 nPos = 1;
451 if ( aTypes.empty() )
453 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
454 if ( nCount < 1 )
455 nCount = 18;
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;
468 ++nPos;
469 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
470 pInfo->nType = aValue;
471 ++nPos;
472 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
473 pInfo->nPrecision = aValue;
474 ++nPos;
475 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
476 pInfo->aLiteralPrefix = aValue;
477 ++nPos;
478 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
479 pInfo->aLiteralSuffix = aValue;
480 ++nPos;
481 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
482 pInfo->aCreateParams = aValue;
483 ++nPos;
484 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
485 pInfo->bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
486 ++nPos;
487 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
488 pInfo->bCaseSensitive = (bool)aValue;
489 ++nPos;
490 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
491 pInfo->nSearchType = aValue;
492 ++nPos;
493 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
494 pInfo->bUnsigned = (bool)aValue;
495 ++nPos;
496 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
497 pInfo->bCurrency = (bool)aValue;
498 ++nPos;
499 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
500 pInfo->bAutoIncrement = (bool)aValue;
501 ++nPos;
502 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
503 pInfo->aLocalTypeName = aValue;
504 ++nPos;
505 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
506 pInfo->nMinimumScale = aValue;
507 ++nPos;
508 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
509 pInfo->nMaximumScale = aValue;
510 assert(nPos == 15);
511 // 16 and 17 are unused
512 nPos = 18;
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;
526 OUString aName;
527 switch(pInfo->nType)
529 case DataType::CHAR:
530 aName = _rsTypeNames.getToken(TYPE_CHAR, ';');
531 break;
532 case DataType::VARCHAR:
533 aName = _rsTypeNames.getToken(TYPE_TEXT, ';');
534 break;
535 case DataType::DECIMAL:
536 aName = _rsTypeNames.getToken(TYPE_DECIMAL, ';');
537 break;
538 case DataType::NUMERIC:
539 aName = _rsTypeNames.getToken(TYPE_NUMERIC, ';');
540 break;
541 case DataType::BIGINT:
542 aName = _rsTypeNames.getToken(TYPE_BIGINT, ';');
543 break;
544 case DataType::FLOAT:
545 aName = _rsTypeNames.getToken(TYPE_FLOAT, ';');
546 break;
547 case DataType::DOUBLE:
548 aName = _rsTypeNames.getToken(TYPE_DOUBLE, ';');
549 break;
550 case DataType::LONGVARCHAR:
551 aName = _rsTypeNames.getToken(TYPE_MEMO, ';');
552 break;
553 case DataType::LONGVARBINARY:
554 aName = _rsTypeNames.getToken(TYPE_IMAGE, ';');
555 break;
556 case DataType::DATE:
557 aName = _rsTypeNames.getToken(TYPE_DATE, ';');
558 break;
559 case DataType::TIME:
560 aName = _rsTypeNames.getToken(TYPE_TIME, ';');
561 break;
562 case DataType::TIMESTAMP:
563 aName = _rsTypeNames.getToken(TYPE_DATETIME, ';');
564 break;
565 case DataType::BIT:
566 if ( !pInfo->aCreateParams.isEmpty() )
568 aName = _rsTypeNames.getToken(TYPE_BIT, ';');
569 break;
571 // run through
572 case DataType::BOOLEAN:
573 aName = _rsTypeNames.getToken(TYPE_BOOL, ';');
574 break;
575 case DataType::TINYINT:
576 aName = _rsTypeNames.getToken(TYPE_TINYINT, ';');
577 break;
578 case DataType::SMALLINT:
579 aName = _rsTypeNames.getToken(TYPE_SMALLINT, ';');
580 break;
581 case DataType::INTEGER:
582 aName = _rsTypeNames.getToken(TYPE_INTEGER, ';');
583 break;
584 case DataType::REAL:
585 aName = _rsTypeNames.getToken(TYPE_REAL, ';');
586 break;
587 case DataType::BINARY:
588 aName = _rsTypeNames.getToken(TYPE_BINARY, ';');
589 break;
590 case DataType::VARBINARY:
591 aName = _rsTypeNames.getToken(TYPE_VARBINARY, ';');
592 break;
593 case DataType::SQLNULL:
594 aName = _rsTypeNames.getToken(TYPE_SQLNULL, ';');
595 break;
596 case DataType::OBJECT:
597 aName = _rsTypeNames.getToken(TYPE_OBJECT, ';');
598 break;
599 case DataType::DISTINCT:
600 aName = _rsTypeNames.getToken(TYPE_DISTINCT, ';');
601 break;
602 case DataType::STRUCT:
603 aName = _rsTypeNames.getToken(TYPE_STRUCT, ';');
604 break;
605 case DataType::ARRAY:
606 aName = _rsTypeNames.getToken(TYPE_ARRAY, ';');
607 break;
608 case DataType::BLOB:
609 aName = _rsTypeNames.getToken(TYPE_BLOB, ';');
610 break;
611 case DataType::CLOB:
612 aName = _rsTypeNames.getToken(TYPE_CLOB, ';');
613 break;
614 case DataType::REF:
615 aName = _rsTypeNames.getToken(TYPE_REF, ';');
616 break;
617 case DataType::OTHER:
618 aName = _rsTypeNames.getToken(TYPE_OTHER, ';');
619 break;
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();
676 if ( xCon.is() )
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);
685 if(!xRow->wasNull())
686 break;
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&)
704 return sDefaultName;
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);
711 if ( !bRet )
712 { // try if this one is a URL
715 bRet = xDataBaseContext->getByName(_sDataSourceName).hasValue();
717 catch(const Exception&)
721 return bRet;
724 sal_Int32 mapTextAllign(const SvxCellHorJustify& _eAlignment)
726 sal_Int32 nAlignment = com::sun::star::awt::TextAlign::LEFT;
727 switch (_eAlignment)
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;
733 default:
734 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
736 return nAlignment;
739 SvxCellHorJustify mapTextJustify(const sal_Int32& _nAlignment)
741 SvxCellHorJustify eJustify = SVX_HOR_JUSTIFY_LEFT;
742 switch (_nAlignment)
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;
747 default:
748 SAL_WARN("dbaccess.ui", "Invalid TextAlign!");
750 return eJustify;
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;
771 if ( bHasFormat )
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)));
777 if (bHasFormat)
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,
794 bool _bHasFormat)
796 bool bRet = false;
798 // UNO->ItemSet
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);
829 // fill it
830 pFormatDescriptor->Put(SvxHorJustifyItem(_eJustify, SBA_ATTR_ALIGN_HOR_JUSTIFY));
831 bool bText = false;
832 if (_bHasFormat)
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))
837 bText = true;
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));
847 if (!bText)
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())
858 // ItemSet->UNO
859 // UNO-properties
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();
869 // format key
870 if (_bHasFormat)
872 SFX_ITEMSET_GET(*pSet, pFormat, SfxUInt32Item, SBA_DEF_FMTVALUE, true);
873 _nFormatKey = (sal_Int32)pFormat->GetValue();
875 bRet = true;
877 // deleted formats
878 const SfxItemSet* pResult = aDlg->GetOutputItemSet();
879 if (pResult)
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)
896 delete pDefaults[i];
898 return bRet;
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!");
905 return pFilter;
908 bool appendToFilter(const Reference<XConnection>& _xConnection,
909 const OUString& _sName,
910 const Reference< XComponentContext >& _rxContext,
911 vcl::Window* _pParent)
913 bool bRet = false;
914 Reference< XChild> xChild(_xConnection,UNO_QUERY);
915 if(xChild.is())
917 Reference< XPropertySet> xProp(xChild->getParent(),UNO_QUERY);
918 if(xProp.is())
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)
930 sal_Int32 nLen;
931 if((nLen = pBegin->lastIndexOf('.')) != -1 && !pBegin->compareTo(_sName,nLen))
932 bHasToInsert = false;
933 else if(pBegin->getLength() == 1)
934 bHasToInsert = false;
938 bRet = true;
939 if(bHasToInsert)
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();
945 bRet = false;
947 else
949 aFilter.realloc(aFilter.getLength()+1);
950 aFilter.getArray()[aFilter.getLength()-1] = _sName;
951 xProp->setPropertyValue(PROPERTY_TABLEFILTER,makeAny(aFilter));
956 return bRet;
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;
963 if ( pSystemWindow )
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();
1004 if ( -1 == nValue )
1005 { // default width
1006 nValue = _pBox->GetDefaultColumnWidth( _pBox->GetColumnTitle( _nColId ) );
1008 else
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);
1062 if(xChild.is())
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);
1086 return sName;
1089 void AppendConfigToken( OUString& _rURL, bool _bQuestionMark )
1091 // query part exists?
1092 if ( _bQuestionMark )
1093 // no, so start with '?'
1094 _rURL += "?";
1095 else
1096 // yes, so only append with '&'
1097 _rURL += "&";
1099 // set parameters
1100 _rURL += "Language=";
1101 _rURL += utl::ConfigManager::getLocale();
1102 _rURL += "&System=";
1103 _rURL += SvtHelpOptions().GetSystem();
1106 namespace
1109 bool GetHelpAnchor_Impl( const OUString& _rURL, OUString& _rAnchor )
1111 bool bRet = false;
1112 OUString sAnchor;
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() )
1124 _rAnchor = sAnchor;
1125 bRet = true;
1128 else
1130 SAL_WARN( "dbaccess.ui", "Property 'AnchorName' is missing" );
1133 catch( Exception& )
1137 return bRet;
1139 } // annonymous
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);
1147 OUString sAnchor;
1148 OUString sTempURL = aURL.Complete;
1149 AppendConfigToken( sTempURL, true );
1150 bool bHasAnchor = GetHelpAnchor_Impl( sTempURL, sAnchor );
1151 AppendConfigToken(aURL.Complete,true);
1152 if ( bHasAnchor )
1154 aURL.Complete += "#";
1155 aURL.Complete += sAnchor;
1157 return aURL;
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
1196 break;
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!");
1208 return pTypeInfo;
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;
1218 switch(_nDataType)
1220 case DataType::TINYINT:
1221 if( (pTypeInfo = queryTypeInfoByType(DataType::SMALLINT,_rTypeInfo) ) )
1222 break;
1223 // run through
1224 case DataType::SMALLINT:
1225 if( (pTypeInfo = queryTypeInfoByType(DataType::INTEGER,_rTypeInfo) ) )
1226 break;
1227 // run through
1228 case DataType::INTEGER:
1229 if( (pTypeInfo = queryTypeInfoByType(DataType::FLOAT,_rTypeInfo) ) )
1230 break;
1231 // run through
1232 case DataType::FLOAT:
1233 if( (pTypeInfo = queryTypeInfoByType(DataType::REAL,_rTypeInfo) ) )
1234 break;
1235 // run through
1236 case DataType::DATE:
1237 case DataType::TIME:
1238 if( DataType::DATE == _nDataType || DataType::TIME == _nDataType )
1240 if( (pTypeInfo = queryTypeInfoByType(DataType::TIMESTAMP,_rTypeInfo) ) )
1241 break;
1243 // run through
1244 case DataType::TIMESTAMP:
1245 case DataType::REAL:
1246 case DataType::BIGINT:
1247 if ( (pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo) ) )
1248 break;
1249 // run through
1250 case DataType::DOUBLE:
1251 if ( (pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo) ) )
1252 break;
1253 // run through
1254 case DataType::NUMERIC:
1255 pTypeInfo = queryTypeInfoByType(DataType::DECIMAL,_rTypeInfo);
1256 break;
1257 case DataType::DECIMAL:
1258 if ( (pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo) ) )
1259 break;
1260 if ( (pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo) ) )
1261 break;
1262 break;
1263 case DataType::VARCHAR:
1264 if ( (pTypeInfo = queryTypeInfoByType(DataType::LONGVARCHAR,_rTypeInfo) ) )
1265 break;
1266 break;
1267 case DataType::LONGVARCHAR:
1268 if ( (pTypeInfo = queryTypeInfoByType(DataType::CLOB,_rTypeInfo) ) )
1269 break;
1270 break;
1271 default:
1274 if ( !pTypeInfo )
1276 OUString sCreate("x"),sTypeName;
1277 bool bForce = true;
1278 pTypeInfo = ::dbaui::getTypeInfoFromType(_rTypeInfo,DataType::VARCHAR,sTypeName,sCreate,50,0,false,bForce);
1280 OSL_ENSURE(pTypeInfo,"Wrong DataType supplied!");
1281 return pTypeInfo;
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);
1290 if ( _bAll )
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();
1298 namespace
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;
1323 if(xSup.is())
1324 xViews = xSup->getViews();
1325 Reference<XDataDescriptorFactory> xFact(xViews,UNO_QUERY);
1326 OSL_ENSURE(xFact.is(),"No XDataDescriptorFactory available!");
1327 if(!xFact.is())
1328 return NULL;
1330 Reference<XPropertySet> xView = xFact->createDataDescriptor();
1331 if ( !xView.is() )
1332 return NULL;
1334 OUString sCatalog,sSchema,sTable;
1335 ::dbtools::qualifiedNameComponents(_rxConnection->getMetaData(),
1336 _rName,
1337 sCatalog,
1338 sSchema,
1339 sTable,
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);
1349 if(xAppend.is())
1350 xAppend->appendByDescriptor(xView);
1352 xView = NULL;
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;
1357 if ( xTabSup.is() )
1359 xTables = xTabSup->getTables();
1360 if ( xTables.is() && xTables->hasByName( _rName ) )
1361 xTables->getByName( _rName ) >>= xView;
1364 return xView;
1367 Reference<XPropertySet> createView( const OUString& _rName, const Reference< XConnection >& _rxConnection
1368 ,const Reference<XPropertySet>& _rxSourceObject)
1370 OUString sCommand;
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 );
1381 else
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,
1391 bool _bForm,
1392 bool _bCollection,
1393 const Reference<XContent>& _xContent,
1394 bool _bMove)
1396 OSL_ENSURE( _xNames.is(), "insertHierachyElement: illegal name container!" );
1397 if ( !_xNames.is() )
1398 return false;
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() )
1412 return false;
1414 OUString sNewName;
1415 Reference<XPropertySet> xProp(_xContent,UNO_QUERY);
1416 if ( xProp.is() )
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;
1426 else
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(
1435 _pParent,
1436 _rxContext,
1437 sTargetName,
1438 sLabel,
1439 aNameChecker,
1440 SAD_ADDITIONAL_DESCRIPTION | SAD_TITLE_PASTE_AS );
1441 if ( RET_OK != aAskForName->Execute() )
1442 // cancelled by the user
1443 return false;
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;
1460 // set as folder
1461 aValue.Name = "Name";
1462 aValue.Value <<= sNewName;
1463 aArguments[0] <<= aValue;
1464 //parent
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();
1486 return false;
1489 return true;
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();
1513 return xFormatter;
1516 } // dbaui
1518 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */