summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2016-10-03 21:51:56 +0200
committerCaolán McNamara <caolanm@redhat.com>2016-12-07 08:56:25 +0000
commit6c2dae8259bf666d906b4d0c1ccd64aa14c6500c (patch)
tree9dc1239373fec7232ab6ccf535d4ae0693b172bf /sw
parent21be787405b840906233530702165bda3da96fc1 (diff)
tdf#102010 Never overwrite MM files via UNO
Fixes the regression introduced by commit e637b6743a506ef74c93ccbe15ab6642f3baa34f This commit removed the crazy bSubjectIsFilename handling, where I didn't understood the case of bSubjectIsFilename and a user supplied prefix. Mail merge to files never overwrites an existing document, but there is the special case, when a user selects a target filename in the MM dialog for single file MM. Should be fixed by a successive commmit, reverting this and removing an existing file before starting the MM job. (cherry picked from commit bbf246e40c7814bfc4038d456d388d1f90048287) Reviewed-on: https://gerrit.libreoffice.org/31207 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de> (cherry picked from commit 5b4b60b2d81452c79ece99c51f63199b7dcf4b1d) This commit also includes: MM allow easier manipulation of MM test arguments Keep the beans::NamedValue vector around and convert it to a uno::Sequence just before executing the mail merge job. (cherry picked from commit 660159a68acd54a8f213920457c1aeed79cffea5) Reviewed-on: https://gerrit.libreoffice.org/31206 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de> (cherry picked from commit fda376a5ebf765789cfa4cb81ee04e0f1dafe44b) Change-Id: Idda487023e6984de9c1e701fc088a6b7f92e9847 Reviewed-on: https://gerrit.libreoffice.org/31636 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/CppunitTest_sw_mailmerge.mk1
-rw-r--r--sw/inc/dbmgr.hxx19
-rw-r--r--sw/qa/extras/mailmerge/mailmerge.cxx109
-rw-r--r--sw/source/uibase/dbui/dbmgr.cxx19
-rw-r--r--sw/source/uibase/uno/unomailmerge.cxx2
5 files changed, 107 insertions, 43 deletions
diff --git a/sw/CppunitTest_sw_mailmerge.mk b/sw/CppunitTest_sw_mailmerge.mk
index d948b892c761..5796fc446ced 100644
--- a/sw/CppunitTest_sw_mailmerge.mk
+++ b/sw/CppunitTest_sw_mailmerge.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_mailmerge, \
sfx \
sw \
test \
+ tl \
unotest \
utl \
))
diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index 442d0e1dfeb7..d3ef3af5ea45 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -162,7 +162,23 @@ struct SwMergeDescriptor
* @defgroup file Mail merge as File settings
* @addtogroup file
* @{ */
- OUString sPath;
+
+ /**
+ * Basename incl. the path for the generated files.
+ *
+ * The final filename will be created by concating a number to prevent
+ * overwriting an existing file and the extension based on the filter
+ * settings.
+ */
+ OUString sPrefix;
+ /**
+ * Use the sPrefix as the target filename also overwriting an existing
+ * target file.
+ *
+ * Just used for the internal mail merge dialogs as mail merge never
+ * overwrites existing files (see SwDBManager::ExecuteFormLetter).
+ */
+ bool bPrefixIsFilename;
/** @} */
/**
@@ -206,6 +222,7 @@ struct SwMergeDescriptor
rSh(rShell),
rDescriptor(rDesc),
bCreateSingleFile( false ),
+ bPrefixIsFilename( false ),
bSendAsHTML( true ),
bSendAsAttachment( false ),
bPrintAsync( false ),
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx
index 8e13aef44069..ed290c2be74d 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -22,6 +22,8 @@
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <tools/urlobj.hxx>
+
#include <wrtsh.hxx>
#include <ndtxt.hxx>
#include <swdtflvr.hxx>
@@ -111,31 +113,31 @@ public:
uno::Reference< task::XJob > xJob( getMultiServiceFactory()->createInstance( "com.sun.star.text.MailMerge" ), uno::UNO_QUERY_THROW );
mxJob.set( xJob );
- int seq_id = 5;
- if (tablename) seq_id += 2;
- mSeqMailMergeArgs.realloc( seq_id );
-
- seq_id = 0;
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_OUTPUT_TYPE ), uno::Any( file ? text::MailMergeType::FILE : text::MailMergeType::SHELL ) );
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DOCUMENT_URL ), uno::Any(
- ( OUString(m_directories.getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(filename)) ) ) );
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DATA_SOURCE_NAME ), uno::Any( aDBName ) );
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_OUTPUT_URL ), uno::Any( aWorkDir ) );
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_FILE_NAME_PREFIX ), uno::Any( aPrefix ));
+ mMMargs.reserve( 15 );
+
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_OUTPUT_TYPE ), uno::Any( file ? text::MailMergeType::FILE : text::MailMergeType::SHELL ) ) );
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_DOCUMENT_URL ), uno::Any(
+ ( OUString( m_directories.getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(filename)) ) ) ) );
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_DATA_SOURCE_NAME ), uno::Any( aDBName ) ) );
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_OUTPUT_URL ), uno::Any( aWorkDir ) ) );
+ if (file)
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_FILE_NAME_PREFIX ), uno::Any( aPrefix )) );
+
if (tablename)
{
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND_TYPE ), uno::Any( sdb::CommandType::TABLE ) );
- mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND ), uno::Any( OUString::createFromAscii(tablename) ) );
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND_TYPE ), uno::Any( sdb::CommandType::TABLE ) ) );
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND ), uno::Any( OUString::createFromAscii(tablename) ) ) );
}
}
- void executeMailMerge()
+ void executeMailMerge( bool bDontLoadResult = false )
{
- uno::Any res = mxJob->execute( mSeqMailMergeArgs );
+ uno::Sequence< beans::NamedValue > aSeqMailMergeArgs = comphelper::containerToSequence( mMMargs );
+ uno::Any res = mxJob->execute( aSeqMailMergeArgs );
- const beans::NamedValue *pArguments = mSeqMailMergeArgs.getConstArray();
+ const beans::NamedValue *pArguments = aSeqMailMergeArgs.getConstArray();
bool bOk = true;
- sal_Int32 nArgs = mSeqMailMergeArgs.getLength();
+ sal_Int32 nArgs = aSeqMailMergeArgs.getLength();
for (sal_Int32 i = 0; i < nArgs; ++i) {
const OUString &rName = pArguments[i].Name;
@@ -143,11 +145,13 @@ public:
// all error checking was already done by the MM job execution
if (rName == UNO_NAME_OUTPUT_URL)
- bOk &= rValue >>= mailMergeOutputURL;
+ bOk &= rValue >>= msMailMergeOutputURL;
else if (rName == UNO_NAME_FILE_NAME_PREFIX)
- bOk &= rValue >>= mailMergeOutputPrefix;
+ bOk &= rValue >>= msMailMergeOutputPrefix;
else if (rName == UNO_NAME_OUTPUT_TYPE)
bOk &= rValue >>= mnCurOutputType;
+ else if (rName == UNO_NAME_DOCUMENT_URL)
+ bOk &= rValue >>= msMailMergeDocumentURL;
}
CPPUNIT_ASSERT(bOk);
@@ -160,7 +164,8 @@ public:
else
{
CPPUNIT_ASSERT(res == true);
- loadMailMergeDocument( 0 );
+ if( !bDontLoadResult )
+ loadMailMergeDocument( 0 );
}
}
@@ -172,38 +177,54 @@ public:
if (mnCurOutputType != text::MailMergeType::FILE)
return nullptr;
- OUString name = mailMergeOutputPrefix + OUString::number( 0 ) + ".odt";
- return parseExportInternal( mailMergeOutputURL + "/" + name, rStreamName );
+ OUString name = msMailMergeOutputPrefix + OUString::number( 0 ) + ".odt";
+ return parseExportInternal( msMailMergeOutputURL + "/" + name, rStreamName );
}
- /**
- Loads number-th document from mail merge. Requires file output from mail merge.
- */
- void loadMailMergeDocument( int number )
+ void loadMailMergeDocument( const OUString &filename )
{
assert( mnCurOutputType == text::MailMergeType::FILE );
if (mxComponent.is())
mxComponent->dispose();
- OUString name = mailMergeOutputPrefix + OUString::number( number ) + ".odt";
// Output name early, so in the case of a hang, the name of the hanging input file is visible.
- std::cout << name << ",";
+ std::cout << filename << ",";
mnStartTime = osl_getGlobalTimer();
- mxComponent = loadFromDesktop(mailMergeOutputURL + "/" + name, "com.sun.star.text.TextDocument");
+ mxComponent = loadFromDesktop(msMailMergeOutputURL + "/" + filename, "com.sun.star.text.TextDocument");
CPPUNIT_ASSERT( mxComponent.is());
- OString name2 = OUStringToOString( name, RTL_TEXTENCODING_UTF8 );
+ OString name2 = OUStringToOString( filename, RTL_TEXTENCODING_UTF8 );
discardDumpedLayout();
if (mustCalcLayoutOf(name2.getStr()))
calcLayout();
}
+ /**
+ Loads number-th document from mail merge. Requires file output from mail merge.
+ */
+ void loadMailMergeDocument( int number )
+ {
+ OUString name;
+ if (!msMailMergeOutputPrefix.isEmpty())
+ name = msMailMergeOutputPrefix;
+ else
+ {
+ INetURLObject aURLObj;
+ aURLObj.SetSmartProtocol( INetProtocol::File );
+ aURLObj.SetSmartURL( msMailMergeDocumentURL );
+ name = aURLObj.GetBase();
+ }
+ name += OUString::number( number ) + ".odt";
+ loadMailMergeDocument( name );
+ }
+
protected:
// Returns page number of the first page of a MM document inside the large MM document (used in the SHELL case).
int documentStartPageNumber( int document ) const;
uno::Reference< css::task::XJob > mxJob;
- uno::Sequence< beans::NamedValue > mSeqMailMergeArgs;
- OUString mailMergeOutputURL;
- OUString mailMergeOutputPrefix;
+ std::vector< beans::NamedValue > mMMargs;
+ OUString msMailMergeDocumentURL;
+ OUString msMailMergeOutputURL;
+ OUString msMailMergeOutputPrefix;
sal_Int16 mnCurOutputType;
uno::Reference< lang::XComponent > mxMMComponent;
};
@@ -463,5 +484,27 @@ DECLARE_SHELL_MAILMERGE_TEST(testTdf92623, "tdf92623.odt", "10-testing-addresses
CPPUNIT_ASSERT_EQUAL(sal_Int32(10), countFieldMarks);
}
+DECLARE_FILE_MAILMERGE_TEST(testTdf102010, "empty.odt", "10-testing-addresses.ods", "testing-addresses")
+{
+ // Create "correct" automatic filename for non-user-supplied-prefix
+ for (auto aNamedValueIter = mMMargs.begin(); aNamedValueIter != mMMargs.end();)
+ {
+ if ( aNamedValueIter->Name == UNO_NAME_FILE_NAME_PREFIX )
+ aNamedValueIter = mMMargs.erase( aNamedValueIter );
+ else
+ {
+ std::cout << aNamedValueIter->Name << ": " << aNamedValueIter->Value << std::endl;
+ ++aNamedValueIter;
+ }
+ }
+ mMMargs.push_back( beans::NamedValue( OUString( UNO_NAME_SAVE_AS_SINGLE_FILE ), uno::Any( true ) ) );
+
+ // Generate correct mail merge result filename
+ executeMailMerge();
+ // Don't overwrite previous result
+ executeMailMerge( true );
+ loadMailMergeDocument( 1 );
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 7b4c2f698525..fe9e87f727bb 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1100,11 +1100,13 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
bool bCheckSingleFile_ = rMergeDescriptor.bCreateSingleFile;
if( bMT_EMAIL )
{
+ assert( !rMergeDescriptor.bPrefixIsFilename );
assert( bMT_EMAIL && !bCheckSingleFile_ );
bCheckSingleFile_ = false;
}
else if( bMT_SHELL || bMT_PRINTER )
{
+ assert( !rMergeDescriptor.bPrefixIsFilename );
assert( (bMT_SHELL || bMT_PRINTER) && bCheckSingleFile_ );
bCheckSingleFile_ = true;
}
@@ -1292,7 +1294,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
{
nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
- OUString sPath = rMergeDescriptor.sPath;
+ OUString sPrefix = rMergeDescriptor.sPrefix;
OUString sColumnData;
// Read the indicated data column, which should contain a valid mail
@@ -1304,14 +1306,14 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
{
if (sColumnData.isEmpty())
sColumnData = "_";
- sPath += sColumnData;
+ sPrefix += sColumnData;
}
}
// create a new temporary file name - only done once in case of bCreateSingleFile
if( bNeedsTempFiles && ( !bWorkDocInitialized || !bCreateSingleFile ))
{
- INetURLObject aEntry(sPath);
+ INetURLObject aEntry(sPrefix);
OUString sLeading;
//#i97667# if the name is from a database field then it will be used _as is_
if( !sColumnData.isEmpty() )
@@ -1319,9 +1321,9 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
else
sLeading = aEntry.GetBase();
aEntry.removeSegment();
- sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE );
+ sPrefix = aEntry.GetMainURL( INetURLObject::NO_DECODE );
OUString sExt(comphelper::string::stripStart(pStoreToFilter->GetDefaultExtension(), '*'));
- aTempFile.reset( new utl::TempFile(sLeading, true, &sExt, &sPath) );
+ aTempFile.reset( new utl::TempFile(sLeading, true, &sExt, &sPrefix) );
if( !aTempFile->IsValid() )
{
ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
@@ -1538,11 +1540,11 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
// save merged document
assert( aTempFile.get() );
INetURLObject aTempFileURL;
- if( rMergeDescriptor.sPath.isEmpty() )
+ if( rMergeDescriptor.sPrefix.isEmpty() || !rMergeDescriptor.bPrefixIsFilename )
aTempFileURL.SetURL( aTempFile->GetURL() );
else
{
- aTempFileURL.SetURL( rMergeDescriptor.sPath );
+ aTempFileURL.SetURL( rMergeDescriptor.sPrefix );
// remove the unneeded temporary file
aTempFile->EnableKillingFile();
}
@@ -2840,7 +2842,8 @@ void SwDBManager::ExecuteFormLetter( SwWrtShell& rSh,
SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), rSh, aDescriptor );
aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter();
aMergeDesc.bCreateSingleFile = pImpl->pMergeDialog->IsSaveSingleDoc();
- aMergeDesc.sPath = pImpl->pMergeDialog->GetTargetURL();
+ aMergeDesc.bPrefixIsFilename = aMergeDesc.bCreateSingleFile;
+ aMergeDesc.sPrefix = pImpl->pMergeDialog->GetTargetURL();
if( !aMergeDesc.bCreateSingleFile && pImpl->pMergeDialog->IsGenerateFromDataBase() )
{
aMergeDesc.sDBcolumn = pImpl->pMergeDialog->GetColumnName();
diff --git a/sw/source/uibase/uno/unomailmerge.cxx b/sw/source/uibase/uno/unomailmerge.cxx
index 3c335f6ea779..2b18c785777b 100644
--- a/sw/source/uibase/uno/unomailmerge.cxx
+++ b/sw/source/uibase/uno/unomailmerge.cxx
@@ -741,7 +741,7 @@ uno::Any SAL_CALL SwXMailMerge::execute(
aPath += aCurFileNamePrefix;
}
- aMergeDesc.sPath = aPath;
+ aMergeDesc.sPrefix = aPath;
aMergeDesc.sSaveToFilter = m_sSaveFilter;
aMergeDesc.sSaveToFilterOptions = m_sSaveFilterOptions;
aMergeDesc.aSaveToFilterData = m_aSaveFilterData;