sot/source/base/exchange.cxx     |    2 -
 sot/source/base/formats.cxx      |    8 ++---
 vcl/source/treelist/transfer.cxx |   56 ++++++++++++++++++++++++---------------
 3 files changed, 40 insertions(+), 26 deletions(-)

New commits:
commit f586839956d6937920aa377fe95854c1a0518d96
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Dec 3 11:51:03 2021 +0300
Commit:     Mike Kaganski <[email protected]>
CommitDate: Fri Dec 3 12:01:39 2021 +0100

    Windows format name is FileGroupDescriptorW for Unicode strings
    
    See also commit 5fb9f4ffa9284c7248e2e82210506babaad4044d
        tdf#145964: Windows format name is FileNameW for Unicode strings
    and commit 52e1d0ca6ad38b4b4fdc77b0951ad26f0ac18ec5
        Windows format name is UniformResourceLocatorW for Unicode strings
    
    We don't use other standard clipboard formats which have W variants.
    
    Change-Id: I45afac76fe3db406c8a761f48eee9e931fd50d45
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126276
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sot/source/base/exchange.cxx b/sot/source/base/exchange.cxx
index 3138d89de0aa..582ca49c5598 100644
--- a/sot/source/base/exchange.cxx
+++ b/sot/source/base/exchange.cxx
@@ -141,7 +141,7 @@ const DataFlavorRepresentation* FormatArray_Impl()
         /* 86 SotClipboardFormatId::LINK_SOURCE*/            { 
"application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source 
(XML)\"", "Star Link Source (XML)", &cppu::UnoType<Sequence<sal_Int8>>::get() },
         /* 87 SotClipboardFormatId::EMBEDDED_OBJ*/           { 
"application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded 
Object (XML)\"", "Star Embedded Object (XML)", 
&cppu::UnoType<Sequence<sal_Int8>>::get() },
         /* 88 SotClipboardFormatId::FILECONTENT*/            { 
"application/x-openoffice-filecontent;windows_formatname=\"FileContents\"", 
"FileContents", &cppu::UnoType<Sequence<sal_Int8>>::get() },
-        /* 89 SotClipboardFormatId::FILEGRPDESCRIPTOR*/      { 
"application/x-openoffice-filegrpdescriptor;windows_formatname=\"FileGroupDescriptor\"",
 "FileGroupDescriptor", &cppu::UnoType<Sequence<sal_Int8>>::get() },
+        /* 89 SotClipboardFormatId::FILEGRPDESCRIPTOR*/      { 
"application/x-openoffice-filegrpdescriptor;windows_formatname=\"FileGroupDescriptorW\"",
 "FileGroupDescriptor", &cppu::UnoType<Sequence<sal_Int8>>::get() },
         /* 90 SotClipboardFormatId::FILENAME*/               { 
"application/x-openoffice-filename;windows_formatname=\"FileNameW\"", 
"FileName", &cppu::UnoType<OUString>::get() },
         /* 91 SotClipboardFormatId::SD_OLE*/                 { 
"application/x-openoffice-sd-ole;windows_formatname=\"SD-OLE\"", "SD-OLE", 
&cppu::UnoType<Sequence<sal_Int8>>::get() },
         /* 92 SotClipboardFormatId::EMBEDDED_OBJ_OLE*/       { 
"application/x-openoffice-embedded-obj-ole;windows_formatname=\"Embedded 
Object\"", "Embedded Object", &cppu::UnoType<Sequence<sal_Int8>>::get() },
diff --git a/sot/source/base/formats.cxx b/sot/source/base/formats.cxx
index 8901064d6901..0b3d80120022 100644
--- a/sot/source/base/formats.cxx
+++ b/sot/source/base/formats.cxx
@@ -23,7 +23,7 @@
 #include <sysformats.hxx>
 #include <comphelper/classids.hxx>
 #include <comphelper/fileformat.h>
-
+#include <o3tl/char16_t2wchar_t.hxx>
 #include <tools/globname.hxx>
 #include <tools/stream.hxx>
 #include <com/sun/star/datatransfer/DataFlavor.hpp>
@@ -1359,12 +1359,12 @@ static bool CheckTransferableContext_Impl( const 
Reference< XTransferable >* pxT
 
                             if( aSeq.getLength() )
                             {
-                                FILEGROUPDESCRIPTOR const * pFDesc = 
reinterpret_cast<FILEGROUPDESCRIPTOR const *>(aSeq.getConstArray());
+                                FILEGROUPDESCRIPTORW const * pFDesc = 
reinterpret_cast<FILEGROUPDESCRIPTORW const *>(aSeq.getConstArray());
 
                                 if( pFDesc->cItems )
                                 {
-                                    OString sDesc( pFDesc->fgd[ 0 ].cFileName 
);
-                                    bRet = 4 < sDesc.getLength() && 
sDesc.copy(sDesc.getLength()-4).equalsIgnoreAsciiCase(".URL");
+                                    OUString sDesc( o3tl::toU(pFDesc->fgd[ 0 
].cFileName) );
+                                    bRet = 4 < sDesc.getLength() && 
sDesc.endsWithIgnoreAsciiCase(".URL");
                                 }
                             }
                         }
diff --git a/vcl/source/treelist/transfer.cxx b/vcl/source/treelist/transfer.cxx
index 4561535d0291..260e3ba65613 100644
--- a/vcl/source/treelist/transfer.cxx
+++ b/vcl/source/treelist/transfer.cxx
@@ -22,6 +22,7 @@
 #include <postwin.h>
 #include <shlobj.h>
 #endif
+#include <o3tl/char16_t2wchar_t.hxx>
 #include <osl/mutex.hxx>
 #include <rtl/uri.hxx>
 #include <sal/log.hxx>
@@ -76,6 +77,7 @@ using namespace ::com::sun::star::io;
 using namespace ::com::sun::star::datatransfer;
 using namespace ::com::sun::star::datatransfer::clipboard;
 using namespace ::com::sun::star::datatransfer::dnd;
+using namespace std::literals::string_view_literals;
 
 
 #define TOD_SIG1 0x01234567
