1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 #if STLPORT_VERSION>=321 27 #include <cstdarg> 28 #endif 29 30 #include <stdio.h> 31 #include <unotxdoc.hxx> 32 #include <com/sun/star/text/NotePrintMode.hpp> 33 #include <sfx2/app.hxx> 34 #include <com/sun/star/sdb/CommandType.hpp> 35 #include <com/sun/star/sdb/XDocumentDataSource.hpp> 36 #include <com/sun/star/frame/XComponentLoader.hpp> 37 #include <com/sun/star/lang/DisposedException.hpp> 38 #include <com/sun/star/lang/XEventListener.hpp> 39 #include <com/sun/star/util/XNumberFormatter.hpp> 40 #include <com/sun/star/sdb/XCompletedConnection.hpp> 41 #include <com/sun/star/sdb/XCompletedExecution.hpp> 42 #include <com/sun/star/container/XChild.hpp> 43 #include <com/sun/star/text/MailMergeEvent.hpp> 44 #include <com/sun/star/frame/XStorable.hpp> 45 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 46 #include <com/sun/star/ui/dialogs/XFilePicker.hpp> 47 #include <com/sun/star/ui/dialogs/XFilterManager.hpp> 48 #include <com/sun/star/uno/XNamingService.hpp> 49 #include <com/sun/star/util/XCloseable.hpp> 50 #include <com/sun/star/beans/XPropertySet.hpp> 51 #include <sfx2/fcontnr.hxx> 52 #include <sfx2/filedlghelper.hxx> 53 #include <sfx2/viewfrm.hxx> 54 #include <dbconfig.hxx> 55 #include <swdbtoolsclient.hxx> 56 #include <pagedesc.hxx> 57 #include <vcl/lstbox.hxx> 58 #include <unotools/tempfile.hxx> 59 #include <unotools/pathoptions.hxx> 60 #include <svl/urihelper.hxx> 61 #define _SVSTDARR_STRINGSDTOR 62 #include <svl/svstdarr.hxx> 63 #include <svl/zforlist.hxx> 64 #include <svl/zformat.hxx> 65 #include <svl/stritem.hxx> 66 #include <svl/eitem.hxx> 67 #include <vcl/oldprintadaptor.hxx> 68 #include <sfx2/docfile.hxx> 69 #include <sfx2/progress.hxx> 70 #include <sfx2/dispatch.hxx> 71 #include <svl/mailenum.hxx> 72 #include <cmdid.h> 73 #include <swmodule.hxx> 74 #include <view.hxx> 75 #include <docsh.hxx> 76 #include <edtwin.hxx> 77 #include <wrtsh.hxx> 78 #include <fldbas.hxx> 79 #include <initui.hxx> 80 #include <swundo.hxx> 81 #include <flddat.hxx> 82 #include <modcfg.hxx> 83 #include <shellio.hxx> 84 #include <dbui.hxx> 85 #include <dbmgr.hxx> 86 #include <doc.hxx> 87 #include <swwait.hxx> 88 #include <swunohelper.hxx> 89 #include <dbui.hrc> 90 #include <globals.hrc> 91 #include <statstr.hrc> 92 #include <mmconfigitem.hxx> 93 #include <sfx2/request.hxx> 94 #include <hintids.hxx> 95 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 96 #include <com/sun/star/sdbc/XRowSet.hpp> 97 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 98 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 99 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 100 #include <com/sun/star/sdb/XColumn.hpp> 101 #include <com/sun/star/sdbc/DataType.hpp> 102 #include <com/sun/star/sdbc/ResultSetType.hpp> 103 #include <com/sun/star/mail/MailAttachment.hpp> 104 #include <comphelper/processfactory.hxx> 105 #include <comphelper/types.hxx> 106 #include <comphelper/property.hxx> 107 #include <mailmergehelper.hxx> 108 #include <maildispatcher.hxx> 109 #include <svtools/htmlcfg.hxx> 110 #include <i18npool/mslangid.hxx> 111 #include <com/sun/star/util/XNumberFormatTypes.hpp> 112 #include <editeng/langitem.hxx> 113 #include <svl/numuno.hxx> 114 115 #include <unomailmerge.hxx> 116 #include <sfx2/event.hxx> 117 #include <vcl/msgbox.hxx> 118 #include <svx/dataaccessdescriptor.hxx> 119 #include <vos/mutex.hxx> 120 #include <rtl/textenc.h> 121 #include <ndindex.hxx> 122 #include <pam.hxx> 123 #include <swcrsr.hxx> 124 #include <swevent.hxx> 125 #include <osl/file.hxx> 126 #include <swabstdlg.hxx> 127 #include <fmthdft.hxx> 128 #include <dbui.hrc> 129 #include <envelp.hrc> 130 #include <memory> 131 #include <vector> 132 #include <unomid.h> 133 #include <section.hxx> 134 135 using namespace ::osl; 136 using namespace ::svx; 137 using namespace ::com::sun::star; 138 using namespace ::com::sun::star::text; 139 using namespace ::com::sun::star::uno; 140 using namespace ::com::sun::star::container; 141 using namespace ::com::sun::star::frame; 142 using namespace ::com::sun::star::lang; 143 using namespace ::com::sun::star::sdb; 144 using namespace ::com::sun::star::sdbc; 145 using namespace ::com::sun::star::sdbcx; 146 using namespace ::com::sun::star::beans; 147 using namespace ::com::sun::star::util; 148 using namespace ::com::sun::star::task; 149 using namespace ::com::sun::star::ui::dialogs; 150 151 #define DB_SEP_SPACE 0 152 #define DB_SEP_TAB 1 153 #define DB_SEP_RETURN 2 154 #define DB_SEP_NEWLINE 3 155 156 SV_IMPL_PTRARR(SwDSParamArr, SwDSParamPtr); 157 const sal_Char cCursor[] = "Cursor"; 158 const sal_Char cCommand[] = "Command"; 159 const sal_Char cCommandType[] = "CommandType"; 160 const sal_Char cDataSourceName[] = "DataSourceName"; 161 const sal_Char cSelection[] = "Selection"; 162 const sal_Char cActiveConnection[] = "ActiveConnection"; 163 164 // ----------------------------------------------------------------------------- 165 // Use nameless namespace to avoid to rubbish the global namespace 166 // ----------------------------------------------------------------------------- 167 namespace 168 { 169 170 bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference<XResultSet>& xResultSet ) 171 { 172 uno::Reference<XPropertySet> xPrSet(xResultSet, UNO_QUERY); 173 if(xPrSet.is()) 174 { 175 try 176 { 177 sal_Bool bFinal = sal_False; 178 Any aFinal = xPrSet->getPropertyValue(C2U("IsRowCountFinal")); 179 aFinal >>= bFinal; 180 if(!bFinal) 181 { 182 xResultSet->last(); 183 xResultSet->first(); 184 } 185 Any aCount = xPrSet->getPropertyValue(C2U("RowCount")); 186 if( aCount >>= rCount ) 187 return true; 188 } 189 catch(Exception&) 190 { 191 } 192 } 193 return false; 194 } 195 // #122799# copy compatibility options 196 void lcl_CopyCompatibilityOptions( SwWrtShell& rSourceShell, SwWrtShell& rTargetShell) 197 { 198 IDocumentSettingAccess* pIDsa = rSourceShell.getIDocumentSettingAccess(); 199 200 rTargetShell.SetParaSpaceMax( pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX)); 201 rTargetShell.SetParaSpaceMaxAtPages(pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES)); 202 rTargetShell.SetTabCompat( pIDsa->get(IDocumentSettingAccess::TAB_COMPAT)); 203 rTargetShell.SetAddExtLeading( pIDsa->get(IDocumentSettingAccess::ADD_EXT_LEADING)); 204 rTargetShell.SetUseVirDev( pIDsa->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE)); 205 rTargetShell.SetAddParaSpacingToTableCells( pIDsa->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS)); 206 rTargetShell.SetUseFormerLineSpacing( pIDsa->get(IDocumentSettingAccess::OLD_LINE_SPACING)); 207 rTargetShell.SetUseFormerObjectPositioning( pIDsa->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS)); 208 rTargetShell.SetConsiderWrapOnObjPos( pIDsa->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION)); 209 rTargetShell.SetUseFormerTextWrapping( pIDsa->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING)); 210 } 211 } 212 /* -----------------09.12.2002 12:35----------------- 213 * 214 * --------------------------------------------------*/ 215 216 class SwConnectionDisposedListener_Impl : public cppu::WeakImplHelper1 217 < lang::XEventListener > 218 { 219 SwNewDBMgr& rDBMgr; 220 221 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); 222 public: 223 SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr); 224 ~SwConnectionDisposedListener_Impl(); 225 226 }; 227 // ----------------------------------------------------------------------------- 228 struct SwNewDBMgr_Impl 229 { 230 SwDSParam* pMergeData; 231 AbstractMailMergeDlg* pMergeDialog; 232 uno::Reference<lang::XEventListener> xDisposeListener; 233 234 SwNewDBMgr_Impl(SwNewDBMgr& rDBMgr) 235 :pMergeData(0) 236 ,pMergeDialog(0) 237 ,xDisposeListener(new SwConnectionDisposedListener_Impl(rDBMgr)) 238 {} 239 }; 240 /*-- 24.10.2003 15:54:18--------------------------------------------------- 241 242 -----------------------------------------------------------------------*/ 243 void lcl_InitNumberFormatter(SwDSParam& rParam, uno::Reference<XDataSource> xSource) 244 { 245 uno::Reference<XMultiServiceFactory> xMgr = ::comphelper::getProcessServiceFactory(); 246 if( xMgr.is() ) 247 { 248 uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.util.NumberFormatter" )); 249 rParam.xFormatter = uno::Reference<util::XNumberFormatter>(xInstance, UNO_QUERY) ; 250 } 251 if(!xSource.is()) 252 xSource = SwNewDBMgr::getDataSourceAsParent(rParam.xConnection, rParam.sDataSource); 253 254 uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY); 255 if(xSourceProps.is()) 256 { 257 Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier")); 258 if(aFormats.hasValue()) 259 { 260 uno::Reference<XNumberFormatsSupplier> xSuppl; 261 aFormats >>= xSuppl; 262 if(xSuppl.is()) 263 { 264 uno::Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings(); 265 Any aNull = xSettings->getPropertyValue(C2U("NullDate")); 266 aNull >>= rParam.aNullDate; 267 if(rParam.xFormatter.is()) 268 rParam.xFormatter->attachNumberFormatsSupplier(xSuppl); 269 } 270 } 271 } 272 } 273 /* -----------------------------17.07.00 17:04-------------------------------- 274 275 ---------------------------------------------------------------------------*/ 276 sal_Bool lcl_MoveAbsolute(SwDSParam* pParam, long nAbsPos) 277 { 278 sal_Bool bRet = sal_False; 279 try 280 { 281 if(pParam->bScrollable) 282 { 283 bRet = pParam->xResultSet->absolute( nAbsPos ); 284 } 285 else 286 { 287 DBG_ERROR("no absolute positioning available"); 288 } 289 } 290 catch(Exception aExcept) 291 { 292 } 293 return bRet; 294 } 295 /* -----------------------------17.07.00 17:23-------------------------------- 296 297 ---------------------------------------------------------------------------*/ 298 sal_Bool lcl_GetColumnCnt(SwDSParam* pParam, 299 const String& rColumnName, long nLanguage, String& rResult, double* pNumber) 300 { 301 uno::Reference< XColumnsSupplier > xColsSupp( pParam->xResultSet, UNO_QUERY ); 302 uno::Reference<XNameAccess> xCols; 303 try 304 { 305 xCols = xColsSupp->getColumns(); 306 } 307 catch( lang::DisposedException& ) 308 { 309 } 310 if(!xCols.is() || !xCols->hasByName(rColumnName)) 311 return sal_False; 312 Any aCol = xCols->getByName(rColumnName); 313 uno::Reference< XPropertySet > xColumnProps; 314 aCol >>= xColumnProps; 315 316 SwDBFormatData aFormatData; 317 if(!pParam->xFormatter.is()) 318 { 319 uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent( 320 pParam->xConnection,pParam->sDataSource); 321 lcl_InitNumberFormatter(*pParam, xSource ); 322 } 323 aFormatData.aNullDate = pParam->aNullDate; 324 aFormatData.xFormatter = pParam->xFormatter; 325 326 MsLangId::convertLanguageToLocale( (LanguageType)nLanguage, aFormatData.aLocale ); 327 328 rResult = SwNewDBMgr::GetDBField( xColumnProps, aFormatData, pNumber); 329 return sal_True; 330 }; 331 /*-------------------------------------------------------------------- 332 Beschreibung: Daten importieren 333 --------------------------------------------------------------------*/ 334 sal_Bool SwNewDBMgr::MergeNew(const SwMergeDescriptor& rMergeDesc ) 335 { 336 SetMergeType( rMergeDesc.nMergeType ); 337 338 DBG_ASSERT(!bInMerge && !pImpl->pMergeData, "merge already activated!"); 339 340 SwDBData aData; 341 aData.nCommandType = CommandType::TABLE; 342 uno::Reference<XResultSet> xResSet; 343 Sequence<Any> aSelection; 344 uno::Reference< XConnection> xConnection; 345 346 aData.sDataSource = rMergeDesc.rDescriptor.getDataSource(); 347 rMergeDesc.rDescriptor[daCommand] >>= aData.sCommand; 348 rMergeDesc.rDescriptor[daCommandType] >>= aData.nCommandType; 349 350 if ( rMergeDesc.rDescriptor.has(daCursor) ) 351 rMergeDesc.rDescriptor[daCursor] >>= xResSet; 352 if ( rMergeDesc.rDescriptor.has(daSelection) ) 353 rMergeDesc.rDescriptor[daSelection] >>= aSelection; 354 if ( rMergeDesc.rDescriptor.has(daConnection) ) 355 rMergeDesc.rDescriptor[daConnection] >>= xConnection; 356 357 if(!aData.sDataSource.getLength() || !aData.sCommand.getLength() || !xResSet.is()) 358 { 359 return sal_False; 360 } 361 362 pImpl->pMergeData = new SwDSParam(aData, xResSet, aSelection); 363 SwDSParam* pTemp = FindDSData(aData, sal_False); 364 if(pTemp) 365 *pTemp = *pImpl->pMergeData; 366 else 367 { 368 //#94779# calls from the calculator may have added a connection with an invalid commandtype 369 //"real" data base connections added here have to re-use the already available 370 //DSData and set the correct CommandType 371 SwDBData aTempData(aData); 372 aData.nCommandType = -1; 373 pTemp = FindDSData(aData, sal_False); 374 if(pTemp) 375 *pTemp = *pImpl->pMergeData; 376 else 377 { 378 SwDSParam* pInsert = new SwDSParam(*pImpl->pMergeData); 379 aDataSourceParams.Insert(pInsert, aDataSourceParams.Count()); 380 try 381 { 382 uno::Reference<XComponent> xComponent(pInsert->xConnection, UNO_QUERY); 383 if(xComponent.is()) 384 xComponent->addEventListener(pImpl->xDisposeListener); 385 } 386 catch(Exception&) 387 { 388 } 389 } 390 } 391 if(!pImpl->pMergeData->xConnection.is()) 392 pImpl->pMergeData->xConnection = xConnection; 393 // add an XEventListener 394 395 try{ 396 //set to start position 397 if(pImpl->pMergeData->aSelection.getLength()) 398 { 399 sal_Int32 nPos = 0; 400 pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos; 401 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos ); 402 pImpl->pMergeData->CheckEndOfDB(); 403 if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength()) 404 pImpl->pMergeData->bEndOfDB = sal_True; 405 } 406 else 407 { 408 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first(); 409 pImpl->pMergeData->CheckEndOfDB(); 410 } 411 } 412 catch(Exception&) 413 { 414 pImpl->pMergeData->bEndOfDB = sal_True; 415 pImpl->pMergeData->CheckEndOfDB(); 416 DBG_ERROR("exception in MergeNew()"); 417 } 418 419 uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,aData.sDataSource); 420 421 lcl_InitNumberFormatter(*pImpl->pMergeData, xSource); 422 423 rMergeDesc.rSh.ChgDBData(aData); 424 bInMerge = sal_True; 425 426 if (IsInitDBFields()) 427 { 428 // Bei Datenbankfeldern ohne DB-Name DB-Name von Dok einsetzen 429 SvStringsDtor aDBNames(1, 1); 430 aDBNames.Insert( new String(), 0); 431 SwDBData aInsertData = rMergeDesc.rSh.GetDBData(); 432 String sDBName = aInsertData.sDataSource; 433 sDBName += DB_DELIM; 434 sDBName += (String)aInsertData.sCommand; 435 sDBName += DB_DELIM; 436 sDBName += String::CreateFromInt32(aInsertData.nCommandType); 437 rMergeDesc.rSh.ChangeDBFields( aDBNames, sDBName); 438 SetInitDBFields(sal_False); 439 } 440 441 sal_Bool bRet = sal_True; 442 switch(rMergeDesc.nMergeType) 443 { 444 case DBMGR_MERGE: 445 bRet = Merge(&rMergeDesc.rSh); // Mischen 446 break; 447 448 case DBMGR_MERGE_MAILMERGE: // printing merge from 'old' merge dialog or from UNO-component 449 case DBMGR_MERGE_MAILING: 450 case DBMGR_MERGE_MAILFILES: 451 case DBMGR_MERGE_SINGLE_FILE: 452 // save files and send them as e-Mail if required 453 bRet = MergeMailFiles(&rMergeDesc.rSh, 454 rMergeDesc); 455 break; 456 457 default: // Einfuegen der selektierten Eintraege 458 // (war: InsertRecord) 459 ImportFromConnection(&rMergeDesc.rSh); 460 break; 461 } 462 463 EndMerge(); 464 return bRet; 465 } 466 467 /*-------------------------------------------------------------------- 468 Beschreibung: Daten importieren 469 --------------------------------------------------------------------*/ 470 471 472 sal_Bool SwNewDBMgr::Merge(SwWrtShell* pSh) 473 { 474 pSh->StartAllAction(); 475 476 pSh->ViewShell::UpdateFlds(sal_True); 477 pSh->SetModified(); 478 479 pSh->EndAllAction(); 480 481 return sal_True; 482 } 483 484 /*-------------------------------------------------------------------- 485 Beschreibung: 486 --------------------------------------------------------------------*/ 487 void SwNewDBMgr::ImportFromConnection( SwWrtShell* pSh ) 488 { 489 if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB) 490 { 491 { 492 pSh->StartAllAction(); 493 pSh->StartUndo(UNDO_EMPTY); 494 sal_Bool bGroupUndo(pSh->DoesGroupUndo()); 495 pSh->DoGroupUndo(sal_False); 496 497 if( pSh->HasSelection() ) 498 pSh->DelRight(); 499 500 SwWait *pWait = 0; 501 502 { 503 sal_uLong i = 0; 504 do { 505 506 ImportDBEntry(pSh); 507 if( 10 == ++i ) 508 pWait = new SwWait( *pSh->GetView().GetDocShell(), sal_True); 509 510 } while(ToNextMergeRecord()); 511 } 512 513 pSh->DoGroupUndo(bGroupUndo); 514 pSh->EndUndo(UNDO_EMPTY); 515 pSh->EndAllAction(); 516 delete pWait; 517 } 518 } 519 } 520 /*-----------------24.02.97 10.30------------------- 521 522 --------------------------------------------------*/ 523 524 String lcl_FindColumn(const String& sFormatStr,sal_uInt16 &nUsedPos, sal_uInt8 &nSeparator) 525 { 526 String sReturn; 527 sal_uInt16 nLen = sFormatStr.Len(); 528 nSeparator = 0xff; 529 while(nUsedPos < nLen && nSeparator == 0xff) 530 { 531 sal_Unicode cAkt = sFormatStr.GetChar(nUsedPos); 532 switch(cAkt) 533 { 534 case ',': 535 nSeparator = DB_SEP_SPACE; 536 break; 537 case ';': 538 nSeparator = DB_SEP_RETURN; 539 break; 540 case ':': 541 nSeparator = DB_SEP_TAB; 542 break; 543 case '#': 544 nSeparator = DB_SEP_NEWLINE; 545 break; 546 default: 547 sReturn += cAkt; 548 } 549 nUsedPos++; 550 551 } 552 return sReturn; 553 } 554 555 /*-------------------------------------------------------------------- 556 Beschreibung: 557 --------------------------------------------------------------------*/ 558 void SwNewDBMgr::ImportDBEntry(SwWrtShell* pSh) 559 { 560 if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB) 561 { 562 uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY ); 563 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); 564 String sFormatStr; 565 sal_uInt16 nFmtLen = sFormatStr.Len(); 566 if( nFmtLen ) 567 { 568 const char cSpace = ' '; 569 const char cTab = '\t'; 570 sal_uInt16 nUsedPos = 0; 571 sal_uInt8 nSeparator; 572 String sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator); 573 while( sColumn.Len() ) 574 { 575 if(!xCols->hasByName(sColumn)) 576 return; 577 Any aCol = xCols->getByName(sColumn); 578 uno::Reference< XPropertySet > xColumnProp; 579 aCol >>= xColumnProp; 580 if(xColumnProp.is()) 581 { 582 SwDBFormatData aDBFormat; 583 String sInsert = GetDBField( xColumnProp, aDBFormat); 584 if( DB_SEP_SPACE == nSeparator ) 585 sInsert += cSpace; 586 else if( DB_SEP_TAB == nSeparator) 587 sInsert += cTab; 588 pSh->Insert(sInsert); 589 if( DB_SEP_RETURN == nSeparator) 590 pSh->SplitNode(); 591 else if(DB_SEP_NEWLINE == nSeparator) 592 pSh->InsertLineBreak(); 593 } 594 else 595 { 596 // Spalte nicht gefunden -> Fehler anzeigen 597 String sInsert = '?'; 598 sInsert += sColumn; 599 sInsert += '?'; 600 pSh->Insert(sInsert); 601 } 602 sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator); 603 } 604 pSh->SplitNode(); 605 } 606 else 607 { 608 String sStr; 609 Sequence<rtl::OUString> aColNames = xCols->getElementNames(); 610 const rtl::OUString* pColNames = aColNames.getConstArray(); 611 long nLength = aColNames.getLength(); 612 for(long i = 0; i < nLength; i++) 613 { 614 Any aCol = xCols->getByName(pColNames[i]); 615 uno::Reference< XPropertySet > xColumnProp; 616 aCol >>= xColumnProp; 617 SwDBFormatData aDBFormat; 618 sStr += GetDBField( xColumnProp, aDBFormat); 619 if (i < nLength - 1) 620 sStr += '\t'; 621 } 622 pSh->SwEditShell::Insert2(sStr); 623 pSh->SwFEShell::SplitNode(); // Zeilenvorschub 624 } 625 } 626 } 627 /*-------------------------------------------------------------------- 628 Beschreibung: Listbox mit Tabellenliste fuellen 629 --------------------------------------------------------------------*/ 630 sal_Bool SwNewDBMgr::GetTableNames(ListBox* pListBox, const String& rDBName) 631 { 632 sal_Bool bRet = sal_False; 633 String sOldTableName(pListBox->GetSelectEntry()); 634 pListBox->Clear(); 635 SwDSParam* pParam = FindDSConnection(rDBName, sal_False); 636 uno::Reference< XConnection> xConnection; 637 if(pParam && pParam->xConnection.is()) 638 xConnection = pParam->xConnection; 639 else 640 { 641 rtl::OUString sDBName(rDBName); 642 if ( sDBName.getLength() ) 643 xConnection = RegisterConnection( sDBName ); 644 } 645 if(xConnection.is()) 646 { 647 uno::Reference<XTablesSupplier> xTSupplier = uno::Reference<XTablesSupplier>(xConnection, UNO_QUERY); 648 if(xTSupplier.is()) 649 { 650 uno::Reference<XNameAccess> xTbls = xTSupplier->getTables(); 651 Sequence<rtl::OUString> aTbls = xTbls->getElementNames(); 652 const rtl::OUString* pTbls = aTbls.getConstArray(); 653 for(long i = 0; i < aTbls.getLength(); i++) 654 { 655 sal_uInt16 nEntry = pListBox->InsertEntry(pTbls[i]); 656 pListBox->SetEntryData(nEntry, (void*)0); 657 } 658 } 659 uno::Reference<XQueriesSupplier> xQSupplier = uno::Reference<XQueriesSupplier>(xConnection, UNO_QUERY); 660 if(xQSupplier.is()) 661 { 662 uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries(); 663 Sequence<rtl::OUString> aQueries = xQueries->getElementNames(); 664 const rtl::OUString* pQueries = aQueries.getConstArray(); 665 for(long i = 0; i < aQueries.getLength(); i++) 666 { 667 sal_uInt16 nEntry = pListBox->InsertEntry(pQueries[i]); 668 pListBox->SetEntryData(nEntry, (void*)1); 669 } 670 } 671 if (sOldTableName.Len()) 672 pListBox->SelectEntry(sOldTableName); 673 bRet = sal_True; 674 } 675 return bRet; 676 } 677 678 /*-------------------------------------------------------------------- 679 Beschreibung: Listbox mit Spaltennamen einer Datenbank fuellen 680 --------------------------------------------------------------------*/ 681 sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox, 682 const String& rDBName, const String& rTableName, sal_Bool bAppend) 683 { 684 if (!bAppend) 685 pListBox->Clear(); 686 SwDBData aData; 687 aData.sDataSource = rDBName; 688 aData.sCommand = rTableName; 689 aData.nCommandType = -1; 690 SwDSParam* pParam = FindDSData(aData, sal_False); 691 uno::Reference< XConnection> xConnection; 692 if(pParam && pParam->xConnection.is()) 693 xConnection = pParam->xConnection; 694 else 695 { 696 rtl::OUString sDBName(rDBName); 697 xConnection = RegisterConnection( sDBName ); 698 } 699 uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); 700 if(xColsSupp.is()) 701 { 702 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); 703 const Sequence<rtl::OUString> aColNames = xCols->getElementNames(); 704 const rtl::OUString* pColNames = aColNames.getConstArray(); 705 for(int nCol = 0; nCol < aColNames.getLength(); nCol++) 706 { 707 pListBox->InsertEntry(pColNames[nCol]); 708 } 709 ::comphelper::disposeComponent( xColsSupp ); 710 } 711 return(sal_True); 712 } 713 /* -----------------------------08.06.01 15:11-------------------------------- 714 715 ---------------------------------------------------------------------------*/ 716 sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox, 717 uno::Reference< XConnection> xConnection, 718 const String& rTableName, sal_Bool bAppend) 719 { 720 if (!bAppend) 721 pListBox->Clear(); 722 uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); 723 if(xColsSupp.is()) 724 { 725 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); 726 const Sequence<rtl::OUString> aColNames = xCols->getElementNames(); 727 const rtl::OUString* pColNames = aColNames.getConstArray(); 728 for(int nCol = 0; nCol < aColNames.getLength(); nCol++) 729 { 730 pListBox->InsertEntry(pColNames[nCol]); 731 } 732 ::comphelper::disposeComponent( xColsSupp ); 733 } 734 return(sal_True); 735 } 736 737 /*-------------------------------------------------------------------- 738 Beschreibung: CTOR 739 --------------------------------------------------------------------*/ 740 741 SwNewDBMgr::SwNewDBMgr() : 742 nMergeType(DBMGR_INSERT), 743 bInitDBFields(sal_False), 744 bInMerge(sal_False), 745 bMergeSilent(sal_False), 746 bMergeLock(sal_False), 747 pImpl(new SwNewDBMgr_Impl(*this)), 748 pMergeEvtSrc(NULL) 749 { 750 } 751 /* -----------------------------18.07.00 08:56-------------------------------- 752 753 ---------------------------------------------------------------------------*/ 754 SwNewDBMgr::~SwNewDBMgr() 755 { 756 for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) 757 { 758 SwDSParam* pParam = aDataSourceParams[nPos]; 759 if(pParam->xConnection.is()) 760 { 761 try 762 { 763 uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY); 764 if(xComp.is()) 765 xComp->dispose(); 766 } 767 catch(const RuntimeException& ) 768 { 769 //may be disposed already since multiple entries may have used the same connection 770 } 771 } 772 } 773 delete pImpl; 774 } 775 776 /*-------------------------------------------------------------------- 777 Beschreibung: Serienbriefe als einzelne Dokumente speichern 778 --------------------------------------------------------------------*/ 779 String lcl_FindUniqueName(SwWrtShell* pTargetShell, const String& rStartingPageDesc, sal_uLong nDocNo ) 780 { 781 do 782 { 783 String sTest = rStartingPageDesc; 784 sTest += String::CreateFromInt32( nDocNo ); 785 if( !pTargetShell->FindPageDescByName( sTest ) ) 786 return sTest; 787 ++nDocNo; 788 }while(true); 789 } 790 void lcl_CopyDynamicDefaults( const SwDoc& rSource, SwDoc& rTarget ) 791 { 792 sal_uInt16 __FAR_DATA aRangeOfDefaults[] = { 793 RES_FRMATR_BEGIN, RES_FRMATR_END-1, 794 RES_CHRATR_BEGIN, RES_CHRATR_END-1, 795 RES_PARATR_BEGIN, RES_PARATR_END-1, 796 // --> OD 2008-02-25 #refactorlists## 797 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1, 798 // <-- 799 RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, 800 0 801 }; 802 803 SfxItemSet aNewDefaults( rTarget.GetAttrPool(), aRangeOfDefaults ); 804 805 sal_uInt16 nWhich; 806 sal_uInt16 nRange = 0; 807 while( aRangeOfDefaults[nRange] != 0) 808 { 809 for( nWhich = aRangeOfDefaults[nRange]; nWhich < aRangeOfDefaults[nRange + 1]; ++nWhich ) 810 { 811 const SfxPoolItem& rSourceAttr = rSource.GetDefault( nWhich ); 812 if( rSourceAttr != rTarget.GetDefault( nWhich ) ) 813 aNewDefaults.Put( rSourceAttr ); 814 } 815 nRange += 2; 816 } 817 if( aNewDefaults.Count() ) 818 rTarget.SetDefault( aNewDefaults ); 819 } 820 void lcl_CopyFollowPageDesc( 821 SwWrtShell& rTargetShell, 822 const SwPageDesc& rSourcePageDesc, 823 const SwPageDesc& rTargetPageDesc, 824 const sal_uLong nDocNo ) 825 { 826 //now copy the follow page desc, too 827 const SwPageDesc* pFollowPageDesc = rSourcePageDesc.GetFollow(); 828 String sFollowPageDesc = pFollowPageDesc->GetName(); 829 if( sFollowPageDesc != rSourcePageDesc.GetName() ) 830 { 831 SwDoc* pTargetDoc = rTargetShell.GetDoc(); 832 String sNewFollowPageDesc = lcl_FindUniqueName(&rTargetShell, sFollowPageDesc, nDocNo ); 833 sal_uInt16 nNewDesc = pTargetDoc->MakePageDesc( sNewFollowPageDesc ); 834 SwPageDesc& rTargetFollowPageDesc = pTargetDoc->_GetPageDesc( nNewDesc ); 835 836 pTargetDoc->CopyPageDesc( *pFollowPageDesc, rTargetFollowPageDesc, sal_False ); 837 SwPageDesc aDesc( rTargetPageDesc ); 838 aDesc.SetFollow( &rTargetFollowPageDesc ); 839 pTargetDoc->ChgPageDesc( rTargetPageDesc.GetName(), aDesc ); 840 } 841 } 842 843 void lcl_RemoveSectionLinks( SwWrtShell& rWorkShell ) 844 { 845 //reset all links of the sections of synchronized labels 846 sal_uInt16 nSections = rWorkShell.GetSectionFmtCount(); 847 for( sal_uInt16 nSection = 0; nSection < nSections; ++nSection ) 848 { 849 SwSectionData aSectionData( *rWorkShell.GetSectionFmt( nSection ).GetSection() ); 850 if( aSectionData.GetType() == FILE_LINK_SECTION ) 851 { 852 aSectionData.SetType( CONTENT_SECTION ); 853 aSectionData.SetLinkFileName( String() ); 854 rWorkShell.UpdateSection( nSection, aSectionData ); 855 } 856 } 857 rWorkShell.SetLabelDoc( sal_False ); 858 } 859 860 sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell, 861 const SwMergeDescriptor& rMergeDescriptor) 862 { 863 //check if the doc is synchronized and contains at least one linked section 864 sal_Bool bSynchronizedDoc = pSourceShell->IsLabelDoc() && pSourceShell->GetSectionFmtCount() > 1; 865 sal_Bool bLoop = sal_True; 866 sal_Bool bEMail = rMergeDescriptor.nMergeType == DBMGR_MERGE_MAILING; 867 const bool bAsSingleFile = rMergeDescriptor.nMergeType == DBMGR_MERGE_SINGLE_FILE; 868 869 ::rtl::Reference< MailDispatcher > xMailDispatcher; 870 ::rtl::OUString sBodyMimeType; 871 rtl_TextEncoding eEncoding = ::gsl_getSystemTextEncoding(); 872 873 if(bEMail) 874 { 875 xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer)); 876 if(!rMergeDescriptor.bSendAsAttachment && rMergeDescriptor.bSendAsHTML) 877 { 878 sBodyMimeType = ::rtl::OUString::createFromAscii("text/html; charset="); 879 sBodyMimeType += ::rtl::OUString::createFromAscii( 880 rtl_getBestMimeCharsetFromTextEncoding( eEncoding )); 881 SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get(); 882 eEncoding = pHtmlOptions->GetTextEncoding(); 883 } 884 else 885 sBodyMimeType = 886 ::rtl::OUString::createFromAscii("text/plain; charset=UTF-8; format=flowed"); 887 } 888 889 uno::Reference< XPropertySet > xColumnProp; 890 { 891 sal_Bool bColumnName = sEMailAddrFld.Len() > 0; 892 893 if (bColumnName) 894 { 895 uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY ); 896 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); 897 if(!xCols->hasByName(sEMailAddrFld)) 898 return sal_False; 899 Any aCol = xCols->getByName(sEMailAddrFld); 900 aCol >>= xColumnProp; 901 } 902 903 SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher(); 904 SwDocShell* pSourrceDocSh = pSourceShell->GetView().GetDocShell(); 905 pSfxDispatcher->Execute( pSourrceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD); 906 // has document been saved successfully? 907 if( !pSourrceDocSh->IsModified() ) 908 { 909 SfxMedium* pOrig = pSourceShell->GetView().GetDocShell()->GetMedium(); 910 String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE )); 911 const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter( 912 sSourceDocumentURL, ::aEmptyStr ); 913 const SfxFilter* pStoreToFilter = pSfxFlt; 914 SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer(); 915 const String* pStoreToFilterOptions = 0; 916 // if a save_to filter is set then use it - otherwise use the default 917 if( bEMail && !rMergeDescriptor.bSendAsAttachment ) 918 { 919 String sExtension( String::CreateFromAscii( 920 rMergeDescriptor.bSendAsHTML ? "html" : "txt" )); 921 pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SFX_FILTER_EXPORT); 922 } 923 else if( rMergeDescriptor.sSaveToFilter.Len()) 924 { 925 const SfxFilter* pFilter = 926 pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter ); 927 if(pFilter) 928 { 929 pStoreToFilter = pFilter; 930 if(rMergeDescriptor.sSaveToFilterOptions.Len()) 931 pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions; 932 } 933 } 934 bCancel = sal_False; 935 936 // in case of creating a single resulting file this has to be created here 937 SwWrtShell* pTargetShell = 0; 938 939 // the shell will be explicitly closed at the end of the method, but it is 940 // still more safe to use SfxObjectShellLock here 941 SfxObjectShellLock xTargetDocShell; 942 943 SwView* pTargetView = 0; 944 std::auto_ptr< utl::TempFile > aTempFile; 945 String sModifiedStartingPageDesc; 946 String sStartingPageDesc; 947 sal_uInt16 nStartingPageNo = 0; 948 bool bPageStylesWithHeaderFooter = false; 949 if(bAsSingleFile || rMergeDescriptor.bCreateSingleFile) 950 { 951 // create a target docshell to put the merged document into 952 xTargetDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD ); 953 xTargetDocShell->DoInitNew( 0 ); 954 SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 ); 955 956 pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() ); 957 958 //initiate SelectShell() to create sub shells 959 pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() ); 960 pTargetShell = pTargetView->GetWrtShellPtr(); 961 //copy the styles from the source to the target document 962 SwgReaderOption aOpt; 963 aOpt.SetTxtFmts( sal_True ); 964 aOpt.SetFrmFmts( sal_True ); 965 aOpt.SetPageDescs( sal_True ); 966 aOpt.SetNumRules( sal_True ); 967 aOpt.SetMerge( sal_False ); 968 pTargetView->GetDocShell()->LoadStylesFromFile( 969 sSourceDocumentURL, aOpt, sal_True ); 970 //determine the page style and number used at the start of the source document 971 pSourceShell->SttEndDoc(sal_True); 972 nStartingPageNo = pSourceShell->GetVirtPageNum(); 973 sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc( 974 pSourceShell->GetCurPageDesc()).GetName(); 975 // #122799# copy compatibility options 976 lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell); 977 // #72821# copy dynamic defaults 978 lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() ); 979 // #i72517# 980 const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc ); 981 const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster(); 982 bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() || 983 rMaster.GetFooter().IsActive(); 984 985 } 986 987 PrintMonitor aPrtMonDlg(&pSourceShell->GetView().GetEditWin(), PrintMonitor::MONITOR_TYPE_PRINT); 988 aPrtMonDlg.aDocName.SetText(pSourceShell->GetView().GetDocShell()->GetTitle(22)); 989 990 aPrtMonDlg.aCancel.SetClickHdl(LINK(this, SwNewDBMgr, PrtCancelHdl)); 991 if (!IsMergeSilent()) 992 aPrtMonDlg.Show(); 993 994 // Progress, um KeyInputs zu unterbinden 995 SfxProgress aProgress(pSourrceDocSh, ::aEmptyStr, 1); 996 997 // Alle Dispatcher sperren 998 SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh); 999 while (pViewFrm) 1000 { 1001 pViewFrm->GetDispatcher()->Lock(sal_True); 1002 pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh); 1003 } 1004 sal_uLong nDocNo = 1; 1005 1006 long nStartRow, nEndRow; 1007 // collect temporary files 1008 ::std::vector< String> aFilesToRemove; 1009 do 1010 { 1011 nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0; 1012 { 1013 String sPath(sSubject); 1014 1015 String sAddress; 1016 if( !bEMail && bColumnName ) 1017 { 1018 SwDBFormatData aDBFormat; 1019 aDBFormat.xFormatter = pImpl->pMergeData->xFormatter; 1020 aDBFormat.aNullDate = pImpl->pMergeData->aNullDate; 1021 sAddress = GetDBField( xColumnProp, aDBFormat); 1022 if (!sAddress.Len()) 1023 sAddress = '_'; 1024 sPath += sAddress; 1025 } 1026 1027 // create a new temporary file name - only done once in case of bCreateSingleFile 1028 if( 1 == nDocNo || (!rMergeDescriptor.bCreateSingleFile && !bAsSingleFile) ) 1029 { 1030 INetURLObject aEntry(sPath); 1031 String sLeading; 1032 //#i97667# if the name is from a database field then it will be used _as is_ 1033 if( sAddress.Len() ) 1034 sLeading = sAddress; 1035 else 1036 sLeading = aEntry.GetBase(); 1037 aEntry.removeSegment(); 1038 sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE ); 1039 String sExt( pStoreToFilter->GetDefaultExtension() ); 1040 sExt.EraseLeadingChars('*'); 1041 aTempFile = std::auto_ptr< utl::TempFile >( 1042 new utl::TempFile(sLeading,&sExt,&sPath )); 1043 if( bAsSingleFile ) 1044 aTempFile->EnableKillingFile(); 1045 } 1046 1047 if( !aTempFile->IsValid() ) 1048 { 1049 ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED ); 1050 bLoop = sal_False; 1051 bCancel = sal_True; 1052 } 1053 else 1054 { 1055 INetURLObject aTempFileURL(aTempFile->GetURL()); 1056 aPrtMonDlg.aPrinter.SetText( aTempFileURL.GetBase() ); 1057 String sStat(SW_RES(STR_STATSTR_LETTER)); // Brief 1058 sStat += ' '; 1059 sStat += String::CreateFromInt32( nDocNo ); 1060 aPrtMonDlg.aPrintInfo.SetText(sStat); 1061 1062 // Rechenzeit fuer Save-Monitor: 1063 for (sal_uInt16 i = 0; i < 10; i++) 1064 Application::Reschedule(); 1065 1066 // Create and save new document 1067 // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here 1068 SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); 1069 SfxMedium* pWorkMed = new SfxMedium( sSourceDocumentURL, STREAM_STD_READ, sal_True ); 1070 pWorkMed->SetFilter( pSfxFlt ); 1071 1072 if (xWorkDocSh->DoLoad(pWorkMed)) 1073 { 1074 //create a view frame for the document 1075 SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 ); 1076 //request the layout calculation 1077 SwWrtShell& rWorkShell = 1078 static_cast< SwView* >(pWorkFrame->GetViewShell())->GetWrtShell(); 1079 rWorkShell.CalcLayout(); 1080 SwDoc* pWorkDoc = ((SwDocShell*)(&xWorkDocSh))->GetDoc(); 1081 SwNewDBMgr* pOldDBMgr = pWorkDoc->GetNewDBMgr(); 1082 pWorkDoc->SetNewDBMgr( this ); 1083 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh)); 1084 pWorkDoc->UpdateFlds(NULL, false); 1085 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh)); 1086 1087 // alle versteckten Felder/Bereiche entfernen 1088 pWorkDoc->RemoveInvisibleContent(); 1089 1090 // launch MailMergeEvent if required 1091 const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc(); 1092 if(pEvtSrc) 1093 { 1094 uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc ); 1095 text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() ); 1096 pEvtSrc->LaunchMailMergeEvent( aEvt ); 1097 } 1098 1099 if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile ) 1100 { 1101 DBG_ASSERT( pTargetShell, "no target shell available!" ); 1102 // copy created file into the target document 1103 rWorkShell.ConvertFieldsToText(); 1104 rWorkShell.SetNumberingRestart(); 1105 if( bSynchronizedDoc ) 1106 { 1107 lcl_RemoveSectionLinks( rWorkShell ); 1108 } 1109 1110 // insert the document into the target document 1111 rWorkShell.SttEndDoc(sal_False); 1112 rWorkShell.SttEndDoc(sal_True); 1113 rWorkShell.SelAll(); 1114 pTargetShell->SwCrsrShell::SttEndDoc( sal_False ); 1115 //#i72517# the headers and footers are still those from the source - update in case of fields inside header/footer 1116 if( !nDocNo && bPageStylesWithHeaderFooter ) 1117 pTargetShell->GetView().GetDocShell()->_LoadStyles( *rWorkShell.GetView().GetDocShell(), sal_True ); 1118 //#i72517# put the styles to the target document 1119 //if the source uses headers or footers each new copy need to copy a new page styles 1120 if(bPageStylesWithHeaderFooter) 1121 { 1122 //create a new pagestyle 1123 //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style 1124 1125 SwDoc* pTargetDoc = pTargetShell->GetDoc(); 1126 SwPageDesc* pSourcePageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc ); 1127 String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo ); 1128 pTargetDoc->MakePageDesc( sNewPageDescName ); 1129 SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName ); 1130 if(pSourcePageDesc && pTargetPageDesc) 1131 { 1132 pTargetDoc->CopyPageDesc( *pSourcePageDesc, *pTargetPageDesc, sal_False ); 1133 sModifiedStartingPageDesc = sNewPageDescName; 1134 lcl_CopyFollowPageDesc( *pTargetShell, *pSourcePageDesc, *pTargetPageDesc, nDocNo ); 1135 } 1136 } 1137 1138 if(nDocNo > 1) 1139 pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo ); 1140 else 1141 pTargetShell->SetPageStyle(sModifiedStartingPageDesc); 1142 DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended"); 1143 //#i51359# add a second paragraph in case there's only one 1144 { 1145 SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 ); 1146 SwPosition aTestPos( aIdx ); 1147 SwCursor aTestCrsr(aTestPos,0,false); 1148 if(!aTestCrsr.MovePara(fnParaNext, fnParaStart)) 1149 { 1150 //append a paragraph 1151 pWorkDoc->AppendTxtNode( aTestPos ); 1152 } 1153 } 1154 pTargetShell->Paste( rWorkShell.GetDoc(), sal_True ); 1155 1156 //convert fields in page styles (header/footer - has to be done after the first document has been pasted 1157 if(1 == nDocNo) 1158 { 1159 pTargetShell->CalcLayout(); 1160 pTargetShell->ConvertFieldsToText(); 1161 } 1162 } 1163 else 1164 { 1165 String sFileURL = aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ); 1166 SfxMedium* pDstMed = new SfxMedium( 1167 sFileURL, 1168 STREAM_STD_READWRITE, sal_True ); 1169 pDstMed->SetFilter( pStoreToFilter ); 1170 if(pDstMed->GetItemSet()) 1171 { 1172 if(pStoreToFilterOptions ) 1173 pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions)); 1174 if(rMergeDescriptor.aSaveToFilterData.getLength()) 1175 pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData))); 1176 } 1177 1178 //convert fields to text if we are exporting to PDF 1179 //this prevents a second merge while updating the fields in SwXTextDocument::getRendererCount() 1180 if( pStoreToFilter && pStoreToFilter->GetFilterName().EqualsAscii("writer_pdf_Export")) 1181 rWorkShell.ConvertFieldsToText(); 1182 xWorkDocSh->DoSaveAs(*pDstMed); 1183 xWorkDocSh->DoSaveCompleted(pDstMed); 1184 if( xWorkDocSh->GetError() ) 1185 { 1186 // error message ?? 1187 ErrorHandler::HandleError( xWorkDocSh->GetError() ); 1188 bCancel = sal_True; 1189 bLoop = sal_False; 1190 } 1191 if( bEMail ) 1192 { 1193 SwDBFormatData aDBFormat; 1194 aDBFormat.xFormatter = pImpl->pMergeData->xFormatter; 1195 aDBFormat.aNullDate = pImpl->pMergeData->aNullDate; 1196 String sMailAddress = GetDBField( xColumnProp, aDBFormat); 1197 if(!SwMailMergeHelper::CheckMailAddress( sMailAddress )) 1198 { 1199 DBG_ERROR("invalid e-Mail address in database column"); 1200 } 1201 else 1202 { 1203 SwMailMessage* pMessage = 0; 1204 uno::Reference< mail::XMailMessage > xMessage = 1205 pMessage = new SwMailMessage; 1206 if(rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo()) 1207 pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo()); 1208 pMessage->addRecipient( sMailAddress ); 1209 pMessage->SetSenderAddress( rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() ); 1210 ::rtl::OUString sBody; 1211 if(rMergeDescriptor.bSendAsAttachment) 1212 { 1213 sBody = rMergeDescriptor.sMailBody; 1214 mail::MailAttachment aAttach; 1215 aAttach.Data = new SwMailTransferable( 1216 sFileURL, 1217 rMergeDescriptor.sAttachmentName, 1218 pStoreToFilter->GetMimeType()); 1219 aAttach.ReadableName = rMergeDescriptor.sAttachmentName; 1220 pMessage->addAttachment( aAttach ); 1221 } 1222 else 1223 { 1224 { 1225 //read in the temporary file and use it as mail body 1226 SfxMedium aMedium( sFileURL, STREAM_READ, sal_True); 1227 SvStream* pInStream = aMedium.GetInStream(); 1228 DBG_ASSERT(pInStream, "no output file created?"); 1229 if(pInStream) 1230 { 1231 pInStream->SetStreamCharSet( eEncoding ); 1232 ByteString sLine; 1233 sal_Bool bDone = pInStream->ReadLine( sLine ); 1234 while ( bDone ) 1235 { 1236 sBody += String(sLine, eEncoding); 1237 sBody += ::rtl::OUString('\n'); 1238 bDone = pInStream->ReadLine( sLine ); 1239 } 1240 } 1241 } 1242 } 1243 pMessage->setSubject( rMergeDescriptor.sSubject ); 1244 uno::Reference< datatransfer::XTransferable> xBody = 1245 new SwMailTransferable( 1246 sBody, 1247 sBodyMimeType); 1248 pMessage->setBody( xBody ); 1249 1250 if(rMergeDescriptor.aCopiesTo.getLength()) 1251 { 1252 const ::rtl::OUString* pCopies = rMergeDescriptor.aCopiesTo.getConstArray(); 1253 for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aCopiesTo.getLength(); ++nToken) 1254 pMessage->addCcRecipient( pCopies[nToken] ); 1255 } 1256 if(rMergeDescriptor.aBlindCopiesTo.getLength()) 1257 { 1258 const ::rtl::OUString* pCopies = rMergeDescriptor.aBlindCopiesTo.getConstArray(); 1259 for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aBlindCopiesTo.getLength(); ++nToken) 1260 pMessage->addBccRecipient( pCopies[nToken] ); 1261 } 1262 xMailDispatcher->enqueueMailMessage( xMessage ); 1263 if(!xMailDispatcher->isStarted()) 1264 xMailDispatcher->start(); 1265 //schedule for removal 1266 aFilesToRemove.push_back(sFileURL); 1267 } 1268 } 1269 } 1270 pWorkDoc->SetNewDBMgr( pOldDBMgr ); 1271 } 1272 xWorkDocSh->DoClose(); 1273 } 1274 } 1275 nDocNo++; 1276 nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0; 1277 } while( !bCancel && 1278 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord())); 1279 1280 aPrtMonDlg.Show( sal_False ); 1281 1282 // save the single output document 1283 if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile) 1284 { 1285 if( rMergeDescriptor.nMergeType != DBMGR_MERGE_MAILMERGE ) 1286 { 1287 DBG_ASSERT( aTempFile.get(), "Temporary file not available" ); 1288 INetURLObject aTempFileURL(bAsSingleFile ? sSubject : aTempFile->GetURL()); 1289 SfxMedium* pDstMed = new SfxMedium( 1290 aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ), 1291 STREAM_STD_READWRITE, sal_True ); 1292 pDstMed->SetFilter( pStoreToFilter ); 1293 if(pDstMed->GetItemSet()) 1294 { 1295 if(pStoreToFilterOptions ) 1296 pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions)); 1297 if(rMergeDescriptor.aSaveToFilterData.getLength()) 1298 pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData))); 1299 } 1300 1301 xTargetDocShell->DoSaveAs(*pDstMed); 1302 xTargetDocShell->DoSaveCompleted(pDstMed); 1303 if( xTargetDocShell->GetError() ) 1304 { 1305 // error message ?? 1306 ErrorHandler::HandleError( xTargetDocShell->GetError() ); 1307 bLoop = sal_False; 1308 } 1309 } 1310 else if( pTargetView ) // must be available! 1311 { 1312 //print the target document 1313 #if OSL_DEBUG_LEVEL > 1 1314 sal_Bool _bVal; 1315 sal_Int16 _nVal; 1316 rtl::OUString _sVal; 1317 const beans::PropertyValue* pDbgPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray(); 1318 for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption) 1319 { 1320 rtl::OUString aName( pDbgPrintOptions[nOption].Name ); 1321 uno::Any aVal( pDbgPrintOptions[nOption].Value ); 1322 aVal >>= _bVal; 1323 aVal >>= _nVal; 1324 aVal >>= _sVal; 1325 } 1326 #endif 1327 // printing should be done synchronously otherwise the document 1328 // might already become invalid during the process 1329 uno::Sequence< beans::PropertyValue > aOptions( rMergeDescriptor.aPrintOptions ); 1330 const sal_Int32 nOpts = aOptions.getLength(); 1331 aOptions.realloc( nOpts + 1 ); 1332 aOptions[ nOpts ].Name = rtl::OUString::createFromAscii( "Wait" ); 1333 aOptions[ nOpts ].Value <<= sal_True ; 1334 // aPrintArgs.Put(SfxBoolItem(FN_QRY_MERGE, sal_True) ); 1335 // // #i52629# aynchronous printing should only be done in silent mode - otherwise 1336 // // the printer dialog does not come up 1337 // aPrintArgs.Put( SfxBoolItem( SID_ASYNCHRON, rMergeDescriptor.bPrintAsync )); 1338 // move print options 1339 const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray(); 1340 for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption) 1341 { 1342 if( pPrintOptions[nOption].Name.equalsAscii( "CopyCount" ) 1343 ||( pPrintOptions[nOption].Name.equalsAscii( "FileName" )) 1344 ||( pPrintOptions[nOption].Name.equalsAscii( "Collate" )) 1345 ||( pPrintOptions[nOption].Name.equalsAscii( "Pages" )) 1346 ||( pPrintOptions[nOption].Name.equalsAscii( "Wait" ))) 1347 { 1348 aOptions.realloc( nOpts + 1 ); 1349 aOptions[ nOpts ].Name = pPrintOptions[nOption].Name; 1350 aOptions[ nOpts ].Value = pPrintOptions[nOption].Value ; 1351 } 1352 } 1353 1354 // const SwModuleOptions * pModOpt = SW_MOD()->GetModuleConfig(); 1355 // if (pModOpt->IsSinglePrintJob()) 1356 // { 1357 // } 1358 // else 1359 // { 1360 pTargetView->ExecPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync ); 1361 // } 1362 } 1363 xTargetDocShell->DoClose(); 1364 } 1365 1366 //remove the temporary files 1367 ::std::vector<String>::iterator aFileIter; 1368 for(aFileIter = aFilesToRemove.begin(); 1369 aFileIter != aFilesToRemove.end(); aFileIter++) 1370 SWUnoHelper::UCB_DeleteFile( *aFileIter ); 1371 1372 // Alle Dispatcher freigeben 1373 pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh); 1374 while (pViewFrm) 1375 { 1376 pViewFrm->GetDispatcher()->Lock(sal_False); 1377 pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh); 1378 } 1379 1380 SW_MOD()->SetView(&pSourceShell->GetView()); 1381 } 1382 1383 nMergeType = DBMGR_INSERT; 1384 } 1385 1386 if(bEMail) 1387 { 1388 xMailDispatcher->stop(); 1389 xMailDispatcher->shutdown(); 1390 1391 } 1392 1393 return bLoop; 1394 } 1395 1396 /*-------------------------------------------------------------------- 1397 Beschreibung: 1398 --------------------------------------------------------------------*/ 1399 1400 IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton ) 1401 { 1402 pButton->GetParent()->Hide(); 1403 bCancel = sal_True; 1404 return 0; 1405 } 1406 IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton ) 1407 1408 1409 /*-------------------------------------------------------------------- 1410 Beschreibung: Numberformat der Spalte ermitteln und ggfs. in 1411 den uebergebenen Formatter uebertragen 1412 --------------------------------------------------------------------*/ 1413 1414 sal_uLong SwNewDBMgr::GetColumnFmt( const String& rDBName, 1415 const String& rTableName, 1416 const String& rColNm, 1417 SvNumberFormatter* pNFmtr, 1418 long nLanguage ) 1419 { 1420 sal_uLong nRet = 0; 1421 if(pNFmtr) 1422 { 1423 uno::Reference< XDataSource> xSource; 1424 uno::Reference< XConnection> xConnection; 1425 sal_Bool bUseMergeData = sal_False; 1426 uno::Reference< XColumnsSupplier> xColsSupp; 1427 bool bDisposeConnection = false; 1428 if(pImpl->pMergeData && 1429 pImpl->pMergeData->sDataSource.equals(rDBName) && pImpl->pMergeData->sCommand.equals(rTableName)) 1430 { 1431 xConnection = pImpl->pMergeData->xConnection; 1432 xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,rDBName); 1433 bUseMergeData = sal_True; 1434 xColsSupp = xColsSupp.query( pImpl->pMergeData->xResultSet ); 1435 } 1436 if(!xConnection.is()) 1437 { 1438 SwDBData aData; 1439 aData.sDataSource = rDBName; 1440 aData.sCommand = rTableName; 1441 aData.nCommandType = -1; 1442 SwDSParam* pParam = FindDSData(aData, sal_False); 1443 if(pParam && pParam->xConnection.is()) 1444 { 1445 xConnection = pParam->xConnection; 1446 xColsSupp = xColsSupp.query( pParam->xResultSet ); 1447 } 1448 else 1449 { 1450 rtl::OUString sDBName(rDBName); 1451 xConnection = RegisterConnection( sDBName ); 1452 bDisposeConnection = true; 1453 } 1454 if(bUseMergeData) 1455 pImpl->pMergeData->xConnection = xConnection; 1456 } 1457 bool bDispose = !xColsSupp.is(); 1458 if(bDispose) 1459 { 1460 xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); 1461 } 1462 if(xColsSupp.is()) 1463 { 1464 uno::Reference<XNameAccess> xCols; 1465 try 1466 { 1467 xCols = xColsSupp->getColumns(); 1468 } 1469 catch(Exception&) 1470 { 1471 DBG_ERROR("Exception in getColumns()"); 1472 } 1473 if(!xCols.is() || !xCols->hasByName(rColNm)) 1474 return nRet; 1475 Any aCol = xCols->getByName(rColNm); 1476 uno::Reference< XPropertySet > xColumn; 1477 aCol >>= xColumn; 1478 nRet = GetColumnFmt(xSource, xConnection, xColumn, pNFmtr, nLanguage); 1479 if(bDispose) 1480 { 1481 ::comphelper::disposeComponent( xColsSupp ); 1482 } 1483 if(bDisposeConnection) 1484 { 1485 ::comphelper::disposeComponent( xConnection ); 1486 } 1487 } 1488 else 1489 nRet = pNFmtr->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM ); 1490 } 1491 return nRet; 1492 } 1493 /* -----------------------------07.06.01 15:43-------------------------------- 1494 1495 ---------------------------------------------------------------------------*/ 1496 sal_uLong SwNewDBMgr::GetColumnFmt( uno::Reference< XDataSource> xSource, 1497 uno::Reference< XConnection> xConnection, 1498 uno::Reference< XPropertySet> xColumn, 1499 SvNumberFormatter* pNFmtr, 1500 long nLanguage ) 1501 { 1502 //JP 12.01.99: ggfs. das NumberFormat im Doc setzen 1503 sal_uLong nRet = 0; 1504 1505 if(!xSource.is()) 1506 { 1507 uno::Reference<XChild> xChild(xConnection, UNO_QUERY); 1508 if ( xChild.is() ) 1509 xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY); 1510 } 1511 if(xSource.is() && xConnection.is() && xColumn.is() && pNFmtr) 1512 { 1513 SvNumberFormatsSupplierObj* pNumFmt = new SvNumberFormatsSupplierObj( pNFmtr ); 1514 uno::Reference< util::XNumberFormatsSupplier > xDocNumFmtsSupplier = pNumFmt; 1515 uno::Reference< XNumberFormats > xDocNumberFormats = xDocNumFmtsSupplier->getNumberFormats(); 1516 uno::Reference< XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY); 1517 1518 Locale aLocale( MsLangId::convertLanguageToLocale( (LanguageType)nLanguage )); 1519 1520 //get the number formatter of the data source 1521 uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY); 1522 uno::Reference< XNumberFormats > xNumberFormats; 1523 if(xSourceProps.is()) 1524 { 1525 Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier")); 1526 if(aFormats.hasValue()) 1527 { 1528 uno::Reference<XNumberFormatsSupplier> xSuppl; 1529 aFormats >>= xSuppl; 1530 if(xSuppl.is()) 1531 { 1532 xNumberFormats = xSuppl->getNumberFormats(); 1533 } 1534 } 1535 } 1536 bool bUseDefault = true; 1537 try 1538 { 1539 Any aFormatKey = xColumn->getPropertyValue(C2U("FormatKey")); 1540 if(aFormatKey.hasValue()) 1541 { 1542 sal_Int32 nFmt = 0; 1543 aFormatKey >>= nFmt; 1544 if(xNumberFormats.is()) 1545 { 1546 try 1547 { 1548 uno::Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFmt ); 1549 Any aFormatString = xNumProps->getPropertyValue(C2U("FormatString")); 1550 Any aLocaleVal = xNumProps->getPropertyValue(C2U("Locale")); 1551 rtl::OUString sFormat; 1552 aFormatString >>= sFormat; 1553 lang::Locale aLoc; 1554 aLocaleVal >>= aLoc; 1555 nFmt = xDocNumberFormats->queryKey( sFormat, aLoc, sal_False ); 1556 if(NUMBERFORMAT_ENTRY_NOT_FOUND == sal::static_int_cast< sal_uInt32, sal_Int32>(nFmt)) 1557 nFmt = xDocNumberFormats->addNew( sFormat, aLoc ); 1558 nRet = nFmt; 1559 bUseDefault = false; 1560 } 1561 catch(const Exception&) 1562 { 1563 DBG_ERROR("illegal number format key"); 1564 } 1565 } 1566 } 1567 } 1568 catch( const Exception& ) 1569 { 1570 DBG_ERROR("no FormatKey property found"); 1571 } 1572 if(bUseDefault) 1573 nRet = SwNewDBMgr::GetDbtoolsClient().getDefaultNumberFormat(xColumn, xDocNumberFormatTypes, aLocale); 1574 } 1575 return nRet; 1576 } 1577 1578 /* -----------------------------17.07.00 09:47-------------------------------- 1579 1580 ---------------------------------------------------------------------------*/ 1581 sal_Int32 SwNewDBMgr::GetColumnType( const String& rDBName, 1582 const String& rTableName, 1583 const String& rColNm ) 1584 { 1585 sal_Int32 nRet = DataType::SQLNULL; 1586 SwDBData aData; 1587 aData.sDataSource = rDBName; 1588 aData.sCommand = rTableName; 1589 aData.nCommandType = -1; 1590 SwDSParam* pParam = FindDSData(aData, sal_False); 1591 uno::Reference< XConnection> xConnection; 1592 uno::Reference< XColumnsSupplier > xColsSupp; 1593 bool bDispose = false; 1594 if(pParam && pParam->xConnection.is()) 1595 { 1596 xConnection = pParam->xConnection; 1597 xColsSupp = uno::Reference< XColumnsSupplier >( pParam->xResultSet, UNO_QUERY ); 1598 } 1599 else 1600 { 1601 rtl::OUString sDBName(rDBName); 1602 xConnection = RegisterConnection( sDBName ); 1603 } 1604 if( !xColsSupp.is() ) 1605 { 1606 xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); 1607 bDispose = true; 1608 } 1609 if(xColsSupp.is()) 1610 { 1611 uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); 1612 if(xCols->hasByName(rColNm)) 1613 { 1614 Any aCol = xCols->getByName(rColNm); 1615 uno::Reference<XPropertySet> xCol; 1616 aCol >>= xCol; 1617 Any aType = xCol->getPropertyValue(C2S("Type")); 1618 aType >>= nRet; 1619 } 1620 if(bDispose) 1621 ::comphelper::disposeComponent( xColsSupp ); 1622 } 1623 return nRet; 1624 } 1625 1626 /* -----------------------------03.07.00 17:12-------------------------------- 1627 1628 ---------------------------------------------------------------------------*/ 1629 uno::Reference< sdbc::XConnection> SwNewDBMgr::GetConnection(const String& rDataSource, 1630 uno::Reference<XDataSource>& rxSource) 1631 { 1632 Reference< sdbc::XConnection> xConnection; 1633 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); 1634 try 1635 { 1636 Reference<XCompletedConnection> xComplConnection(SwNewDBMgr::GetDbtoolsClient().getDataSource(rDataSource, xMgr),UNO_QUERY); 1637 if ( xComplConnection.is() ) 1638 { 1639 rxSource.set(xComplConnection,UNO_QUERY); 1640 Reference< XInteractionHandler > xHandler( 1641 xMgr->createInstance( C2U( "com.sun.star.task.InteractionHandler" )), UNO_QUERY); 1642 xConnection = xComplConnection->connectWithCompletion( xHandler ); 1643 } 1644 } 1645 catch(Exception&) {} 1646 1647 return xConnection; 1648 } 1649 /* -----------------------------03.07.00 17:12-------------------------------- 1650 1651 ---------------------------------------------------------------------------*/ 1652 uno::Reference< sdbcx::XColumnsSupplier> SwNewDBMgr::GetColumnSupplier(uno::Reference<sdbc::XConnection> xConnection, 1653 const String& rTableOrQuery, 1654 sal_uInt8 eTableOrQuery) 1655 { 1656 Reference< sdbcx::XColumnsSupplier> xRet; 1657 try 1658 { 1659 if(eTableOrQuery == SW_DB_SELECT_UNKNOWN) 1660 { 1661 //search for a table with the given command name 1662 Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY); 1663 if(xTSupplier.is()) 1664 { 1665 Reference<XNameAccess> xTbls = xTSupplier->getTables(); 1666 eTableOrQuery = xTbls->hasByName(rTableOrQuery) ? 1667 SW_DB_SELECT_TABLE : SW_DB_SELECT_QUERY; 1668 } 1669 } 1670 sal_Int32 nCommandType = SW_DB_SELECT_TABLE == eTableOrQuery ? 1671 CommandType::TABLE : CommandType::QUERY; 1672 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); 1673 Reference<XRowSet> xRowSet( 1674 xMgr->createInstance(C2U("com.sun.star.sdb.RowSet")), UNO_QUERY); 1675 1676 ::rtl::OUString sDataSource; 1677 Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection, sDataSource); 1678 Reference<XPropertySet> xSourceProperties(xSource, UNO_QUERY); 1679 if(xSourceProperties.is()) 1680 { 1681 xSourceProperties->getPropertyValue(C2U("Name")) >>= sDataSource; 1682 } 1683 1684 Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY); 1685 xRowProperties->setPropertyValue(C2U("DataSourceName"), makeAny(sDataSource)); 1686 xRowProperties->setPropertyValue(C2U("Command"), makeAny(::rtl::OUString(rTableOrQuery))); 1687 xRowProperties->setPropertyValue(C2U("CommandType"), makeAny(nCommandType)); 1688 xRowProperties->setPropertyValue(C2U("FetchSize"), makeAny((sal_Int32)10)); 1689 xRowProperties->setPropertyValue(C2U("ActiveConnection"), makeAny(xConnection)); 1690 xRowSet->execute(); 1691 xRet = Reference<XColumnsSupplier>( xRowSet, UNO_QUERY ); 1692 } 1693 catch( const uno::Exception& ) 1694 { 1695 DBG_ERROR("Exception in SwDBMgr::GetColumnSupplier"); 1696 } 1697 1698 return xRet; 1699 } 1700 /* -----------------------------05.07.00 13:44-------------------------------- 1701 1702 ---------------------------------------------------------------------------*/ 1703 String SwNewDBMgr::GetDBField(uno::Reference<XPropertySet> xColumnProps, 1704 const SwDBFormatData& rDBFormatData, 1705 double* pNumber) 1706 { 1707 uno::Reference< XColumn > xColumn(xColumnProps, UNO_QUERY); 1708 String sRet; 1709 DBG_ASSERT(xColumn.is(), "SwNewDBMgr::::ImportDBField: illegal arguments"); 1710 if(!xColumn.is()) 1711 return sRet; 1712 1713 Any aType = xColumnProps->getPropertyValue(C2U("Type")); 1714 sal_Int32 eDataType = 0; 1715 aType >>= eDataType; 1716 switch(eDataType) 1717 { 1718 case DataType::CHAR: 1719 case DataType::VARCHAR: 1720 case DataType::LONGVARCHAR: 1721 try 1722 { 1723 sRet = xColumn->getString(); 1724 } 1725 catch( SQLException& ) 1726 { 1727 } 1728 break; 1729 case DataType::BIT: 1730 case DataType::BOOLEAN: 1731 case DataType::TINYINT: 1732 case DataType::SMALLINT: 1733 case DataType::INTEGER: 1734 case DataType::BIGINT: 1735 case DataType::FLOAT: 1736 case DataType::REAL: 1737 case DataType::DOUBLE: 1738 case DataType::NUMERIC: 1739 case DataType::DECIMAL: 1740 case DataType::DATE: 1741 case DataType::TIME: 1742 case DataType::TIMESTAMP: 1743 { 1744 // ::Date aTempDate(rDBFormatData.aNullDate.Day, 1745 // rDBFormatData.aNullDate.Month, rDBFormatData.aNullDate.Year); 1746 1747 try 1748 { 1749 SwDbtoolsClient& aClient = SwNewDBMgr::GetDbtoolsClient(); 1750 sRet = aClient.getFormattedValue( 1751 xColumnProps, 1752 rDBFormatData.xFormatter, 1753 rDBFormatData.aLocale, 1754 rDBFormatData.aNullDate); 1755 if (pNumber) 1756 { 1757 double fVal = xColumn->getDouble(); 1758 if(!xColumn->wasNull()) 1759 { 1760 *pNumber = fVal; 1761 } 1762 } 1763 } 1764 catch(Exception& ) 1765 { 1766 DBG_ERROR("exception caught"); 1767 } 1768 1769 } 1770 break; 1771 1772 // case DataType::BINARY: 1773 // case DataType::VARBINARY: 1774 // case DataType::LONGVARBINARY: 1775 // case DataType::SQLNULL: 1776 // case DataType::OTHER: 1777 // case DataType::OBJECT: 1778 // case DataType::DISTINCT: 1779 // case DataType::STRUCT: 1780 // case DataType::ARRAY: 1781 // case DataType::BLOB: 1782 // case DataType::CLOB: 1783 // case DataType::REF: 1784 // default: 1785 } 1786 // if (pFormat) 1787 // { 1788 // SFX_ITEMSET_GET(*pCol, pFormatItem, SfxUInt32Item, SBA_DEF_FMTVALUE, sal_True); 1789 // *pFormat = pFormatItem->GetValue(); 1790 // } 1791 1792 return sRet; 1793 } 1794 /* -----------------------------06.07.00 14:28-------------------------------- 1795 releases the merge data source table or query after merge is completed 1796 ---------------------------------------------------------------------------*/ 1797 void SwNewDBMgr::EndMerge() 1798 { 1799 DBG_ASSERT(bInMerge, "merge is not active"); 1800 bInMerge = sal_False; 1801 delete pImpl->pMergeData; 1802 pImpl->pMergeData = 0; 1803 } 1804 /* -----------------------------06.07.00 14:28-------------------------------- 1805 checks if a desired data source table or query is open 1806 ---------------------------------------------------------------------------*/ 1807 sal_Bool SwNewDBMgr::IsDataSourceOpen(const String& rDataSource, 1808 const String& rTableOrQuery, sal_Bool bMergeOnly) 1809 { 1810 if(pImpl->pMergeData) 1811 { 1812 return !bMergeLock && 1813 ((rDataSource == (String)pImpl->pMergeData->sDataSource && 1814 rTableOrQuery == (String)pImpl->pMergeData->sCommand) 1815 ||(!rDataSource.Len() && !rTableOrQuery.Len())) 1816 && 1817 pImpl->pMergeData->xResultSet.is(); 1818 } 1819 else if(!bMergeOnly) 1820 { 1821 SwDBData aData; 1822 aData.sDataSource = rDataSource; 1823 aData.sCommand = rTableOrQuery; 1824 aData.nCommandType = -1; 1825 SwDSParam* pFound = FindDSData(aData, sal_False); 1826 return (pFound && pFound->xResultSet.is()); 1827 } 1828 return sal_False; 1829 } 1830 /* -----------------------------17.07.00 16:44-------------------------------- 1831 read column data a a specified position 1832 ---------------------------------------------------------------------------*/ 1833 sal_Bool SwNewDBMgr::GetColumnCnt(const String& rSourceName, const String& rTableName, 1834 const String& rColumnName, sal_uInt32 nAbsRecordId, 1835 long nLanguage, 1836 String& rResult, double* pNumber) 1837 { 1838 sal_Bool bRet = sal_False; 1839 SwDSParam* pFound = 0; 1840 //check if it's the merge data source 1841 if(pImpl->pMergeData && 1842 rSourceName == (String)pImpl->pMergeData->sDataSource && 1843 rTableName == (String)pImpl->pMergeData->sCommand) 1844 { 1845 pFound = pImpl->pMergeData; 1846 } 1847 else 1848 { 1849 SwDBData aData; 1850 aData.sDataSource = rSourceName; 1851 aData.sCommand = rTableName; 1852 aData.nCommandType = -1; 1853 pFound = FindDSData(aData, sal_False); 1854 } 1855 //check validity of supplied record Id 1856 if(pFound->aSelection.getLength()) 1857 { 1858 //the destination has to be an element of the selection 1859 const Any* pSelection = pFound->aSelection.getConstArray(); 1860 sal_Bool bFound = sal_False; 1861 for(sal_Int32 nPos = 0; !bFound && nPos < pFound->aSelection.getLength(); nPos++) 1862 { 1863 sal_Int32 nSelection = 0; 1864 pSelection[nPos] >>= nSelection; 1865 if(nSelection == static_cast<sal_Int32>(nAbsRecordId)) 1866 bFound = sal_True; 1867 } 1868 if(!bFound) 1869 return sal_False; 1870 } 1871 if(pFound && pFound->xResultSet.is() && !pFound->bAfterSelection) 1872 { 1873 sal_Int32 nOldRow = 0; 1874 try 1875 { 1876 nOldRow = pFound->xResultSet->getRow(); 1877 } 1878 catch(const Exception& ) 1879 { 1880 return sal_False; 1881 } 1882 //position to the desired index 1883 sal_Bool bMove = sal_True; 1884 if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) ) 1885 bMove = lcl_MoveAbsolute(pFound, nAbsRecordId); 1886 if(bMove) 1887 { 1888 bRet = lcl_GetColumnCnt(pFound, rColumnName, nLanguage, rResult, pNumber); 1889 } 1890 if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) ) 1891 bMove = lcl_MoveAbsolute(pFound, nOldRow); 1892 } 1893 return bRet; 1894 } 1895 /* -----------------------------06.07.00 16:47-------------------------------- 1896 reads the column data at the current position 1897 ---------------------------------------------------------------------------*/ 1898 sal_Bool SwNewDBMgr::GetMergeColumnCnt(const String& rColumnName, sal_uInt16 nLanguage, 1899 String &rResult, double *pNumber, sal_uInt32 * /*pFormat*/) 1900 { 1901 if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is() || pImpl->pMergeData->bAfterSelection ) 1902 { 1903 rResult.Erase(); 1904 return sal_False; 1905 } 1906 1907 sal_Bool bRet = lcl_GetColumnCnt(pImpl->pMergeData, rColumnName, nLanguage, rResult, pNumber); 1908 return bRet; 1909 } 1910 /* -----------------------------07.07.00 14:28-------------------------------- 1911 1912 ---------------------------------------------------------------------------*/ 1913 sal_Bool SwNewDBMgr::ToNextMergeRecord() 1914 { 1915 DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge"); 1916 return ToNextRecord(pImpl->pMergeData); 1917 } 1918 /* -----------------------------10.07.01 14:28-------------------------------- 1919 1920 ---------------------------------------------------------------------------*/ 1921 sal_Bool SwNewDBMgr::ToNextRecord( 1922 const String& rDataSource, const String& rCommand, sal_Int32 /*nCommandType*/) 1923 { 1924 SwDSParam* pFound = 0; 1925 if(pImpl->pMergeData && 1926 rDataSource == (String)pImpl->pMergeData->sDataSource && 1927 rCommand == (String)pImpl->pMergeData->sCommand) 1928 pFound = pImpl->pMergeData; 1929 else 1930 { 1931 SwDBData aData; 1932 aData.sDataSource = rDataSource; 1933 aData.sCommand = rCommand; 1934 aData.nCommandType = -1; 1935 pFound = FindDSData(aData, sal_False); 1936 } 1937 return ToNextRecord(pFound); 1938 } 1939 /* -----------------------------10.07.01 14:38-------------------------------- 1940 1941 ---------------------------------------------------------------------------*/ 1942 sal_Bool SwNewDBMgr::ToNextRecord(SwDSParam* pParam) 1943 { 1944 sal_Bool bRet = sal_True; 1945 if(!pParam || !pParam->xResultSet.is() || pParam->bEndOfDB || 1946 (pParam->aSelection.getLength() && pParam->aSelection.getLength() <= pParam->nSelectionIndex)) 1947 { 1948 if(pParam) 1949 pParam->CheckEndOfDB(); 1950 return sal_False; 1951 } 1952 try 1953 { 1954 if(pParam->aSelection.getLength()) 1955 { 1956 sal_Int32 nPos = 0; 1957 pParam->aSelection.getConstArray()[ pParam->nSelectionIndex++ ] >>= nPos; 1958 pParam->bEndOfDB = !pParam->xResultSet->absolute( nPos ); 1959 pParam->CheckEndOfDB(); 1960 bRet = !pParam->bEndOfDB; 1961 if(pParam->nSelectionIndex >= pParam->aSelection.getLength()) 1962 pParam->bEndOfDB = sal_True; 1963 } 1964 else 1965 { 1966 sal_Int32 nBefore = pParam->xResultSet->getRow(); 1967 pParam->bEndOfDB = !pParam->xResultSet->next(); 1968 if( !pParam->bEndOfDB && nBefore == pParam->xResultSet->getRow()) 1969 { 1970 //next returned true but it didn't move 1971 pParam->bEndOfDB = sal_True; 1972 } 1973 1974 pParam->CheckEndOfDB(); 1975 bRet = !pParam->bEndOfDB; 1976 ++pParam->nSelectionIndex; 1977 } 1978 } 1979 catch(Exception&) 1980 { 1981 } 1982 return bRet; 1983 } 1984 1985 /* -----------------------------13.07.00 17:23-------------------------------- 1986 synchronized labels contain a next record field at their end 1987 to assure that the next page can be created in mail merge 1988 the cursor position must be validated 1989 ---------------------------------------------------------------------------*/ 1990 sal_Bool SwNewDBMgr::ExistsNextRecord() const 1991 { 1992 return pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB; 1993 } 1994 /* -----------------------------13.07.00 10:41-------------------------------- 1995 1996 ---------------------------------------------------------------------------*/ 1997 sal_uInt32 SwNewDBMgr::GetSelectedRecordId() 1998 { 1999 sal_uInt32 nRet = 0; 2000 DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge"); 2001 if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()) 2002 return sal_False; 2003 try 2004 { 2005 nRet = pImpl->pMergeData->xResultSet->getRow(); 2006 } 2007 catch(Exception& ) 2008 { 2009 } 2010 return nRet; 2011 } 2012 /* -----------------------------13.07.00 10:58-------------------------------- 2013 2014 ---------------------------------------------------------------------------*/ 2015 sal_Bool SwNewDBMgr::ToRecordId(sal_Int32 nSet) 2016 { 2017 DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge"); 2018 if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()|| nSet < 0) 2019 return sal_False; 2020 sal_Bool bRet = sal_False; 2021 sal_Int32 nAbsPos = nSet; 2022 2023 if(nAbsPos >= 0) 2024 { 2025 bRet = lcl_MoveAbsolute(pImpl->pMergeData, nAbsPos); 2026 pImpl->pMergeData->bEndOfDB = !bRet; 2027 pImpl->pMergeData->CheckEndOfDB(); 2028 } 2029 return bRet; 2030 } 2031 2032 /* -----------------------------17.07.00 14:17-------------------------------- 2033 2034 ---------------------------------------------------------------------------*/ 2035 sal_Bool SwNewDBMgr::OpenDataSource(const String& rDataSource, const String& rTableOrQuery, 2036 sal_Int32 nCommandType, bool bCreate) 2037 { 2038 SwDBData aData; 2039 aData.sDataSource = rDataSource; 2040 aData.sCommand = rTableOrQuery; 2041 aData.nCommandType = nCommandType; 2042 2043 SwDSParam* pFound = FindDSData(aData, sal_True); 2044 uno::Reference< XDataSource> xSource; 2045 if(pFound->xResultSet.is()) 2046 return sal_True; 2047 SwDSParam* pParam = FindDSConnection(rDataSource, sal_False); 2048 uno::Reference< XConnection> xConnection; 2049 if(pParam && pParam->xConnection.is()) 2050 pFound->xConnection = pParam->xConnection; 2051 else if(bCreate) 2052 { 2053 rtl::OUString sDataSource(rDataSource); 2054 pFound->xConnection = RegisterConnection( sDataSource ); 2055 } 2056 if(pFound->xConnection.is()) 2057 { 2058 try 2059 { 2060 uno::Reference< sdbc::XDatabaseMetaData > xMetaData = pFound->xConnection->getMetaData(); 2061 try 2062 { 2063 pFound->bScrollable = xMetaData 2064 ->supportsResultSetType((sal_Int32)ResultSetType::SCROLL_INSENSITIVE); 2065 } 2066 catch(Exception&) 2067 { 2068 //#98373# DB driver may not be ODBC 3.0 compliant 2069 pFound->bScrollable = sal_True; 2070 } 2071 pFound->xStatement = pFound->xConnection->createStatement(); 2072 rtl::OUString aQuoteChar = xMetaData->getIdentifierQuoteString(); 2073 rtl::OUString sStatement(C2U("SELECT * FROM ")); 2074 sStatement = C2U("SELECT * FROM "); 2075 sStatement += aQuoteChar; 2076 sStatement += rTableOrQuery; 2077 sStatement += aQuoteChar; 2078 pFound->xResultSet = pFound->xStatement->executeQuery( sStatement ); 2079 2080 //after executeQuery the cursor must be positioned 2081 pFound->bEndOfDB = !pFound->xResultSet->next(); 2082 pFound->bAfterSelection = sal_False; 2083 pFound->CheckEndOfDB(); 2084 ++pFound->nSelectionIndex; 2085 } 2086 catch (Exception&) 2087 { 2088 pFound->xResultSet = 0; 2089 pFound->xStatement = 0; 2090 pFound->xConnection = 0; 2091 } 2092 } 2093 return pFound->xResultSet.is(); 2094 } 2095 /* -----------------------------14.08.2001 10:26------------------------------ 2096 2097 ---------------------------------------------------------------------------*/ 2098 uno::Reference< XConnection> SwNewDBMgr::RegisterConnection(rtl::OUString& rDataSource) 2099 { 2100 SwDSParam* pFound = SwNewDBMgr::FindDSConnection(rDataSource, sal_True); 2101 uno::Reference< XDataSource> xSource; 2102 if(!pFound->xConnection.is()) 2103 { 2104 pFound->xConnection = SwNewDBMgr::GetConnection(rDataSource, xSource ); 2105 try 2106 { 2107 uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY); 2108 if(xComponent.is()) 2109 xComponent->addEventListener(pImpl->xDisposeListener); 2110 } 2111 catch(Exception&) 2112 { 2113 } 2114 } 2115 return pFound->xConnection; 2116 } 2117 /* -----------------------------17.07.00 15:55-------------------------------- 2118 2119 ---------------------------------------------------------------------------*/ 2120 sal_uInt32 SwNewDBMgr::GetSelectedRecordId( 2121 const String& rDataSource, const String& rTableOrQuery, sal_Int32 nCommandType) 2122 { 2123 sal_uInt32 nRet = 0xffffffff; 2124 //check for merge data source first 2125 if(pImpl->pMergeData && rDataSource == (String)pImpl->pMergeData->sDataSource && 2126 rTableOrQuery == (String)pImpl->pMergeData->sCommand && 2127 (nCommandType == -1 || nCommandType == pImpl->pMergeData->nCommandType) && 2128 pImpl->pMergeData->xResultSet.is()) 2129 nRet = GetSelectedRecordId(); 2130 else 2131 { 2132 SwDBData aData; 2133 aData.sDataSource = rDataSource; 2134 aData.sCommand = rTableOrQuery; 2135 aData.nCommandType = nCommandType; 2136 SwDSParam* pFound = FindDSData(aData, sal_False); 2137 if(pFound && pFound->xResultSet.is()) 2138 { 2139 try 2140 { //if a selection array is set the current row at the result set may not be set yet 2141 if(pFound->aSelection.getLength()) 2142 { 2143 sal_Int32 nSelIndex = pFound->nSelectionIndex; 2144 if(nSelIndex >= pFound->aSelection.getLength()) 2145 nSelIndex = pFound->aSelection.getLength() -1; 2146 pFound->aSelection.getConstArray()[nSelIndex] >>= nRet; 2147 2148 } 2149 else 2150 nRet = pFound->xResultSet->getRow(); 2151 } 2152 catch(Exception&){} 2153 } 2154 } 2155 return nRet; 2156 } 2157 2158 /* -----------------------------17.07.00 14:18-------------------------------- 2159 close all data sources - after fields were updated 2160 ---------------------------------------------------------------------------*/ 2161 void SwNewDBMgr::CloseAll(sal_Bool bIncludingMerge) 2162 { 2163 //the only thing done here is to reset the selection index 2164 //all connections stay open 2165 for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) 2166 { 2167 SwDSParam* pParam = aDataSourceParams[nPos]; 2168 if(bIncludingMerge || pParam != pImpl->pMergeData) 2169 { 2170 pParam->nSelectionIndex = 0; 2171 pParam->bAfterSelection = sal_False; 2172 pParam->bEndOfDB = sal_False; 2173 try 2174 { 2175 if(!bInMerge && pParam->xResultSet.is()) 2176 pParam->xResultSet->first(); 2177 } 2178 catch(Exception& ) 2179 {} 2180 } 2181 } 2182 } 2183 /* -----------------------------17.07.00 14:54-------------------------------- 2184 2185 ---------------------------------------------------------------------------*/ 2186 SwDSParam* SwNewDBMgr::FindDSData(const SwDBData& rData, sal_Bool bCreate) 2187 { 2188 //prefer merge data if available 2189 if(pImpl->pMergeData && rData.sDataSource == pImpl->pMergeData->sDataSource && 2190 rData.sCommand == pImpl->pMergeData->sCommand && 2191 (rData.nCommandType == -1 || rData.nCommandType == pImpl->pMergeData->nCommandType || 2192 (bCreate && pImpl->pMergeData->nCommandType == -1))) 2193 { 2194 return pImpl->pMergeData; 2195 } 2196 2197 SwDSParam* pFound = 0; 2198 for(sal_uInt16 nPos = aDataSourceParams.Count(); nPos; nPos--) 2199 { 2200 SwDSParam* pParam = aDataSourceParams[nPos - 1]; 2201 if(rData.sDataSource == pParam->sDataSource && 2202 rData.sCommand == pParam->sCommand && 2203 (rData.nCommandType == -1 || rData.nCommandType == pParam->nCommandType || 2204 (bCreate && pParam->nCommandType == -1))) 2205 { 2206 //#94779# calls from the calculator may add a connection with an invalid commandtype 2207 //later added "real" data base connections have to re-use the already available 2208 //DSData and set the correct CommandType 2209 if(bCreate && pParam->nCommandType == -1) 2210 pParam->nCommandType = rData.nCommandType; 2211 pFound = pParam; 2212 break; 2213 } 2214 } 2215 if(bCreate) 2216 { 2217 if(!pFound) 2218 { 2219 pFound = new SwDSParam(rData); 2220 aDataSourceParams.Insert(pFound, aDataSourceParams.Count()); 2221 try 2222 { 2223 uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY); 2224 if(xComponent.is()) 2225 xComponent->addEventListener(pImpl->xDisposeListener); 2226 } 2227 catch(Exception&) 2228 { 2229 } 2230 } 2231 } 2232 return pFound; 2233 } 2234 /* -----------------------------14.08.2001 10:27------------------------------ 2235 2236 ---------------------------------------------------------------------------*/ 2237 2238 SwDSParam* SwNewDBMgr::FindDSConnection(const rtl::OUString& rDataSource, sal_Bool bCreate) 2239 { 2240 //prefer merge data if available 2241 if(pImpl->pMergeData && rDataSource == pImpl->pMergeData->sDataSource ) 2242 { 2243 return pImpl->pMergeData; 2244 } 2245 SwDSParam* pFound = 0; 2246 for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) 2247 { 2248 SwDSParam* pParam = aDataSourceParams[nPos]; 2249 if(rDataSource == pParam->sDataSource) 2250 { 2251 pFound = pParam; 2252 break; 2253 } 2254 } 2255 if(bCreate && !pFound) 2256 { 2257 SwDBData aData; 2258 aData.sDataSource = rDataSource; 2259 pFound = new SwDSParam(aData); 2260 aDataSourceParams.Insert(pFound, aDataSourceParams.Count()); 2261 try 2262 { 2263 uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY); 2264 if(xComponent.is()) 2265 xComponent->addEventListener(pImpl->xDisposeListener); 2266 } 2267 catch(Exception&) 2268 { 2269 } 2270 } 2271 return pFound; 2272 } 2273 2274 /* -----------------------------17.07.00 14:34-------------------------------- 2275 2276 ---------------------------------------------------------------------------*/ 2277 const SwDBData& SwNewDBMgr::GetAddressDBName() 2278 { 2279 return SW_MOD()->GetDBConfig()->GetAddressSource(); 2280 } 2281 /* -----------------------------18.07.00 13:13-------------------------------- 2282 2283 ---------------------------------------------------------------------------*/ 2284 Sequence<rtl::OUString> SwNewDBMgr::GetExistingDatabaseNames() 2285 { 2286 uno::Reference<XNameAccess> xDBContext; 2287 uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); 2288 if( xMgr.is() ) 2289 { 2290 uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" )); 2291 xDBContext = uno::Reference<XNameAccess>(xInstance, UNO_QUERY) ; 2292 } 2293 if(xDBContext.is()) 2294 { 2295 return xDBContext->getElementNames(); 2296 } 2297 return Sequence<rtl::OUString>(); 2298 } 2299 /*-- 26.05.2004 14:33:13--------------------------------------------------- 2300 2301 -----------------------------------------------------------------------*/ 2302 String SwNewDBMgr::LoadAndRegisterDataSource() 2303 { 2304 sfx2::FileDialogHelper aDlgHelper( TemplateDescription::FILEOPEN_SIMPLE, 0 ); 2305 Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker(); 2306 2307 String sHomePath(SvtPathOptions().GetWorkPath()); 2308 aDlgHelper.SetDisplayDirectory( sHomePath ); 2309 2310 Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY); 2311 2312 String sFilterAll(SW_RES(STR_FILTER_ALL)); 2313 String sFilterAllData(SW_RES(STR_FILTER_ALL_DATA)); 2314 String sFilterSXB(SW_RES(STR_FILTER_SXB)); 2315 String sFilterSXC(SW_RES(STR_FILTER_SXC)); 2316 String sFilterDBF(SW_RES(STR_FILTER_DBF)); 2317 String sFilterXLS(SW_RES(STR_FILTER_XLS)); 2318 String sFilterTXT(SW_RES(STR_FILTER_TXT)); 2319 String sFilterCSV(SW_RES(STR_FILTER_CSV)); 2320 #ifdef WNT 2321 String sFilterMDB(SW_RES(STR_FILTER_MDB)); 2322 String sFilterACCDB(SW_RES(STR_FILTER_ACCDB)); 2323 #endif 2324 xFltMgr->appendFilter( sFilterAll, C2U("*") ); 2325 xFltMgr->appendFilter( sFilterAllData, C2U("*.ods;*.sxc;*.dbf;*.xls;*.txt;*.csv")); 2326 2327 xFltMgr->appendFilter( sFilterSXB, C2U("*.odb") ); 2328 xFltMgr->appendFilter( sFilterSXC, C2U("*.ods;*.sxc") ); 2329 xFltMgr->appendFilter( sFilterDBF, C2U("*.dbf") ); 2330 xFltMgr->appendFilter( sFilterXLS, C2U("*.xls") ); 2331 xFltMgr->appendFilter( sFilterTXT, C2U("*.txt") ); 2332 xFltMgr->appendFilter( sFilterCSV, C2U("*.csv") ); 2333 #ifdef WNT 2334 xFltMgr->appendFilter( sFilterMDB, C2U("*.mdb") ); 2335 xFltMgr->appendFilter( sFilterACCDB, C2U("*.accdb") ); 2336 #endif 2337 2338 xFltMgr->setCurrentFilter( sFilterAll ) ; 2339 String sFind; 2340 bool bTextConnection = false; 2341 if( ERRCODE_NONE == aDlgHelper.Execute() ) 2342 { 2343 String sURL = xFP->getFiles().getConstArray()[0]; 2344 //data sources have to be registered depending on their extensions 2345 INetURLObject aURL( sURL ); 2346 String sExt( aURL.GetExtension() ); 2347 Any aURLAny; 2348 Any aTableFilterAny; 2349 Any aSuppressVersionsAny; 2350 Any aInfoAny; 2351 INetURLObject aTempURL(aURL); 2352 bool bStore = true; 2353 if(sExt.EqualsAscii("odb")) 2354 { 2355 bStore = false; 2356 } 2357 else if(sExt.EqualsIgnoreCaseAscii("sxc") 2358 || sExt.EqualsIgnoreCaseAscii("ods") 2359 || sExt.EqualsIgnoreCaseAscii("xls")) 2360 { 2361 rtl::OUString sDBURL(C2U("sdbc:calc:")); 2362 sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE); 2363 aURLAny <<= sDBURL; 2364 } 2365 else if(sExt.EqualsIgnoreCaseAscii("dbf")) 2366 { 2367 aTempURL.removeSegment(); 2368 aTempURL.removeFinalSlash(); 2369 rtl::OUString sDBURL(C2U("sdbc:dbase:")); 2370 sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE); 2371 aURLAny <<= sDBURL; 2372 //set the filter to the file name without extension 2373 Sequence<rtl::OUString> aFilters(1); 2374 rtl::OUString sTmp(aURL.getBase()); 2375 aFilters[0] = aURL.getBase(); 2376 aTableFilterAny <<= aFilters; 2377 } 2378 else if(sExt.EqualsIgnoreCaseAscii("csv") || sExt.EqualsIgnoreCaseAscii("txt")) 2379 { 2380 aTempURL.removeSegment(); 2381 aTempURL.removeFinalSlash(); 2382 rtl::OUString sDBURL(C2U("sdbc:flat:")); 2383 //only the 'path' has to be added 2384 sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE); 2385 aURLAny <<= sDBURL; 2386 2387 bTextConnection = true; 2388 //set the filter to the file name without extension 2389 Sequence<rtl::OUString> aFilters(1); 2390 rtl::OUString sTmp(aURL.getBase()); 2391 aFilters[0] = aURL.getBase(); 2392 aTableFilterAny <<= aFilters; 2393 } 2394 #ifdef WNT 2395 else if(sExt.EqualsIgnoreCaseAscii("mdb")) 2396 { 2397 rtl::OUString sDBURL(C2U("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=")); 2398 sDBURL += aTempURL.PathToFileName(); 2399 aURLAny <<= sDBURL; 2400 aSuppressVersionsAny <<= makeAny(true); 2401 } 2402 else if(sExt.EqualsIgnoreCaseAscii("accdb")) 2403 { 2404 rtl::OUString sDBURL(C2U("sdbc:ado:PROVIDER=Microsoft.ACE.OLEDB.12.0;DATA SOURCE=")); 2405 sDBURL += aTempURL.PathToFileName(); 2406 aURLAny <<= sDBURL; 2407 aSuppressVersionsAny <<= makeAny(true); 2408 } 2409 #endif 2410 try 2411 { 2412 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); 2413 Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" )); 2414 Reference<XNameAccess> xDBContext(xInstance, UNO_QUERY_THROW); 2415 Reference<XSingleServiceFactory> xFact( xDBContext, UNO_QUERY); 2416 2417 String sNewName = INetURLObject::decode( aURL.getName(), 2418 INET_HEX_ESCAPE, 2419 INetURLObject::DECODE_UNAMBIGUOUS, 2420 RTL_TEXTENCODING_UTF8 ); 2421 xub_StrLen nExtLen = static_cast< xub_StrLen >(aURL.GetExtension().getLength()); 2422 sNewName.Erase( sNewName.Len() - nExtLen - 1, nExtLen + 1 ); 2423 2424 //find a unique name if sNewName already exists 2425 sFind = sNewName; 2426 sal_Int32 nIndex = 0; 2427 while(xDBContext->hasByName(sFind)) 2428 { 2429 sFind = sNewName; 2430 sFind += String::CreateFromInt32(++nIndex); 2431 } 2432 2433 Reference<XInterface> xNewInstance; 2434 if(!bStore) 2435 { 2436 //odb-file 2437 Any aDataSource = xDBContext->getByName(aTempURL.GetMainURL(INetURLObject::NO_DECODE)); 2438 aDataSource >>= xNewInstance; 2439 } 2440 else 2441 { 2442 xNewInstance = xFact->createInstance(); 2443 Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY); 2444 2445 if(aURLAny.hasValue()) 2446 xDataProperties->setPropertyValue(C2U("URL"), aURLAny); 2447 if(aTableFilterAny.hasValue()) 2448 xDataProperties->setPropertyValue(C2U("TableFilter"), aTableFilterAny); 2449 if(aSuppressVersionsAny.hasValue()) 2450 xDataProperties->setPropertyValue(C2U("SuppressVersionColumns"), aSuppressVersionsAny); 2451 if(aInfoAny.hasValue()) 2452 xDataProperties->setPropertyValue(C2U("Info"), aInfoAny); 2453 2454 if( bTextConnection ) 2455 { 2456 uno::Reference < ui::dialogs::XExecutableDialog > xSettingsDlg( 2457 xMgr->createInstance( C2U( "com.sun.star.sdb.TextConnectionSettings" ) ), uno::UNO_QUERY); 2458 if( xSettingsDlg->execute() ) 2459 { 2460 uno::Any aSettings = xDataProperties->getPropertyValue( C2U( "Settings" ) ); 2461 uno::Reference < beans::XPropertySet > xDSSettings; 2462 aSettings >>= xDSSettings; 2463 ::comphelper::copyProperties( 2464 uno::Reference < beans::XPropertySet >( xSettingsDlg, uno::UNO_QUERY ), 2465 xDSSettings ); 2466 xDSSettings->setPropertyValue( C2U("Extension"), uno::makeAny( ::rtl::OUString( sExt ))); 2467 } 2468 } 2469 2470 Reference<XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW); 2471 Reference<XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW); 2472 String sOutputExt = String::CreateFromAscii(".odb"); 2473 String sTmpName; 2474 { 2475 utl::TempFile aTempFile(sNewName , &sOutputExt, &sHomePath); 2476 aTempFile.EnableKillingFile(sal_True); 2477 sTmpName = aTempFile.GetURL(); 2478 } 2479 xStore->storeAsURL(sTmpName, Sequence< PropertyValue >()); 2480 } 2481 Reference<XNamingService> xNaming(xDBContext, UNO_QUERY); 2482 xNaming->registerObject( sFind, xNewInstance ); 2483 2484 } 2485 catch(Exception&) 2486 { 2487 } 2488 } 2489 return sFind; 2490 2491 } 2492 /* -----------------------------10.11.00 17:10-------------------------------- 2493 2494 ---------------------------------------------------------------------------*/ 2495 void SwNewDBMgr::ExecuteFormLetter( SwWrtShell& rSh, 2496 const Sequence<PropertyValue>& rProperties, 2497 sal_Bool bWithDataSourceBrowser) 2498 { 2499 //prevent second call 2500 if(pImpl->pMergeDialog) 2501 return ; 2502 rtl::OUString sDataSource, sDataTableOrQuery; 2503 Sequence<Any> aSelection; 2504 2505 sal_Int16 nCmdType = CommandType::TABLE; 2506 uno::Reference< XConnection> xConnection; 2507 2508 ODataAccessDescriptor aDescriptor(rProperties); 2509 sDataSource = aDescriptor.getDataSource(); 2510 aDescriptor[daCommand] >>= sDataTableOrQuery; 2511 aDescriptor[daCommandType] >>= nCmdType; 2512 2513 if ( aDescriptor.has(daSelection) ) 2514 aDescriptor[daSelection] >>= aSelection; 2515 if ( aDescriptor.has(daConnection) ) 2516 aDescriptor[daConnection] >>= xConnection; 2517 2518 if(!sDataSource.getLength() || !sDataTableOrQuery.getLength()) 2519 { 2520 DBG_ERROR("PropertyValues missing or unset"); 2521 return; 2522 } 2523 2524 //always create a connection for the dialog and dispose it after the dialog has been closed 2525 SwDSParam* pFound = 0; 2526 if(!xConnection.is()) 2527 { 2528 xConnection = SwNewDBMgr::RegisterConnection(sDataSource); 2529 pFound = FindDSConnection(sDataSource, sal_True); 2530 } 2531 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 2532 DBG_ASSERT(pFact, "Dialogdiet fail!"); 2533 pImpl->pMergeDialog = pFact->CreateMailMergeDlg( DLG_MAILMERGE, 2534 &rSh.GetView().GetViewFrame()->GetWindow(), rSh, 2535 sDataSource, 2536 sDataTableOrQuery, 2537 nCmdType, 2538 xConnection, 2539 bWithDataSourceBrowser ? 0 : &aSelection); 2540 DBG_ASSERT(pImpl->pMergeDialog, "Dialogdiet fail!"); 2541 if(pImpl->pMergeDialog->Execute() == RET_OK) 2542 { 2543 aDescriptor[daSelection] <<= pImpl->pMergeDialog->GetSelection(); 2544 2545 uno::Reference<XResultSet> xResSet = pImpl->pMergeDialog->GetResultSet(); 2546 if(xResSet.is()) 2547 aDescriptor[daCursor] <<= xResSet; 2548 2549 // SfxObjectShellRef is ok, since there should be no control over the document lifetime here 2550 SfxObjectShellRef xDocShell = rSh.GetView().GetViewFrame()->GetObjectShell(); 2551 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xDocShell)); 2552 { 2553 //copy rSh to aTempFile 2554 ::rtl::OUString sTempURL; 2555 const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat( 2556 String::CreateFromAscii( FILTER_XML ), 2557 SwDocShell::Factory().GetFilterContainer() ); 2558 try 2559 { 2560 2561 uno::Sequence< beans::PropertyValue > aValues(1); 2562 beans::PropertyValue* pValues = aValues.getArray(); 2563 pValues[0].Name = C2U("FilterName"); 2564 pValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName()); 2565 uno::Reference< frame::XStorable > xStore( xDocShell->GetModel(), uno::UNO_QUERY); 2566 sTempURL = URIHelper::SmartRel2Abs( INetURLObject(), utl::TempFile::CreateTempName() ); 2567 xStore->storeToURL( sTempURL, aValues ); 2568 } 2569 catch( const uno::Exception& rEx ) 2570 { 2571 (void) rEx; 2572 } 2573 if( xDocShell->GetError() ) 2574 { 2575 // error message ?? 2576 ErrorHandler::HandleError( xDocShell->GetError() ); 2577 } 2578 else 2579 { 2580 // the shell will be explicitly closed, but it is more safe to use SfxObjectShellLock here 2581 // especially for the case that the loading has failed 2582 SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); 2583 SfxMedium* pWorkMed = new SfxMedium( sTempURL, STREAM_STD_READ, sal_True ); 2584 pWorkMed->SetFilter( pSfxFlt ); 2585 if( xWorkDocSh->DoLoad(pWorkMed) ) 2586 { 2587 SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 ); 2588 SwView *pView = (SwView*) pFrame->GetViewShell(); 2589 pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird. 2590 //set the current DBMgr 2591 SwDoc* pWorkDoc = pView->GetWrtShell().GetDoc(); 2592 SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr(); 2593 pWorkDoc->SetNewDBMgr( this ); 2594 2595 SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), pView->GetWrtShell(), aDescriptor ); 2596 aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter(); 2597 aMergeDesc.bCreateSingleFile = !pImpl->pMergeDialog->IsSaveIndividualDocs(); 2598 if( !aMergeDesc.bCreateSingleFile && pImpl->pMergeDialog->IsGenerateFromDataBase() ) 2599 { 2600 aMergeDesc.sAddressFromColumn = pImpl->pMergeDialog->GetColumnName(); 2601 aMergeDesc.sSubject = pImpl->pMergeDialog->GetPath(); 2602 } 2603 2604 MergeNew(aMergeDesc); 2605 2606 pWorkDoc->SetNewDBMgr( pWorkDBMgr ); 2607 //close the temporary file 2608 uno::Reference< util::XCloseable > xClose( xWorkDocSh->GetModel(), uno::UNO_QUERY ); 2609 if (xClose.is()) 2610 { 2611 try 2612 { 2613 //! 'sal_True' -> transfer ownership to vetoing object if vetoed! 2614 //! I.e. now that object is responsible for closing the model and doc shell. 2615 xClose->close( sal_True ); 2616 } 2617 catch ( const uno::Exception& ) 2618 { 2619 } 2620 } 2621 } 2622 } 2623 //remove the temporary file 2624 SWUnoHelper::UCB_DeleteFile( sTempURL ); 2625 } 2626 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), rSh.GetView().GetViewFrame()->GetObjectShell())); 2627 2628 // reset the cursor inside 2629 xResSet = NULL; 2630 aDescriptor[daCursor] <<= xResSet; 2631 } 2632 if(pFound) 2633 { 2634 for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) 2635 { 2636 SwDSParam* pParam = aDataSourceParams[nPos]; 2637 if(pParam == pFound) 2638 { 2639 try 2640 { 2641 uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY); 2642 if(xComp.is()) 2643 xComp->dispose(); 2644 } 2645 catch(const RuntimeException& ) 2646 { 2647 //may be disposed already since multiple entries may have used the same connection 2648 } 2649 break; 2650 } 2651 //pFound doesn't need to be removed/deleted - 2652 //this has been done by the SwConnectionDisposedListener_Impl already 2653 } 2654 } 2655 DELETEZ(pImpl->pMergeDialog); 2656 } 2657 /* -----------------------------13.11.00 08:20-------------------------------- 2658 2659 ---------------------------------------------------------------------------*/ 2660 void SwNewDBMgr::InsertText(SwWrtShell& rSh, 2661 const Sequence< PropertyValue>& rProperties) 2662 { 2663 rtl::OUString sDataSource, sDataTableOrQuery; 2664 uno::Reference<XResultSet> xResSet; 2665 Sequence<Any> aSelection; 2666 sal_Bool bHasSelectionProperty = sal_False; 2667 sal_Int32 nSelectionPos = 0; 2668 sal_Int16 nCmdType = CommandType::TABLE; 2669 const PropertyValue* pValues = rProperties.getConstArray(); 2670 uno::Reference< XConnection> xConnection; 2671 for(sal_Int32 nPos = 0; nPos < rProperties.getLength(); nPos++) 2672 { 2673 if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cDataSourceName))) 2674 pValues[nPos].Value >>= sDataSource; 2675 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommand))) 2676 pValues[nPos].Value >>= sDataTableOrQuery; 2677 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCursor))) 2678 pValues[nPos].Value >>= xResSet; 2679 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cSelection))) 2680 { 2681 bHasSelectionProperty = sal_True; 2682 nSelectionPos = nPos; 2683 pValues[nPos].Value >>= aSelection; 2684 } 2685 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommandType))) 2686 pValues[nPos].Value >>= nCmdType; 2687 else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cActiveConnection))) 2688 pValues[nPos].Value >>= xConnection; 2689 } 2690 if(!sDataSource.getLength() || !sDataTableOrQuery.getLength() || !xResSet.is()) 2691 { 2692 DBG_ERROR("PropertyValues missing or unset"); 2693 return; 2694 } 2695 uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); 2696 uno::Reference<XDataSource> xSource; 2697 uno::Reference<XChild> xChild(xConnection, UNO_QUERY); 2698 if(xChild.is()) 2699 xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY); 2700 if(!xSource.is()) 2701 xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(sDataSource, xMgr); 2702 uno::Reference< XColumnsSupplier > xColSupp( xResSet, UNO_QUERY ); 2703 SwDBData aDBData; 2704 aDBData.sDataSource = sDataSource; 2705 aDBData.sCommand = sDataTableOrQuery; 2706 aDBData.nCommandType = nCmdType; 2707 2708 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 2709 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!"); 2710 2711 AbstractSwInsertDBColAutoPilot* pDlg = pFact->CreateSwInsertDBColAutoPilot( rSh.GetView(), 2712 xSource, 2713 xColSupp, 2714 aDBData, 2715 DLG_AP_INSERT_DB_SEL ); 2716 DBG_ASSERT(pDlg, "Dialogdiet fail!"); 2717 if( RET_OK == pDlg->Execute() ) 2718 { 2719 rtl::OUString sDummy; 2720 if(!xConnection.is()) 2721 xConnection = xSource->getConnection(sDummy, sDummy); 2722 try 2723 { 2724 pDlg->DataToDoc( aSelection , xSource, xConnection, xResSet); 2725 } 2726 catch(Exception& ) 2727 { 2728 DBG_ERROR("exception caught"); 2729 } 2730 } 2731 delete pDlg; 2732 2733 } 2734 /* -----------------------------30.08.2001 12:00------------------------------ 2735 2736 ---------------------------------------------------------------------------*/ 2737 SwDbtoolsClient* SwNewDBMgr::pDbtoolsClient = NULL; 2738 2739 SwDbtoolsClient& SwNewDBMgr::GetDbtoolsClient() 2740 { 2741 if ( !pDbtoolsClient ) 2742 pDbtoolsClient = new SwDbtoolsClient; 2743 return *pDbtoolsClient; 2744 } 2745 /* -----------------13.05.2003 15:34----------------- 2746 2747 --------------------------------------------------*/ 2748 void SwNewDBMgr::RemoveDbtoolsClient() 2749 { 2750 delete pDbtoolsClient; 2751 pDbtoolsClient = 0; 2752 } 2753 /* -----------------------------20.08.2002 12:00------------------------------ 2754 2755 ---------------------------------------------------------------------------*/ 2756 uno::Reference<XDataSource> SwNewDBMgr::getDataSourceAsParent(const uno::Reference< XConnection>& _xConnection,const ::rtl::OUString& _sDataSourceName) 2757 { 2758 uno::Reference<XDataSource> xSource; 2759 try 2760 { 2761 uno::Reference<XChild> xChild(_xConnection, UNO_QUERY); 2762 if ( xChild.is() ) 2763 xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY); 2764 if ( !xSource.is() ) 2765 xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(_sDataSourceName, ::comphelper::getProcessServiceFactory()); 2766 } 2767 catch(const Exception&) 2768 { 2769 DBG_ERROR("exception in getDataSourceAsParent caught"); 2770 } 2771 return xSource; 2772 } 2773 /* -----------------------------20.08.2002 12:00------------------------------ 2774 2775 ---------------------------------------------------------------------------*/ 2776 uno::Reference<XResultSet> SwNewDBMgr::createCursor(const ::rtl::OUString& _sDataSourceName, 2777 const ::rtl::OUString& _sCommand, 2778 sal_Int32 _nCommandType, 2779 const uno::Reference<XConnection>& _xConnection 2780 ) 2781 { 2782 uno::Reference<XResultSet> xResultSet; 2783 try 2784 { 2785 uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); 2786 if( xMgr.is() ) 2787 { 2788 uno::Reference<XInterface> xInstance = xMgr->createInstance( 2789 C2U( "com.sun.star.sdb.RowSet" )); 2790 uno::Reference<XPropertySet> xRowSetPropSet(xInstance, UNO_QUERY); 2791 if(xRowSetPropSet.is()) 2792 { 2793 xRowSetPropSet->setPropertyValue(C2U("DataSourceName"), makeAny(_sDataSourceName)); 2794 xRowSetPropSet->setPropertyValue(C2U("ActiveConnection"), makeAny(_xConnection)); 2795 xRowSetPropSet->setPropertyValue(C2U("Command"), makeAny(_sCommand)); 2796 xRowSetPropSet->setPropertyValue(C2U("CommandType"), makeAny(_nCommandType)); 2797 2798 uno::Reference< XCompletedExecution > xRowSet(xInstance, UNO_QUERY); 2799 2800 if ( xRowSet.is() ) 2801 { 2802 uno::Reference< XInteractionHandler > xHandler(xMgr->createInstance(C2U("com.sun.star.task.InteractionHandler")), UNO_QUERY); 2803 xRowSet->executeWithCompletion(xHandler); 2804 } 2805 xResultSet = uno::Reference<XResultSet>(xRowSet, UNO_QUERY); 2806 } 2807 } 2808 } 2809 catch(const Exception&) 2810 { 2811 DBG_ASSERT(0,"Caught exception while creating a new RowSet!"); 2812 } 2813 return xResultSet; 2814 } 2815 /*-- 13.05.2004 16:14:15--------------------------------------------------- 2816 merge all data into one resulting document and return the number of 2817 merged documents 2818 -----------------------------------------------------------------------*/ 2819 2820 sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig, 2821 SwView& rSourceView ) 2822 { 2823 // check the availability of all data in the config item 2824 uno::Reference< XResultSet> xResultSet = rMMConfig.GetResultSet(); 2825 if(!xResultSet.is()) 2826 return false; 2827 bInMerge = sal_True; 2828 sal_Int32 nRet = 0; 2829 pImpl->pMergeData = new SwDSParam( 2830 rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection()); 2831 2832 try{ 2833 //set to start position 2834 if(pImpl->pMergeData->aSelection.getLength()) 2835 { 2836 sal_Int32 nPos = 0; 2837 pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos; 2838 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos ); 2839 pImpl->pMergeData->CheckEndOfDB(); 2840 if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength()) 2841 pImpl->pMergeData->bEndOfDB = sal_True; 2842 } 2843 else 2844 { 2845 pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first(); 2846 pImpl->pMergeData->CheckEndOfDB(); 2847 } 2848 } 2849 catch(Exception&) 2850 { 2851 pImpl->pMergeData->bEndOfDB = sal_True; 2852 pImpl->pMergeData->CheckEndOfDB(); 2853 DBG_ERROR("exception in MergeNew()"); 2854 } 2855 2856 //bCancel is set from the PrintMonitor 2857 bCancel = sal_False; 2858 2859 CreateMonitor aMonitorDlg(&rSourceView.GetEditWin()); 2860 aMonitorDlg.SetCancelHdl(LINK(this, SwNewDBMgr, PrtCancelHdl)); 2861 if (!IsMergeSilent()) 2862 { 2863 aMonitorDlg.Show(); 2864 aMonitorDlg.Invalidate(); 2865 aMonitorDlg.Update(); 2866 // the print monitor needs some time to act 2867 for( sal_uInt16 i = 0; i < 25; i++) 2868 Application::Reschedule(); 2869 } 2870 2871 SwWrtShell& rSourceShell = rSourceView.GetWrtShell(); 2872 sal_Bool bSynchronizedDoc = rSourceShell.IsLabelDoc() && rSourceShell.GetSectionFmtCount() > 1; 2873 //save the settings of the first 2874 rSourceShell.SttEndDoc(sal_True); 2875 sal_uInt16 nStartingPageNo = rSourceShell.GetVirtPageNum(); 2876 String sModifiedStartingPageDesc; 2877 String sStartingPageDesc = sModifiedStartingPageDesc = rSourceShell.GetPageDesc( 2878 rSourceShell.GetCurPageDesc()).GetName(); 2879 2880 try 2881 { 2882 // create a target docshell to put the merged document into 2883 SfxObjectShellRef xTargetDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) ); 2884 xTargetDocShell->DoInitNew( 0 ); 2885 SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 ); 2886 2887 //the created window has to be located at the same position as the source window 2888 Window& rTargetWindow = pTargetFrame->GetFrame().GetWindow(); 2889 Window& rSourceWindow = rSourceView.GetViewFrame()->GetFrame().GetWindow(); 2890 rTargetWindow.SetPosPixel(rSourceWindow.GetPosPixel()); 2891 2892 // pTargetFrame->GetFrame().Appear(); 2893 SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() ); 2894 rMMConfig.SetTargetView(pTargetView); 2895 //initiate SelectShell() to create sub shells 2896 pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() ); 2897 SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr(); 2898 // #i63806# 2899 const SwPageDesc* pSourcePageDesc = rSourceShell.FindPageDescByName( sStartingPageDesc ); 2900 const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster(); 2901 bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() || 2902 rMaster.GetFooter().IsActive(); 2903 2904 2905 // #122799# copy compatibility options 2906 lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell); 2907 // #72821# copy dynamic defaults 2908 lcl_CopyDynamicDefaults( *rSourceShell.GetDoc(), *pTargetShell->GetDoc() ); 2909 2910 2911 long nStartRow, nEndRow; 2912 sal_uLong nDocNo = 1; 2913 sal_Int32 nDocCount = 0; 2914 if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) ) 2915 aMonitorDlg.SetTotalCount( nDocCount ); 2916 2917 do 2918 { 2919 nStartRow = pImpl->pMergeData->xResultSet->getRow(); 2920 if (!IsMergeSilent()) 2921 { 2922 aMonitorDlg.SetCurrentPosition( nDocNo ); 2923 aMonitorDlg.Invalidate(); 2924 aMonitorDlg.Update(); 2925 // the print monitor needs some time to act 2926 for( sal_uInt16 i = 0; i < 25; i++) 2927 Application::Reschedule(); 2928 } 2929 2930 // copy the source document 2931 // the copy will be closed later, but it is more safe to use SfxObjectShellLock here 2932 SfxObjectShellLock xWorkDocSh; 2933 if(nDocNo == 1 ) 2934 { 2935 uno::Reference< util::XCloneable > xClone( rSourceView.GetDocShell()->GetModel(), uno::UNO_QUERY); 2936 uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY); 2937 SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId())); 2938 xWorkDocSh = pWorkModel->GetDocShell(); 2939 } 2940 else 2941 { 2942 xWorkDocSh = rSourceView.GetDocShell()->GetDoc()->CreateCopy(true); 2943 } 2944 //create a ViewFrame 2945 SwView* pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() ); 2946 SwWrtShell& rWorkShell = pWorkView->GetWrtShell(); 2947 pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird. 2948 2949 // merge the data 2950 SwDoc* pWorkDoc = rWorkShell.GetDoc(); 2951 SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr(); 2952 pWorkDoc->SetNewDBMgr( this ); 2953 pWorkDoc->EmbedAllLinks(); 2954 SwUndoId nLastUndoId(UNDO_EMPTY); 2955 if (rWorkShell.GetLastUndoInfo(0, & nLastUndoId)) 2956 { 2957 if (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId) 2958 { 2959 rWorkShell.Undo(); 2960 } 2961 } 2962 // #i69485# lock fields to prevent access to the result set while calculating layout 2963 rWorkShell.LockExpFlds(); 2964 // create a layout 2965 rWorkShell.CalcLayout(); 2966 rWorkShell.UnlockExpFlds(); 2967 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell())); 2968 rWorkShell.ViewShell::UpdateFlds(); 2969 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell())); 2970 2971 // strip invisible content and convert fields to text 2972 rWorkShell.RemoveInvisibleContent(); 2973 rWorkShell.ConvertFieldsToText(); 2974 rWorkShell.SetNumberingRestart(); 2975 if( bSynchronizedDoc ) 2976 { 2977 lcl_RemoveSectionLinks( rWorkShell ); 2978 } 2979 2980 // insert the document into the target document 2981 rWorkShell.SttEndDoc(sal_False); 2982 rWorkShell.SttEndDoc(sal_True); 2983 rWorkShell.SelAll(); 2984 pTargetShell->SttEndDoc(sal_False); 2985 2986 //#i63806# put the styles to the target document 2987 //if the source uses headers or footers each new copy need to copy a new page styles 2988 if(bPageStylesWithHeaderFooter) 2989 { 2990 //create a new pagestyle 2991 //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style 2992 2993 SwDoc* pTargetDoc = pTargetShell->GetDoc(); 2994 String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo ); 2995 pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName ); 2996 SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName ); 2997 const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc ); 2998 2999 if(pWorkPageDesc && pTargetPageDesc) 3000 { 3001 pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, sal_False ); 3002 sModifiedStartingPageDesc = sNewPageDescName; 3003 lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo ); 3004 } 3005 } 3006 if(nDocNo == 1 || bPageStylesWithHeaderFooter) 3007 { 3008 pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), sal_True ); 3009 } 3010 if(nDocNo > 1) 3011 { 3012 pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo ); 3013 } 3014 else 3015 { 3016 pTargetShell->SetPageStyle(sModifiedStartingPageDesc); 3017 } 3018 sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt(); 3019 DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended"); 3020 //#i51359# add a second paragraph in case there's only one 3021 { 3022 SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 ); 3023 SwPosition aTestPos( aIdx ); 3024 SwCursor aTestCrsr(aTestPos,0,false); 3025 if(!aTestCrsr.MovePara(fnParaNext, fnParaStart)) 3026 { 3027 //append a paragraph 3028 pWorkDoc->AppendTxtNode( aTestPos ); 3029 } 3030 } 3031 pTargetShell->Paste( rWorkShell.GetDoc(), sal_True ); 3032 //convert fields in page styles (header/footer - has to be done after the first document has been pasted 3033 if(1 == nDocNo) 3034 { 3035 pTargetShell->CalcLayout(); 3036 pTargetShell->ConvertFieldsToText(); 3037 } 3038 //add the document info to the config item 3039 SwDocMergeInfo aMergeInfo; 3040 aMergeInfo.nStartPageInTarget = nPageCountBefore; 3041 //#i72820# calculate layout to be able to find the correct page index 3042 pTargetShell->CalcLayout(); 3043 aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt(); 3044 aMergeInfo.nDBRow = nStartRow; 3045 rMMConfig.AddMergedDocument( aMergeInfo ); 3046 ++nRet; 3047 3048 // the print monitor needs some time to act 3049 for( sal_uInt16 i = 0; i < 25; i++) 3050 Application::Reschedule(); 3051 3052 //restore the ole DBMgr 3053 pWorkDoc->SetNewDBMgr( pWorkDBMgr ); 3054 //now the temporary document should be closed 3055 SfxObjectShellRef xDocSh(pWorkView->GetDocShell()); 3056 xDocSh->DoClose(); 3057 nEndRow = pImpl->pMergeData->xResultSet->getRow(); 3058 ++nDocNo; 3059 } while( !bCancel && 3060 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord())); 3061 3062 //deselect all, go out of the frame and go to the beginning of the document 3063 Point aPt(LONG_MIN, LONG_MIN); 3064 pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME); 3065 if (pTargetShell->IsSelFrmMode()) 3066 { 3067 pTargetShell->UnSelectFrm(); 3068 pTargetShell->LeaveSelFrmMode(); 3069 } 3070 pTargetShell->EnterStdMode(); 3071 pTargetShell->SttDoc(); 3072 // 3073 } 3074 catch( Exception& rEx) 3075 { 3076 (void)rEx; 3077 DBG_ERROR("exception caught in SwNewDBMgr::MergeDocuments"); 3078 } 3079 DELETEZ(pImpl->pMergeData); 3080 bInMerge = sal_False; 3081 return nRet; 3082 } 3083 /* -----------------09.12.2002 12:38----------------- 3084 * 3085 * --------------------------------------------------*/ 3086 SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr) : 3087 rDBMgr(rMgr) 3088 {}; 3089 /* -----------------09.12.2002 12:39----------------- 3090 * 3091 * --------------------------------------------------*/ 3092 SwConnectionDisposedListener_Impl::~SwConnectionDisposedListener_Impl() 3093 {}; 3094 /* -----------------09.12.2002 12:39----------------- 3095 * 3096 * --------------------------------------------------*/ 3097 void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource ) 3098 throw (RuntimeException) 3099 { 3100 ::vos::OGuard aGuard(Application::GetSolarMutex()); 3101 uno::Reference<XConnection> xSource(rSource.Source, UNO_QUERY); 3102 for(sal_uInt16 nPos = rDBMgr.aDataSourceParams.Count(); nPos; nPos--) 3103 { 3104 SwDSParam* pParam = rDBMgr.aDataSourceParams[nPos - 1]; 3105 if(pParam->xConnection.is() && 3106 (xSource == pParam->xConnection)) 3107 { 3108 rDBMgr.aDataSourceParams.DeleteAndDestroy(nPos - 1); 3109 } 3110 } 3111 } 3112