diff options
-rw-r--r-- | include/unotools/tempfile.hxx | 5 | ||||
-rw-r--r-- | sw/qa/extras/mailmerge/data/10-testing-addresses.ods | bin | 12130 -> 14816 bytes | |||
-rw-r--r-- | sw/qa/extras/mailmerge/mailmerge.cxx | 71 | ||||
-rw-r--r-- | sw/source/uibase/dbui/dbmgr.cxx | 29 | ||||
-rw-r--r-- | unotools/source/ucbhelper/tempfile.cxx | 42 |
5 files changed, 110 insertions, 37 deletions
diff --git a/include/unotools/tempfile.hxx b/include/unotools/tempfile.hxx index 4b8bff801edb..edb9c9f39498 100644 --- a/include/unotools/tempfile.hxx +++ b/include/unotools/tempfile.hxx @@ -66,8 +66,11 @@ public: rLeadingChars="abc" means "abc0","abc1" and so on, depending on existing files in the folder ). The extension string may be f.e. ".txt" or "", if no extension string is given, ".tmp" is used @param _bStartWithZero If set to false names will be generated like "abc","abc0","abc1" + @param bCreateParentDirs If rLeadingChars contains a slash, this will create the required + parent directories. */ - TempFile( const OUString& rLeadingChars, bool _bStartWithZero=true, const OUString* pExtension=nullptr, const OUString* pParent=nullptr); + TempFile( const OUString& rLeadingChars, bool _bStartWithZero=true, const OUString* pExtension=nullptr, + const OUString* pParent=nullptr, bool bCreateParentDirs=false ); /** TempFile will be removed from disk in dtor if EnableKillingFile(true) was called before. diff --git a/sw/qa/extras/mailmerge/data/10-testing-addresses.ods b/sw/qa/extras/mailmerge/data/10-testing-addresses.ods Binary files differindex 33b82e65a28b..6792da491733 100644 --- a/sw/qa/extras/mailmerge/data/10-testing-addresses.ods +++ b/sw/qa/extras/mailmerge/data/10-testing-addresses.ods diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx index 36009a179be6..bb4ec55cce75 100644 --- a/sw/qa/extras/mailmerge/mailmerge.cxx +++ b/sw/qa/extras/mailmerge/mailmerge.cxx @@ -70,7 +70,8 @@ public: * The 'verify' method actually has to execute the mail merge by * calling executeMailMerge() after modifying the job arguments. */ - void executeMailMergeTest(const char* filename, const char* datasource, const char* tablename, bool file, int selection) + void executeMailMergeTest( const char* filename, const char* datasource, const char* tablename, + bool file, int selection, const char* column ) { maMMtestFilename = filename; header(); @@ -79,8 +80,9 @@ public: utl::TempFile aTempDir(nullptr, true); const OUString aWorkDir = aTempDir.GetURL(); const OUString aURI( m_directories.getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(datasource) ); - OUString aDBName = registerDBsource( aURI, aWorkDir ); - initMailMergeJobAndArgs( filename, tablename, aDBName, "LOMM_", aWorkDir, file, selection ); + const OUString aPrefix = column ? OUString::createFromAscii( column ) : "LOMM_"; + const OUString aDBName = registerDBsource( aURI, aWorkDir ); + initMailMergeJobAndArgs( filename, tablename, aDBName, aPrefix, aWorkDir, file, selection, column != nullptr ); verify(); finish(); @@ -130,7 +132,8 @@ public: } void initMailMergeJobAndArgs( const char* filename, const char* tablename, const OUString &aDBName, - const OUString &aPrefix, const OUString &aWorkDir, bool file, int nDataSets ) + const OUString &aPrefix, const OUString &aWorkDir, bool file, int nDataSets, + const bool bPrefixIsColumn ) { uno::Reference< task::XJob > xJob( getMultiServiceFactory()->createInstance( "com.sun.star.text.MailMerge" ), uno::UNO_QUERY_THROW ); mxJob.set( xJob ); @@ -144,6 +147,9 @@ public: args.push_back( beans::NamedValue( OUString( UNO_NAME_OUTPUT_URL ), uno::Any( aWorkDir ) ) ); args.push_back( beans::NamedValue( OUString( UNO_NAME_FILE_NAME_PREFIX ), uno::Any( aPrefix )) ); + if (bPrefixIsColumn) + args.push_back( beans::NamedValue( OUString( UNO_NAME_FILE_NAME_FROM_COLUMN ), uno::Any( true ) ) ); + if (tablename) { args.push_back( beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND_TYPE ), uno::Any( sdb::CommandType::TABLE ) ) ); @@ -174,6 +180,7 @@ public: const beans::NamedValue *pArguments = mSeqMailMergeArgs.getConstArray(); bool bOk = true; + bool bMMFilenameFromColumn = false; sal_Int32 nArgs = mSeqMailMergeArgs.getLength(); for (sal_Int32 i = 0; i < nArgs; ++i) { @@ -187,6 +194,8 @@ public: bOk &= rValue >>= mailMergeOutputPrefix; else if (rName == UNO_NAME_OUTPUT_TYPE) bOk &= rValue >>= mnCurOutputType; + else if (rName == UNO_NAME_FILE_NAME_FROM_COLUMN) + bOk &= rValue >>= bMMFilenameFromColumn; } CPPUNIT_ASSERT(bOk); @@ -205,7 +214,8 @@ public: else { CPPUNIT_ASSERT(res == true); - loadMailMergeDocument( 0 ); + if( !bMMFilenameFromColumn ) + loadMailMergeDocument( 0 ); } } @@ -221,26 +231,31 @@ public: return parseExportInternal( mailMergeOutputURL + "/" + 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(mailMergeOutputURL + "/" + 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 = mailMergeOutputPrefix + 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; @@ -254,7 +269,7 @@ protected: const char* maMMtestFilename; }; -#define DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, file, BaseClass, selection) \ +#define DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, file, BaseClass, selection, column) \ class TestName : public BaseClass { \ protected: \ virtual OUString getTestName() override { return OUString(#TestName); } \ @@ -264,7 +279,7 @@ protected: CPPUNIT_TEST_SUITE_END(); \ \ void MailMerge() { \ - executeMailMergeTest(filename, datasource, tablename, file, selection); \ + executeMailMergeTest(filename, datasource, tablename, file, selection, column); \ } \ void verify() override; \ }; \ @@ -273,14 +288,17 @@ protected: // Will generate the resulting document in mxMMDocument. #define DECLARE_SHELL_MAILMERGE_TEST(TestName, filename, datasource, tablename) \ - DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, false, MMTest, 0) + DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, false, MMTest, 0, nullptr) // Will generate documents as files, use loadMailMergeDocument(). #define DECLARE_FILE_MAILMERGE_TEST(TestName, filename, datasource, tablename) \ - DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, true, MMTest, 0) + DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, true, MMTest, 0, nullptr) #define DECLARE_SHELL_MAILMERGE_TEST_SELECTION(TestName, filename, datasource, tablename, selection) \ - DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, false, MMTest, selection) + DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, false, MMTest, selection, nullptr) + +#define DECLARE_FILE_MAILMERGE_TEST_COLUMN(TestName, filename, datasource, tablename, column) \ + DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, true, MMTest, 0, column) int MMTest::documentStartPageNumber( int document ) const { // See documentStartPageNumber() . @@ -568,5 +586,22 @@ DECLARE_SHELL_MAILMERGE_TEST(test_sections_first_last, "sections_first_last.odt" } } +DECLARE_FILE_MAILMERGE_TEST_COLUMN(testDirMailMerge, "simple-mail-merge.odt", "10-testing-addresses.ods", "testing-addresses", "Filename") +{ + executeMailMerge(); + for( int doc = 1; + doc <= 10; + ++doc ) + { + OUString filename = "sub/lastname" + OUString::number( doc ) + + " firstname" + OUString::number( doc ) + ".odt"; + loadMailMergeDocument( filename ); + CPPUNIT_ASSERT_EQUAL( 1, getPages()); + CPPUNIT_ASSERT_EQUAL( OUString( "Fixed text." ), getRun( getParagraph( 1 ), 1 )->getString()); + CPPUNIT_ASSERT_EQUAL( OUString( "lastname" + OUString::number( doc )), getRun( getParagraph( 2 ), 1 )->getString()); + CPPUNIT_ASSERT_EQUAL( OUString( "Another fixed text." ), getRun( getParagraph( 3 ), 1 )->getString()); + } +} + 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 ff90ea629dba..86e2d7e171ca 100644 --- a/sw/source/uibase/dbui/dbmgr.cxx +++ b/sw/source/uibase/dbui/dbmgr.cxx @@ -1314,7 +1314,6 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell, { nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0; - OUString sPath = rMergeDescriptor.sPath; OUString sColumnData; // Read the indicated data column, which should contain a valid mail @@ -1322,28 +1321,32 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell, if( bMT_EMAIL || bColumnName ) { sColumnData = GetDBField( xColumnProp, aColumnDBFormat ); - if( !bMT_EMAIL ) - { - if (sColumnData.isEmpty()) - sColumnData = "_"; - sPath += sColumnData; - } } // create a new temporary file name - only done once in case of bCreateSingleFile if( bNeedsTempFiles && ( !bWorkDocInitialized || !bCreateSingleFile )) { - INetURLObject aEntry(sPath); + OUString sPath = rMergeDescriptor.sPath; OUString sLeading; + //#i97667# if the name is from a database field then it will be used _as is_ - if( !sColumnData.isEmpty() ) - sLeading = sColumnData; + if( bColumnName && !bMT_EMAIL ) + { + if (!sColumnData.isEmpty()) + sLeading = sColumnData; + else + sLeading = "_"; + } else + { + INetURLObject aEntry( sPath ); sLeading = aEntry.GetBase(); - aEntry.removeSegment(); - sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE ); + aEntry.removeSegment(); + sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE ); + } + OUString sExt(comphelper::string::stripStart(pStoreToFilter->GetDefaultExtension(), '*')); - aTempFile.reset( new utl::TempFile(sLeading, sColumnData.isEmpty(), &sExt, &sPath) ); + aTempFile.reset( new utl::TempFile(sLeading, sColumnData.isEmpty(), &sExt, &sPath, true) ); if( !aTempFile->IsValid() ) { ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED ); diff --git a/unotools/source/ucbhelper/tempfile.cxx b/unotools/source/ucbhelper/tempfile.cxx index dcc4068b2ac3..fa2cbf567436 100644 --- a/unotools/source/ucbhelper/tempfile.cxx +++ b/unotools/source/ucbhelper/tempfile.cxx @@ -225,11 +225,39 @@ private: sal_uInt32 UniqueTokens::globalValue = SAL_MAX_UINT32; +namespace +{ + class TempDirCreatedObserver : public DirectoryCreationObserver + { + public: + virtual void DirectoryCreated(const rtl::OUString& aDirectoryUrl) override + { + File::setAttributes( aDirectoryUrl, osl_File_Attribute_OwnRead | + osl_File_Attribute_OwnWrite | osl_File_Attribute_OwnExe ); + }; + }; +}; + OUString lcl_createName( const OUString& rLeadingChars, Tokens & tokens, const OUString* pExtension, - const OUString* pParent, bool bDirectory, bool bKeep, bool bLock) + const OUString* pParent, bool bDirectory, bool bKeep, bool bLock, + bool bCreateParentDirs ) { - OUString aName = ConstructTempDir_Impl( pParent ) + rLeadingChars; + OUString aName = ConstructTempDir_Impl( pParent ); + if ( bCreateParentDirs ) + { + sal_Int32 nOffset = rLeadingChars.lastIndexOf("/"); + if (-1 != nOffset) + { + OUString aDirName = aName + OUString( rLeadingChars.getStr(), nOffset ); + TempDirCreatedObserver observer; + FileBase::RC err = Directory::createPath( aDirName, &observer ); + if ( err != FileBase::E_None && err != FileBase::E_EXIST ) + return OUString(); + } + } + aName += rLeadingChars; + OUString token; while (tokens.next(&token)) { @@ -306,7 +334,8 @@ OUString CreateTempName_Impl( const OUString* pParent, bool bKeep, bool bDir = t aEyeCatcher += aPidString; #endif UniqueTokens t; - return lcl_createName(aEyeCatcher, t, nullptr, pParent, bDir, bKeep, false); + return lcl_createName( aEyeCatcher, t, nullptr, pParent, bDir, bKeep, + false, false); } OUString TempFile::CreateTempName() @@ -328,13 +357,16 @@ TempFile::TempFile( const OUString* pParent, bool bDirectory ) aName = CreateTempName_Impl( pParent, true, bDirectory ); } -TempFile::TempFile( const OUString& rLeadingChars, bool _bStartWithZero, const OUString* pExtension, const OUString* pParent) +TempFile::TempFile( const OUString& rLeadingChars, bool _bStartWithZero, + const OUString* pExtension, const OUString* pParent, + bool bCreateParentDirs ) : pStream( nullptr ) , bIsDirectory( false ) , bKillingFileEnabled( false ) { SequentialTokens t(_bStartWithZero); - aName = lcl_createName(rLeadingChars, t, pExtension, pParent, false/*bDirectory*/, true, true); + aName = lcl_createName( rLeadingChars, t, pExtension, pParent, false, + true, true, bCreateParentDirs ); } TempFile::~TempFile() |