/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
bool ImplDdeService::MakeTopic( const OUString& rNm )
{ // Workaround for Event after Main() under OS/2 // happens when exiting starts the App again if ( !Application::IsInExecute() && !o3tl::IsRunningUnitTest() ) returnfalse;
// The Topic rNm is sought, do we have it? // First only loop over the ObjectShells to find those // with the specific name: bool bRet = false;
OUString sNm( rNm.toAsciiLowerCase() );
SfxObjectShell* pShell = SfxObjectShell::GetFirst(); while( pShell )
{
OUString sTmp( pShell->GetTitle(SFX_TITLE_FULLNAME) ); if( sNm == sTmp.toAsciiLowerCase() )
{
SfxGetpApp()->AddDdeTopic( pShell );
bRet = true; break;
}
pShell = SfxObjectShell::GetNext( *pShell );
}
Checks if 'rCmd' of the event 'rEvent' is (without '(') and then assemble this data into a <ApplicationEvent>, which is then executed through <Application::AppEvent()>. If 'rCmd' is the given event 'rEvent', then TRUE is returned, otherwise FALSE.
[Example]
rCmd = "Open(\"d:\doc\doc.sdw\")" rEvent = "Open"
*/ bool SfxAppEvent_Impl( const OUString& rCmd, std::u16string_view rEvent,
ApplicationEvent::Type eType )
{
OUString sEvent(OUString::Concat(rEvent) + "("); if (rCmd.startsWithIgnoreAsciiCase(sEvent))
{
sal_Int32 start = sEvent.getLength(); if ( rCmd.getLength() - start >= 2 )
{ // Transform into the ApplicationEvent Format //TODO: I /assume/ that rCmd should match the syntax of // <http://msdn.microsoft.com/en-us/library/ms648995.aspx> // "WM_DDE_EXECUTE message" but does not (handle commands enclosed // in [...]; handle commas separating multiple arguments; handle // double "", ((, )), [[, ]] in quoted arguments); see also the mail // thread starting at <http://lists.freedesktop.org/archives/ // libreoffice/2013-July/054779.html> "DDE on Windows."
std::vector<OUString> aData; for ( sal_Int32 n = start; n < rCmd.getLength() - 1; )
{ // 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'"':
{
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' ':
++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;
}
}
}
This method can be overridden by application developers, to receive DDE-commands directed to their SfxApplication subclass.
The base implementation understands the API functionality of the relevant SfxApplication subclass in BASIC syntax. Return values can not be transferred, unfortunately.
*/ bool SfxApplication::DdeExecute( const OUString& rCmd ) // Expressed in our BASIC-Syntax
{ // Print or Open-Event? if ( !( SfxAppEvent_Impl( rCmd, u"Print", ApplicationEvent::Type::Print ) ||
SfxAppEvent_Impl( rCmd, u"Open", ApplicationEvent::Type::Open ) ) )
{ // all others are BASIC
StarBASIC* pBasic = GetBasic();
DBG_ASSERT( pBasic, "Where is the Basic???" );
SbxVariable* pRet = pBasic->Execute( rCmd ); if( !pRet )
{
SbxBase::ResetError(); returnfalse;
}
} returntrue;
}
/* [Description]
This method can be overridden by application developers, to receive DDE-commands directed to the their SfxApplication subclass.
The base implementation does nothing and returns 0.
*/ bool SfxObjectShell::DdeExecute( const OUString& rCmd ) // Expressed in our BASIC-Syntax
{ #if !HAVE_FEATURE_SCRIPTING
(void) rCmd; #else
StarBASIC* pBasic = GetBasic();
DBG_ASSERT( pBasic, "Where is the Basic???" ) ;
SbxVariable* pRet = pBasic->Execute( rCmd ); if( !pRet )
{
SbxBase::ResetError(); returnfalse;
} #endif returntrue;
}
/* [Description]
This method can be overridden by application developers, to receive DDE-data-requests directed to their SfxApplication subclass.
The base implementation provides no data and returns false.
*/ bool SfxObjectShell::DdeGetData( const OUString&, // the Item to be addressed const OUString&, // in: Format
css::uno::Any& )// out: requested data
{ returnfalse;
}
/* [Description]
This method can be overridden by application developers, to receive DDE-data directed to their SfxApplication subclass.
The base implementation is not receiving any data and returns false.
*/ bool SfxObjectShell::DdeSetData( const OUString&, // the Item to be addressed const OUString&, // in: Format const css::uno::Any& )// out: requested data
{ returnfalse;
}
#endif
/* [Description]
This method can be overridden by application developers, to establish a DDE-hotlink to their SfxApplication subclass.
The base implementation is not generate a link and returns 0.
*/
::sfx2::SvLinkSource* SfxObjectShell::DdeCreateLinkSource( const OUString& ) // the Item to be addressed
{ return nullptr;
}
void SfxObjectShell::ReconnectDdeLinks(SfxObjectShell& rServer)
{
SfxObjectShell* p = GetFirst(nullptr, false); while (p)
{ if (&rServer != p)
p->ReconnectDdeLink(rServer);
p = GetNext(*p, nullptr, false);
}
}
bool SfxApplication::InitializeDde()
{ int nError = 0; #ifdefined(_WIN32)
DBG_ASSERT( !pImpl->pDdeService, "Dde can not be initialized multiple times" );
pImpl->pDdeService.reset(new ImplDdeService( Application::GetAppName() ));
nError = pImpl->pDdeService->GetError(); if( !nError )
{ // we certainly want to support RTF!
pImpl->pDdeService->AddFormat( SotClipboardFormatId::RTF );
pImpl->pDdeService->AddFormat( SotClipboardFormatId::RICHTEXT );
// Config path as a topic because of multiple starts
INetURLObject aOfficeLockFile( SvtPathOptions().GetUserConfigPath() );
aOfficeLockFile.insertName( u"soffice.lck" );
OUString aService( SfxDdeServiceName_Impl(
aOfficeLockFile.GetMainURL(INetURLObject::DecodeMechanism::ToIUri) ) );
aService = aService.toAsciiUpperCase();
pImpl->pDdeService2.reset( new ImplDdeService( aService ));
pImpl->pTriggerTopic.reset(new SfxDdeTriggerTopic_Impl);
pImpl->pDdeService2->AddTopic( *pImpl->pTriggerTopic );
} #endif return !nError;
}
#ifdefined(_WIN32) void SfxApplication::AddDdeTopic( SfxObjectShell* pSh )
{ //OV: DDE is disconnected in server mode! if (!pImpl->pDdeService) return;
// prevent double submit
OUString sShellNm; bool bFnd = false; for (size_t n = pImpl->maDocTopics.size(); n;)
{ if( pImpl->maDocTopics[ --n ]->pSh == pSh )
{ // If the document is untitled, is still a new Topic is created! if( !bFnd )
{
bFnd = true;
sShellNm = pSh->GetTitle(SFX_TITLE_FULLNAME).toAsciiLowerCase();
}
OUString sNm( pImpl->maDocTopics[ n ]->GetName() ); if( sShellNm == sNm.toAsciiLowerCase() ) return ;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.