| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| #include <cstdarg> |
| #include <cstdio> |
| |
| #include <unotxdoc.hxx> |
| #include <com/sun/star/text/NotePrintMode.hpp> |
| #include <sfx2/app.hxx> |
| #include <com/sun/star/sdb/CommandType.hpp> |
| #include <com/sun/star/sdb/XDocumentDataSource.hpp> |
| #include <com/sun/star/frame/XComponentLoader.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/lang/XEventListener.hpp> |
| #include <com/sun/star/util/XNumberFormatter.hpp> |
| #include <com/sun/star/sdb/XCompletedConnection.hpp> |
| #include <com/sun/star/sdb/XCompletedExecution.hpp> |
| #include <com/sun/star/container/XChild.hpp> |
| #include <com/sun/star/text/MailMergeEvent.hpp> |
| #include <com/sun/star/frame/XStorable.hpp> |
| #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> |
| #include <com/sun/star/ui/dialogs/XFilePicker.hpp> |
| #include <com/sun/star/ui/dialogs/XFilterManager.hpp> |
| #include <com/sun/star/uno/XNamingService.hpp> |
| #include <com/sun/star/util/XCloseable.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <sfx2/fcontnr.hxx> |
| #include <sfx2/filedlghelper.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <dbconfig.hxx> |
| #include <swdbtoolsclient.hxx> |
| #include <pagedesc.hxx> |
| #include <vcl/lstbox.hxx> |
| #include <unotools/tempfile.hxx> |
| #include <unotools/pathoptions.hxx> |
| #include <svl/urihelper.hxx> |
| #define _SVSTDARR_STRINGSDTOR |
| #include <svl/svstdarr.hxx> |
| #include <svl/zforlist.hxx> |
| #include <svl/zformat.hxx> |
| #include <svl/stritem.hxx> |
| #include <svl/eitem.hxx> |
| #include <vcl/oldprintadaptor.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/progress.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <svl/mailenum.hxx> |
| #include <cmdid.h> |
| #include <swmodule.hxx> |
| #include <view.hxx> |
| #include <docsh.hxx> |
| #include <edtwin.hxx> |
| #include <wrtsh.hxx> |
| #include <fldbas.hxx> |
| #include <initui.hxx> |
| #include <swundo.hxx> |
| #include <flddat.hxx> |
| #include <modcfg.hxx> |
| #include <shellio.hxx> |
| #include <dbui.hxx> |
| #include <dbmgr.hxx> |
| #include <doc.hxx> |
| #include <swwait.hxx> |
| #include <swunohelper.hxx> |
| #include <dbui.hrc> |
| #include <globals.hrc> |
| #include <statstr.hrc> |
| #include <mmconfigitem.hxx> |
| #include <sfx2/request.hxx> |
| #include <hintids.hxx> |
| #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> |
| #include <com/sun/star/sdbc/XRowSet.hpp> |
| #include <com/sun/star/sdbcx/XTablesSupplier.hpp> |
| #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> |
| #include <com/sun/star/sdb/XQueriesSupplier.hpp> |
| #include <com/sun/star/sdb/XColumn.hpp> |
| #include <com/sun/star/sdbc/DataType.hpp> |
| #include <com/sun/star/sdbc/ResultSetType.hpp> |
| #include <com/sun/star/mail/MailAttachment.hpp> |
| #include <comphelper/processfactory.hxx> |
| #include <comphelper/types.hxx> |
| #include <comphelper/property.hxx> |
| #include <mailmergehelper.hxx> |
| #include <maildispatcher.hxx> |
| #include <svtools/htmlcfg.hxx> |
| #include <i18npool/mslangid.hxx> |
| #include <com/sun/star/util/XNumberFormatTypes.hpp> |
| #include <editeng/langitem.hxx> |
| #include <svl/numuno.hxx> |
| |
| #include <unomailmerge.hxx> |
| #include <sfx2/event.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <svx/dataaccessdescriptor.hxx> |
| #include <vos/mutex.hxx> |
| #include <rtl/textenc.h> |
| #include <ndindex.hxx> |
| #include <pam.hxx> |
| #include <swcrsr.hxx> |
| #include <swevent.hxx> |
| #include <osl/file.hxx> |
| #include <swabstdlg.hxx> |
| #include <fmthdft.hxx> |
| #include <dbui.hrc> |
| #include <envelp.hrc> |
| #include <memory> |
| #include <vector> |
| #include <unomid.h> |
| #include <section.hxx> |
| |
| using namespace ::osl; |
| using namespace ::svx; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::text; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::sdb; |
| using namespace ::com::sun::star::sdbc; |
| using namespace ::com::sun::star::sdbcx; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::task; |
| using namespace ::com::sun::star::ui::dialogs; |
| |
| #define DB_SEP_SPACE 0 |
| #define DB_SEP_TAB 1 |
| #define DB_SEP_RETURN 2 |
| #define DB_SEP_NEWLINE 3 |
| |
| SV_IMPL_PTRARR(SwDSParamArr, SwDSParamPtr); |
| const sal_Char cCursor[] = "Cursor"; |
| const sal_Char cCommand[] = "Command"; |
| const sal_Char cCommandType[] = "CommandType"; |
| const sal_Char cDataSourceName[] = "DataSourceName"; |
| const sal_Char cSelection[] = "Selection"; |
| const sal_Char cActiveConnection[] = "ActiveConnection"; |
| |
| // ----------------------------------------------------------------------------- |
| // Use nameless namespace to avoid to rubbish the global namespace |
| // ----------------------------------------------------------------------------- |
| namespace |
| { |
| |
| bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference<XResultSet>& xResultSet ) |
| { |
| uno::Reference<XPropertySet> xPrSet(xResultSet, UNO_QUERY); |
| if(xPrSet.is()) |
| { |
| try |
| { |
| sal_Bool bFinal = sal_False; |
| Any aFinal = xPrSet->getPropertyValue(C2U("IsRowCountFinal")); |
| aFinal >>= bFinal; |
| if(!bFinal) |
| { |
| xResultSet->last(); |
| xResultSet->first(); |
| } |
| Any aCount = xPrSet->getPropertyValue(C2U("RowCount")); |
| if( aCount >>= rCount ) |
| return true; |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| return false; |
| } |
| // #122799# copy compatibility options |
| void lcl_CopyCompatibilityOptions( SwWrtShell& rSourceShell, SwWrtShell& rTargetShell) |
| { |
| IDocumentSettingAccess* pIDsa = rSourceShell.getIDocumentSettingAccess(); |
| |
| rTargetShell.SetParaSpaceMax( pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX)); |
| rTargetShell.SetParaSpaceMaxAtPages(pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES)); |
| rTargetShell.SetTabCompat( pIDsa->get(IDocumentSettingAccess::TAB_COMPAT)); |
| rTargetShell.SetAddExtLeading( pIDsa->get(IDocumentSettingAccess::ADD_EXT_LEADING)); |
| rTargetShell.SetUseVirDev( pIDsa->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE)); |
| rTargetShell.SetAddParaSpacingToTableCells( pIDsa->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS)); |
| rTargetShell.SetUseFormerLineSpacing( pIDsa->get(IDocumentSettingAccess::OLD_LINE_SPACING)); |
| rTargetShell.SetUseFormerObjectPositioning( pIDsa->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS)); |
| rTargetShell.SetConsiderWrapOnObjPos( pIDsa->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION)); |
| rTargetShell.SetUseFormerTextWrapping( pIDsa->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING)); |
| } |
| } |
| /* -----------------09.12.2002 12:35----------------- |
| * |
| * --------------------------------------------------*/ |
| |
| class SwConnectionDisposedListener_Impl : public cppu::WeakImplHelper1 |
| < lang::XEventListener > |
| { |
| SwNewDBMgr& rDBMgr; |
| |
| virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); |
| public: |
| SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr); |
| ~SwConnectionDisposedListener_Impl(); |
| |
| }; |
| // ----------------------------------------------------------------------------- |
| struct SwNewDBMgr_Impl |
| { |
| SwDSParam* pMergeData; |
| AbstractMailMergeDlg* pMergeDialog; |
| uno::Reference<lang::XEventListener> xDisposeListener; |
| |
| SwNewDBMgr_Impl(SwNewDBMgr& rDBMgr) |
| :pMergeData(0) |
| ,pMergeDialog(0) |
| ,xDisposeListener(new SwConnectionDisposedListener_Impl(rDBMgr)) |
| {} |
| }; |
| /*-- 24.10.2003 15:54:18--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void lcl_InitNumberFormatter(SwDSParam& rParam, uno::Reference<XDataSource> xSource) |
| { |
| uno::Reference<XMultiServiceFactory> xMgr = ::comphelper::getProcessServiceFactory(); |
| if( xMgr.is() ) |
| { |
| uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.util.NumberFormatter" )); |
| rParam.xFormatter = uno::Reference<util::XNumberFormatter>(xInstance, UNO_QUERY) ; |
| } |
| if(!xSource.is()) |
| xSource = SwNewDBMgr::getDataSourceAsParent(rParam.xConnection, rParam.sDataSource); |
| |
| uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY); |
| if(xSourceProps.is()) |
| { |
| Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier")); |
| if(aFormats.hasValue()) |
| { |
| uno::Reference<XNumberFormatsSupplier> xSuppl; |
| aFormats >>= xSuppl; |
| if(xSuppl.is()) |
| { |
| uno::Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings(); |
| Any aNull = xSettings->getPropertyValue(C2U("NullDate")); |
| aNull >>= rParam.aNullDate; |
| if(rParam.xFormatter.is()) |
| rParam.xFormatter->attachNumberFormatsSupplier(xSuppl); |
| } |
| } |
| } |
| } |
| /* -----------------------------17.07.00 17:04-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool lcl_MoveAbsolute(SwDSParam* pParam, long nAbsPos) |
| { |
| sal_Bool bRet = sal_False; |
| try |
| { |
| if(pParam->bScrollable) |
| { |
| bRet = pParam->xResultSet->absolute( nAbsPos ); |
| } |
| else |
| { |
| DBG_ERROR("no absolute positioning available"); |
| } |
| } |
| catch(Exception aExcept) |
| { |
| } |
| return bRet; |
| } |
| /* -----------------------------17.07.00 17:23-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool lcl_GetColumnCnt(SwDSParam* pParam, |
| const String& rColumnName, long nLanguage, String& rResult, double* pNumber) |
| { |
| uno::Reference< XColumnsSupplier > xColsSupp( pParam->xResultSet, UNO_QUERY ); |
| uno::Reference<XNameAccess> xCols; |
| try |
| { |
| xCols = xColsSupp->getColumns(); |
| } |
| catch( lang::DisposedException& ) |
| { |
| } |
| if(!xCols.is() || !xCols->hasByName(rColumnName)) |
| return sal_False; |
| Any aCol = xCols->getByName(rColumnName); |
| uno::Reference< XPropertySet > xColumnProps; |
| aCol >>= xColumnProps; |
| |
| SwDBFormatData aFormatData; |
| if(!pParam->xFormatter.is()) |
| { |
| uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent( |
| pParam->xConnection,pParam->sDataSource); |
| lcl_InitNumberFormatter(*pParam, xSource ); |
| } |
| aFormatData.aNullDate = pParam->aNullDate; |
| aFormatData.xFormatter = pParam->xFormatter; |
| |
| MsLangId::convertLanguageToLocale( (LanguageType)nLanguage, aFormatData.aLocale ); |
| |
| rResult = SwNewDBMgr::GetDBField( xColumnProps, aFormatData, pNumber); |
| return sal_True; |
| }; |
| /*-------------------------------------------------------------------- |
| Beschreibung: Daten importieren |
| --------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::MergeNew(const SwMergeDescriptor& rMergeDesc ) |
| { |
| SetMergeType( rMergeDesc.nMergeType ); |
| |
| DBG_ASSERT(!bInMerge && !pImpl->pMergeData, "merge already activated!"); |
| |
| SwDBData aData; |
| aData.nCommandType = CommandType::TABLE; |
| uno::Reference<XResultSet> xResSet; |
| Sequence<Any> aSelection; |
| uno::Reference< XConnection> xConnection; |
| |
| aData.sDataSource = rMergeDesc.rDescriptor.getDataSource(); |
| rMergeDesc.rDescriptor[daCommand] >>= aData.sCommand; |
| rMergeDesc.rDescriptor[daCommandType] >>= aData.nCommandType; |
| |
| if ( rMergeDesc.rDescriptor.has(daCursor) ) |
| rMergeDesc.rDescriptor[daCursor] >>= xResSet; |
| if ( rMergeDesc.rDescriptor.has(daSelection) ) |
| rMergeDesc.rDescriptor[daSelection] >>= aSelection; |
| if ( rMergeDesc.rDescriptor.has(daConnection) ) |
| rMergeDesc.rDescriptor[daConnection] >>= xConnection; |
| |
| if(!aData.sDataSource.getLength() || !aData.sCommand.getLength() || !xResSet.is()) |
| { |
| return sal_False; |
| } |
| |
| pImpl->pMergeData = new SwDSParam(aData, xResSet, aSelection); |
| SwDSParam* pTemp = FindDSData(aData, sal_False); |
| if(pTemp) |
| *pTemp = *pImpl->pMergeData; |
| else |
| { |
| //#94779# calls from the calculator may have added a connection with an invalid commandtype |
| //"real" data base connections added here have to re-use the already available |
| //DSData and set the correct CommandType |
| SwDBData aTempData(aData); |
| aData.nCommandType = -1; |
| pTemp = FindDSData(aData, sal_False); |
| if(pTemp) |
| *pTemp = *pImpl->pMergeData; |
| else |
| { |
| SwDSParam* pInsert = new SwDSParam(*pImpl->pMergeData); |
| aDataSourceParams.Insert(pInsert, aDataSourceParams.Count()); |
| try |
| { |
| uno::Reference<XComponent> xComponent(pInsert->xConnection, UNO_QUERY); |
| if(xComponent.is()) |
| xComponent->addEventListener(pImpl->xDisposeListener); |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| } |
| if(!pImpl->pMergeData->xConnection.is()) |
| pImpl->pMergeData->xConnection = xConnection; |
| // add an XEventListener |
| |
| try{ |
| //set to start position |
| if(pImpl->pMergeData->aSelection.getLength()) |
| { |
| sal_Int32 nPos = 0; |
| pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos; |
| pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos ); |
| pImpl->pMergeData->CheckEndOfDB(); |
| if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength()) |
| pImpl->pMergeData->bEndOfDB = sal_True; |
| } |
| else |
| { |
| pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first(); |
| pImpl->pMergeData->CheckEndOfDB(); |
| } |
| } |
| catch(Exception&) |
| { |
| pImpl->pMergeData->bEndOfDB = sal_True; |
| pImpl->pMergeData->CheckEndOfDB(); |
| DBG_ERROR("exception in MergeNew()"); |
| } |
| |
| uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,aData.sDataSource); |
| |
| lcl_InitNumberFormatter(*pImpl->pMergeData, xSource); |
| |
| rMergeDesc.rSh.ChgDBData(aData); |
| bInMerge = sal_True; |
| |
| if (IsInitDBFields()) |
| { |
| // Bei Datenbankfeldern ohne DB-Name DB-Name von Dok einsetzen |
| SvStringsDtor aDBNames(1, 1); |
| aDBNames.Insert( new String(), 0); |
| SwDBData aInsertData = rMergeDesc.rSh.GetDBData(); |
| String sDBName = aInsertData.sDataSource; |
| sDBName += DB_DELIM; |
| sDBName += (String)aInsertData.sCommand; |
| sDBName += DB_DELIM; |
| sDBName += String::CreateFromInt32(aInsertData.nCommandType); |
| rMergeDesc.rSh.ChangeDBFields( aDBNames, sDBName); |
| SetInitDBFields(sal_False); |
| } |
| |
| sal_Bool bRet = sal_True; |
| switch(rMergeDesc.nMergeType) |
| { |
| case DBMGR_MERGE: |
| bRet = Merge(&rMergeDesc.rSh); // Mischen |
| break; |
| |
| case DBMGR_MERGE_MAILMERGE: // printing merge from 'old' merge dialog or from UNO-component |
| case DBMGR_MERGE_MAILING: |
| case DBMGR_MERGE_MAILFILES: |
| case DBMGR_MERGE_SINGLE_FILE: |
| // save files and send them as e-Mail if required |
| bRet = MergeMailFiles(&rMergeDesc.rSh, |
| rMergeDesc); |
| break; |
| |
| default: // Einfuegen der selektierten Eintraege |
| // (war: InsertRecord) |
| ImportFromConnection(&rMergeDesc.rSh); |
| break; |
| } |
| |
| EndMerge(); |
| return bRet; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: Daten importieren |
| --------------------------------------------------------------------*/ |
| |
| |
| sal_Bool SwNewDBMgr::Merge(SwWrtShell* pSh) |
| { |
| pSh->StartAllAction(); |
| |
| pSh->ViewShell::UpdateFlds(sal_True); |
| pSh->SetModified(); |
| |
| pSh->EndAllAction(); |
| |
| return sal_True; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| void SwNewDBMgr::ImportFromConnection( SwWrtShell* pSh ) |
| { |
| if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB) |
| { |
| { |
| pSh->StartAllAction(); |
| pSh->StartUndo(UNDO_EMPTY); |
| sal_Bool bGroupUndo(pSh->DoesGroupUndo()); |
| pSh->DoGroupUndo(sal_False); |
| |
| if( pSh->HasSelection() ) |
| pSh->DelRight(); |
| |
| SwWait *pWait = 0; |
| |
| { |
| sal_uLong i = 0; |
| do { |
| |
| ImportDBEntry(pSh); |
| if( 10 == ++i ) |
| pWait = new SwWait( *pSh->GetView().GetDocShell(), true ); |
| |
| } while(ToNextMergeRecord()); |
| } |
| |
| pSh->DoGroupUndo(bGroupUndo); |
| pSh->EndUndo(UNDO_EMPTY); |
| pSh->EndAllAction(); |
| delete pWait; |
| } |
| } |
| } |
| /*-----------------24.02.97 10.30------------------- |
| |
| --------------------------------------------------*/ |
| |
| String lcl_FindColumn(const String& sFormatStr,sal_uInt16 &nUsedPos, sal_uInt8 &nSeparator) |
| { |
| String sReturn; |
| sal_uInt16 nLen = sFormatStr.Len(); |
| nSeparator = 0xff; |
| while(nUsedPos < nLen && nSeparator == 0xff) |
| { |
| sal_Unicode cAkt = sFormatStr.GetChar(nUsedPos); |
| switch(cAkt) |
| { |
| case ',': |
| nSeparator = DB_SEP_SPACE; |
| break; |
| case ';': |
| nSeparator = DB_SEP_RETURN; |
| break; |
| case ':': |
| nSeparator = DB_SEP_TAB; |
| break; |
| case '#': |
| nSeparator = DB_SEP_NEWLINE; |
| break; |
| default: |
| sReturn += cAkt; |
| } |
| nUsedPos++; |
| |
| } |
| return sReturn; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| void SwNewDBMgr::ImportDBEntry(SwWrtShell* pSh) |
| { |
| if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB) |
| { |
| uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY ); |
| uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); |
| String sFormatStr; |
| sal_uInt16 nFmtLen = sFormatStr.Len(); |
| if( nFmtLen ) |
| { |
| const char cSpace = ' '; |
| const char cTab = '\t'; |
| sal_uInt16 nUsedPos = 0; |
| sal_uInt8 nSeparator; |
| String sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator); |
| while( sColumn.Len() ) |
| { |
| if(!xCols->hasByName(sColumn)) |
| return; |
| Any aCol = xCols->getByName(sColumn); |
| uno::Reference< XPropertySet > xColumnProp; |
| aCol >>= xColumnProp; |
| if(xColumnProp.is()) |
| { |
| SwDBFormatData aDBFormat; |
| String sInsert = GetDBField( xColumnProp, aDBFormat); |
| if( DB_SEP_SPACE == nSeparator ) |
| sInsert += cSpace; |
| else if( DB_SEP_TAB == nSeparator) |
| sInsert += cTab; |
| pSh->Insert(sInsert); |
| if( DB_SEP_RETURN == nSeparator) |
| pSh->SplitNode(); |
| else if(DB_SEP_NEWLINE == nSeparator) |
| pSh->InsertLineBreak(); |
| } |
| else |
| { |
| // Spalte nicht gefunden -> Fehler anzeigen |
| String sInsert = '?'; |
| sInsert += sColumn; |
| sInsert += '?'; |
| pSh->Insert(sInsert); |
| } |
| sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator); |
| } |
| pSh->SplitNode(); |
| } |
| else |
| { |
| String sStr; |
| Sequence<rtl::OUString> aColNames = xCols->getElementNames(); |
| const rtl::OUString* pColNames = aColNames.getConstArray(); |
| long nLength = aColNames.getLength(); |
| for(long i = 0; i < nLength; i++) |
| { |
| Any aCol = xCols->getByName(pColNames[i]); |
| uno::Reference< XPropertySet > xColumnProp; |
| aCol >>= xColumnProp; |
| SwDBFormatData aDBFormat; |
| sStr += GetDBField( xColumnProp, aDBFormat); |
| if (i < nLength - 1) |
| sStr += '\t'; |
| } |
| pSh->SwEditShell::Insert2(sStr); |
| pSh->SwFEShell::SplitNode(); // Zeilenvorschub |
| } |
| } |
| } |
| /*-------------------------------------------------------------------- |
| Beschreibung: Listbox mit Tabellenliste fuellen |
| --------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::GetTableNames(ListBox* pListBox, const String& rDBName) |
| { |
| sal_Bool bRet = sal_False; |
| String sOldTableName(pListBox->GetSelectEntry()); |
| pListBox->Clear(); |
| SwDSParam* pParam = FindDSConnection(rDBName, sal_False); |
| uno::Reference< XConnection> xConnection; |
| if(pParam && pParam->xConnection.is()) |
| xConnection = pParam->xConnection; |
| else |
| { |
| rtl::OUString sDBName(rDBName); |
| if ( sDBName.getLength() ) |
| xConnection = RegisterConnection( sDBName ); |
| } |
| if(xConnection.is()) |
| { |
| uno::Reference<XTablesSupplier> xTSupplier = uno::Reference<XTablesSupplier>(xConnection, UNO_QUERY); |
| if(xTSupplier.is()) |
| { |
| uno::Reference<XNameAccess> xTbls = xTSupplier->getTables(); |
| Sequence<rtl::OUString> aTbls = xTbls->getElementNames(); |
| const rtl::OUString* pTbls = aTbls.getConstArray(); |
| for(long i = 0; i < aTbls.getLength(); i++) |
| { |
| sal_uInt16 nEntry = pListBox->InsertEntry(pTbls[i]); |
| pListBox->SetEntryData(nEntry, (void*)0); |
| } |
| } |
| uno::Reference<XQueriesSupplier> xQSupplier = uno::Reference<XQueriesSupplier>(xConnection, UNO_QUERY); |
| if(xQSupplier.is()) |
| { |
| uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries(); |
| Sequence<rtl::OUString> aQueries = xQueries->getElementNames(); |
| const rtl::OUString* pQueries = aQueries.getConstArray(); |
| for(long i = 0; i < aQueries.getLength(); i++) |
| { |
| sal_uInt16 nEntry = pListBox->InsertEntry(pQueries[i]); |
| pListBox->SetEntryData(nEntry, (void*)1); |
| } |
| } |
| if (sOldTableName.Len()) |
| pListBox->SelectEntry(sOldTableName); |
| bRet = sal_True; |
| } |
| return bRet; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: Listbox mit Spaltennamen einer Datenbank fuellen |
| --------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox, |
| const String& rDBName, const String& rTableName, sal_Bool bAppend) |
| { |
| if (!bAppend) |
| pListBox->Clear(); |
| SwDBData aData; |
| aData.sDataSource = rDBName; |
| aData.sCommand = rTableName; |
| aData.nCommandType = -1; |
| SwDSParam* pParam = FindDSData(aData, sal_False); |
| uno::Reference< XConnection> xConnection; |
| if(pParam && pParam->xConnection.is()) |
| xConnection = pParam->xConnection; |
| else |
| { |
| rtl::OUString sDBName(rDBName); |
| xConnection = RegisterConnection( sDBName ); |
| } |
| uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); |
| if(xColsSupp.is()) |
| { |
| uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); |
| const Sequence<rtl::OUString> aColNames = xCols->getElementNames(); |
| const rtl::OUString* pColNames = aColNames.getConstArray(); |
| for(int nCol = 0; nCol < aColNames.getLength(); nCol++) |
| { |
| pListBox->InsertEntry(pColNames[nCol]); |
| } |
| ::comphelper::disposeComponent( xColsSupp ); |
| } |
| return(sal_True); |
| } |
| /* -----------------------------08.06.01 15:11-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox, |
| uno::Reference< XConnection> xConnection, |
| const String& rTableName, sal_Bool bAppend) |
| { |
| if (!bAppend) |
| pListBox->Clear(); |
| uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); |
| if(xColsSupp.is()) |
| { |
| uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); |
| const Sequence<rtl::OUString> aColNames = xCols->getElementNames(); |
| const rtl::OUString* pColNames = aColNames.getConstArray(); |
| for(int nCol = 0; nCol < aColNames.getLength(); nCol++) |
| { |
| pListBox->InsertEntry(pColNames[nCol]); |
| } |
| ::comphelper::disposeComponent( xColsSupp ); |
| } |
| return(sal_True); |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: CTOR |
| --------------------------------------------------------------------*/ |
| |
| SwNewDBMgr::SwNewDBMgr() : |
| nMergeType(DBMGR_INSERT), |
| bInitDBFields(sal_False), |
| bInMerge(sal_False), |
| bMergeSilent(sal_False), |
| bMergeLock(sal_False), |
| pImpl(new SwNewDBMgr_Impl(*this)), |
| pMergeEvtSrc(NULL) |
| { |
| } |
| /* -----------------------------18.07.00 08:56-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| SwNewDBMgr::~SwNewDBMgr() |
| { |
| for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) |
| { |
| SwDSParam* pParam = aDataSourceParams[nPos]; |
| if(pParam->xConnection.is()) |
| { |
| try |
| { |
| uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY); |
| if(xComp.is()) |
| xComp->dispose(); |
| } |
| catch(const RuntimeException& ) |
| { |
| //may be disposed already since multiple entries may have used the same connection |
| } |
| } |
| } |
| delete pImpl; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: Serienbriefe als einzelne Dokumente speichern |
| --------------------------------------------------------------------*/ |
| String lcl_FindUniqueName(SwWrtShell* pTargetShell, const String& rStartingPageDesc, sal_uLong nDocNo ) |
| { |
| do |
| { |
| String sTest = rStartingPageDesc; |
| sTest += String::CreateFromInt32( nDocNo ); |
| if( !pTargetShell->FindPageDescByName( sTest ) ) |
| return sTest; |
| ++nDocNo; |
| }while(true); |
| } |
| void lcl_CopyDynamicDefaults( const SwDoc& rSource, SwDoc& rTarget ) |
| { |
| sal_uInt16 __FAR_DATA aRangeOfDefaults[] = { |
| RES_FRMATR_BEGIN, RES_FRMATR_END-1, |
| RES_CHRATR_BEGIN, RES_CHRATR_END-1, |
| RES_PARATR_BEGIN, RES_PARATR_END-1, |
| // --> OD 2008-02-25 #refactorlists## |
| RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1, |
| // <-- |
| RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, |
| 0 |
| }; |
| |
| SfxItemSet aNewDefaults( rTarget.GetAttrPool(), aRangeOfDefaults ); |
| |
| sal_uInt16 nWhich; |
| sal_uInt16 nRange = 0; |
| while( aRangeOfDefaults[nRange] != 0) |
| { |
| for( nWhich = aRangeOfDefaults[nRange]; nWhich < aRangeOfDefaults[nRange + 1]; ++nWhich ) |
| { |
| const SfxPoolItem& rSourceAttr = rSource.GetDefault( nWhich ); |
| if( rSourceAttr != rTarget.GetDefault( nWhich ) ) |
| aNewDefaults.Put( rSourceAttr ); |
| } |
| nRange += 2; |
| } |
| if( aNewDefaults.Count() ) |
| rTarget.SetDefault( aNewDefaults ); |
| } |
| void lcl_CopyFollowPageDesc( |
| SwWrtShell& rTargetShell, |
| const SwPageDesc& rSourcePageDesc, |
| const SwPageDesc& rTargetPageDesc, |
| const sal_uLong nDocNo ) |
| { |
| //now copy the follow page desc, too |
| const SwPageDesc* pFollowPageDesc = rSourcePageDesc.GetFollow(); |
| String sFollowPageDesc = pFollowPageDesc->GetName(); |
| if( sFollowPageDesc != rSourcePageDesc.GetName() ) |
| { |
| SwDoc* pTargetDoc = rTargetShell.GetDoc(); |
| String sNewFollowPageDesc = lcl_FindUniqueName(&rTargetShell, sFollowPageDesc, nDocNo ); |
| sal_uInt16 nNewDesc = pTargetDoc->MakePageDesc( sNewFollowPageDesc ); |
| SwPageDesc& rTargetFollowPageDesc = pTargetDoc->_GetPageDesc( nNewDesc ); |
| |
| pTargetDoc->CopyPageDesc( *pFollowPageDesc, rTargetFollowPageDesc, sal_False ); |
| SwPageDesc aDesc( rTargetPageDesc ); |
| aDesc.SetFollow( &rTargetFollowPageDesc ); |
| pTargetDoc->ChgPageDesc( rTargetPageDesc.GetName(), aDesc ); |
| } |
| } |
| |
| void lcl_RemoveSectionLinks( SwWrtShell& rWorkShell ) |
| { |
| //reset all links of the sections of synchronized labels |
| sal_uInt16 nSections = rWorkShell.GetSectionFmtCount(); |
| for( sal_uInt16 nSection = 0; nSection < nSections; ++nSection ) |
| { |
| SwSectionData aSectionData( *rWorkShell.GetSectionFmt( nSection ).GetSection() ); |
| if( aSectionData.GetType() == FILE_LINK_SECTION ) |
| { |
| aSectionData.SetType( CONTENT_SECTION ); |
| aSectionData.SetLinkFileName( String() ); |
| rWorkShell.UpdateSection( nSection, aSectionData ); |
| } |
| } |
| rWorkShell.SetLabelDoc( sal_False ); |
| } |
| |
| sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell, |
| const SwMergeDescriptor& rMergeDescriptor) |
| { |
| //check if the doc is synchronized and contains at least one linked section |
| sal_Bool bSynchronizedDoc = pSourceShell->IsLabelDoc() && pSourceShell->GetSectionFmtCount() > 1; |
| sal_Bool bLoop = sal_True; |
| sal_Bool bEMail = rMergeDescriptor.nMergeType == DBMGR_MERGE_MAILING; |
| const bool bAsSingleFile = rMergeDescriptor.nMergeType == DBMGR_MERGE_SINGLE_FILE; |
| |
| ::rtl::Reference< MailDispatcher > xMailDispatcher; |
| ::rtl::OUString sBodyMimeType; |
| rtl_TextEncoding eEncoding = ::gsl_getSystemTextEncoding(); |
| |
| if(bEMail) |
| { |
| xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer)); |
| if(!rMergeDescriptor.bSendAsAttachment && rMergeDescriptor.bSendAsHTML) |
| { |
| sBodyMimeType = ::rtl::OUString::createFromAscii("text/html; charset="); |
| sBodyMimeType += ::rtl::OUString::createFromAscii( |
| rtl_getBestMimeCharsetFromTextEncoding( eEncoding )); |
| SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get(); |
| eEncoding = pHtmlOptions->GetTextEncoding(); |
| } |
| else |
| sBodyMimeType = |
| ::rtl::OUString::createFromAscii("text/plain; charset=UTF-8; format=flowed"); |
| } |
| |
| uno::Reference< XPropertySet > xColumnProp; |
| { |
| sal_Bool bColumnName = sEMailAddrFld.Len() > 0; |
| |
| if (bColumnName) |
| { |
| uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY ); |
| uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); |
| if(!xCols->hasByName(sEMailAddrFld)) |
| return sal_False; |
| Any aCol = xCols->getByName(sEMailAddrFld); |
| aCol >>= xColumnProp; |
| } |
| |
| SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher(); |
| SwDocShell* pSourrceDocSh = pSourceShell->GetView().GetDocShell(); |
| pSfxDispatcher->Execute( pSourrceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD); |
| // has document been saved successfully? |
| if( !pSourrceDocSh->IsModified() ) |
| { |
| SfxMedium* pOrig = pSourceShell->GetView().GetDocShell()->GetMedium(); |
| String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE )); |
| const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter( |
| sSourceDocumentURL, ::aEmptyStr ); |
| const SfxFilter* pStoreToFilter = pSfxFlt; |
| SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer(); |
| const String* pStoreToFilterOptions = 0; |
| // if a save_to filter is set then use it - otherwise use the default |
| if( bEMail && !rMergeDescriptor.bSendAsAttachment ) |
| { |
| String sExtension( String::CreateFromAscii( |
| rMergeDescriptor.bSendAsHTML ? "html" : "txt" )); |
| pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SFX_FILTER_EXPORT); |
| } |
| else if( rMergeDescriptor.sSaveToFilter.Len()) |
| { |
| const SfxFilter* pFilter = |
| pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter ); |
| if(pFilter) |
| { |
| pStoreToFilter = pFilter; |
| if(rMergeDescriptor.sSaveToFilterOptions.Len()) |
| pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions; |
| } |
| } |
| bCancel = sal_False; |
| |
| // in case of creating a single resulting file this has to be created here |
| SwWrtShell* pTargetShell = 0; |
| |
| // the shell will be explicitly closed at the end of the method, but it is |
| // still more safe to use SfxObjectShellLock here |
| SfxObjectShellLock xTargetDocShell; |
| |
| SwView* pTargetView = 0; |
| std::auto_ptr< utl::TempFile > aTempFile; |
| String sModifiedStartingPageDesc; |
| String sStartingPageDesc; |
| sal_uInt16 nStartingPageNo = 0; |
| bool bPageStylesWithHeaderFooter = false; |
| if(bAsSingleFile || rMergeDescriptor.bCreateSingleFile) |
| { |
| // create a target docshell to put the merged document into |
| xTargetDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD ); |
| xTargetDocShell->DoInitNew( 0 ); |
| SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 ); |
| |
| pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() ); |
| |
| //initiate SelectShell() to create sub shells |
| pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() ); |
| pTargetShell = pTargetView->GetWrtShellPtr(); |
| //copy the styles from the source to the target document |
| SwgReaderOption aOpt; |
| aOpt.SetTxtFmts( sal_True ); |
| aOpt.SetFrmFmts( sal_True ); |
| aOpt.SetPageDescs( sal_True ); |
| aOpt.SetNumRules( sal_True ); |
| aOpt.SetMerge( sal_False ); |
| pTargetView->GetDocShell()->LoadStylesFromFile( |
| sSourceDocumentURL, aOpt, sal_True ); |
| //determine the page style and number used at the start of the source document |
| pSourceShell->SttEndDoc(sal_True); |
| nStartingPageNo = pSourceShell->GetVirtPageNum(); |
| sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc( |
| pSourceShell->GetCurPageDesc()).GetName(); |
| // #122799# copy compatibility options |
| lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell); |
| // #72821# copy dynamic defaults |
| lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() ); |
| // #i72517# |
| const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc ); |
| const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster(); |
| bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() || |
| rMaster.GetFooter().IsActive(); |
| |
| } |
| |
| PrintMonitor aPrtMonDlg(&pSourceShell->GetView().GetEditWin(), PrintMonitor::MONITOR_TYPE_PRINT); |
| aPrtMonDlg.aDocName.SetText(pSourceShell->GetView().GetDocShell()->GetTitle(22)); |
| |
| aPrtMonDlg.aCancel.SetClickHdl(LINK(this, SwNewDBMgr, PrtCancelHdl)); |
| if (!IsMergeSilent()) |
| aPrtMonDlg.Show(); |
| |
| // Progress, um KeyInputs zu unterbinden |
| SfxProgress aProgress(pSourrceDocSh, ::aEmptyStr, 1); |
| |
| // Alle Dispatcher sperren |
| SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh); |
| while (pViewFrm) |
| { |
| pViewFrm->GetDispatcher()->Lock(sal_True); |
| pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh); |
| } |
| sal_uLong nDocNo = 1; |
| |
| long nStartRow, nEndRow; |
| // collect temporary files |
| ::std::vector< String> aFilesToRemove; |
| do |
| { |
| nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0; |
| { |
| String sPath(sSubject); |
| |
| String sAddress; |
| if( !bEMail && bColumnName ) |
| { |
| SwDBFormatData aDBFormat; |
| aDBFormat.xFormatter = pImpl->pMergeData->xFormatter; |
| aDBFormat.aNullDate = pImpl->pMergeData->aNullDate; |
| sAddress = GetDBField( xColumnProp, aDBFormat); |
| if (!sAddress.Len()) |
| sAddress = '_'; |
| sPath += sAddress; |
| } |
| |
| // create a new temporary file name - only done once in case of bCreateSingleFile |
| if( 1 == nDocNo || (!rMergeDescriptor.bCreateSingleFile && !bAsSingleFile) ) |
| { |
| INetURLObject aEntry(sPath); |
| String sLeading; |
| //#i97667# if the name is from a database field then it will be used _as is_ |
| if( sAddress.Len() ) |
| sLeading = sAddress; |
| else |
| sLeading = aEntry.GetBase(); |
| aEntry.removeSegment(); |
| sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE ); |
| String sExt( pStoreToFilter->GetDefaultExtension() ); |
| sExt.EraseLeadingChars('*'); |
| aTempFile = std::auto_ptr< utl::TempFile >( |
| new utl::TempFile(sLeading,&sExt,&sPath )); |
| if( bAsSingleFile ) |
| aTempFile->EnableKillingFile(); |
| } |
| |
| if( !aTempFile->IsValid() ) |
| { |
| ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED ); |
| bLoop = sal_False; |
| bCancel = sal_True; |
| } |
| else |
| { |
| INetURLObject aTempFileURL(aTempFile->GetURL()); |
| aPrtMonDlg.aPrinter.SetText( aTempFileURL.GetBase() ); |
| String sStat(SW_RES(STR_STATSTR_LETTER)); // Brief |
| sStat += ' '; |
| sStat += String::CreateFromInt32( nDocNo ); |
| aPrtMonDlg.aPrintInfo.SetText(sStat); |
| |
| // Rechenzeit fuer Save-Monitor: |
| for (sal_uInt16 i = 0; i < 10; i++) |
| Application::Reschedule(); |
| |
| // Create and save new document |
| // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here |
| SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); |
| SfxMedium* pWorkMed = new SfxMedium( sSourceDocumentURL, STREAM_STD_READ, sal_True ); |
| pWorkMed->SetFilter( pSfxFlt ); |
| |
| if (xWorkDocSh->DoLoad(pWorkMed)) |
| { |
| //create a view frame for the document |
| SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 ); |
| //request the layout calculation |
| SwWrtShell& rWorkShell = |
| static_cast< SwView* >(pWorkFrame->GetViewShell())->GetWrtShell(); |
| rWorkShell.CalcLayout(); |
| SwDoc* pWorkDoc = ((SwDocShell*)(&xWorkDocSh))->GetDoc(); |
| SwNewDBMgr* pOldDBMgr = pWorkDoc->GetNewDBMgr(); |
| pWorkDoc->SetNewDBMgr( this ); |
| SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh)); |
| pWorkDoc->UpdateFlds(NULL, false); |
| SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh)); |
| |
| // alle versteckten Felder/Bereiche entfernen |
| pWorkDoc->RemoveInvisibleContent(); |
| |
| // launch MailMergeEvent if required |
| const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc(); |
| if(pEvtSrc) |
| { |
| uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc ); |
| text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() ); |
| pEvtSrc->LaunchMailMergeEvent( aEvt ); |
| } |
| |
| if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile ) |
| { |
| DBG_ASSERT( pTargetShell, "no target shell available!" ); |
| // copy created file into the target document |
| rWorkShell.ConvertFieldsToText(); |
| rWorkShell.SetNumberingRestart(); |
| if( bSynchronizedDoc ) |
| { |
| lcl_RemoveSectionLinks( rWorkShell ); |
| } |
| |
| // insert the document into the target document |
| rWorkShell.SttEndDoc(sal_False); |
| rWorkShell.SttEndDoc(sal_True); |
| rWorkShell.SelAll(); |
| pTargetShell->SwCrsrShell::SttEndDoc( sal_False ); |
| //#i72517# the headers and footers are still those from the source - update in case of fields inside header/footer |
| if( !nDocNo && bPageStylesWithHeaderFooter ) |
| pTargetShell->GetView().GetDocShell()->_LoadStyles( *rWorkShell.GetView().GetDocShell(), sal_True ); |
| //#i72517# put the styles to the target document |
| //if the source uses headers or footers each new copy need to copy a new page styles |
| if(bPageStylesWithHeaderFooter) |
| { |
| //create a new pagestyle |
| //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style |
| |
| SwDoc* pTargetDoc = pTargetShell->GetDoc(); |
| SwPageDesc* pSourcePageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc ); |
| String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo ); |
| pTargetDoc->MakePageDesc( sNewPageDescName ); |
| SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName ); |
| if(pSourcePageDesc && pTargetPageDesc) |
| { |
| pTargetDoc->CopyPageDesc( *pSourcePageDesc, *pTargetPageDesc, sal_False ); |
| sModifiedStartingPageDesc = sNewPageDescName; |
| lcl_CopyFollowPageDesc( *pTargetShell, *pSourcePageDesc, *pTargetPageDesc, nDocNo ); |
| } |
| } |
| |
| if(nDocNo > 1) |
| pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo ); |
| else |
| pTargetShell->SetPageStyle(sModifiedStartingPageDesc); |
| DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended"); |
| //#i51359# add a second paragraph in case there's only one |
| { |
| SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 ); |
| SwPosition aTestPos( aIdx ); |
| SwCursor aTestCrsr(aTestPos,0,false); |
| if(!aTestCrsr.MovePara(fnParaNext, fnParaStart)) |
| { |
| //append a paragraph |
| pWorkDoc->AppendTxtNode( aTestPos ); |
| } |
| } |
| pTargetShell->Paste( rWorkShell.GetDoc(), sal_True ); |
| |
| //convert fields in page styles (header/footer - has to be done after the first document has been pasted |
| if(1 == nDocNo) |
| { |
| pTargetShell->CalcLayout(); |
| pTargetShell->ConvertFieldsToText(); |
| } |
| } |
| else |
| { |
| String sFileURL = aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ); |
| SfxMedium* pDstMed = new SfxMedium( |
| sFileURL, |
| STREAM_STD_READWRITE, sal_True ); |
| pDstMed->SetFilter( pStoreToFilter ); |
| if(pDstMed->GetItemSet()) |
| { |
| if(pStoreToFilterOptions ) |
| pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions)); |
| if(rMergeDescriptor.aSaveToFilterData.getLength()) |
| pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData))); |
| } |
| |
| //convert fields to text if we are exporting to PDF |
| //this prevents a second merge while updating the fields in SwXTextDocument::getRendererCount() |
| if( pStoreToFilter && pStoreToFilter->GetFilterName().EqualsAscii("writer_pdf_Export")) |
| rWorkShell.ConvertFieldsToText(); |
| xWorkDocSh->DoSaveAs(*pDstMed); |
| xWorkDocSh->DoSaveCompleted(pDstMed); |
| if( xWorkDocSh->GetError() ) |
| { |
| // error message ?? |
| ErrorHandler::HandleError( xWorkDocSh->GetError() ); |
| bCancel = sal_True; |
| bLoop = sal_False; |
| } |
| if( bEMail ) |
| { |
| SwDBFormatData aDBFormat; |
| aDBFormat.xFormatter = pImpl->pMergeData->xFormatter; |
| aDBFormat.aNullDate = pImpl->pMergeData->aNullDate; |
| String sMailAddress = GetDBField( xColumnProp, aDBFormat); |
| if(!SwMailMergeHelper::CheckMailAddress( sMailAddress )) |
| { |
| DBG_ERROR("invalid e-Mail address in database column"); |
| } |
| else |
| { |
| SwMailMessage* pMessage = 0; |
| uno::Reference< mail::XMailMessage > xMessage = |
| pMessage = new SwMailMessage; |
| if(rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo()) |
| pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo()); |
| pMessage->addRecipient( sMailAddress ); |
| pMessage->SetSenderAddress( rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() ); |
| ::rtl::OUString sBody; |
| if(rMergeDescriptor.bSendAsAttachment) |
| { |
| sBody = rMergeDescriptor.sMailBody; |
| mail::MailAttachment aAttach; |
| aAttach.Data = new SwMailTransferable( |
| sFileURL, |
| rMergeDescriptor.sAttachmentName, |
| pStoreToFilter->GetMimeType()); |
| aAttach.ReadableName = rMergeDescriptor.sAttachmentName; |
| pMessage->addAttachment( aAttach ); |
| } |
| else |
| { |
| { |
| //read in the temporary file and use it as mail body |
| SfxMedium aMedium( sFileURL, STREAM_READ, sal_True); |
| SvStream* pInStream = aMedium.GetInStream(); |
| DBG_ASSERT(pInStream, "no output file created?"); |
| if(pInStream) |
| { |
| pInStream->SetStreamCharSet( eEncoding ); |
| ByteString sLine; |
| sal_Bool bDone = pInStream->ReadLine( sLine ); |
| while ( bDone ) |
| { |
| sBody += String(sLine, eEncoding); |
| sBody += ::rtl::OUString('\n'); |
| bDone = pInStream->ReadLine( sLine ); |
| } |
| } |
| } |
| } |
| pMessage->setSubject( rMergeDescriptor.sSubject ); |
| uno::Reference< datatransfer::XTransferable> xBody = |
| new SwMailTransferable( |
| sBody, |
| sBodyMimeType); |
| pMessage->setBody( xBody ); |
| |
| if(rMergeDescriptor.aCopiesTo.getLength()) |
| { |
| const ::rtl::OUString* pCopies = rMergeDescriptor.aCopiesTo.getConstArray(); |
| for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aCopiesTo.getLength(); ++nToken) |
| pMessage->addCcRecipient( pCopies[nToken] ); |
| } |
| if(rMergeDescriptor.aBlindCopiesTo.getLength()) |
| { |
| const ::rtl::OUString* pCopies = rMergeDescriptor.aBlindCopiesTo.getConstArray(); |
| for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aBlindCopiesTo.getLength(); ++nToken) |
| pMessage->addBccRecipient( pCopies[nToken] ); |
| } |
| xMailDispatcher->enqueueMailMessage( xMessage ); |
| if(!xMailDispatcher->isStarted()) |
| xMailDispatcher->start(); |
| //schedule for removal |
| aFilesToRemove.push_back(sFileURL); |
| } |
| } |
| } |
| pWorkDoc->SetNewDBMgr( pOldDBMgr ); |
| } |
| xWorkDocSh->DoClose(); |
| } |
| } |
| nDocNo++; |
| nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0; |
| } while( !bCancel && |
| (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord())); |
| |
| aPrtMonDlg.Show( sal_False ); |
| |
| // save the single output document |
| if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile) |
| { |
| if( rMergeDescriptor.nMergeType != DBMGR_MERGE_MAILMERGE ) |
| { |
| DBG_ASSERT( aTempFile.get(), "Temporary file not available" ); |
| INetURLObject aTempFileURL(bAsSingleFile ? sSubject : aTempFile->GetURL()); |
| SfxMedium* pDstMed = new SfxMedium( |
| aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ), |
| STREAM_STD_READWRITE, sal_True ); |
| pDstMed->SetFilter( pStoreToFilter ); |
| if(pDstMed->GetItemSet()) |
| { |
| if(pStoreToFilterOptions ) |
| pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions)); |
| if(rMergeDescriptor.aSaveToFilterData.getLength()) |
| pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData))); |
| } |
| |
| xTargetDocShell->DoSaveAs(*pDstMed); |
| xTargetDocShell->DoSaveCompleted(pDstMed); |
| if( xTargetDocShell->GetError() ) |
| { |
| // error message ?? |
| ErrorHandler::HandleError( xTargetDocShell->GetError() ); |
| bLoop = sal_False; |
| } |
| } |
| else if( pTargetView ) // must be available! |
| { |
| //print the target document |
| #if OSL_DEBUG_LEVEL > 1 |
| sal_Bool _bVal; |
| sal_Int16 _nVal; |
| rtl::OUString _sVal; |
| const beans::PropertyValue* pDbgPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray(); |
| for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption) |
| { |
| rtl::OUString aName( pDbgPrintOptions[nOption].Name ); |
| uno::Any aVal( pDbgPrintOptions[nOption].Value ); |
| aVal >>= _bVal; |
| aVal >>= _nVal; |
| aVal >>= _sVal; |
| } |
| #endif |
| // printing should be done synchronously otherwise the document |
| // might already become invalid during the process |
| uno::Sequence< beans::PropertyValue > aOptions( rMergeDescriptor.aPrintOptions ); |
| const sal_Int32 nOpts = aOptions.getLength(); |
| aOptions.realloc( nOpts + 1 ); |
| aOptions[ nOpts ].Name = rtl::OUString::createFromAscii( "Wait" ); |
| aOptions[ nOpts ].Value <<= sal_True ; |
| // aPrintArgs.Put(SfxBoolItem(FN_QRY_MERGE, sal_True) ); |
| // // #i52629# aynchronous printing should only be done in silent mode - otherwise |
| // // the printer dialog does not come up |
| // aPrintArgs.Put( SfxBoolItem( SID_ASYNCHRON, rMergeDescriptor.bPrintAsync )); |
| // move print options |
| const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray(); |
| for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption) |
| { |
| if( pPrintOptions[nOption].Name.equalsAscii( "CopyCount" ) |
| ||( pPrintOptions[nOption].Name.equalsAscii( "FileName" )) |
| ||( pPrintOptions[nOption].Name.equalsAscii( "Collate" )) |
| ||( pPrintOptions[nOption].Name.equalsAscii( "Pages" )) |
| ||( pPrintOptions[nOption].Name.equalsAscii( "Wait" ))) |
| { |
| aOptions.realloc( nOpts + 1 ); |
| aOptions[ nOpts ].Name = pPrintOptions[nOption].Name; |
| aOptions[ nOpts ].Value = pPrintOptions[nOption].Value ; |
| } |
| } |
| |
| // const SwModuleOptions * pModOpt = SW_MOD()->GetModuleConfig(); |
| // if (pModOpt->IsSinglePrintJob()) |
| // { |
| // } |
| // else |
| // { |
| pTargetView->ExecPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync ); |
| // } |
| } |
| xTargetDocShell->DoClose(); |
| } |
| |
| //remove the temporary files |
| ::std::vector<String>::iterator aFileIter; |
| for(aFileIter = aFilesToRemove.begin(); |
| aFileIter != aFilesToRemove.end(); aFileIter++) |
| SWUnoHelper::UCB_DeleteFile( *aFileIter ); |
| |
| // Alle Dispatcher freigeben |
| pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh); |
| while (pViewFrm) |
| { |
| pViewFrm->GetDispatcher()->Lock(sal_False); |
| pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh); |
| } |
| |
| SW_MOD()->SetView(&pSourceShell->GetView()); |
| } |
| |
| nMergeType = DBMGR_INSERT; |
| } |
| |
| if(bEMail) |
| { |
| xMailDispatcher->stop(); |
| xMailDispatcher->shutdown(); |
| |
| } |
| |
| return bLoop; |
| } |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: |
| --------------------------------------------------------------------*/ |
| |
| IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton ) |
| { |
| pButton->GetParent()->Hide(); |
| bCancel = sal_True; |
| return 0; |
| } |
| IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton ) |
| |
| |
| /*-------------------------------------------------------------------- |
| Beschreibung: Numberformat der Spalte ermitteln und ggfs. in |
| den uebergebenen Formatter uebertragen |
| --------------------------------------------------------------------*/ |
| |
| sal_uLong SwNewDBMgr::GetColumnFmt( const String& rDBName, |
| const String& rTableName, |
| const String& rColNm, |
| SvNumberFormatter* pNFmtr, |
| long nLanguage ) |
| { |
| sal_uLong nRet = 0; |
| if(pNFmtr) |
| { |
| uno::Reference< XDataSource> xSource; |
| uno::Reference< XConnection> xConnection; |
| sal_Bool bUseMergeData = sal_False; |
| uno::Reference< XColumnsSupplier> xColsSupp; |
| bool bDisposeConnection = false; |
| if(pImpl->pMergeData && |
| pImpl->pMergeData->sDataSource.equals(rDBName) && pImpl->pMergeData->sCommand.equals(rTableName)) |
| { |
| xConnection = pImpl->pMergeData->xConnection; |
| xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,rDBName); |
| bUseMergeData = sal_True; |
| xColsSupp = xColsSupp.query( pImpl->pMergeData->xResultSet ); |
| } |
| if(!xConnection.is()) |
| { |
| SwDBData aData; |
| aData.sDataSource = rDBName; |
| aData.sCommand = rTableName; |
| aData.nCommandType = -1; |
| SwDSParam* pParam = FindDSData(aData, sal_False); |
| if(pParam && pParam->xConnection.is()) |
| { |
| xConnection = pParam->xConnection; |
| xColsSupp = xColsSupp.query( pParam->xResultSet ); |
| } |
| else |
| { |
| rtl::OUString sDBName(rDBName); |
| xConnection = RegisterConnection( sDBName ); |
| bDisposeConnection = true; |
| } |
| if(bUseMergeData) |
| pImpl->pMergeData->xConnection = xConnection; |
| } |
| bool bDispose = !xColsSupp.is(); |
| if(bDispose) |
| { |
| xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); |
| } |
| if(xColsSupp.is()) |
| { |
| uno::Reference<XNameAccess> xCols; |
| try |
| { |
| xCols = xColsSupp->getColumns(); |
| } |
| catch(Exception&) |
| { |
| DBG_ERROR("Exception in getColumns()"); |
| } |
| if(!xCols.is() || !xCols->hasByName(rColNm)) |
| return nRet; |
| Any aCol = xCols->getByName(rColNm); |
| uno::Reference< XPropertySet > xColumn; |
| aCol >>= xColumn; |
| nRet = GetColumnFmt(xSource, xConnection, xColumn, pNFmtr, nLanguage); |
| if(bDispose) |
| { |
| ::comphelper::disposeComponent( xColsSupp ); |
| } |
| if(bDisposeConnection) |
| { |
| ::comphelper::disposeComponent( xConnection ); |
| } |
| } |
| else |
| nRet = pNFmtr->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM ); |
| } |
| return nRet; |
| } |
| /* -----------------------------07.06.01 15:43-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_uLong SwNewDBMgr::GetColumnFmt( uno::Reference< XDataSource> xSource, |
| uno::Reference< XConnection> xConnection, |
| uno::Reference< XPropertySet> xColumn, |
| SvNumberFormatter* pNFmtr, |
| long nLanguage ) |
| { |
| //JP 12.01.99: ggfs. das NumberFormat im Doc setzen |
| sal_uLong nRet = 0; |
| |
| if(!xSource.is()) |
| { |
| uno::Reference<XChild> xChild(xConnection, UNO_QUERY); |
| if ( xChild.is() ) |
| xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY); |
| } |
| if(xSource.is() && xConnection.is() && xColumn.is() && pNFmtr) |
| { |
| SvNumberFormatsSupplierObj* pNumFmt = new SvNumberFormatsSupplierObj( pNFmtr ); |
| uno::Reference< util::XNumberFormatsSupplier > xDocNumFmtsSupplier = pNumFmt; |
| uno::Reference< XNumberFormats > xDocNumberFormats = xDocNumFmtsSupplier->getNumberFormats(); |
| uno::Reference< XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY); |
| |
| Locale aLocale( MsLangId::convertLanguageToLocale( (LanguageType)nLanguage )); |
| |
| //get the number formatter of the data source |
| uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY); |
| uno::Reference< XNumberFormats > xNumberFormats; |
| if(xSourceProps.is()) |
| { |
| Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier")); |
| if(aFormats.hasValue()) |
| { |
| uno::Reference<XNumberFormatsSupplier> xSuppl; |
| aFormats >>= xSuppl; |
| if(xSuppl.is()) |
| { |
| xNumberFormats = xSuppl->getNumberFormats(); |
| } |
| } |
| } |
| bool bUseDefault = true; |
| try |
| { |
| Any aFormatKey = xColumn->getPropertyValue(C2U("FormatKey")); |
| if(aFormatKey.hasValue()) |
| { |
| sal_Int32 nFmt = 0; |
| aFormatKey >>= nFmt; |
| if(xNumberFormats.is()) |
| { |
| try |
| { |
| uno::Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFmt ); |
| Any aFormatString = xNumProps->getPropertyValue(C2U("FormatString")); |
| Any aLocaleVal = xNumProps->getPropertyValue(C2U("Locale")); |
| rtl::OUString sFormat; |
| aFormatString >>= sFormat; |
| lang::Locale aLoc; |
| aLocaleVal >>= aLoc; |
| nFmt = xDocNumberFormats->queryKey( sFormat, aLoc, sal_False ); |
| if(NUMBERFORMAT_ENTRY_NOT_FOUND == sal::static_int_cast< sal_uInt32, sal_Int32>(nFmt)) |
| nFmt = xDocNumberFormats->addNew( sFormat, aLoc ); |
| nRet = nFmt; |
| bUseDefault = false; |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR("illegal number format key"); |
| } |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR("no FormatKey property found"); |
| } |
| if(bUseDefault) |
| nRet = SwNewDBMgr::GetDbtoolsClient().getDefaultNumberFormat(xColumn, xDocNumberFormatTypes, aLocale); |
| } |
| return nRet; |
| } |
| |
| /* -----------------------------17.07.00 09:47-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Int32 SwNewDBMgr::GetColumnType( const String& rDBName, |
| const String& rTableName, |
| const String& rColNm ) |
| { |
| sal_Int32 nRet = DataType::SQLNULL; |
| SwDBData aData; |
| aData.sDataSource = rDBName; |
| aData.sCommand = rTableName; |
| aData.nCommandType = -1; |
| SwDSParam* pParam = FindDSData(aData, sal_False); |
| uno::Reference< XConnection> xConnection; |
| uno::Reference< XColumnsSupplier > xColsSupp; |
| bool bDispose = false; |
| if(pParam && pParam->xConnection.is()) |
| { |
| xConnection = pParam->xConnection; |
| xColsSupp = uno::Reference< XColumnsSupplier >( pParam->xResultSet, UNO_QUERY ); |
| } |
| else |
| { |
| rtl::OUString sDBName(rDBName); |
| xConnection = RegisterConnection( sDBName ); |
| } |
| if( !xColsSupp.is() ) |
| { |
| xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName); |
| bDispose = true; |
| } |
| if(xColsSupp.is()) |
| { |
| uno::Reference<XNameAccess> xCols = xColsSupp->getColumns(); |
| if(xCols->hasByName(rColNm)) |
| { |
| Any aCol = xCols->getByName(rColNm); |
| uno::Reference<XPropertySet> xCol; |
| aCol >>= xCol; |
| Any aType = xCol->getPropertyValue(C2S("Type")); |
| aType >>= nRet; |
| } |
| if(bDispose) |
| ::comphelper::disposeComponent( xColsSupp ); |
| } |
| return nRet; |
| } |
| |
| /* -----------------------------03.07.00 17:12-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| uno::Reference< sdbc::XConnection> SwNewDBMgr::GetConnection(const String& rDataSource, |
| uno::Reference<XDataSource>& rxSource) |
| { |
| Reference< sdbc::XConnection> xConnection; |
| Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| try |
| { |
| Reference<XCompletedConnection> xComplConnection(SwNewDBMgr::GetDbtoolsClient().getDataSource(rDataSource, xMgr),UNO_QUERY); |
| if ( xComplConnection.is() ) |
| { |
| rxSource.set(xComplConnection,UNO_QUERY); |
| Reference< XInteractionHandler > xHandler( |
| xMgr->createInstance( C2U( "com.sun.star.task.InteractionHandler" )), UNO_QUERY); |
| xConnection = xComplConnection->connectWithCompletion( xHandler ); |
| } |
| } |
| catch(Exception&) {} |
| |
| return xConnection; |
| } |
| /* -----------------------------03.07.00 17:12-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| uno::Reference< sdbcx::XColumnsSupplier> SwNewDBMgr::GetColumnSupplier(uno::Reference<sdbc::XConnection> xConnection, |
| const String& rTableOrQuery, |
| sal_uInt8 eTableOrQuery) |
| { |
| Reference< sdbcx::XColumnsSupplier> xRet; |
| try |
| { |
| if(eTableOrQuery == SW_DB_SELECT_UNKNOWN) |
| { |
| //search for a table with the given command name |
| Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY); |
| if(xTSupplier.is()) |
| { |
| Reference<XNameAccess> xTbls = xTSupplier->getTables(); |
| eTableOrQuery = xTbls->hasByName(rTableOrQuery) ? |
| SW_DB_SELECT_TABLE : SW_DB_SELECT_QUERY; |
| } |
| } |
| sal_Int32 nCommandType = SW_DB_SELECT_TABLE == eTableOrQuery ? |
| CommandType::TABLE : CommandType::QUERY; |
| Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| Reference<XRowSet> xRowSet( |
| xMgr->createInstance(C2U("com.sun.star.sdb.RowSet")), UNO_QUERY); |
| |
| ::rtl::OUString sDataSource; |
| Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection, sDataSource); |
| Reference<XPropertySet> xSourceProperties(xSource, UNO_QUERY); |
| if(xSourceProperties.is()) |
| { |
| xSourceProperties->getPropertyValue(C2U("Name")) >>= sDataSource; |
| } |
| |
| Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY); |
| xRowProperties->setPropertyValue(C2U("DataSourceName"), makeAny(sDataSource)); |
| xRowProperties->setPropertyValue(C2U("Command"), makeAny(::rtl::OUString(rTableOrQuery))); |
| xRowProperties->setPropertyValue(C2U("CommandType"), makeAny(nCommandType)); |
| xRowProperties->setPropertyValue(C2U("FetchSize"), makeAny((sal_Int32)10)); |
| xRowProperties->setPropertyValue(C2U("ActiveConnection"), makeAny(xConnection)); |
| xRowSet->execute(); |
| xRet = Reference<XColumnsSupplier>( xRowSet, UNO_QUERY ); |
| } |
| catch( const uno::Exception& ) |
| { |
| DBG_ERROR("Exception in SwDBMgr::GetColumnSupplier"); |
| } |
| |
| return xRet; |
| } |
| /* -----------------------------05.07.00 13:44-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| String SwNewDBMgr::GetDBField(uno::Reference<XPropertySet> xColumnProps, |
| const SwDBFormatData& rDBFormatData, |
| double* pNumber) |
| { |
| uno::Reference< XColumn > xColumn(xColumnProps, UNO_QUERY); |
| String sRet; |
| DBG_ASSERT(xColumn.is(), "SwNewDBMgr::::ImportDBField: illegal arguments"); |
| if(!xColumn.is()) |
| return sRet; |
| |
| Any aType = xColumnProps->getPropertyValue(C2U("Type")); |
| sal_Int32 eDataType = 0; |
| aType >>= eDataType; |
| switch(eDataType) |
| { |
| case DataType::CHAR: |
| case DataType::VARCHAR: |
| case DataType::LONGVARCHAR: |
| try |
| { |
| sRet = xColumn->getString(); |
| } |
| catch( SQLException& ) |
| { |
| } |
| break; |
| case DataType::BIT: |
| case DataType::BOOLEAN: |
| case DataType::TINYINT: |
| case DataType::SMALLINT: |
| case DataType::INTEGER: |
| case DataType::BIGINT: |
| case DataType::FLOAT: |
| case DataType::REAL: |
| case DataType::DOUBLE: |
| case DataType::NUMERIC: |
| case DataType::DECIMAL: |
| case DataType::DATE: |
| case DataType::TIME: |
| case DataType::TIMESTAMP: |
| { |
| // ::Date aTempDate(rDBFormatData.aNullDate.Day, |
| // rDBFormatData.aNullDate.Month, rDBFormatData.aNullDate.Year); |
| |
| try |
| { |
| SwDbtoolsClient& aClient = SwNewDBMgr::GetDbtoolsClient(); |
| sRet = aClient.getFormattedValue( |
| xColumnProps, |
| rDBFormatData.xFormatter, |
| rDBFormatData.aLocale, |
| rDBFormatData.aNullDate); |
| if (pNumber) |
| { |
| double fVal = xColumn->getDouble(); |
| if(!xColumn->wasNull()) |
| { |
| *pNumber = fVal; |
| } |
| } |
| } |
| catch(Exception& ) |
| { |
| DBG_ERROR("exception caught"); |
| } |
| |
| } |
| break; |
| |
| // case DataType::BINARY: |
| // case DataType::VARBINARY: |
| // case DataType::LONGVARBINARY: |
| // case DataType::SQLNULL: |
| // case DataType::OTHER: |
| // case DataType::OBJECT: |
| // case DataType::DISTINCT: |
| // case DataType::STRUCT: |
| // case DataType::ARRAY: |
| // case DataType::BLOB: |
| // case DataType::CLOB: |
| // case DataType::REF: |
| // default: |
| } |
| // if (pFormat) |
| // { |
| // SFX_ITEMSET_GET(*pCol, pFormatItem, SfxUInt32Item, SBA_DEF_FMTVALUE, sal_True); |
| // *pFormat = pFormatItem->GetValue(); |
| // } |
| |
| return sRet; |
| } |
| /* -----------------------------06.07.00 14:28-------------------------------- |
| releases the merge data source table or query after merge is completed |
| ---------------------------------------------------------------------------*/ |
| void SwNewDBMgr::EndMerge() |
| { |
| DBG_ASSERT(bInMerge, "merge is not active"); |
| bInMerge = sal_False; |
| delete pImpl->pMergeData; |
| pImpl->pMergeData = 0; |
| } |
| /* -----------------------------06.07.00 14:28-------------------------------- |
| checks if a desired data source table or query is open |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::IsDataSourceOpen(const String& rDataSource, |
| const String& rTableOrQuery, sal_Bool bMergeOnly) |
| { |
| if(pImpl->pMergeData) |
| { |
| return !bMergeLock && |
| ((rDataSource == (String)pImpl->pMergeData->sDataSource && |
| rTableOrQuery == (String)pImpl->pMergeData->sCommand) |
| ||(!rDataSource.Len() && !rTableOrQuery.Len())) |
| && |
| pImpl->pMergeData->xResultSet.is(); |
| } |
| else if(!bMergeOnly) |
| { |
| SwDBData aData; |
| aData.sDataSource = rDataSource; |
| aData.sCommand = rTableOrQuery; |
| aData.nCommandType = -1; |
| SwDSParam* pFound = FindDSData(aData, sal_False); |
| return (pFound && pFound->xResultSet.is()); |
| } |
| return sal_False; |
| } |
| /* -----------------------------17.07.00 16:44-------------------------------- |
| read column data a a specified position |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::GetColumnCnt(const String& rSourceName, const String& rTableName, |
| const String& rColumnName, sal_uInt32 nAbsRecordId, |
| long nLanguage, |
| String& rResult, double* pNumber) |
| { |
| sal_Bool bRet = sal_False; |
| SwDSParam* pFound = 0; |
| //check if it's the merge data source |
| if(pImpl->pMergeData && |
| rSourceName == (String)pImpl->pMergeData->sDataSource && |
| rTableName == (String)pImpl->pMergeData->sCommand) |
| { |
| pFound = pImpl->pMergeData; |
| } |
| else |
| { |
| SwDBData aData; |
| aData.sDataSource = rSourceName; |
| aData.sCommand = rTableName; |
| aData.nCommandType = -1; |
| pFound = FindDSData(aData, sal_False); |
| } |
| //check validity of supplied record Id |
| if(pFound->aSelection.getLength()) |
| { |
| //the destination has to be an element of the selection |
| const Any* pSelection = pFound->aSelection.getConstArray(); |
| sal_Bool bFound = sal_False; |
| for(sal_Int32 nPos = 0; !bFound && nPos < pFound->aSelection.getLength(); nPos++) |
| { |
| sal_Int32 nSelection = 0; |
| pSelection[nPos] >>= nSelection; |
| if(nSelection == static_cast<sal_Int32>(nAbsRecordId)) |
| bFound = sal_True; |
| } |
| if(!bFound) |
| return sal_False; |
| } |
| if(pFound && pFound->xResultSet.is() && !pFound->bAfterSelection) |
| { |
| sal_Int32 nOldRow = 0; |
| try |
| { |
| nOldRow = pFound->xResultSet->getRow(); |
| } |
| catch(const Exception& ) |
| { |
| return sal_False; |
| } |
| //position to the desired index |
| sal_Bool bMove = sal_True; |
| if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) ) |
| bMove = lcl_MoveAbsolute(pFound, nAbsRecordId); |
| if(bMove) |
| { |
| bRet = lcl_GetColumnCnt(pFound, rColumnName, nLanguage, rResult, pNumber); |
| } |
| if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) ) |
| bMove = lcl_MoveAbsolute(pFound, nOldRow); |
| } |
| return bRet; |
| } |
| /* -----------------------------06.07.00 16:47-------------------------------- |
| reads the column data at the current position |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::GetMergeColumnCnt(const String& rColumnName, sal_uInt16 nLanguage, |
| String &rResult, double *pNumber, sal_uInt32 * /*pFormat*/) |
| { |
| if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is() || pImpl->pMergeData->bAfterSelection ) |
| { |
| rResult.Erase(); |
| return sal_False; |
| } |
| |
| sal_Bool bRet = lcl_GetColumnCnt(pImpl->pMergeData, rColumnName, nLanguage, rResult, pNumber); |
| return bRet; |
| } |
| /* -----------------------------07.07.00 14:28-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::ToNextMergeRecord() |
| { |
| DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge"); |
| return ToNextRecord(pImpl->pMergeData); |
| } |
| /* -----------------------------10.07.01 14:28-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::ToNextRecord( |
| const String& rDataSource, const String& rCommand, sal_Int32 /*nCommandType*/) |
| { |
| SwDSParam* pFound = 0; |
| if(pImpl->pMergeData && |
| rDataSource == (String)pImpl->pMergeData->sDataSource && |
| rCommand == (String)pImpl->pMergeData->sCommand) |
| pFound = pImpl->pMergeData; |
| else |
| { |
| SwDBData aData; |
| aData.sDataSource = rDataSource; |
| aData.sCommand = rCommand; |
| aData.nCommandType = -1; |
| pFound = FindDSData(aData, sal_False); |
| } |
| return ToNextRecord(pFound); |
| } |
| /* -----------------------------10.07.01 14:38-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::ToNextRecord(SwDSParam* pParam) |
| { |
| sal_Bool bRet = sal_True; |
| if(!pParam || !pParam->xResultSet.is() || pParam->bEndOfDB || |
| (pParam->aSelection.getLength() && pParam->aSelection.getLength() <= pParam->nSelectionIndex)) |
| { |
| if(pParam) |
| pParam->CheckEndOfDB(); |
| return sal_False; |
| } |
| try |
| { |
| if(pParam->aSelection.getLength()) |
| { |
| sal_Int32 nPos = 0; |
| pParam->aSelection.getConstArray()[ pParam->nSelectionIndex++ ] >>= nPos; |
| pParam->bEndOfDB = !pParam->xResultSet->absolute( nPos ); |
| pParam->CheckEndOfDB(); |
| bRet = !pParam->bEndOfDB; |
| if(pParam->nSelectionIndex >= pParam->aSelection.getLength()) |
| pParam->bEndOfDB = sal_True; |
| } |
| else |
| { |
| sal_Int32 nBefore = pParam->xResultSet->getRow(); |
| pParam->bEndOfDB = !pParam->xResultSet->next(); |
| if( !pParam->bEndOfDB && nBefore == pParam->xResultSet->getRow()) |
| { |
| //next returned true but it didn't move |
| pParam->bEndOfDB = sal_True; |
| } |
| |
| pParam->CheckEndOfDB(); |
| bRet = !pParam->bEndOfDB; |
| ++pParam->nSelectionIndex; |
| } |
| } |
| catch(Exception&) |
| { |
| } |
| return bRet; |
| } |
| |
| /* -----------------------------13.07.00 17:23-------------------------------- |
| synchronized labels contain a next record field at their end |
| to assure that the next page can be created in mail merge |
| the cursor position must be validated |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::ExistsNextRecord() const |
| { |
| return pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB; |
| } |
| /* -----------------------------13.07.00 10:41-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_uInt32 SwNewDBMgr::GetSelectedRecordId() |
| { |
| sal_uInt32 nRet = 0; |
| DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge"); |
| if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()) |
| return sal_False; |
| try |
| { |
| nRet = pImpl->pMergeData->xResultSet->getRow(); |
| } |
| catch(Exception& ) |
| { |
| } |
| return nRet; |
| } |
| /* -----------------------------13.07.00 10:58-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::ToRecordId(sal_Int32 nSet) |
| { |
| DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge"); |
| if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()|| nSet < 0) |
| return sal_False; |
| sal_Bool bRet = sal_False; |
| sal_Int32 nAbsPos = nSet; |
| |
| if(nAbsPos >= 0) |
| { |
| bRet = lcl_MoveAbsolute(pImpl->pMergeData, nAbsPos); |
| pImpl->pMergeData->bEndOfDB = !bRet; |
| pImpl->pMergeData->CheckEndOfDB(); |
| } |
| return bRet; |
| } |
| |
| /* -----------------------------17.07.00 14:17-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwNewDBMgr::OpenDataSource(const String& rDataSource, const String& rTableOrQuery, |
| sal_Int32 nCommandType, bool bCreate) |
| { |
| SwDBData aData; |
| aData.sDataSource = rDataSource; |
| aData.sCommand = rTableOrQuery; |
| aData.nCommandType = nCommandType; |
| |
| SwDSParam* pFound = FindDSData(aData, sal_True); |
| uno::Reference< XDataSource> xSource; |
| if(pFound->xResultSet.is()) |
| return sal_True; |
| SwDSParam* pParam = FindDSConnection(rDataSource, sal_False); |
| uno::Reference< XConnection> xConnection; |
| if(pParam && pParam->xConnection.is()) |
| pFound->xConnection = pParam->xConnection; |
| else if(bCreate) |
| { |
| rtl::OUString sDataSource(rDataSource); |
| pFound->xConnection = RegisterConnection( sDataSource ); |
| } |
| if(pFound->xConnection.is()) |
| { |
| try |
| { |
| uno::Reference< sdbc::XDatabaseMetaData > xMetaData = pFound->xConnection->getMetaData(); |
| try |
| { |
| pFound->bScrollable = xMetaData |
| ->supportsResultSetType((sal_Int32)ResultSetType::SCROLL_INSENSITIVE); |
| } |
| catch(Exception&) |
| { |
| //#98373# DB driver may not be ODBC 3.0 compliant |
| pFound->bScrollable = sal_True; |
| } |
| pFound->xStatement = pFound->xConnection->createStatement(); |
| rtl::OUString aQuoteChar = xMetaData->getIdentifierQuoteString(); |
| rtl::OUString sStatement(C2U("SELECT * FROM ")); |
| sStatement = C2U("SELECT * FROM "); |
| sStatement += aQuoteChar; |
| sStatement += rTableOrQuery; |
| sStatement += aQuoteChar; |
| pFound->xResultSet = pFound->xStatement->executeQuery( sStatement ); |
| |
| //after executeQuery the cursor must be positioned |
| pFound->bEndOfDB = !pFound->xResultSet->next(); |
| pFound->bAfterSelection = sal_False; |
| pFound->CheckEndOfDB(); |
| ++pFound->nSelectionIndex; |
| } |
| catch (Exception&) |
| { |
| pFound->xResultSet = 0; |
| pFound->xStatement = 0; |
| pFound->xConnection = 0; |
| } |
| } |
| return pFound->xResultSet.is(); |
| } |
| /* -----------------------------14.08.2001 10:26------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| uno::Reference< XConnection> SwNewDBMgr::RegisterConnection(rtl::OUString& rDataSource) |
| { |
| SwDSParam* pFound = SwNewDBMgr::FindDSConnection(rDataSource, sal_True); |
| uno::Reference< XDataSource> xSource; |
| if(!pFound->xConnection.is()) |
| { |
| pFound->xConnection = SwNewDBMgr::GetConnection(rDataSource, xSource ); |
| try |
| { |
| uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY); |
| if(xComponent.is()) |
| xComponent->addEventListener(pImpl->xDisposeListener); |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| return pFound->xConnection; |
| } |
| /* -----------------------------17.07.00 15:55-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_uInt32 SwNewDBMgr::GetSelectedRecordId( |
| const String& rDataSource, const String& rTableOrQuery, sal_Int32 nCommandType) |
| { |
| sal_uInt32 nRet = 0xffffffff; |
| //check for merge data source first |
| if(pImpl->pMergeData && rDataSource == (String)pImpl->pMergeData->sDataSource && |
| rTableOrQuery == (String)pImpl->pMergeData->sCommand && |
| (nCommandType == -1 || nCommandType == pImpl->pMergeData->nCommandType) && |
| pImpl->pMergeData->xResultSet.is()) |
| nRet = GetSelectedRecordId(); |
| else |
| { |
| SwDBData aData; |
| aData.sDataSource = rDataSource; |
| aData.sCommand = rTableOrQuery; |
| aData.nCommandType = nCommandType; |
| SwDSParam* pFound = FindDSData(aData, sal_False); |
| if(pFound && pFound->xResultSet.is()) |
| { |
| try |
| { //if a selection array is set the current row at the result set may not be set yet |
| if(pFound->aSelection.getLength()) |
| { |
| sal_Int32 nSelIndex = pFound->nSelectionIndex; |
| if(nSelIndex >= pFound->aSelection.getLength()) |
| nSelIndex = pFound->aSelection.getLength() -1; |
| pFound->aSelection.getConstArray()[nSelIndex] >>= nRet; |
| |
| } |
| else |
| nRet = pFound->xResultSet->getRow(); |
| } |
| catch(Exception&){} |
| } |
| } |
| return nRet; |
| } |
| |
| /* -----------------------------17.07.00 14:18-------------------------------- |
| close all data sources - after fields were updated |
| ---------------------------------------------------------------------------*/ |
| void SwNewDBMgr::CloseAll(sal_Bool bIncludingMerge) |
| { |
| //the only thing done here is to reset the selection index |
| //all connections stay open |
| for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) |
| { |
| SwDSParam* pParam = aDataSourceParams[nPos]; |
| if(bIncludingMerge || pParam != pImpl->pMergeData) |
| { |
| pParam->nSelectionIndex = 0; |
| pParam->bAfterSelection = sal_False; |
| pParam->bEndOfDB = sal_False; |
| try |
| { |
| if(!bInMerge && pParam->xResultSet.is()) |
| pParam->xResultSet->first(); |
| } |
| catch(Exception& ) |
| {} |
| } |
| } |
| } |
| /* -----------------------------17.07.00 14:54-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| SwDSParam* SwNewDBMgr::FindDSData(const SwDBData& rData, sal_Bool bCreate) |
| { |
| //prefer merge data if available |
| if(pImpl->pMergeData && rData.sDataSource == pImpl->pMergeData->sDataSource && |
| rData.sCommand == pImpl->pMergeData->sCommand && |
| (rData.nCommandType == -1 || rData.nCommandType == pImpl->pMergeData->nCommandType || |
| (bCreate && pImpl->pMergeData->nCommandType == -1))) |
| { |
| return pImpl->pMergeData; |
| } |
| |
| SwDSParam* pFound = 0; |
| for(sal_uInt16 nPos = aDataSourceParams.Count(); nPos; nPos--) |
| { |
| SwDSParam* pParam = aDataSourceParams[nPos - 1]; |
| if(rData.sDataSource == pParam->sDataSource && |
| rData.sCommand == pParam->sCommand && |
| (rData.nCommandType == -1 || rData.nCommandType == pParam->nCommandType || |
| (bCreate && pParam->nCommandType == -1))) |
| { |
| //#94779# calls from the calculator may add a connection with an invalid commandtype |
| //later added "real" data base connections have to re-use the already available |
| //DSData and set the correct CommandType |
| if(bCreate && pParam->nCommandType == -1) |
| pParam->nCommandType = rData.nCommandType; |
| pFound = pParam; |
| break; |
| } |
| } |
| if(bCreate) |
| { |
| if(!pFound) |
| { |
| pFound = new SwDSParam(rData); |
| aDataSourceParams.Insert(pFound, aDataSourceParams.Count()); |
| try |
| { |
| uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY); |
| if(xComponent.is()) |
| xComponent->addEventListener(pImpl->xDisposeListener); |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| } |
| return pFound; |
| } |
| /* -----------------------------14.08.2001 10:27------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| |
| SwDSParam* SwNewDBMgr::FindDSConnection(const rtl::OUString& rDataSource, sal_Bool bCreate) |
| { |
| //prefer merge data if available |
| if(pImpl->pMergeData && rDataSource == pImpl->pMergeData->sDataSource ) |
| { |
| return pImpl->pMergeData; |
| } |
| SwDSParam* pFound = 0; |
| for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) |
| { |
| SwDSParam* pParam = aDataSourceParams[nPos]; |
| if(rDataSource == pParam->sDataSource) |
| { |
| pFound = pParam; |
| break; |
| } |
| } |
| if(bCreate && !pFound) |
| { |
| SwDBData aData; |
| aData.sDataSource = rDataSource; |
| pFound = new SwDSParam(aData); |
| aDataSourceParams.Insert(pFound, aDataSourceParams.Count()); |
| try |
| { |
| uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY); |
| if(xComponent.is()) |
| xComponent->addEventListener(pImpl->xDisposeListener); |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| return pFound; |
| } |
| |
| /* -----------------------------17.07.00 14:34-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| const SwDBData& SwNewDBMgr::GetAddressDBName() |
| { |
| return SW_MOD()->GetDBConfig()->GetAddressSource(); |
| } |
| /* -----------------------------18.07.00 13:13-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| Sequence<rtl::OUString> SwNewDBMgr::GetExistingDatabaseNames() |
| { |
| uno::Reference<XNameAccess> xDBContext; |
| uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| if( xMgr.is() ) |
| { |
| uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" )); |
| xDBContext = uno::Reference<XNameAccess>(xInstance, UNO_QUERY) ; |
| } |
| if(xDBContext.is()) |
| { |
| return xDBContext->getElementNames(); |
| } |
| return Sequence<rtl::OUString>(); |
| } |
| /*-- 26.05.2004 14:33:13--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| String SwNewDBMgr::LoadAndRegisterDataSource() |
| { |
| sfx2::FileDialogHelper aDlgHelper( TemplateDescription::FILEOPEN_SIMPLE, 0 ); |
| Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker(); |
| |
| String sHomePath(SvtPathOptions().GetWorkPath()); |
| aDlgHelper.SetDisplayDirectory( sHomePath ); |
| |
| Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY); |
| |
| String sFilterAll(SW_RES(STR_FILTER_ALL)); |
| String sFilterAllData(SW_RES(STR_FILTER_ALL_DATA)); |
| String sFilterSXB(SW_RES(STR_FILTER_SXB)); |
| String sFilterSXC(SW_RES(STR_FILTER_SXC)); |
| String sFilterDBF(SW_RES(STR_FILTER_DBF)); |
| String sFilterXLS(SW_RES(STR_FILTER_XLS)); |
| String sFilterTXT(SW_RES(STR_FILTER_TXT)); |
| String sFilterCSV(SW_RES(STR_FILTER_CSV)); |
| #ifdef WNT |
| String sFilterMDB(SW_RES(STR_FILTER_MDB)); |
| String sFilterACCDB(SW_RES(STR_FILTER_ACCDB)); |
| #endif |
| xFltMgr->appendFilter( sFilterAll, C2U("*") ); |
| xFltMgr->appendFilter( sFilterAllData, C2U("*.ods;*.sxc;*.dbf;*.xls;*.txt;*.csv")); |
| |
| xFltMgr->appendFilter( sFilterSXB, C2U("*.odb") ); |
| xFltMgr->appendFilter( sFilterSXC, C2U("*.ods;*.sxc") ); |
| xFltMgr->appendFilter( sFilterDBF, C2U("*.dbf") ); |
| xFltMgr->appendFilter( sFilterXLS, C2U("*.xls") ); |
| xFltMgr->appendFilter( sFilterTXT, C2U("*.txt") ); |
| xFltMgr->appendFilter( sFilterCSV, C2U("*.csv") ); |
| #ifdef WNT |
| xFltMgr->appendFilter( sFilterMDB, C2U("*.mdb") ); |
| xFltMgr->appendFilter( sFilterACCDB, C2U("*.accdb") ); |
| #endif |
| |
| xFltMgr->setCurrentFilter( sFilterAll ) ; |
| String sFind; |
| bool bTextConnection = false; |
| if( ERRCODE_NONE == aDlgHelper.Execute() ) |
| { |
| String sURL = xFP->getFiles().getConstArray()[0]; |
| //data sources have to be registered depending on their extensions |
| INetURLObject aURL( sURL ); |
| String sExt( aURL.GetExtension() ); |
| Any aURLAny; |
| Any aTableFilterAny; |
| Any aSuppressVersionsAny; |
| Any aInfoAny; |
| INetURLObject aTempURL(aURL); |
| bool bStore = true; |
| if(sExt.EqualsAscii("odb")) |
| { |
| bStore = false; |
| } |
| else if(sExt.EqualsIgnoreCaseAscii("sxc") |
| || sExt.EqualsIgnoreCaseAscii("ods") |
| || sExt.EqualsIgnoreCaseAscii("xls")) |
| { |
| rtl::OUString sDBURL(C2U("sdbc:calc:")); |
| sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE); |
| aURLAny <<= sDBURL; |
| } |
| else if(sExt.EqualsIgnoreCaseAscii("dbf")) |
| { |
| aTempURL.removeSegment(); |
| aTempURL.removeFinalSlash(); |
| rtl::OUString sDBURL(C2U("sdbc:dbase:")); |
| sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE); |
| aURLAny <<= sDBURL; |
| //set the filter to the file name without extension |
| Sequence<rtl::OUString> aFilters(1); |
| rtl::OUString sTmp(aURL.getBase()); |
| aFilters[0] = aURL.getBase(); |
| aTableFilterAny <<= aFilters; |
| } |
| else if(sExt.EqualsIgnoreCaseAscii("csv") || sExt.EqualsIgnoreCaseAscii("txt")) |
| { |
| aTempURL.removeSegment(); |
| aTempURL.removeFinalSlash(); |
| rtl::OUString sDBURL(C2U("sdbc:flat:")); |
| //only the 'path' has to be added |
| sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE); |
| aURLAny <<= sDBURL; |
| |
| bTextConnection = true; |
| //set the filter to the file name without extension |
| Sequence<rtl::OUString> aFilters(1); |
| rtl::OUString sTmp(aURL.getBase()); |
| aFilters[0] = aURL.getBase(); |
| aTableFilterAny <<= aFilters; |
| } |
| #ifdef WNT |
| else if(sExt.EqualsIgnoreCaseAscii("mdb")) |
| { |
| rtl::OUString sDBURL(C2U("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=")); |
| sDBURL += aTempURL.PathToFileName(); |
| aURLAny <<= sDBURL; |
| aSuppressVersionsAny <<= makeAny(true); |
| } |
| else if(sExt.EqualsIgnoreCaseAscii("accdb")) |
| { |
| rtl::OUString sDBURL(C2U("sdbc:ado:PROVIDER=Microsoft.ACE.OLEDB.12.0;DATA SOURCE=")); |
| sDBURL += aTempURL.PathToFileName(); |
| aURLAny <<= sDBURL; |
| aSuppressVersionsAny <<= makeAny(true); |
| } |
| #endif |
| try |
| { |
| Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" )); |
| Reference<XNameAccess> xDBContext(xInstance, UNO_QUERY_THROW); |
| Reference<XSingleServiceFactory> xFact( xDBContext, UNO_QUERY); |
| |
| String sNewName = INetURLObject::decode( aURL.getName(), |
| INET_HEX_ESCAPE, |
| INetURLObject::DECODE_UNAMBIGUOUS, |
| RTL_TEXTENCODING_UTF8 ); |
| xub_StrLen nExtLen = static_cast< xub_StrLen >(aURL.GetExtension().getLength()); |
| sNewName.Erase( sNewName.Len() - nExtLen - 1, nExtLen + 1 ); |
| |
| //find a unique name if sNewName already exists |
| sFind = sNewName; |
| sal_Int32 nIndex = 0; |
| while(xDBContext->hasByName(sFind)) |
| { |
| sFind = sNewName; |
| sFind += String::CreateFromInt32(++nIndex); |
| } |
| |
| Reference<XInterface> xNewInstance; |
| if(!bStore) |
| { |
| //odb-file |
| Any aDataSource = xDBContext->getByName(aTempURL.GetMainURL(INetURLObject::NO_DECODE)); |
| aDataSource >>= xNewInstance; |
| } |
| else |
| { |
| xNewInstance = xFact->createInstance(); |
| Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY); |
| |
| if(aURLAny.hasValue()) |
| xDataProperties->setPropertyValue(C2U("URL"), aURLAny); |
| if(aTableFilterAny.hasValue()) |
| xDataProperties->setPropertyValue(C2U("TableFilter"), aTableFilterAny); |
| if(aSuppressVersionsAny.hasValue()) |
| xDataProperties->setPropertyValue(C2U("SuppressVersionColumns"), aSuppressVersionsAny); |
| if(aInfoAny.hasValue()) |
| xDataProperties->setPropertyValue(C2U("Info"), aInfoAny); |
| |
| if( bTextConnection ) |
| { |
| uno::Reference < ui::dialogs::XExecutableDialog > xSettingsDlg( |
| xMgr->createInstance( C2U( "com.sun.star.sdb.TextConnectionSettings" ) ), uno::UNO_QUERY); |
| if( xSettingsDlg->execute() ) |
| { |
| uno::Any aSettings = xDataProperties->getPropertyValue( C2U( "Settings" ) ); |
| uno::Reference < beans::XPropertySet > xDSSettings; |
| aSettings >>= xDSSettings; |
| ::comphelper::copyProperties( |
| uno::Reference < beans::XPropertySet >( xSettingsDlg, uno::UNO_QUERY ), |
| xDSSettings ); |
| xDSSettings->setPropertyValue( C2U("Extension"), uno::makeAny( ::rtl::OUString( sExt ))); |
| } |
| } |
| |
| Reference<XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW); |
| Reference<XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW); |
| String sOutputExt = String::CreateFromAscii(".odb"); |
| String sTmpName; |
| { |
| utl::TempFile aTempFile(sNewName , &sOutputExt, &sHomePath); |
| aTempFile.EnableKillingFile(sal_True); |
| sTmpName = aTempFile.GetURL(); |
| } |
| xStore->storeAsURL(sTmpName, Sequence< PropertyValue >()); |
| } |
| Reference<XNamingService> xNaming(xDBContext, UNO_QUERY); |
| xNaming->registerObject( sFind, xNewInstance ); |
| |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| return sFind; |
| |
| } |
| /* -----------------------------10.11.00 17:10-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwNewDBMgr::ExecuteFormLetter( SwWrtShell& rSh, |
| const Sequence<PropertyValue>& rProperties, |
| sal_Bool bWithDataSourceBrowser) |
| { |
| //prevent second call |
| if(pImpl->pMergeDialog) |
| return ; |
| rtl::OUString sDataSource, sDataTableOrQuery; |
| Sequence<Any> aSelection; |
| |
| sal_Int32 nCmdType = CommandType::TABLE; |
| uno::Reference< XConnection> xConnection; |
| |
| ODataAccessDescriptor aDescriptor(rProperties); |
| sDataSource = aDescriptor.getDataSource(); |
| aDescriptor[daCommand] >>= sDataTableOrQuery; |
| aDescriptor[daCommandType] >>= nCmdType; |
| |
| if ( aDescriptor.has(daSelection) ) |
| aDescriptor[daSelection] >>= aSelection; |
| if ( aDescriptor.has(daConnection) ) |
| aDescriptor[daConnection] >>= xConnection; |
| |
| if(!sDataSource.getLength() || !sDataTableOrQuery.getLength()) |
| { |
| DBG_ERROR("PropertyValues missing or unset"); |
| return; |
| } |
| |
| //always create a connection for the dialog and dispose it after the dialog has been closed |
| SwDSParam* pFound = 0; |
| if(!xConnection.is()) |
| { |
| xConnection = SwNewDBMgr::RegisterConnection(sDataSource); |
| pFound = FindDSConnection(sDataSource, sal_True); |
| } |
| SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); |
| DBG_ASSERT(pFact, "Dialogdiet fail!"); |
| pImpl->pMergeDialog = pFact->CreateMailMergeDlg( DLG_MAILMERGE, |
| &rSh.GetView().GetViewFrame()->GetWindow(), rSh, |
| sDataSource, |
| sDataTableOrQuery, |
| nCmdType, |
| xConnection, |
| bWithDataSourceBrowser ? 0 : &aSelection); |
| DBG_ASSERT(pImpl->pMergeDialog, "Dialogdiet fail!"); |
| if(pImpl->pMergeDialog->Execute() == RET_OK) |
| { |
| aDescriptor[daSelection] <<= pImpl->pMergeDialog->GetSelection(); |
| |
| uno::Reference<XResultSet> xResSet = pImpl->pMergeDialog->GetResultSet(); |
| if(xResSet.is()) |
| aDescriptor[daCursor] <<= xResSet; |
| |
| // SfxObjectShellRef is ok, since there should be no control over the document lifetime here |
| SfxObjectShellRef xDocShell = rSh.GetView().GetViewFrame()->GetObjectShell(); |
| SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xDocShell)); |
| { |
| //copy rSh to aTempFile |
| ::rtl::OUString sTempURL; |
| const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat( |
| String::CreateFromAscii( FILTER_XML ), |
| SwDocShell::Factory().GetFilterContainer() ); |
| try |
| { |
| |
| uno::Sequence< beans::PropertyValue > aValues(1); |
| beans::PropertyValue* pValues = aValues.getArray(); |
| pValues[0].Name = C2U("FilterName"); |
| pValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName()); |
| uno::Reference< frame::XStorable > xStore( xDocShell->GetModel(), uno::UNO_QUERY); |
| sTempURL = URIHelper::SmartRel2Abs( INetURLObject(), utl::TempFile::CreateTempName() ); |
| xStore->storeToURL( sTempURL, aValues ); |
| } |
| catch( const uno::Exception& rEx ) |
| { |
| (void) rEx; |
| } |
| if( xDocShell->GetError() ) |
| { |
| // error message ?? |
| ErrorHandler::HandleError( xDocShell->GetError() ); |
| } |
| else |
| { |
| // the shell will be explicitly closed, but it is more safe to use SfxObjectShellLock here |
| // especially for the case that the loading has failed |
| SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); |
| SfxMedium* pWorkMed = new SfxMedium( sTempURL, STREAM_STD_READ, sal_True ); |
| pWorkMed->SetFilter( pSfxFlt ); |
| if( xWorkDocSh->DoLoad(pWorkMed) ) |
| { |
| SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 ); |
| SwView *pView = (SwView*) pFrame->GetViewShell(); |
| pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird. |
| //set the current DBMgr |
| SwDoc* pWorkDoc = pView->GetWrtShell().GetDoc(); |
| SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr(); |
| pWorkDoc->SetNewDBMgr( this ); |
| |
| SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), pView->GetWrtShell(), aDescriptor ); |
| aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter(); |
| aMergeDesc.bCreateSingleFile = !pImpl->pMergeDialog->IsSaveIndividualDocs(); |
| if( !aMergeDesc.bCreateSingleFile && pImpl->pMergeDialog->IsGenerateFromDataBase() ) |
| { |
| aMergeDesc.sAddressFromColumn = pImpl->pMergeDialog->GetColumnName(); |
| aMergeDesc.sSubject = pImpl->pMergeDialog->GetPath(); |
| } |
| |
| MergeNew(aMergeDesc); |
| |
| pWorkDoc->SetNewDBMgr( pWorkDBMgr ); |
| //close the temporary file |
| uno::Reference< util::XCloseable > xClose( xWorkDocSh->GetModel(), uno::UNO_QUERY ); |
| if (xClose.is()) |
| { |
| try |
| { |
| //! 'sal_True' -> transfer ownership to vetoing object if vetoed! |
| //! I.e. now that object is responsible for closing the model and doc shell. |
| xClose->close( sal_True ); |
| } |
| catch ( const uno::Exception& ) |
| { |
| } |
| } |
| } |
| } |
| //remove the temporary file |
| SWUnoHelper::UCB_DeleteFile( sTempURL ); |
| } |
| SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), rSh.GetView().GetViewFrame()->GetObjectShell())); |
| |
| // reset the cursor inside |
| xResSet = NULL; |
| aDescriptor[daCursor] <<= xResSet; |
| } |
| if(pFound) |
| { |
| for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++) |
| { |
| SwDSParam* pParam = aDataSourceParams[nPos]; |
| if(pParam == pFound) |
| { |
| try |
| { |
| uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY); |
| if(xComp.is()) |
| xComp->dispose(); |
| } |
| catch(const RuntimeException& ) |
| { |
| //may be disposed already since multiple entries may have used the same connection |
| } |
| break; |
| } |
| //pFound doesn't need to be removed/deleted - |
| //this has been done by the SwConnectionDisposedListener_Impl already |
| } |
| } |
| DELETEZ(pImpl->pMergeDialog); |
| } |
| /* -----------------------------13.11.00 08:20-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwNewDBMgr::InsertText(SwWrtShell& rSh, |
| const Sequence< PropertyValue>& rProperties) |
| { |
| rtl::OUString sDataSource, sDataTableOrQuery; |
| uno::Reference<XResultSet> xResSet; |
| Sequence<Any> aSelection; |
| sal_Bool bHasSelectionProperty = sal_False; |
| sal_Int32 nSelectionPos = 0; |
| sal_Int16 nCmdType = CommandType::TABLE; |
| const PropertyValue* pValues = rProperties.getConstArray(); |
| uno::Reference< XConnection> xConnection; |
| for(sal_Int32 nPos = 0; nPos < rProperties.getLength(); nPos++) |
| { |
| if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cDataSourceName))) |
| pValues[nPos].Value >>= sDataSource; |
| else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommand))) |
| pValues[nPos].Value >>= sDataTableOrQuery; |
| else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCursor))) |
| pValues[nPos].Value >>= xResSet; |
| else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cSelection))) |
| { |
| bHasSelectionProperty = sal_True; |
| nSelectionPos = nPos; |
| pValues[nPos].Value >>= aSelection; |
| } |
| else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommandType))) |
| pValues[nPos].Value >>= nCmdType; |
| else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cActiveConnection))) |
| pValues[nPos].Value >>= xConnection; |
| } |
| if(!sDataSource.getLength() || !sDataTableOrQuery.getLength() || !xResSet.is()) |
| { |
| DBG_ERROR("PropertyValues missing or unset"); |
| return; |
| } |
| uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| uno::Reference<XDataSource> xSource; |
| uno::Reference<XChild> xChild(xConnection, UNO_QUERY); |
| if(xChild.is()) |
| xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY); |
| if(!xSource.is()) |
| xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(sDataSource, xMgr); |
| uno::Reference< XColumnsSupplier > xColSupp( xResSet, UNO_QUERY ); |
| SwDBData aDBData; |
| aDBData.sDataSource = sDataSource; |
| aDBData.sCommand = sDataTableOrQuery; |
| aDBData.nCommandType = nCmdType; |
| |
| SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); |
| DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!"); |
| |
| AbstractSwInsertDBColAutoPilot* pDlg = pFact->CreateSwInsertDBColAutoPilot( rSh.GetView(), |
| xSource, |
| xColSupp, |
| aDBData, |
| DLG_AP_INSERT_DB_SEL ); |
| DBG_ASSERT(pDlg, "Dialogdiet fail!"); |
| if( RET_OK == pDlg->Execute() ) |
| { |
| rtl::OUString sDummy; |
| if(!xConnection.is()) |
| xConnection = xSource->getConnection(sDummy, sDummy); |
| try |
| { |
| pDlg->DataToDoc( aSelection , xSource, xConnection, xResSet); |
| } |
| catch(Exception& ) |
| { |
| DBG_ERROR("exception caught"); |
| } |
| } |
| delete pDlg; |
| |
| } |
| /* -----------------------------30.08.2001 12:00------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| SwDbtoolsClient* SwNewDBMgr::pDbtoolsClient = NULL; |
| |
| SwDbtoolsClient& SwNewDBMgr::GetDbtoolsClient() |
| { |
| if ( !pDbtoolsClient ) |
| pDbtoolsClient = new SwDbtoolsClient; |
| return *pDbtoolsClient; |
| } |
| /* -----------------13.05.2003 15:34----------------- |
| |
| --------------------------------------------------*/ |
| void SwNewDBMgr::RemoveDbtoolsClient() |
| { |
| delete pDbtoolsClient; |
| pDbtoolsClient = 0; |
| } |
| /* -----------------------------20.08.2002 12:00------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| uno::Reference<XDataSource> SwNewDBMgr::getDataSourceAsParent(const uno::Reference< XConnection>& _xConnection,const ::rtl::OUString& _sDataSourceName) |
| { |
| uno::Reference<XDataSource> xSource; |
| try |
| { |
| uno::Reference<XChild> xChild(_xConnection, UNO_QUERY); |
| if ( xChild.is() ) |
| xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY); |
| if ( !xSource.is() ) |
| xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(_sDataSourceName, ::comphelper::getProcessServiceFactory()); |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR("exception in getDataSourceAsParent caught"); |
| } |
| return xSource; |
| } |
| /* -----------------------------20.08.2002 12:00------------------------------ |
| |
| ---------------------------------------------------------------------------*/ |
| uno::Reference<XResultSet> SwNewDBMgr::createCursor(const ::rtl::OUString& _sDataSourceName, |
| const ::rtl::OUString& _sCommand, |
| sal_Int32 _nCommandType, |
| const uno::Reference<XConnection>& _xConnection |
| ) |
| { |
| uno::Reference<XResultSet> xResultSet; |
| try |
| { |
| uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| if( xMgr.is() ) |
| { |
| uno::Reference<XInterface> xInstance = xMgr->createInstance( |
| C2U( "com.sun.star.sdb.RowSet" )); |
| uno::Reference<XPropertySet> xRowSetPropSet(xInstance, UNO_QUERY); |
| if(xRowSetPropSet.is()) |
| { |
| xRowSetPropSet->setPropertyValue(C2U("DataSourceName"), makeAny(_sDataSourceName)); |
| xRowSetPropSet->setPropertyValue(C2U("ActiveConnection"), makeAny(_xConnection)); |
| xRowSetPropSet->setPropertyValue(C2U("Command"), makeAny(_sCommand)); |
| xRowSetPropSet->setPropertyValue(C2U("CommandType"), makeAny(_nCommandType)); |
| |
| uno::Reference< XCompletedExecution > xRowSet(xInstance, UNO_QUERY); |
| |
| if ( xRowSet.is() ) |
| { |
| uno::Reference< XInteractionHandler > xHandler(xMgr->createInstance(C2U("com.sun.star.task.InteractionHandler")), UNO_QUERY); |
| xRowSet->executeWithCompletion(xHandler); |
| } |
| xResultSet = uno::Reference<XResultSet>(xRowSet, UNO_QUERY); |
| } |
| } |
| } |
| catch(const Exception&) |
| { |
| DBG_ASSERT(0,"Caught exception while creating a new RowSet!"); |
| } |
| return xResultSet; |
| } |
| /*-- 13.05.2004 16:14:15--------------------------------------------------- |
| merge all data into one resulting document and return the number of |
| merged documents |
| -----------------------------------------------------------------------*/ |
| |
| sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig, |
| SwView& rSourceView ) |
| { |
| // check the availability of all data in the config item |
| uno::Reference< XResultSet> xResultSet = rMMConfig.GetResultSet(); |
| if(!xResultSet.is()) |
| return false; |
| bInMerge = sal_True; |
| sal_Int32 nRet = 0; |
| pImpl->pMergeData = new SwDSParam( |
| rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection()); |
| |
| try{ |
| //set to start position |
| if(pImpl->pMergeData->aSelection.getLength()) |
| { |
| sal_Int32 nPos = 0; |
| pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos; |
| pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos ); |
| pImpl->pMergeData->CheckEndOfDB(); |
| if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength()) |
| pImpl->pMergeData->bEndOfDB = sal_True; |
| } |
| else |
| { |
| pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first(); |
| pImpl->pMergeData->CheckEndOfDB(); |
| } |
| } |
| catch(Exception&) |
| { |
| pImpl->pMergeData->bEndOfDB = sal_True; |
| pImpl->pMergeData->CheckEndOfDB(); |
| DBG_ERROR("exception in MergeNew()"); |
| } |
| |
| //bCancel is set from the PrintMonitor |
| bCancel = sal_False; |
| |
| CreateMonitor aMonitorDlg(&rSourceView.GetEditWin()); |
| aMonitorDlg.SetCancelHdl(LINK(this, SwNewDBMgr, PrtCancelHdl)); |
| if (!IsMergeSilent()) |
| { |
| aMonitorDlg.Show(); |
| aMonitorDlg.Invalidate(); |
| aMonitorDlg.Update(); |
| // the print monitor needs some time to act |
| for( sal_uInt16 i = 0; i < 25; i++) |
| Application::Reschedule(); |
| } |
| |
| SwWrtShell& rSourceShell = rSourceView.GetWrtShell(); |
| sal_Bool bSynchronizedDoc = rSourceShell.IsLabelDoc() && rSourceShell.GetSectionFmtCount() > 1; |
| //save the settings of the first |
| rSourceShell.SttEndDoc(sal_True); |
| sal_uInt16 nStartingPageNo = rSourceShell.GetVirtPageNum(); |
| String sModifiedStartingPageDesc; |
| String sStartingPageDesc = sModifiedStartingPageDesc = rSourceShell.GetPageDesc( |
| rSourceShell.GetCurPageDesc()).GetName(); |
| |
| try |
| { |
| // create a target docshell to put the merged document into |
| SfxObjectShellRef xTargetDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) ); |
| xTargetDocShell->DoInitNew( 0 ); |
| SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 ); |
| |
| //the created window has to be located at the same position as the source window |
| Window& rTargetWindow = pTargetFrame->GetFrame().GetWindow(); |
| Window& rSourceWindow = rSourceView.GetViewFrame()->GetFrame().GetWindow(); |
| rTargetWindow.SetPosPixel(rSourceWindow.GetPosPixel()); |
| |
| // pTargetFrame->GetFrame().Appear(); |
| SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() ); |
| rMMConfig.SetTargetView(pTargetView); |
| //initiate SelectShell() to create sub shells |
| pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() ); |
| SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr(); |
| // #i63806# |
| const SwPageDesc* pSourcePageDesc = rSourceShell.FindPageDescByName( sStartingPageDesc ); |
| const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster(); |
| bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive() || |
| rMaster.GetFooter().IsActive(); |
| |
| |
| // #122799# copy compatibility options |
| lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell); |
| // #72821# copy dynamic defaults |
| lcl_CopyDynamicDefaults( *rSourceShell.GetDoc(), *pTargetShell->GetDoc() ); |
| |
| |
| long nStartRow, nEndRow; |
| sal_uLong nDocNo = 1; |
| sal_Int32 nDocCount = 0; |
| if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) ) |
| aMonitorDlg.SetTotalCount( nDocCount ); |
| |
| do |
| { |
| nStartRow = pImpl->pMergeData->xResultSet->getRow(); |
| if (!IsMergeSilent()) |
| { |
| aMonitorDlg.SetCurrentPosition( nDocNo ); |
| aMonitorDlg.Invalidate(); |
| aMonitorDlg.Update(); |
| // the print monitor needs some time to act |
| for( sal_uInt16 i = 0; i < 25; i++) |
| Application::Reschedule(); |
| } |
| |
| // copy the source document |
| // the copy will be closed later, but it is more safe to use SfxObjectShellLock here |
| SfxObjectShellLock xWorkDocSh; |
| if(nDocNo == 1 ) |
| { |
| uno::Reference< util::XCloneable > xClone( rSourceView.GetDocShell()->GetModel(), uno::UNO_QUERY); |
| uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY); |
| SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId())); |
| xWorkDocSh = pWorkModel->GetDocShell(); |
| } |
| else |
| { |
| xWorkDocSh = rSourceView.GetDocShell()->GetDoc()->CreateCopy(true); |
| } |
| //create a ViewFrame |
| SwView* pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() ); |
| SwWrtShell& rWorkShell = pWorkView->GetWrtShell(); |
| pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird. |
| |
| // merge the data |
| SwDoc* pWorkDoc = rWorkShell.GetDoc(); |
| SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr(); |
| pWorkDoc->SetNewDBMgr( this ); |
| pWorkDoc->EmbedAllLinks(); |
| SwUndoId nLastUndoId(UNDO_EMPTY); |
| if (rWorkShell.GetLastUndoInfo(0, & nLastUndoId)) |
| { |
| if (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId) |
| { |
| rWorkShell.Undo(); |
| } |
| } |
| // #i69485# lock fields to prevent access to the result set while calculating layout |
| rWorkShell.LockExpFlds(); |
| // create a layout |
| rWorkShell.CalcLayout(); |
| rWorkShell.UnlockExpFlds(); |
| SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell())); |
| rWorkShell.ViewShell::UpdateFlds(); |
| SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell())); |
| |
| // strip invisible content and convert fields to text |
| rWorkShell.RemoveInvisibleContent(); |
| rWorkShell.ConvertFieldsToText(); |
| rWorkShell.SetNumberingRestart(); |
| if( bSynchronizedDoc ) |
| { |
| lcl_RemoveSectionLinks( rWorkShell ); |
| } |
| |
| // insert the document into the target document |
| rWorkShell.SttEndDoc(sal_False); |
| rWorkShell.SttEndDoc(sal_True); |
| rWorkShell.SelAll(); |
| pTargetShell->SttEndDoc(sal_False); |
| |
| //#i63806# put the styles to the target document |
| //if the source uses headers or footers each new copy need to copy a new page styles |
| if(bPageStylesWithHeaderFooter) |
| { |
| //create a new pagestyle |
| //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style |
| |
| SwDoc* pTargetDoc = pTargetShell->GetDoc(); |
| String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo ); |
| pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName ); |
| SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName ); |
| const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc ); |
| |
| if(pWorkPageDesc && pTargetPageDesc) |
| { |
| pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, sal_False ); |
| sModifiedStartingPageDesc = sNewPageDescName; |
| lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo ); |
| } |
| } |
| if(nDocNo == 1 || bPageStylesWithHeaderFooter) |
| { |
| pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), sal_True ); |
| } |
| if(nDocNo > 1) |
| { |
| pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo ); |
| } |
| else |
| { |
| pTargetShell->SetPageStyle(sModifiedStartingPageDesc); |
| } |
| sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt(); |
| DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended"); |
| //#i51359# add a second paragraph in case there's only one |
| { |
| SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 ); |
| SwPosition aTestPos( aIdx ); |
| SwCursor aTestCrsr(aTestPos,0,false); |
| if(!aTestCrsr.MovePara(fnParaNext, fnParaStart)) |
| { |
| //append a paragraph |
| pWorkDoc->AppendTxtNode( aTestPos ); |
| } |
| } |
| pTargetShell->Paste( rWorkShell.GetDoc(), sal_True ); |
| //convert fields in page styles (header/footer - has to be done after the first document has been pasted |
| if(1 == nDocNo) |
| { |
| pTargetShell->CalcLayout(); |
| pTargetShell->ConvertFieldsToText(); |
| } |
| //add the document info to the config item |
| SwDocMergeInfo aMergeInfo; |
| aMergeInfo.nStartPageInTarget = nPageCountBefore; |
| //#i72820# calculate layout to be able to find the correct page index |
| pTargetShell->CalcLayout(); |
| aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt(); |
| aMergeInfo.nDBRow = nStartRow; |
| rMMConfig.AddMergedDocument( aMergeInfo ); |
| ++nRet; |
| |
| // the print monitor needs some time to act |
| for( sal_uInt16 i = 0; i < 25; i++) |
| Application::Reschedule(); |
| |
| //restore the ole DBMgr |
| pWorkDoc->SetNewDBMgr( pWorkDBMgr ); |
| //now the temporary document should be closed |
| SfxObjectShellRef xDocSh(pWorkView->GetDocShell()); |
| xDocSh->DoClose(); |
| nEndRow = pImpl->pMergeData->xResultSet->getRow(); |
| ++nDocNo; |
| } while( !bCancel && |
| (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord())); |
| |
| //deselect all, go out of the frame and go to the beginning of the document |
| Point aPt(LONG_MIN, LONG_MIN); |
| pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME); |
| if (pTargetShell->IsSelFrmMode()) |
| { |
| pTargetShell->UnSelectFrm(); |
| pTargetShell->LeaveSelFrmMode(); |
| } |
| pTargetShell->EnterStdMode(); |
| pTargetShell->SttDoc(); |
| // |
| } |
| catch( Exception& rEx) |
| { |
| (void)rEx; |
| DBG_ERROR("exception caught in SwNewDBMgr::MergeDocuments"); |
| } |
| DELETEZ(pImpl->pMergeData); |
| bInMerge = sal_False; |
| return nRet; |
| } |
| /* -----------------09.12.2002 12:38----------------- |
| * |
| * --------------------------------------------------*/ |
| SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr) : |
| rDBMgr(rMgr) |
| {}; |
| /* -----------------09.12.2002 12:39----------------- |
| * |
| * --------------------------------------------------*/ |
| SwConnectionDisposedListener_Impl::~SwConnectionDisposedListener_Impl() |
| {}; |
| /* -----------------09.12.2002 12:39----------------- |
| * |
| * --------------------------------------------------*/ |
| void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource ) |
| throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard(Application::GetSolarMutex()); |
| uno::Reference<XConnection> xSource(rSource.Source, UNO_QUERY); |
| for(sal_uInt16 nPos = rDBMgr.aDataSourceParams.Count(); nPos; nPos--) |
| { |
| SwDSParam* pParam = rDBMgr.aDataSourceParams[nPos - 1]; |
| if(pParam->xConnection.is() && |
| (xSource == pParam->xConnection)) |
| { |
| rDBMgr.aDataSourceParams.DeleteAndDestroy(nPos - 1); |
| } |
| } |
| } |