summaryrefslogtreecommitdiff
path: root/desktop/source/app/dispatchwatcher.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/app/dispatchwatcher.cxx')
-rw-r--r--desktop/source/app/dispatchwatcher.cxx201
1 files changed, 127 insertions, 74 deletions
diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
index 9ab77f399ec4..af26ef9eaab9 100644
--- a/desktop/source/app/dispatchwatcher.cxx
+++ b/desktop/source/app/dispatchwatcher.cxx
@@ -20,7 +20,6 @@
#include <sal/config.h>
#include <sal/log.hxx>
-#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/fcontnr.hxx>
#include <svl/fstathelper.hxx>
@@ -52,8 +51,9 @@
#include <com/sun/star/script/XLibraryContainer2.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <comphelper/propertyvalue.hxx>
#include <comphelper/sequence.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <tools/urlobj.hxx>
#include <unotools/mediadescriptor.hxx>
#include <unotools/tempfile.hxx>
@@ -62,6 +62,7 @@
#include <osl/file.hxx>
#include <iostream>
#include <string_view>
+#include <utility>
using namespace ::osl;
using namespace ::com::sun::star::uno;
@@ -83,24 +84,23 @@ namespace {
struct DispatchHolder
{
- DispatchHolder( const URL& rURL, Reference< XDispatch > const & rDispatch ) :
- aURL( rURL ), xDispatch( rDispatch ) {}
+ DispatchHolder( URL _aURL, Reference< XDispatch > const & rDispatch ) :
+ aURL(std::move( _aURL )), xDispatch( rDispatch ) {}
URL aURL;
Reference< XDispatch > xDispatch;
};
-std::shared_ptr<const SfxFilter> impl_lookupExportFilterForUrl( std::u16string_view rUrl, const OUString& rFactory )
+std::shared_ptr<const SfxFilter> impl_lookupExportFilterForUrl( std::u16string_view rUrl, std::u16string_view rFactory )
{
// create the list of filters
- OUStringBuffer sQuery(256);
- sQuery.append("getSortedFilterList()");
- sQuery.append(":module=");
- sQuery.append(rFactory); // use long name here !
- sQuery.append(":iflags=");
- sQuery.append(OUString::number(static_cast<sal_Int32>(SfxFilterFlags::EXPORT)));
- sQuery.append(":eflags=");
- sQuery.append(OUString::number(static_cast<int>(SFX_FILTER_NOTINSTALLED)));
+ OUString sQuery = "getSortedFilterList()"
+ ":module=" +
+ OUString::Concat(rFactory) + // use long name here !
+ ":iflags=" +
+ OUString::number(static_cast<sal_Int32>(SfxFilterFlags::EXPORT)) +
+ ":eflags=" +
+ OUString::number(static_cast<int>(SFX_FILTER_NOTINSTALLED));
const Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
const Reference< XContainerQuery > xFilterFactory(
@@ -110,7 +110,7 @@ std::shared_ptr<const SfxFilter> impl_lookupExportFilterForUrl( std::u16string_v
std::shared_ptr<const SfxFilter> pBestMatch;
const Reference< XEnumeration > xFilterEnum(
- xFilterFactory->createSubSetEnumerationByQuery( sQuery.makeStringAndClear() ), UNO_SET_THROW );
+ xFilterFactory->createSubSetEnumerationByQuery( sQuery ), UNO_SET_THROW );
while ( xFilterEnum->hasMoreElements() )
{
comphelper::SequenceAsHashMap aFilterProps( xFilterEnum->nextElement() );
@@ -215,7 +215,7 @@ void scriptCat(const Reference< XModel >& xDoc )
std::cout << aObjectNames.getLength() << "\n\n";
for ( sal_Int32 j = 0 ; j < aObjectNames.getLength() ; ++j )
{
- OUString &rObjectName = aObjectNames[j];
+ const OUString &rObjectName = aObjectNames[j];
try
{
@@ -243,19 +243,19 @@ void scriptCat(const Reference< XModel >& xDoc )
}
// Perform batch print
-void batchPrint( const OUString &rPrinterName, const Reference< XPrintable > &xDoc,
+void batchPrint( std::u16string_view rPrinterName, const Reference< XPrintable > &xDoc,
const INetURLObject &aObj, const OUString &aName )
{
OUString aFilterOut;
OUString aPrinterName;
- sal_Int32 nPathIndex = rPrinterName.lastIndexOf( ';' );
- if( nPathIndex != -1 )
- aFilterOut=rPrinterName.copy( nPathIndex+1 );
+ size_t nPathIndex = rPrinterName.rfind( ';' );
+ if( nPathIndex != std::u16string_view::npos )
+ aFilterOut=rPrinterName.substr( nPathIndex+1 );
if( nPathIndex != 0 )
- aPrinterName=rPrinterName.copy( 0, nPathIndex );
+ aPrinterName=rPrinterName.substr( 0, nPathIndex );
INetURLObject aOutFilename( aObj );
- aOutFilename.SetExtension( "pdf" );
+ aOutFilename.SetExtension( u"pdf" );
FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
OUString aOutFile = aFilterOut + "/" + aOutFilename.getName();
@@ -266,27 +266,61 @@ void batchPrint( const OUString &rPrinterName, const Reference< XPrintable > &xD
OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding() );
std::cout << "print " << aSource8 << " -> " << aTargetURL8;
- std::cout << " using " << (aPrinterName.isEmpty() ? "<default_printer>" : OUStringToOString( aPrinterName, osl_getThreadTextEncoding() ));
+ std::cout << " using " << (aPrinterName.isEmpty() ? "<default_printer>"_ostr : OUStringToOString( aPrinterName, osl_getThreadTextEncoding() ));
std::cout << std::endl;
// create the custom printer, if given
- Sequence < PropertyValue > aPrinterArgs( 1 );
+ Sequence < PropertyValue > aPrinterArgs;
if( !aPrinterName.isEmpty() )
{
- aPrinterArgs[0].Name = "Name";
- aPrinterArgs[0].Value <<= aPrinterName;
+ aPrinterArgs = { comphelper::makePropertyValue("Name", aPrinterName) };
xDoc->setPrinter( aPrinterArgs );
}
// print ( also without user interaction )
- aPrinterArgs.realloc(2);
- aPrinterArgs[0].Name = "FileName";
- aPrinterArgs[0].Value <<= aOutFile;
- aPrinterArgs[1].Name = "Wait";
- aPrinterArgs[1].Value <<= true;
+ aPrinterArgs = { comphelper::makePropertyValue("FileName", aOutFile),
+ comphelper::makePropertyValue("Wait", true) };
xDoc->print( aPrinterArgs );
}
+// Get xDoc module name
+OUString getName(const Reference< XInterface > & xDoc)
+{
+ Reference< XModel > xModel( xDoc, UNO_QUERY );
+ if (!xModel)
+ return OUString();
+ utl::MediaDescriptor aMediaDesc( xModel->getArgs() );
+ OUString aDocService = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE, OUString() );
+ if (aDocService == "com.sun.star.text.TextDocument")
+ return "Writer";
+ else if (aDocService == "com.sun.star.text.GlobalDocument")
+ return "Writer master";
+ else if (aDocService == "com.sun.star.text.WebDocument")
+ return "Writer/Web";
+ else if (aDocService == "com.sun.star.drawing.DrawingDocument")
+ return "Draw";
+ else if (aDocService == "com.sun.star.presentation.PresentationDocument")
+ return "Impress";
+ else if (aDocService == "com.sun.star.sheet.SpreadsheetDocument")
+ return "Calc";
+ else if (aDocService == "com.sun.star.script.BasicIDE")
+ return "Basic";
+ else if (aDocService == "com.sun.star.formula.FormulaProperties")
+ return "Math";
+ else if (aDocService == "com.sun.star.sdb.RelationDesign")
+ return "Relation Design";
+ else if (aDocService == "com.sun.star.sdb.QueryDesign")
+ return "Query Design";
+ else if (aDocService == "com.sun.star.sdb.TableDesign")
+ return "Table Design";
+ else if (aDocService == "com.sun.star.sdb.DataSourceBrowser")
+ return "Data Source Browser";
+ else if (aDocService == "com.sun.star.sdb.DatabaseDocument")
+ return "Database";
+
+ return OUString();
+}
+
} // anonymous namespace
DispatchWatcher::DispatchWatcher()
@@ -367,7 +401,7 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
if ( !aDispatchRequest.aPreselectedFactory.isEmpty() )
{
- aArgs.emplace_back(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), 0,
+ aArgs.emplace_back(utl::MediaDescriptor::PROP_DOCUMENTSERVICE, 0,
Any(aDispatchRequest.aPreselectedFactory),
PropertyState_DIRECT_VALUE);
}
@@ -401,11 +435,8 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
"unsupported dispatch request <" << aName << ">");
if( xDispatcher.is() )
{
- {
- osl::MutexGuard aGuard(m_mutex);
- // Remember request so we can find it in statusChanged!
- m_nRequestCount++;
- }
+ // Remember request so we can find it in statusChanged!
+ m_nRequestCount++;
// Use local vector to store dispatcher because we have to fill our request container before
// we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
@@ -433,9 +464,8 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
// We have to be listener to catch errors during dispatching URLs.
// Otherwise it would be possible to have an office running without an open
// window!!
- Sequence < PropertyValue > aArgs2(1);
- aArgs2[0].Name = "SynchronMode";
- aArgs2[0].Value <<= true;
+ Sequence < PropertyValue > aArgs2{ comphelper::makePropertyValue("SynchronMode",
+ true) };
Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
if ( xDisp.is() )
xDisp->dispatchWithNotification( aURL, aArgs2, this );
@@ -576,10 +606,10 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
OUString aOutFile
= aOutFilename.GetMainURL(INetURLObject::DecodeMechanism::NONE);
- std::unique_ptr<utl::TempFile> fileForCat;
+ std::unique_ptr<utl::TempFileNamed> fileForCat;
if( aDispatchRequest.aRequestType == REQUEST_CAT )
{
- fileForCat = std::make_unique<utl::TempFile>();
+ fileForCat = std::make_unique<utl::TempFileNamed>();
if (fileForCat->IsValid())
fileForCat->EnableKillingFile();
else
@@ -594,11 +624,13 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
if ( xModel.is() )
{
utl::MediaDescriptor aMediaDesc( xModel->getArgs() );
- aDocService = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), OUString() );
+ aDocService = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE, OUString() );
}
aFilter = impl_GuessFilter( aOutFile, aDocService );
}
+ bool bMultiFileTarget = false;
+
if (aFilter.isEmpty())
{
std::cerr << "Error: no export filter" << std::endl;
@@ -606,31 +638,57 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
else
{
sal_Int32 nFilterOptionsIndex = aFilter.indexOf(':');
- sal_Int32 nProps = ( 0 < nFilterOptionsIndex ) ? 3 : 2;
+ sal_Int32 nProps = ( 0 < nFilterOptionsIndex ) ? 4 : 3;
if ( !aImgOut.isEmpty() )
nProps +=1;
Sequence<PropertyValue> conversionProperties( nProps );
- conversionProperties[0].Name = "Overwrite";
- conversionProperties[0].Value <<= true;
+ auto pconversionProperties = conversionProperties.getArray();
+ pconversionProperties[0].Name = "ConversionRequestOrigin";
+ pconversionProperties[0].Value <<= OUString("CommandLine");
+ pconversionProperties[1].Name = "Overwrite";
+ pconversionProperties[1].Value <<= true;
- conversionProperties[1].Name = "FilterName";
+ pconversionProperties[2].Name = "FilterName";
if( 0 < nFilterOptionsIndex )
{
- conversionProperties[1].Value <<= aFilter.copy(0, nFilterOptionsIndex);
+ OUString sFilterName = aFilter.copy(0, nFilterOptionsIndex);
+ OUString sFilterOptions = aFilter.copy(nFilterOptionsIndex + 1);
- conversionProperties[2].Name = "FilterOptions";
- conversionProperties[2].Value <<= aFilter.copy(nFilterOptionsIndex + 1);
+ if (sFilterName == "Text - txt - csv (StarCalc)")
+ {
+ sal_Int32 nIdx(0);
+ // If the 11th token is '-1' then we export a file
+ // per sheet where the file name is based on the suggested
+ // output filename concatenated with the sheet name, so adjust
+ // the output and overwrite messages
+ // If the 11th token is not present or numeric 0 then the
+ // default sheet is exported with the output filename. If it
+ // is numeric >0 then that sheet (1-based) with the output
+ // filename concatenated with the sheet name. So even if
+ // that is a single file, the multi file target mechanism is
+ // used.
+ const OUString aTok(sFilterOptions.getToken(11, ',', nIdx));
+ // Actual validity is checked in Calc, here just check for
+ // presence of numeric value at start.
+ bMultiFileTarget = (!aTok.isEmpty() && aTok.toInt32() != 0);
+ }
+
+ pconversionProperties[2].Value <<= sFilterName;
+
+ pconversionProperties[3].Name = "FilterOptions";
+ pconversionProperties[3].Value <<= sFilterOptions;
}
else
{
- conversionProperties[1].Value <<= aFilter;
+ pconversionProperties[2].Value <<= aFilter;
}
if ( !aImgOut.isEmpty() )
{
- conversionProperties[nProps-1].Name = "ImageFilter";
- conversionProperties[nProps-1].Value <<= aImgOut;
+ assert(conversionProperties[nProps-1].Name.isEmpty());
+ pconversionProperties[nProps-1].Name = "ImageFilter";
+ pconversionProperties[nProps-1].Value <<= aImgOut;
}
OUString aTempName;
@@ -640,9 +698,14 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding());
if (aDispatchRequest.aRequestType != REQUEST_CAT)
{
- std::cout << "convert " << aSource8 << " -> " << aTargetURL8;
+ OUString name=getName(xDoc);
+ std::cout << "convert " << aSource8;
+ if (!name.isEmpty())
+ std::cout << " as a " << name <<" document";
+ if (!bMultiFileTarget)
+ std::cout << " -> " << aTargetURL8;
std::cout << " using filter : " << OUStringToOString(aFilter, osl_getThreadTextEncoding()) << std::endl;
- if (FStatHelper::IsDocument(aOutFile))
+ if (!bMultiFileTarget && FStatHelper::IsDocument(aOutFile))
std::cout << "Overwriting: " << OUStringToOString(aTempName, osl_getThreadTextEncoding()) << std::endl ;
}
try
@@ -689,16 +752,14 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
{
// create the printer
- Sequence < PropertyValue > aPrinterArgs( 1 );
- aPrinterArgs[0].Name = "Name";
- aPrinterArgs[0].Value <<= aDispatchRequest.aPrinterName;
+ Sequence < PropertyValue > aPrinterArgs{ comphelper::makePropertyValue(
+ "Name", aDispatchRequest.aPrinterName) };
xDoc->setPrinter( aPrinterArgs );
}
// print ( also without user interaction )
- Sequence < PropertyValue > aPrinterArgs( 1 );
- aPrinterArgs[0].Name = "Wait";
- aPrinterArgs[0].Value <<= true;
+ Sequence < PropertyValue > aPrinterArgs{ comphelper::makePropertyValue("Wait",
+ true) };
xDoc->print( aPrinterArgs );
}
}
@@ -733,11 +794,10 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
if ( !aDispatches.empty() )
{
// Execute all asynchronous dispatches now after we placed them into our request container!
- Sequence < PropertyValue > aArgs( 2 );
- aArgs[0].Name = "Referer";
- aArgs[0].Value <<= OUString("private:OpenEvent");
- aArgs[1].Name = "SynchronMode";
- aArgs[1].Value <<= true;
+ Sequence < PropertyValue > aArgs{
+ comphelper::makePropertyValue("Referer", OUString("private:OpenEvent")),
+ comphelper::makePropertyValue("SynchronMode", true)
+ };
for (const DispatchHolder & aDispatche : aDispatches)
{
@@ -747,18 +807,13 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
xDisp->dispatchWithNotification( aDispatche.aURL, aArgs, this );
else
{
- {
- osl::MutexGuard aGuard(m_mutex);
- m_nRequestCount--;
- }
+ m_nRequestCount--;
xDispatch->dispatch( aDispatche.aURL, aArgs );
}
}
}
- ::osl::ClearableMutexGuard aGuard(m_mutex);
bool bEmpty = (m_nRequestCount == 0);
- aGuard.clear();
// No more asynchronous requests?
// The requests are removed from the request container after they called back to this
@@ -786,9 +841,7 @@ void SAL_CALL DispatchWatcher::disposing( const css::lang::EventObject& )
void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& )
{
- osl::ClearableMutexGuard aGuard(m_mutex);
- sal_Int16 nCount = --m_nRequestCount;
- aGuard.clear();
+ int nCount = --m_nRequestCount;
RequestHandler::RequestsCompleted();
if ( !nCount && !RequestHandler::AreRequestsPending() )
{