21#include <com/sun/star/beans/XPropertySet.hpp>
22#include <com/sun/star/frame/XModel.hpp>
23#include <com/sun/star/text/XTextFieldsSupplier.hpp>
24#include <com/sun/star/text/FilenameDisplayFormat.hpp>
25#include <com/sun/star/util/XRefreshable.hpp>
26#include <com/sun/star/util/XUpdatable.hpp>
27#include <ooo/vba/word/WdFieldType.hpp>
37SwVbaField::SwVbaField(
const uno::Reference< ooo::vba::XHelperInterface >& rParent,
const uno::Reference< uno::XComponentContext >& rContext,
const uno::Reference< css::text::XTextField >& xTextField) :
SwVbaField_BASE( rParent, rContext )
44 uno::Reference< util::XUpdatable > xUpdatable(
mxTextField, uno::UNO_QUERY );
60uno::Sequence<OUString>
74class SwVbaReadFieldParams
78 sal_Int32 m_nLen, m_nFnd, m_nNext, m_nSavPtr;
79 OUString m_aFieldName;
81 explicit SwVbaReadFieldParams(
const OUString& rData );
85 sal_Int32 FindNextStringPiece( sal_Int32 _nStart );
87 OUString GetResult()
const;
88 const OUString& GetFieldName()
const {
return m_aFieldName; }
93SwVbaReadFieldParams::SwVbaReadFieldParams(
const OUString& _rData )
99 while( (m_nLen > m_nNext) && (m_aData[ m_nNext ] ==
' ') )
103 while( m_nLen > m_nNext
104 && (c = m_aData[ m_nNext ]) !=
' '
113 m_aFieldName =
m_aData.copy( 0, m_nFnd );
116OUString SwVbaReadFieldParams::GetResult()
const
118 return (-1 == m_nFnd)
128 (-1 != m_nNext) && (m_nLen > m_nNext) &&
129 -1 != (m_nFnd = FindNextStringPiece(m_nNext))
134 if (
'\\' == m_aData[m_nFnd] &&
'\\' != m_aData[m_nFnd + 1])
143 (-1 != m_nSavPtr ) &&
145 (
'"' == m_aData[m_nSavPtr - 1]) ||
146 (0x201d == m_aData[m_nSavPtr - 1])
165sal_Int32 SwVbaReadFieldParams::FindNextStringPiece(
const sal_Int32 nStart)
167 sal_Int32
n = ( -1 == nStart ) ? m_nFnd : nStart;
172 while( (m_nLen > n) && (
m_aData[
n ] ==
' ') )
178 if( (m_aData[ n ] ==
'"')
180 || (m_aData[ n ] == 132) )
186 && (m_aData[ n2 ] != 0x201d)
193 while( (m_nLen > n2) && (
m_aData[
n2 ] !=
' ') )
195 if( m_aData[ n2 ] ==
'\\' )
197 if( m_aData[ n2+1 ] ==
'\\' )
212 if(m_aData[ n2 ] !=
' ')
n2++;
220static uno::Any lcl_createField(
const uno::Reference< XHelperInterface >& xParent,
const uno::Reference< uno::XComponentContext >& xContext,
const uno::Reference< frame::XModel >& xModel,
const uno::Any& aSource )
222 uno::Reference< text::XTextField > xTextField( aSource, uno::UNO_QUERY_THROW );
223 uno::Reference< text::XTextDocument > xTextDocument(
xModel, uno::UNO_QUERY_THROW );
224 uno::Reference< word::XField > xField(
new SwVbaField( xParent, xContext, xTextField ) );
230class FieldEnumeration :
public ::cppu::WeakImplHelper< css::container::XEnumeration >
232 uno::Reference< XHelperInterface >
mxParent;
233 uno::Reference< uno::XComponentContext >
mxContext;
234 uno::Reference< frame::XModel >
mxModel;
235 uno::Reference< container::XEnumeration > mxEnumeration;
237 FieldEnumeration( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, uno::Reference< container::XEnumeration > xEnumeration ) :
mxParent(
std::move( xParent )),
mxContext(
std::move( xContext )),
mxModel(
std::move(
xModel )), mxEnumeration(
std::move( xEnumeration ))
240 virtual sal_Bool SAL_CALL hasMoreElements( )
override
242 return mxEnumeration->hasMoreElements();
244 virtual uno::Any SAL_CALL nextElement( )
override
246 if ( !hasMoreElements() )
247 throw container::NoSuchElementException();
248 return lcl_createField( mxParent, mxContext, mxModel, mxEnumeration->nextElement() );
252class FieldCollectionHelper :
public ::cppu::WeakImplHelper< container::XIndexAccess,
253 container::XEnumerationAccess >
255 uno::Reference< XHelperInterface >
mxParent;
256 uno::Reference< uno::XComponentContext >
mxContext;
257 uno::Reference< frame::XModel >
mxModel;
258 uno::Reference< container::XEnumerationAccess > mxEnumerationAccess;
261 FieldCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext,
const uno::Reference< frame::XModel >& xModel ) :
mxParent(
std::move( xParent )),
mxContext(
std::move( xContext )),
mxModel(
xModel )
263 uno::Reference< text::XTextFieldsSupplier > xSupp( xModel, uno::UNO_QUERY_THROW );
264 mxEnumerationAccess.set( xSupp->getTextFields(), uno::UNO_SET_THROW );
267 virtual uno::Type SAL_CALL getElementType( )
override {
return mxEnumerationAccess->getElementType(); }
268 virtual sal_Bool SAL_CALL hasElements( )
override {
return mxEnumerationAccess->hasElements(); }
270 virtual ::sal_Int32 SAL_CALL getCount( )
override
272 uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
274 while( xEnumeration->hasMoreElements() )
277 xEnumeration->nextElement();
281 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32
Index )
override
284 throw lang::IndexOutOfBoundsException();
286 uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
288 while( xEnumeration->hasMoreElements() )
290 if( nCount ==
Index )
292 return xEnumeration->nextElement();
296 throw lang::IndexOutOfBoundsException();
299 virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( )
override
301 uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
302 return uno::Reference< container::XEnumeration >(
new FieldEnumeration( mxParent, mxContext, mxModel, xEnumeration ) );
313uno::Reference< word::XField > SAL_CALL
314SwVbaFields::Add(
const css::uno::Reference< ::ooo::vba::word::XRange >&
Range,
const css::uno::Any&
Type,
const css::uno::Any& Text,
const css::uno::Any& )
316 sal_Int32
nType = word::WdFieldType::wdFieldEmpty;
322 if( (
nType == word::WdFieldType::wdFieldEmpty ) && !sText.isEmpty() )
324 SwVbaReadFieldParams aReadParam(sText);
325 sFieldName = aReadParam.GetFieldName();
326 SAL_INFO(
"sw.vba",
"the field name is " << sFieldName );
329 uno::Reference< text::XTextContent > xTextField;
330 if(
nType == word::WdFieldType::wdFieldFileName || sFieldName.equalsIgnoreAsciiCase(
"FILENAME") )
334 else if(
nType == word::WdFieldType::wdFieldDocProperty || sFieldName.equalsIgnoreAsciiCase(
"DOCPROPERTY") )
340 throw uno::RuntimeException(
"Not implemented" );
344 uno::Reference< text::XTextRange > xTextRange = rVbaRange.
getXTextRange();
345 uno::Reference< text::XText > xText = xTextRange->getText();
346 xText->insertTextContent( xTextRange, xTextField,
true );
347 return uno::Reference< word::XField >(
new SwVbaField(
mxParent,
mxContext, uno::Reference< text::XTextField >( xTextField, uno::UNO_QUERY_THROW ) ) );
352 uno::Reference< text::XTextField > xTextField(
mxMSF->createInstance(
"com.sun.star.text.TextField.FileName"), uno::UNO_QUERY_THROW );
353 sal_Int16 nFileFormat = text::FilenameDisplayFormat::NAME_AND_EXT;
354 if( !_text.isEmpty() )
357 SwVbaReadFieldParams aReadParam( _text );
358 while (-1 != (nRet = aReadParam.SkipToNextToken()))
363 nFileFormat = text::FilenameDisplayFormat::FULL;
367 aReadParam.SkipToNextToken();
376 uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW );
377 xProps->setPropertyValue(
"FileFormat",
uno::Any( nFileFormat ) );
384struct DocPropertyTable
386 const char* sDocPropertyName;
387 const char* sFieldService;
394 {
"Author",
"com.sun.star.text.textfield.docinfo.CreateAuthor" },
395 {
"Bytes",
nullptr },
396 {
"Category",
nullptr },
397 {
"Characters",
nullptr },
398 {
"CharactersWithSpaces",
nullptr },
399 {
"Comments",
"com.sun.star.text.textfield.docinfo.Description" },
400 {
"Company",
nullptr },
401 {
"CreateTime",
"com.sun.star.text.textfield.docinfo.CreateDateTime" },
402 {
"HyperlinkBase",
nullptr },
403 {
"Keywords",
"com.sun.star.text.textfield.docinfo.Keywords" },
404 {
"LastPrinted",
"com.sun.star.text.textfield.docinfo.PrintDateTime" },
405 {
"LastSavedBy",
"com.sun.star.text.textfield.docinfo.ChangeAuthor" },
406 {
"LastSavedTime",
"com.sun.star.text.textfield.docinfo.ChangeDateTime" },
407 {
"Lines",
nullptr },
408 {
"Manager",
nullptr },
409 {
"NameofApplication",
nullptr },
410 {
"ODMADocID",
nullptr },
411 {
"Pages",
"com.sun.star.text.textfield.PageCount" },
412 {
"Paragraphs",
"com.sun.star.text.textfield.ParagraphCount" },
413 {
"RevisionNumber",
"com.sun.star.text.textfield.docinfo.Revision" },
414 {
"Security",
nullptr },
415 {
"Subject",
"com.sun.star.text.textfield.docinfo.Subject" },
416 {
"Template",
"com.sun.star.text.textfield.TemplateName" },
417 {
"Title",
"com.sun.star.text.textfield.docinfo.Title" },
418 {
"TotalEditingTime",
"com.sun.star.text.textfield.docinfo.EditTime" },
419 {
"Words",
"com.sun.star.text.textfield.WordCount" },
425 OUString aDocProperty;
426 SwVbaReadFieldParams aReadParam( _text );
428 while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
433 if( aDocProperty.isEmpty() )
434 aDocProperty = aReadParam.GetResult();
438 aReadParam.SkipToNextToken();
442 aDocProperty = aDocProperty.replaceAll(
"\"",
"");
443 SAL_INFO(
"sw.vba",
"SwVbaFields::Create_Field_DocProperty, the document property name is " << aDocProperty );
444 if( aDocProperty.isEmpty() )
446 throw uno::RuntimeException();
450 OUString sFieldService;
452 for(
const DocPropertyTable* pTable =
aDocPropertyTables; pTable->sDocPropertyName !=
nullptr; pTable++ )
454 if( aDocProperty.equalsIgnoreAsciiCaseAscii( pTable->sDocPropertyName ) )
456 if( pTable->sFieldService !=
nullptr )
457 sFieldService = OUString::createFromAscii(pTable->sFieldService);
465 sFieldService =
"com.sun.star.text.textfield.docinfo.Custom";
467 else if( sFieldService.isEmpty() )
469 throw uno::RuntimeException(
"Not implemented" );
472 uno::Reference< text::XTextField > xTextField(
mxMSF->createInstance( sFieldService ), uno::UNO_QUERY_THROW );
476 uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW );
477 xProps->setPropertyValue(
"Name",
uno::Any( aDocProperty ) );
483uno::Reference< container::XEnumeration > SAL_CALL
486 uno::Reference< container::XEnumerationAccess > xEnumerationAccess(
m_xIndexAccess, uno::UNO_QUERY_THROW );
487 return xEnumerationAccess->createEnumeration();
499 sal_Int32 nUpdate = 1;
502 uno::Reference< text::XTextFieldsSupplier > xSupp(
mxModel, uno::UNO_QUERY_THROW );
503 uno::Reference< util::XRefreshable > xRef( xSupp->getTextFields(), uno::UNO_QUERY_THROW );
507 catch(
const uno::Exception&)
518 return "SwVbaFields";
528uno::Sequence<OUString>
533 "ooo.vba.word.Fields"
css::uno::Reference< css::frame::XModel2 > mxModel
unotools::WeakReference< AnimationNode > mxParent
css::uno::Reference< css::uno::XComponentContext > mxContext
css::uno::WeakReference< ov::XHelperInterface > mxParent
css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess
css::uno::Reference< css::text::XTextField > mxTextField
SwVbaField(const css::uno::Reference< ooo::vba::XHelperInterface > &rParent, const css::uno::Reference< css::uno::XComponentContext > &rContext, const css::uno::Reference< css::text::XTextField > &xTextField)
virtual OUString getServiceImplName() override
virtual sal_Bool SAL_CALL Update() override
virtual css::uno::Sequence< OUString > getServiceNames() override
virtual OUString getServiceImplName() override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF
virtual css::uno::Type SAL_CALL getElementType() override
css::uno::Reference< css::text::XTextField > Create_Field_DocProperty(const OUString &_text)
virtual sal_Int32 SAL_CALL Update() override
virtual css::uno::Sequence< OUString > getServiceNames() override
css::uno::Reference< css::frame::XModel > mxModel
virtual css::uno::Reference< ::ooo::vba::word::XField > SAL_CALL Add(const css::uno::Reference< ::ooo::vba::word::XRange > &Range, const css::uno::Any &Type, const css::uno::Any &Text, const css::uno::Any &PreserveFormatting) override
css::uno::Reference< css::text::XTextField > Create_Field_FileName(const OUString &rText)
SwVbaFields(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel > &xModel)
virtual css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getXTextRange() override
css::uno::Type const & get()
Sequence< OUString > aServiceNames
#define SAL_INFO(area, stream)
double getLength(const B2DPolygon &rCandidate)
void copy(const fs::path &src, const fs::path &dest)
#define ERRCODE_BASIC_BAD_ARGUMENT
Reference< XModel > xModel
const DocPropertyTable aDocPropertyTables[]
static uno::Any lcl_createField(const uno::Reference< XHelperInterface > &xParent, const uno::Reference< uno::XComponentContext > &xContext, const uno::Reference< frame::XModel > &xModel, const uno::Any &aSource)