/* -*- 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 .
*/
using com::sun::star::beans::PropertyValue; using com::sun::star::io::TextInputStream; using com::sun::star::io::XTextInputStream2; using com::sun::star::container::XEnumeration; using com::sun::star::container::XNameContainer; using com::sun::star::xforms::XFormsSupplier;
OUString Model::getDefaultServiceNameForNode( const css::uno::Reference<css::xml::dom::XNode>& xNode )
{ // determine service for control. string/text field is default.
OUString sService = u"com.sun.star.form.component.TextField"_ustr;
// query repository for suitable type
OSL_ENSURE( mxDataTypes.is(), "no type repository?" );
OUString sTypeName = queryMIP( xNode ).getTypeName(); if( mxDataTypes->hasByName( sTypeName ) )
{
OSL_ENSURE( mxDataTypes->getDataType( sTypeName ).is(), "has or has not?" );
switch( mxDataTypes->getDataType( sTypeName )->getTypeClass() )
{ case css::xsd::DataTypeClass::BOOLEAN:
sService = "com.sun.star.form.component.CheckBox"; break; case css::xsd::DataTypeClass::DOUBLE: case css::xsd::DataTypeClass::DECIMAL: case css::xsd::DataTypeClass::FLOAT:
sService = "com.sun.star.form.component.NumericField"; break;
case css::xsd::DataTypeClass::STRING: case css::xsd::DataTypeClass::DURATION: case css::xsd::DataTypeClass::DATETIME: case css::xsd::DataTypeClass::TIME: case css::xsd::DataTypeClass::DATE: case css::xsd::DataTypeClass::gYearMonth: case css::xsd::DataTypeClass::gYear: case css::xsd::DataTypeClass::gMonthDay: case css::xsd::DataTypeClass::gDay: case css::xsd::DataTypeClass::gMonth: case css::xsd::DataTypeClass::hexBinary: case css::xsd::DataTypeClass::base64Binary: case css::xsd::DataTypeClass::anyURI: case css::xsd::DataTypeClass::QName: case css::xsd::DataTypeClass::NOTATION: default: // keep default break;
}
}
// iterate upwards and put sections into the expression buffer. // Stop iteration either at context node (relative expression) or // at document root, whichever occurs first.
OUStringBuffer aBuffer; for( Reference<XNode> xCurrent = xNode;
xCurrent.is() && xCurrent != rContext.mxContextNode;
xCurrent = xCurrent->getParentNode() )
{ // insert a '/' for every step except the first if( !aBuffer.isEmpty() )
aBuffer.insert( 0, '/' );
css::uno::Reference< ::css::beans::XPropertySet > Model::cloneBindingAsGhost( const css::uno::Reference< ::css::beans::XPropertySet > &xBinding )
{ // Create a new binding instance first...
rtl::Reference<Binding> pBinding = new Binding();
// ...and bump up the "deferred notification counter" // to prevent this binding from contributing to the // MIPs table...
pBinding->deferNotifications(true);
// Copy the propertyset and return result...
copy( xBinding, XPropertySet_t(pBinding) ); return pBinding;
}
css::uno::Reference<css::xml::dom::XNode> Model::renameNode( const css::uno::Reference<css::xml::dom::XNode>& xNode, const OUString& sName )
{ // early out if we don't have to change the name if( xNode->getNodeName() == sName ) return xNode;
// refuse to change name if it's an attribute, and the name is already used if( xNode->getNodeType() == NodeType_ATTRIBUTE_NODE
&& xNode->getParentNode().is()
&& Reference<XElement>(xNode->getParentNode(), UNO_QUERY_THROW)->hasAttribute( sName ) ) return xNode;
// note old binding expression so we can adjust bindings below
OUString sOldDefaultBindingExpression =
getDefaultBindingExpressionForNode( xNode );
// iterate over all attributes and append them to the new element
Reference<XElement> xOldElem( xNode, UNO_QUERY );
OSL_ENSURE( xNode.is(), "no element?" );
Reference<XNamedNodeMap> xMap = xNode->getAttributes();
sal_Int32 nLength = xMap.is() ? xMap->getLength() : 0; // looping until nLength is suspicious wrt removeAttributeNode // presumably shrinking XNamedNodeMap::getLength by 1 for( sal_Int32 n = 0; n < nLength; n++ )
{
Reference<XAttr> xAttr( xMap->item(n), UNO_QUERY );
xElem->setAttributeNode( xOldElem->removeAttributeNode( xAttr ) );
}
// iterate over all children and append them to the new element for( Reference<XNode> xCurrent = xNode->getFirstChild();
xCurrent.is();
xCurrent = xNode->getFirstChild() )
{
xNew->appendChild( xNode->removeChild( xCurrent ) );
}
// We will iterate over all bindings and determine the // appropriateness of the respective binding for this node. The // best one will be used. If we don't find any and bCreate is set, // then we will create a suitable binding.
rtl::Reference<Binding> pBestBinding;
sal_Int32 nBestScore = 0;
for( sal_Int32 n = 0; n < mxBindings->countItems(); n++ )
{
Binding* pBinding = comphelper::getFromUnoTunnel<Binding>(
mxBindings->Collection<XPropertySet_t>::getItem( n ) );
assert(pBinding != nullptr && "no binding?");
Reference<XNodeList> xNodeList = pBinding->getXNodeList();
sal_Int32 nNodes = xNodeList.is() ? xNodeList->getLength() : 0; if( nNodes > 0 && xNodeList->item( 0 ) == xNode )
{ // allright, we found a suitable node. Let's determine how // well it fits. Score: // - bind to exactly this node is better than whole nodeset // - simple binding expressions is better than complex ones
sal_Int32 nScore = 0; if( nNodes == 1 )
nScore ++; if( pBinding->isSimpleBindingExpression() )
nScore ++;
// if we found a better binding, remember it if( nScore > nBestScore )
{
pBestBinding = pBinding;
nBestScore = nScore;
}
}
}
// create binding, if none was found and bCreate is set
OSL_ENSURE( ( nBestScore == 0 ) == ( pBestBinding == nullptr ), "score != binding?" ); if( bCreate && pBestBinding == nullptr )
{
pBestBinding = new Binding();
pBestBinding->setBindingExpression(
getDefaultBindingExpressionForNode( xNode ) );
mxBindings->addItem( pBestBinding );
}
return pBestBinding;
}
void Model::removeBindingForNode( const css::uno::Reference<css::xml::dom::XNode>& )
{ // determine whether suitable binding is still used
}
/* WORK AROUND for problem in serialization: currently, multiple XML declarations (<?xml...?>) are being written out and we don't want them. When this is fixed, the code below is nice and simple. The current code filters out the declarations. OUString sResult = xTextInputStream->readString( Sequence<sal_Unicode>(), sal_True );
*/
// well, the serialization prepends XML header(s) that we need to // remove first.
sResult.setLength(0); while( ! xTextInputStream->isEOF() )
{
OUString sLine = xTextInputStream->readLine(); if( !sLine.isEmpty()
&& !sLine.startsWith( " ) )
{
sResult.append( sLine + "\n" );
}
}
case XPathObjectType_XPATH_STRING: return"\"" + xResult->getString() + "\"";
case XPathObjectType_XPATH_NODESET: return lcl_serializeForDisplay( xResult->getNodeList() );
case XPathObjectType_XPATH_NUMBER: return OUString::number(xResult->getDouble());
case XPathObjectType_XPATH_UNDEFINED: case XPathObjectType_XPATH_POINT: case XPathObjectType_XPATH_RANGE: case XPathObjectType_XPATH_LOCATIONSET: case XPathObjectType_XPATH_USERS: case XPathObjectType_XPATH_XSLT_TREE: default: // TODO: localized error message? return OUString();
}
}
// determine new instance data if (_pID != nullptr)
pID = _pID; if (_pInstance != nullptr)
pInstance = _pInstance; if (_pURL != nullptr)
pURL = _pURL; if (_pURLOnce != nullptr)
pURLOnce = _pURLOnce;
// count # of values we want to set
sal_Int32 nCount = 0; if (pID != nullptr)
++nCount; if (pInstance != nullptr)
++nCount; if (pURL != nullptr)
++nCount; if (pURLOnce != nullptr)
++nCount;
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 ist noch experimentell.