1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <vcl/dialog.hxx>
22 #include <vcl/edit.hxx>
23 #include <vcl/button.hxx>
24 #include <vcl/msgbox.hxx>
25 #include <vcl/svapp.hxx>
26 #include <osl/security.h>
27 #include <osl/file.hxx>
28 #include <tools/urlobj.hxx>
29 #include <osl/mutex.hxx>
31 #include "runtime.hxx"
33 #include <sal/alloca.h>
36 #include <rtl/byteseq.hxx>
37 #include <rtl/textenc.h>
38 #include <rtl/strbuf.hxx>
39 #include <rtl/ustrbuf.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <comphelper/string.hxx>
44 #include <com/sun/star/bridge/BridgeFactory.hpp>
45 #include <com/sun/star/bridge/XBridge.hpp>
46 #include <com/sun/star/uno/Sequence.hxx>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
49 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
50 #include <com/sun/star/ucb/XContentProvider.hpp>
51 #include <com/sun/star/ucb/XContentProviderManager.hpp>
52 #include <com/sun/star/io/XInputStream.hpp>
53 #include <com/sun/star/io/XOutputStream.hpp>
54 #include <com/sun/star/io/XStream.hpp>
55 #include <com/sun/star/io/XSeekable.hpp>
57 using namespace com::sun::star::uno
;
58 using namespace com::sun::star::lang
;
59 using namespace com::sun::star::ucb
;
60 using namespace com::sun::star::io
;
61 using namespace com::sun::star::bridge
;
64 #include "sbintern.hxx"
68 class SbiInputDialog
: public ModalDialog
{
71 VclPtr
<CancelButton
> aCancel
;
73 DECL_LINK( Ok
, vcl::Window
* );
74 DECL_LINK( Cancel
, vcl::Window
* );
76 SbiInputDialog( vcl::Window
*, const OUString
& );
77 virtual ~SbiInputDialog() { disposeOnce(); }
78 virtual void dispose() SAL_OVERRIDE
;
79 const OUString
& GetInput() { return aText
; }
82 SbiInputDialog::SbiInputDialog( vcl::Window
* pParent
, const OUString
& rPrompt
)
83 :ModalDialog( pParent
, WB_3DLOOK
| WB_MOVEABLE
| WB_CLOSEABLE
),
84 aInput( VclPtr
<Edit
>::Create(this, WB_3DLOOK
| WB_LEFT
| WB_BORDER
) ),
85 aOk( VclPtr
<OKButton
>::Create(this) ), aCancel( VclPtr
<CancelButton
>::Create(this) )
88 aOk
->SetClickHdl( LINK( this, SbiInputDialog
, Ok
) );
89 aCancel
->SetClickHdl( LINK( this, SbiInputDialog
, Cancel
) );
90 SetMapMode( MapMode( MAP_APPFONT
) );
92 Point aPt
= LogicToPixel( Point( 50, 50 ) );
93 Size aSz
= LogicToPixel( Size( 145, 65 ) );
94 SetPosSizePixel( aPt
, aSz
);
95 aPt
= LogicToPixel( Point( 10, 10 ) );
96 aSz
= LogicToPixel( Size( 120, 12 ) );
97 aInput
->SetPosSizePixel( aPt
, aSz
);
98 aPt
= LogicToPixel( Point( 15, 30 ) );
99 aSz
= LogicToPixel( Size( 45, 15) );
100 aOk
->SetPosSizePixel( aPt
, aSz
);
101 aPt
= LogicToPixel( Point( 80, 30 ) );
102 aSz
= LogicToPixel( Size( 45, 15) );
103 aCancel
->SetPosSizePixel( aPt
, aSz
);
110 void SbiInputDialog::dispose()
112 aInput
.disposeAndClear();
113 aOk
.disposeAndClear();
114 aCancel
.disposeAndClear();
115 ModalDialog::dispose();
118 IMPL_LINK( SbiInputDialog
, Ok
, vcl::Window
*, pWindow
)
122 aText
= aInput
->GetText();
127 IMPL_LINK( SbiInputDialog
, Cancel
, vcl::Window
*, pWindow
)
135 SbiStream::SbiStream()
137 , nExpandOnWriteTo(0)
146 SbiStream::~SbiStream()
151 // map an SvStream-error to StarBASIC-code
153 void SbiStream::MapError()
157 switch( pStrm
->GetError() )
162 case SVSTREAM_FILE_NOT_FOUND
:
163 nError
= SbERR_FILE_NOT_FOUND
;
165 case SVSTREAM_PATH_NOT_FOUND
:
166 nError
= SbERR_PATH_NOT_FOUND
;
168 case SVSTREAM_TOO_MANY_OPEN_FILES
:
169 nError
= SbERR_TOO_MANY_FILES
;
171 case SVSTREAM_ACCESS_DENIED
:
172 nError
= SbERR_ACCESS_DENIED
;
174 case SVSTREAM_INVALID_PARAMETER
:
175 nError
= SbERR_BAD_ARGUMENT
;
177 case SVSTREAM_OUTOFMEMORY
:
178 nError
= SbERR_NO_MEMORY
;
181 nError
= SbERR_IO_ERROR
;
187 // TODO: Code is copied from daemons2/source/uno/asciiEncoder.cxx
189 OUString
findUserInDescription( const OUString
& aDescription
)
194 sal_Int32 lastIndex
= 0;
198 index
= aDescription
.indexOf((sal_Unicode
) ',', lastIndex
);
199 OUString token
= (index
== -1) ? aDescription
.copy(lastIndex
) : aDescription
.copy(lastIndex
, index
- lastIndex
);
201 lastIndex
= index
+ 1;
203 sal_Int32 eindex
= token
.indexOf((sal_Unicode
)'=');
204 OUString left
= token
.copy(0, eindex
).toAsciiLowerCase().trim();
205 OUString right
= INetURLObject::decode( token
.copy(eindex
+ 1).trim(),
206 INetURLObject::DECODE_WITH_CHARSET
);
219 bool needSecurityRestrictions()
221 static bool bNeedInit
= true;
222 static bool bRetVal
= true;
228 // Get system user to compare to portal user
229 oslSecurity aSecurity
= osl_getCurrentSecurity();
230 OUString aSystemUser
;
231 bool bRet
= osl_getUserName( aSecurity
, &aSystemUser
.pData
);
232 osl_freeSecurityHandle(aSecurity
);
235 // No valid security! -> Secure mode!
239 Reference
< XComponentContext
> xContext
= comphelper::getProcessComponentContext();
240 Reference
< XBridgeFactory2
> xBridgeFac( BridgeFactory::create(xContext
) );
242 Sequence
< Reference
< XBridge
> > aBridgeSeq
= xBridgeFac
->getExistingBridges();
243 sal_Int32 nBridgeCount
= aBridgeSeq
.getLength();
245 if( nBridgeCount
== 0 )
247 // No bridges -> local
252 // Iterate through all bridges to find (portal) user property
253 const Reference
< XBridge
>* pBridges
= aBridgeSeq
.getConstArray();
254 bRetVal
= false; // Now only sal_True if user different from portal user is found
256 for( i
= 0 ; i
< nBridgeCount
; i
++ )
258 const Reference
< XBridge
>& rxBridge
= pBridges
[ i
];
259 OUString aDescription
= rxBridge
->getDescription();
260 OUString aPortalUser
= findUserInDescription( aDescription
);
261 if( !aPortalUser
.isEmpty() )
263 // User Found, compare to system user
264 if( aPortalUser
== aSystemUser
)
266 // Same user -> system security is ok, bRetVal stays FALSE
271 // Different user -> Secure mode!
277 // No user found or PortalUser != SystemUser -> Secure mode! (Keep default value)
283 // Returns sal_True if UNO is available, otherwise the old file
284 // system implementation has to be used
285 // #89378 New semantic: Don't just ask for UNO but for UCB
288 static bool bNeedInit
= true;
289 static bool bRetVal
= true;
294 Reference
< XComponentContext
> xContext
= comphelper::getProcessComponentContext();
297 // No service manager at all
302 Reference
< XUniversalContentBroker
> xManager
= UniversalContentBroker::create(xContext
);
304 if ( !( xManager
->queryContentProvider( OUString("file:///" ) ).is() ) )
316 class OslStream
: public SvStream
321 OslStream( const OUString
& rName
, StreamMode nStrmMode
);
322 virtual ~OslStream();
323 virtual sal_Size
GetData( void* pData
, sal_Size nSize
) SAL_OVERRIDE
;
324 virtual sal_Size
PutData( const void* pData
, sal_Size nSize
) SAL_OVERRIDE
;
325 virtual sal_uInt64
SeekPos( sal_uInt64 nPos
) SAL_OVERRIDE
;
326 virtual void FlushData() SAL_OVERRIDE
;
327 virtual void SetSize( sal_uInt64 nSize
) SAL_OVERRIDE
;
330 OslStream::OslStream( const OUString
& rName
, StreamMode nStrmMode
)
335 if( (nStrmMode
& (StreamMode::READ
| StreamMode::WRITE
)) == (StreamMode::READ
| StreamMode::WRITE
) )
337 nFlags
= osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
;
339 else if( nStrmMode
& StreamMode::WRITE
)
341 nFlags
= osl_File_OpenFlag_Write
;
343 else //if( nStrmMode & StreamMode::READ )
345 nFlags
= osl_File_OpenFlag_Read
;
348 osl::FileBase::RC nRet
= maFile
.open( nFlags
);
349 if( nRet
== osl::FileBase::E_NOENT
&& nFlags
!= osl_File_OpenFlag_Read
)
351 nFlags
|= osl_File_OpenFlag_Create
;
352 nRet
= maFile
.open( nFlags
);
355 if( nRet
!= osl::FileBase::E_None
)
357 SetError( ERRCODE_IO_GENERAL
);
362 OslStream::~OslStream()
367 sal_Size
OslStream::GetData(void* pData
, sal_Size nSize
)
369 sal_uInt64 nBytesRead
= nSize
;
370 maFile
.read( pData
, nBytesRead
, nBytesRead
);
374 sal_Size
OslStream::PutData(const void* pData
, sal_Size nSize
)
376 sal_uInt64 nBytesWritten
;
377 maFile
.write( pData
, nSize
, nBytesWritten
);
378 return nBytesWritten
;
381 sal_uInt64
OslStream::SeekPos( sal_uInt64 nPos
)
383 ::osl::FileBase::RC rc
= ::osl::FileBase::E_None
;
384 // check if a truncated STREAM_SEEK_TO_END was passed
385 assert(nPos
!= SAL_MAX_UINT32
);
386 if( nPos
== STREAM_SEEK_TO_END
)
388 rc
= maFile
.setPos( osl_Pos_End
, 0 );
392 rc
= maFile
.setPos( osl_Pos_Absolut
, (sal_uInt64
)nPos
);
394 OSL_VERIFY(rc
== ::osl::FileBase::E_None
);
395 sal_uInt64
nRealPos(0);
396 maFile
.getPos( nRealPos
);
400 void OslStream::FlushData()
404 void OslStream::SetSize( sal_uInt64 nSize
)
406 maFile
.setSize( nSize
);
410 class UCBStream
: public SvStream
412 Reference
< XInputStream
> xIS
;
413 Reference
< XStream
> xS
;
414 Reference
< XSeekable
> xSeek
;
416 UCBStream( Reference
< XInputStream
> & xIS
);
417 UCBStream( Reference
< XStream
> & xS
);
418 virtual ~UCBStream();
419 virtual sal_Size
GetData( void* pData
, sal_Size nSize
) SAL_OVERRIDE
;
420 virtual sal_Size
PutData( const void* pData
, sal_Size nSize
) SAL_OVERRIDE
;
421 virtual sal_uInt64
SeekPos( sal_uInt64 nPos
) SAL_OVERRIDE
;
422 virtual void FlushData() SAL_OVERRIDE
;
423 virtual void SetSize( sal_uInt64 nSize
) SAL_OVERRIDE
;
426 UCBStream::UCBStream( Reference
< XInputStream
> & rStm
)
428 , xSeek( rStm
, UNO_QUERY
)
432 UCBStream::UCBStream( Reference
< XStream
> & rStm
)
434 , xSeek( rStm
, UNO_QUERY
)
439 UCBStream::~UCBStream()
449 Reference
< XInputStream
> xIS_
= xS
->getInputStream();
456 catch(const Exception
& )
458 SetError( ERRCODE_IO_GENERAL
);
462 sal_Size
UCBStream::GetData(void* pData
, sal_Size nSize
)
466 Reference
< XInputStream
> xISFromS
;
469 Sequence
<sal_Int8
> aData
;
470 nSize
= xIS
->readBytes( aData
, nSize
);
471 memcpy( pData
, aData
.getConstArray(), nSize
);
474 else if( xS
.is() && (xISFromS
= xS
->getInputStream()).is() )
476 Sequence
<sal_Int8
> aData
;
477 nSize
= xISFromS
->readBytes( aData
, nSize
);
478 memcpy(pData
, aData
.getConstArray(), nSize
);
483 SetError( ERRCODE_IO_GENERAL
);
486 catch(const Exception
& )
488 SetError( ERRCODE_IO_GENERAL
);
493 sal_Size
UCBStream::PutData(const void* pData
, sal_Size nSize
)
497 Reference
< XOutputStream
> xOSFromS
;
498 if( xS
.is() && (xOSFromS
= xS
->getOutputStream()).is() )
500 Sequence
<sal_Int8
> aData( static_cast<const sal_Int8
*>(pData
), nSize
);
501 xOSFromS
->writeBytes( aData
);
506 SetError( ERRCODE_IO_GENERAL
);
509 catch(const Exception
& )
511 SetError( ERRCODE_IO_GENERAL
);
516 sal_uInt64
UCBStream::SeekPos( sal_uInt64 nPos
)
522 sal_uInt64 nLen
= static_cast<sal_uInt64
>( xSeek
->getLength() );
532 SetError( ERRCODE_IO_GENERAL
);
535 catch(const Exception
& )
537 SetError( ERRCODE_IO_GENERAL
);
542 void UCBStream::FlushData()
546 Reference
< XOutputStream
> xOSFromS
;
547 if( xS
.is() && (xOSFromS
= xS
->getOutputStream()).is() )
553 SetError( ERRCODE_IO_GENERAL
);
556 catch(const Exception
& )
558 SetError( ERRCODE_IO_GENERAL
);
562 void UCBStream::SetSize( sal_uInt64 nSize
)
566 SAL_WARN("basic", "UCBStream::SetSize not allowed to call from basic" );
567 SetError( ERRCODE_IO_GENERAL
);
571 SbError
SbiStream::Open
572 ( short nCh
, const OString
& rName
, StreamMode nStrmMode
, short nFlags
, short nL
)
578 nExpandOnWriteTo
= 0;
579 if( ( nStrmMode
& ( StreamMode::READ
|StreamMode::WRITE
) ) == StreamMode::READ
)
581 nStrmMode
|= StreamMode::NOCREATE
;
583 OUString
aStr(OStringToOUString(rName
, osl_getThreadTextEncoding()));
584 OUString aNameStr
= getFullPath( aStr
);
588 Reference
< XSimpleFileAccess3
> xSFI( SimpleFileAccess::create( comphelper::getProcessComponentContext() ) );
592 // #??? For write access delete file if it already exists (not for appending)
593 if( (nStrmMode
& StreamMode::WRITE
) && !IsAppend() && !IsBinary() &&
594 xSFI
->exists( aNameStr
) && !xSFI
->isFolder( aNameStr
) )
596 xSFI
->kill( aNameStr
);
599 if( (nStrmMode
& (StreamMode::READ
| StreamMode::WRITE
)) == (StreamMode::READ
| StreamMode::WRITE
) )
601 Reference
< XStream
> xIS
= xSFI
->openFileReadWrite( aNameStr
);
602 pStrm
= new UCBStream( xIS
);
604 else if( nStrmMode
& StreamMode::WRITE
)
606 Reference
< XStream
> xIS
= xSFI
->openFileReadWrite( aNameStr
);
607 pStrm
= new UCBStream( xIS
);
609 else //if( nStrmMode & StreamMode::READ )
611 Reference
< XInputStream
> xIS
= xSFI
->openFileRead( aNameStr
);
612 pStrm
= new UCBStream( xIS
);
616 catch(const Exception
& )
618 nError
= ERRCODE_IO_GENERAL
;
624 pStrm
= new OslStream( aNameStr
, nStrmMode
);
628 pStrm
->Seek( STREAM_SEEK_TO_END
);
633 delete pStrm
, pStrm
= NULL
;
638 SbError
SbiStream::Close()
650 SbError
SbiStream::Read(OString
& rBuf
, sal_uInt16 n
, bool bForceReadingPerByte
)
652 nExpandOnWriteTo
= 0;
653 if( !bForceReadingPerByte
&& IsText() )
655 pStrm
->ReadLine(rBuf
);
666 return nError
= SbERR_BAD_RECORD_LENGTH
;
668 OStringBuffer
aBuffer(read_uInt8s_ToOString(*pStrm
, n
));
669 //Pad it out with ' ' to the requested length on short read
670 sal_Int32 nRequested
= sal::static_int_cast
<sal_Int32
>(n
);
671 comphelper::string::padToLength(aBuffer
, nRequested
, ' ');
672 rBuf
= aBuffer
.makeStringAndClear();
675 if( !nError
&& pStrm
->IsEof() )
677 nError
= SbERR_READ_PAST_EOF
;
682 SbError
SbiStream::Read( char& ch
)
684 nExpandOnWriteTo
= 0;
688 aLine
= aLine
+ OString('\n');
691 aLine
= aLine
.copy(1);
695 void SbiStream::ExpandFile()
697 if ( nExpandOnWriteTo
)
699 sal_uInt64 nCur
= pStrm
->Seek(STREAM_SEEK_TO_END
);
700 if( nCur
< nExpandOnWriteTo
)
702 sal_uInt64 nDiff
= nExpandOnWriteTo
- nCur
;
706 pStrm
->WriteChar( c
);
711 pStrm
->Seek( nExpandOnWriteTo
);
713 nExpandOnWriteTo
= 0;
719 void WriteLines(SvStream
&rStream
, const OString
& rStr
)
721 OString
aStr(convertLineEnd(rStr
, rStream
.GetLineDelimiter()) );
722 write_uInt8s_FromOString(rStream
, aStr
);
727 SbError
SbiStream::Write( const OString
& rBuf
, sal_uInt16 n
)
732 pStrm
->Seek( STREAM_SEEK_TO_END
);
736 aLine
= aLine
+ rBuf
;
737 // Get it out, if the end is an LF, but strip CRLF before,
738 // because the SvStrm adds a CRLF!
739 sal_Int32 nLineLen
= aLine
.getLength();
740 if (nLineLen
&& aLine
[--nLineLen
] == 0x0A)
742 aLine
= aLine
.copy(0, nLineLen
);
743 if (nLineLen
&& aLine
[--nLineLen
] == 0x0D)
745 aLine
= aLine
.copy(0, nLineLen
);
747 WriteLines(*pStrm
, aLine
);
759 return nError
= SbERR_BAD_RECORD_LENGTH
;
761 pStrm
->Write(rBuf
.getStr(), n
);
769 SbiIoSystem
* SbGetIoSystem()
771 SbiInstance
* pInst
= GetSbData()->pInst
;
772 return pInst
? pInst
->GetIoSystem() : NULL
;
776 SbiIoSystem::SbiIoSystem()
778 for( short i
= 0; i
< CHANNELS
; i
++ )
786 SbiIoSystem::~SbiIoSystem()
791 SbError
SbiIoSystem::GetError()
793 SbError n
= nError
; nError
= 0;
797 void SbiIoSystem::Open(short nCh
, const OString
& rName
, StreamMode nMode
, short nFlags
, short nLen
)
800 if( nCh
>= CHANNELS
|| !nCh
)
802 nError
= SbERR_BAD_CHANNEL
;
804 else if( pChan
[ nCh
] )
806 nError
= SbERR_FILE_ALREADY_OPEN
;
810 pChan
[ nCh
] = new SbiStream
;
811 nError
= pChan
[ nCh
]->Open( nCh
, rName
, nMode
, nFlags
, nLen
);
814 delete pChan
[ nCh
], pChan
[ nCh
] = NULL
;
821 void SbiIoSystem::Close()
825 nError
= SbERR_BAD_CHANNEL
;
827 else if( !pChan
[ nChan
] )
829 nError
= SbERR_BAD_CHANNEL
;
833 nError
= pChan
[ nChan
]->Close();
834 delete pChan
[ nChan
];
835 pChan
[ nChan
] = NULL
;
841 void SbiIoSystem::Shutdown()
843 for( short i
= 1; i
< CHANNELS
; i
++ )
847 SbError n
= pChan
[ i
]->Close();
857 // anything left to PRINT?
858 if( !aOut
.isEmpty() )
861 vcl::Window
* pParent
= Application::GetDefDialogParent();
862 ScopedVclPtrInstance
<MessBox
>::Create( pParent
, WinBits( WB_OK
), OUString(), aOut
)->Execute();
864 ScopedVclPtrInstance
<MessBox
>::Create( GetpApp()->GetDefDialogParent(), WinBits( WB_OK
), OUString(), aOut
)->Execute();
871 void SbiIoSystem::Read(OString
& rBuf
, short n
)
877 else if( !pChan
[ nChan
] )
879 nError
= SbERR_BAD_CHANNEL
;
883 nError
= pChan
[ nChan
]->Read( rBuf
, n
);
887 char SbiIoSystem::Read()
895 aIn
= aIn
+ OString('\n');
900 else if( !pChan
[ nChan
] )
902 nError
= SbERR_BAD_CHANNEL
;
906 nError
= pChan
[ nChan
]->Read( ch
);
911 void SbiIoSystem::Write(const OUString
& rBuf
, short n
)
917 else if( !pChan
[ nChan
] )
919 nError
= SbERR_BAD_CHANNEL
;
923 nError
= pChan
[ nChan
]->Write( OUStringToOString(rBuf
, osl_getThreadTextEncoding()), n
);
927 // nChannel == 0..CHANNELS-1
929 SbiStream
* SbiIoSystem::GetStream( short nChannel
) const
932 if( nChannel
>= 0 && nChannel
< CHANNELS
)
934 pRet
= pChan
[ nChannel
];
939 void SbiIoSystem::CloseAll()
941 for( short i
= 1; i
< CHANNELS
; i
++ )
945 SbError n
= pChan
[ i
]->Close();
956 /***************************************************************************
960 ***************************************************************************/
963 void SbiIoSystem::ReadCon(OString
& rIn
)
965 OUString
aPromptStr(OStringToOUString(aPrompt
, osl_getThreadTextEncoding()));
966 ScopedVclPtrInstance
< SbiInputDialog
> aDlg(nullptr, aPromptStr
);
967 if( aDlg
->Execute() )
969 rIn
= OUStringToOString(aDlg
->GetInput(), osl_getThreadTextEncoding());
973 nError
= SbERR_USER_ABORT
;
978 // output of a MessageBox, if theres a CR in the console-buffer
980 void SbiIoSystem::WriteCon(const OUString
& rText
)
983 sal_Int32 n1
= aOut
.indexOf('\n');
984 sal_Int32 n2
= aOut
.indexOf('\r');
985 if( n1
!= -1 || n2
!= -1 )
999 OUString
s(aOut
.copy(0, n1
));
1000 aOut
= aOut
.copy(n1
);
1001 while ( !aOut
.isEmpty() && (aOut
[0] == '\n' || aOut
[0] == '\r') )
1003 aOut
= aOut
.copy(1);
1006 SolarMutexGuard aSolarGuard
;
1007 if( !ScopedVclPtr
<MessBox
>::Create(
1008 Application::GetDefDialogParent(),
1009 WinBits( WB_OK_CANCEL
| WB_DEF_OK
),
1010 OUString(), s
)->Execute() )
1012 nError
= SbERR_USER_ABORT
;
1018 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */