[Libreoffice-commits] core.git: desktop/source include/sfx2 include/vcl sfx2/source vcl/aqua

Stephan Bergmann sbergman at redhat.com
Sat Jul 27 10:50:57 PDT 2013


 desktop/source/app/app.cxx      |   24 +++++++------
 include/sfx2/app.hxx            |    1 
 include/vcl/svapp.hxx           |   40 ++++++++++++++++++----
 sfx2/source/appl/appdde.cxx     |   71 ++++++++++++++++++++++++----------------
 vcl/aqua/source/app/salinst.cxx |    3 -
 vcl/aqua/source/app/vclnsapp.mm |   30 ++++++++--------
 6 files changed, 106 insertions(+), 63 deletions(-)

New commits:
commit 787940e0ac285aa1101ca8964d252faaab3ea8c1
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Sat Jul 27 19:47:01 2013 +0200

    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

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 137dbac..96e244d 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 d202219..e2b9095 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 886a414..2ceb713 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 dd68081..5f2ab9c 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 3a8e5c1..9dfc4e4 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 c4773b9..e211642 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]


More information about the Libreoffice-commits mailing list