@@ -797,23 +799,21 @@ bool TransferableHelper::SetINetBookmark( const 
INetBookmark& rBmk,
 #ifdef _WIN32
         case SotClipboardFormatId::FILEGRPDESCRIPTOR:
         {
-            Sequence< sal_Int8 >    aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
-            FILEGROUPDESCRIPTOR*    pFDesc = 
reinterpret_cast<FILEGROUPDESCRIPTOR*>(aSeq.getArray());
-            FILEDESCRIPTOR&         rFDesc1 = pFDesc->fgd[ 0 ];
+            Sequence< sal_Int8 >    aSeq( sizeof( FILEGROUPDESCRIPTORW ) );
+            FILEGROUPDESCRIPTORW*   pFDesc = 
reinterpret_cast<FILEGROUPDESCRIPTORW*>(aSeq.getArray());
+            FILEDESCRIPTORW&        rFDesc1 = pFDesc->fgd[ 0 ];
 
             pFDesc->cItems = 1;
-            memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
+            memset( &rFDesc1, 0, sizeof( rFDesc1 ) );
             rFDesc1.dwFlags = FD_LINKUI;
 
-            OStringBuffer aStr(OUStringToOString(
-                rBmk.GetDescription(), eSysCSet));
-            for( sal_Int32 nChar = 0; nChar < aStr.getLength(); ++nChar )
-                if( strchr( "\\/:*?\"<>|", aStr[nChar] ) )
-                    aStr.remove(nChar--, 1);
+            OUStringBuffer aStr(rBmk.GetDescription());
+            for( size_t nChar = 0; (nChar = 
std::u16string_view(aStr).find_first_of(u"\\/:*?\"<>|"sv, nChar)) != 
std::u16string_view::npos; )
+                aStr.remove(nChar, 1);
 
             aStr.insert(0, "Shortcut to ");
             aStr.append(".URL");
-            strcpy( rFDesc1.cFileName, aStr.getStr() );
+            wcscpy( rFDesc1.cFileName, o3tl::toW(aStr.getStr()) );
 
             maAny <<= aSeq;
         }
@@ -1895,16 +1895,15 @@ bool TransferableDataHelper::GetINetBookmark( const 
css::datatransfer::DataFlavo
 
             if (aSeq.getLength())
             {
-                FILEGROUPDESCRIPTOR const * pFDesc = 
reinterpret_cast<FILEGROUPDESCRIPTOR const *>(aSeq.getConstArray());
+                FILEGROUPDESCRIPTORW const * pFDesc = 
reinterpret_cast<FILEGROUPDESCRIPTORW const *>(aSeq.getConstArray());
 
                 if( pFDesc->cItems )
                 {
-                    OString aDesc( pFDesc->fgd[ 0 ].cFileName );
-                    rtl_TextEncoding    eTextEncoding = 
osl_getThreadTextEncoding();
+                    OUString aDesc( o3tl::toU(pFDesc->fgd[ 0 ].cFileName) );
 
-                    if( ( aDesc.getLength() > 4 ) && 
aDesc.copy(aDesc.getLength() - 4).equalsIgnoreAsciiCase(".URL") )
+                    if( ( aDesc.getLength() > 4 ) && 
aDesc.endsWithIgnoreAsciiCase(".URL") )
                     {
-                        std::unique_ptr<SvStream> 
pStream(::utl::UcbStreamHelper::CreateStream( INetURLObject( 
OStringToOUString(aDesc, eTextEncoding) ).GetMainURL( 
INetURLObject::DecodeMechanism::NONE ),
+                        std::unique_ptr<SvStream> 
pStream(::utl::UcbStreamHelper::CreateStream( INetURLObject( aDesc 
).GetMainURL( INetURLObject::DecodeMechanism::NONE ),
                                                                                
   StreamMode::STD_READ ));
 
                         if( !pStream || pStream->GetError() )
@@ -1925,18 +1924,33 @@ bool TransferableDataHelper::GetINetBookmark( const 
css::datatransfer::DataFlavo
                         if( pStream )
                         {
                             OString aLine;
-                            bool    bSttFnd = false;
+                            bool bInA = false, bInW = false, bAFound = false;
 
                             while( pStream->ReadLine( aLine ) )
                             {
-                                if 
(aLine.equalsIgnoreAsciiCase("[InternetShortcut]"))
-                                    bSttFnd = true;
-                                else if (bSttFnd && aLine.copy(0, 
4).equalsIgnoreAsciiCase("URL="))
+                                if 
(aLine.startsWithIgnoreAsciiCase("[InternetShortcut", &aLine))
                                 {
+                                    // May be [InternetShortcut], or 
[InternetShortcut.A], or
+                                    // [InternetShortcut.W] (the latter has 
UTF-7-encoded URL)
+                                    bInW = aLine.equalsIgnoreAsciiCase(".W]");
+                                    bInA = !bAFound && !bInW
+                                           && (aLine == "]" || 
aLine.equalsIgnoreAsciiCase(".A]"));
+                                }
+                                else if (aLine.startsWith("["))
+                                {
+                                    bInA = bInW = false;
+                                }
+                                else if ((bInA || bInW) && 
aLine.startsWithIgnoreAsciiCase("URL="))
+                                {
+                                    auto eTextEncoding = bInW ? 
RTL_TEXTENCODING_UTF7
+                                                              : 
osl_getThreadTextEncoding();
                                     rBmk = INetBookmark( 
OStringToOUString(aLine.subView(4), eTextEncoding),
-                                                         
OStringToOUString(aDesc.subView(0, aDesc.getLength() - 4), eTextEncoding) );
+                                                         aDesc.copy(0, 
aDesc.getLength() - 4) );
                                     bRet = true;
-                                    break;
+                                    if (bInW)
+                                        break;
+                                    else
+                                        bAFound = true; // Keep looking for "W"
                                 }
                             }
                         }

Reply via email to