summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-07-27 19:47:01 +0200
committerStephan Bergmann <sbergman@redhat.com>2013-07-27 19:47:01 +0200
commit787940e0ac285aa1101ca8964d252faaab3ea8c1 (patch)
tree1f9dc8a0ae0693e31aa79d4e2d47586b5e603fde
parenta1c081a7c213a56321b0b60651a1dbd63bcaec80 (diff)
fdo#54264: Fix multi-argument ApplicationEvent::TYPE_OPEN/PRINT
...that had been broken when 5c22a03320f20ae9ac2c3c16025e7c5e3a7915d5> "Cleaned up CommandLineArgs" changed the representation of those multi-arguments from a single string with \n delimiters to vector<string> in desktop/soruce/app/cmdlineargs.hxx, but missed updating other producers of such ApplicationEvents. Change-Id: I527d620c60a87f3a01d970927c521163fb6df192
-rw-r--r--desktop/source/app/app.cxx24
-rw-r--r--include/sfx2/app.hxx1
-rw-r--r--include/vcl/svapp.hxx40
-rw-r--r--sfx2/source/appl/appdde.cxx71
-rw-r--r--vcl/aqua/source/app/salinst.cxx3
-rw-r--r--vcl/aqua/source/app/vclnsapp.mm30
6 files changed, 106 insertions, 63 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 137dbac24979..96e244dc208e 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -2616,7 +2616,7 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
case ApplicationEvent::TYPE_ACCEPT:
// every time an accept parameter is used we create an acceptor
// with the corresponding accept-string
- createAcceptor(rAppEvent.GetData());
+ createAcceptor(rAppEvent.GetStringData());
break;
case ApplicationEvent::TYPE_APPEAR:
if ( !GetCommandLineArgs().IsInvisible() )
@@ -2665,7 +2665,7 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
}
break;
case ApplicationEvent::TYPE_HELP:
- displayCmdlineHelp(rAppEvent.GetData());
+ displayCmdlineHelp(rAppEvent.GetStringData());
break;
case ApplicationEvent::TYPE_VERSION:
displayVersion();
@@ -2677,7 +2677,9 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
{
ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
rCmdLine.getCwdUrl());
- pDocsRequest->aOpenList.push_back(rAppEvent.GetData());
+ std::vector<OUString> const & data(rAppEvent.GetStringsData());
+ pDocsRequest->aOpenList.insert(
+ pDocsRequest->aOpenList.end(), data.begin(), data.end());
pDocsRequest->pcProcessed = NULL;
OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
@@ -2687,7 +2689,7 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
break;
case ApplicationEvent::TYPE_OPENHELPURL:
// start help for a specific URL
- Application::GetHelp()->Start(rAppEvent.GetData(), NULL);
+ Application::GetHelp()->Start(rAppEvent.GetStringData(), NULL);
break;
case ApplicationEvent::TYPE_PRINT:
{
@@ -2696,7 +2698,9 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
{
ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
rCmdLine.getCwdUrl());
- pDocsRequest->aPrintList.push_back(rAppEvent.GetData());
+ std::vector<OUString> const & data(rAppEvent.GetStringsData());
+ pDocsRequest->aPrintList.insert(
+ pDocsRequest->aPrintList.end(), data.begin(), data.end());
pDocsRequest->pcProcessed = NULL;
OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
@@ -2735,10 +2739,10 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
css::util::URL aCommand;
- if( rAppEvent.GetData() == OUString("PREFERENCES") )
- aCommand.Complete = OUString( ".uno:OptionsTreeDialog" );
- else if( rAppEvent.GetData() == OUString("ABOUT") )
- aCommand.Complete = OUString( ".uno:About" );
+ if( rAppEvent.GetStringData() == "PREFERENCES" )
+ aCommand.Complete = ".uno:OptionsTreeDialog";
+ else if( rAppEvent.GetStringData() == "ABOUT" )
+ aCommand.Complete = ".uno:About";
if( !aCommand.Complete.isEmpty() )
{
xParser->parseStrict(aCommand);
@@ -2753,7 +2757,7 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
break;
case ApplicationEvent::TYPE_UNACCEPT:
// try to remove corresponding acceptor
- destroyAcceptor(rAppEvent.GetData());
+ destroyAcceptor(rAppEvent.GetStringData());
break;
default:
SAL_WARN( "desktop.app", "this cannot happen");
diff --git a/include/sfx2/app.hxx b/include/sfx2/app.hxx
index d202219d917b..e2b90959af88 100644
--- a/include/sfx2/app.hxx
+++ b/include/sfx2/app.hxx
@@ -40,7 +40,6 @@
#include <vector>
class Timer;
-class ApplicationEvent;
class WorkWindow;
class ISfxTemplateCommon;
class BasicManager;
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index 886a41401be7..2ceb713367f4 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -24,7 +24,9 @@
#include <sal/config.h>
+#include <cassert>
#include <stdexcept>
+#include <vector>
#include <comphelper/solarmutex.hxx>
#include <osl/thread.hxx>
@@ -100,20 +102,42 @@ public:
TYPE_SHOWDIALOG, TYPE_UNACCEPT
};
- ApplicationEvent() {}
+ explicit ApplicationEvent(Type type): aEvent(type) {
+ assert(
+ type == TYPE_APPEAR || type == TYPE_VERSION
+ || type == TYPE_PRIVATE_DOSHUTDOWN || type == TYPE_QUICKSTART);
+ }
+
+ ApplicationEvent(Type type, OUString const & data): aEvent(type) {
+ assert(
+ type == TYPE_ACCEPT || type == TYPE_HELP || type == TYPE_OPENHELPURL
+ || type == TYPE_SHOWDIALOG || type == TYPE_UNACCEPT);
+ aData.push_back(data);
+ }
- explicit ApplicationEvent(
- Type rEvent, const OUString& rData = OUString()):
- aEvent(rEvent),
- aData(rData)
- {}
+ ApplicationEvent(Type type, std::vector<OUString> const & data):
+ aEvent(type), aData(data)
+ { assert(type == TYPE_OPEN || type == TYPE_PRINT); }
Type GetEvent() const { return aEvent; }
- const OUString& GetData() const { return aData; }
+
+ OUString GetStringData() const {
+ assert(
+ aEvent == TYPE_ACCEPT || aEvent == TYPE_HELP
+ || aEvent == TYPE_OPENHELPURL || aEvent == TYPE_SHOWDIALOG
+ || aEvent == TYPE_UNACCEPT);
+ assert(aData.size() == 1);
+ return aData[0];
+ }
+
+ std::vector<OUString> const & GetStringsData() const {
+ assert(aEvent == TYPE_OPEN || aEvent == TYPE_PRINT);
+ return aData;
+ }
private:
Type aEvent;
- OUString aData;
+ std::vector<OUString> aData;
};
diff --git a/sfx2/source/appl/appdde.cxx b/sfx2/source/appl/appdde.cxx
index dd680810c3ac..5f2ab9cf0f36 100644
--- a/sfx2/source/appl/appdde.cxx
+++ b/sfx2/source/appl/appdde.cxx
@@ -230,10 +230,14 @@ public:
class SfxDdeDocTopics_Impl : public std::vector<SfxDdeDocTopic_Impl*> {};
+#if defined( WNT )
+
+namespace {
+
/* [Description]
Checks if 'rCmd' of the event 'rEvent' is (without '(') and then assemble
- this data into a <ApplicationEvent>, which can be excecuted through
+ this data into a <ApplicationEvent>, which is then excecuted through
<Application::AppEvent()>. If 'rCmd' is the given event 'rEvent', then
TRUE is returned, otherwise FALSE.
@@ -242,41 +246,55 @@ class SfxDdeDocTopics_Impl : public std::vector<SfxDdeDocTopic_Impl*> {};
rCmd = "Open(\"d:\doc\doc.sdw\")"
rEvent = "Open"
*/
-sal_Bool SfxAppEvent_Impl( ApplicationEvent &rAppEvent,
- const OUString& rCmd, const OUString& rEvent,
+sal_Bool SfxAppEvent_Impl( const OUString& rCmd, const OUString& rEvent,
ApplicationEvent::Type eType )
{
- OUString sEvent(rEvent);
- sEvent += "(";
+ OUString sEvent(rEvent + "(");
if (rCmd.startsWithIgnoreAsciiCase(sEvent))
{
- OUStringBuffer aData( rCmd );
- aData.remove(0, sEvent.getLength());
- if ( aData.getLength() > 2 )
+ sal_Int32 start = sEvent.getLength();
+ if ( rCmd.getLength() - start >= 2 )
{
// Transform into the ApplicationEvent Format
- aData.remove( aData.getLength() - 1, 1 );
- for ( sal_Int32 n = 0; n < aData.getLength(); )
+ std::vector<OUString> aData;
+ for ( sal_Int32 n = start; n < rCmd.getLength() - 1; )
{
- switch ( aData[n] )
+ // Resiliently read arguments either starting with " and
+ // spanning to the next " (if any; TODO: do we need to undo any
+ // escaping within the string?) or with neither " nor SPC and
+ // spanning to the next SPC (if any; TODO: is this from not
+ // wrapped in "..." relevant? it would have been parsed by the
+ // original code even if that was only by accident, so I left it
+ // in), with runs of SPCs treated like single ones:
+ switch ( rCmd[n] )
{
case '"':
- aData.remove( n, 1 );
- while ( n < aData.getLength() && aData[n] != '"' )
- ++n;
- if ( n < aData.getLength() )
- aData.remove( n, 1 );
- break;
+ {
+ sal_Int32 i = rCmd.indexOf('"', ++n);
+ if (i < 0 || i > rCmd.getLength() - 1) {
+ i = rCmd.getLength() - 1;
+ }
+ aData.push_back(rCmd.copy(n, i - n));
+ n = i + 1;
+ break;
+ }
case ' ':
- aData[n++] = '\n';
- break;
- default:
++n;
break;
+ default:
+ {
+ sal_Int32 i = rCmd.indexOf(' ', n);
+ if (i < 0 || i > rCmd.getLength() - 1) {
+ i = rCmd.getLength() - 1;
+ }
+ aData.push_back(rCmd.copy(n, i - n));
+ n = i + 1;
+ break;
+ }
}
}
- rAppEvent = ApplicationEvent(eType, aData.makeStringAndClear());
+ GetpApp()->AppEvent( ApplicationEvent(eType, aData) );
return sal_True;
}
}
@@ -284,7 +302,8 @@ sal_Bool SfxAppEvent_Impl( ApplicationEvent &rAppEvent,
return sal_False;
}
-#if defined( WNT )
+}
+
/* Description]
This method can be overloaded by application developers, to receive
@@ -297,11 +316,8 @@ sal_Bool SfxAppEvent_Impl( ApplicationEvent &rAppEvent,
long SfxApplication::DdeExecute( const OUString& rCmd ) // Expressed in our BASIC-Syntax
{
// Print or Open-Event?
- ApplicationEvent aAppEvent;
- if ( SfxAppEvent_Impl( aAppEvent, rCmd, "Print", ApplicationEvent::TYPE_PRINT ) ||
- SfxAppEvent_Impl( aAppEvent, rCmd, "Open", ApplicationEvent::TYPE_OPEN ) )
- GetpApp()->AppEvent( aAppEvent );
- else
+ if ( !( SfxAppEvent_Impl( rCmd, "Print", ApplicationEvent::TYPE_PRINT ) ||
+ SfxAppEvent_Impl( rCmd, "Open", ApplicationEvent::TYPE_OPEN ) ) )
{
// all others are BASIC
StarBASIC* pBasic = GetBasic();
@@ -315,6 +331,7 @@ long SfxApplication::DdeExecute( const OUString& rCmd ) // Expressed in our B
}
return 1;
}
+
#endif
/* [Description]
diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx
index 3a8e5c1697c7..9dfc4e441b5f 100644
--- a/vcl/aqua/source/app/salinst.cxx
+++ b/vcl/aqua/source/app/salinst.cxx
@@ -110,8 +110,7 @@ void AquaSalInstance::delayedSettingsChanged( bool bInvalidate )
// the AppEventList must be available before any SalData/SalInst/etc. objects are ready
-typedef std::list<const ApplicationEvent*> AppEventList;
-AppEventList AquaSalInstance::aAppEventList;
+AquaSalInstance::AppEventList AquaSalInstance::aAppEventList;
NSMenu* AquaSalInstance::GetDynamicDockMenu()
{
diff --git a/vcl/aqua/source/app/vclnsapp.mm b/vcl/aqua/source/app/vclnsapp.mm
index c4773b946c2e..e211642d91ae 100644
--- a/vcl/aqua/source/app/vclnsapp.mm
+++ b/vcl/aqua/source/app/vclnsapp.mm
@@ -17,7 +17,9 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include "rtl/ustrbuf.hxx"
+#include "sal/config.h"
+
+#include <vector>
#include "vcl/window.hxx"
#include "vcl/svapp.hxx"
@@ -288,8 +290,9 @@
-(BOOL)application: (NSApplication*)app openFile: (NSString*)pFile
{
(void)app;
- const rtl::OUString aFile( GetOUString( pFile ) );
- if( ! AquaSalInstance::isOnCommandLine( aFile ) )
+ std::vector<OUString> aFile;
+ aFile.push_back( GetOUString( pFile ) );
+ if( ! AquaSalInstance::isOnCommandLine( aFile[0] ) )
{
const ApplicationEvent* pAppEvent = new ApplicationEvent(ApplicationEvent::TYPE_OPEN, aFile);
AquaSalInstance::aAppEventList.push_back( pAppEvent );
@@ -300,7 +303,7 @@
-(void)application: (NSApplication*) app openFiles: (NSArray*)files
{
(void)app;
- rtl::OUStringBuffer aFileList( 256 );
+ std::vector<OUString> aFileList;
NSEnumerator* it = [files objectEnumerator];
NSString* pFile = nil;
@@ -310,18 +313,16 @@
const rtl::OUString aFile( GetOUString( pFile ) );
if( ! AquaSalInstance::isOnCommandLine( aFile ) )
{
- if( aFileList.getLength() > 0 )
- aFileList.append('\n');
- aFileList.append( aFile );
+ aFileList.push_back( aFile );
}
}
- if( aFileList.getLength() )
+ if( !aFileList.empty() )
{
// we have no back channel here, we have to assume success, in which case
// replyToOpenOrPrint does not need to be called according to documentation
// [app replyToOpenOrPrint: NSApplicationDelegateReplySuccess];
- const ApplicationEvent* pAppEvent = new ApplicationEvent(ApplicationEvent::TYPE_OPEN, aFileList.makeStringAndClear());
+ const ApplicationEvent* pAppEvent = new ApplicationEvent(ApplicationEvent::TYPE_OPEN, aFileList);
AquaSalInstance::aAppEventList.push_back( pAppEvent );
}
}
@@ -329,7 +330,8 @@
-(BOOL)application: (NSApplication*)app printFile: (NSString*)pFile
{
(void)app;
- const rtl::OUString aFile( GetOUString( pFile ) );
+ std::vector<OUString> aFile;
+ aFile.push_back( GetOUString( pFile ) );
const ApplicationEvent* pAppEvent = new ApplicationEvent(ApplicationEvent::TYPE_PRINT, aFile);
AquaSalInstance::aAppEventList.push_back( pAppEvent );
return YES;
@@ -340,18 +342,16 @@
(void)printSettings;
(void)bShowPrintPanels;
// currently ignores print settings an bShowPrintPanels
- rtl::OUStringBuffer aFileList( 256 );
+ std::vector<OUString> aFileList;
NSEnumerator* it = [files objectEnumerator];
NSString* pFile = nil;
while( (pFile = [it nextObject]) != nil )
{
- if( aFileList.getLength() > 0 )
- aFileList.append('\n');
- aFileList.append( GetOUString( pFile ) );
+ aFileList.push_back( GetOUString( pFile ) );
}
- const ApplicationEvent* pAppEvent = new ApplicationEvent(ApplicationEvent::TYPE_PRINT, aFileList.makeStringAndClear());
+ const ApplicationEvent* pAppEvent = new ApplicationEvent(ApplicationEvent::TYPE_PRINT, aFileList);
AquaSalInstance::aAppEventList.push_back( pAppEvent );
// we have no back channel here, we have to assume success
// correct handling would be NSPrintingReplyLater and then send [app replyToOpenOrPrint]