21 #include <com/sun/star/beans/XPropertySet.hpp>
22 #include <com/sun/star/frame/XModel.hpp>
23 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
24 #include <com/sun/star/view/XSelectionSupplier.hpp>
25 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
26 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
27 #include <com/sun/star/util/XRefreshable.hpp>
28 #include <com/sun/star/util/XUpdatable.hpp>
29 #include <ooo/vba/word/WdFieldType.hpp>
38 SwVbaField::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 )
45 uno::Reference< util::XUpdatable > xUpdatable(
mxTextField, uno::UNO_QUERY );
61 uno::Sequence<OUString>
75 class SwVbaReadFieldParams
79 sal_Int32 nLen, nFnd, nNext, nSavPtr;
82 explicit SwVbaReadFieldParams(
const OUString& rData );
84 long SkipToNextToken();
86 sal_Int32 FindNextStringPiece( sal_Int32 _nStart );
88 OUString GetResult()
const;
89 const OUString& GetFieldName()
const {
return aFieldName; }
94 SwVbaReadFieldParams::SwVbaReadFieldParams(
const OUString& _rData )
100 while( (nLen > nNext) && (
aData[ nNext ] ==
' ') )
105 && (c =
aData[ nNext ]) !=
' '
114 aFieldName =
aData.copy( 0, nFnd );
117 OUString SwVbaReadFieldParams::GetResult()
const
125 long SwVbaReadFieldParams::SkipToNextToken()
129 (-1 != nNext) && (nLen > nNext) &&
130 -1 != (nFnd = FindNextStringPiece(nNext))
135 if (
'\\' ==
aData[nFnd] &&
'\\' !=
aData[nFnd + 1])
137 nRet =
aData[++nFnd];
146 (
'"' ==
aData[nSavPtr - 1]) ||
147 (0x201d ==
aData[nSavPtr - 1])
166 sal_Int32 SwVbaReadFieldParams::FindNextStringPiece(
const sal_Int32 nStart)
168 sal_Int32
n = ( -1 == nStart ) ? nFnd : nStart;
173 while( (nLen > n) && (
aData[ n ] ==
' ') )
179 if( (
aData[ n ] ==
'"')
180 || (
aData[ n ] == 0x201c)
181 || (
aData[ n ] == 132) )
186 && (
aData[ n2 ] !=
'"')
187 && (
aData[ n2 ] != 0x201d)
188 && (
aData[ n2 ] != 147) )
194 while( (nLen > n2) && (
aData[ n2 ] !=
' ') )
196 if(
aData[ n2 ] ==
'\\' )
198 if(
aData[ n2+1 ] ==
'\\' )
213 if(
aData[ n2 ] !=
' ') n2++;
221 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 )
223 uno::Reference< text::XTextField > xTextField( aSource, uno::UNO_QUERY_THROW );
224 uno::Reference< text::XTextDocument > xTextDocument( xModel, uno::UNO_QUERY_THROW );
225 uno::Reference< word::XField > xField(
new SwVbaField( xParent, xContext, xTextField ) );
226 return uno::makeAny( xField );
231 class FieldEnumeration :
public ::cppu::WeakImplHelper< css::container::XEnumeration >
233 uno::Reference< XHelperInterface >
mxParent;
234 uno::Reference< uno::XComponentContext >
mxContext;
235 uno::Reference< frame::XModel >
mxModel;
236 uno::Reference< container::XEnumeration > mxEnumeration;
238 FieldEnumeration(
const uno::Reference< XHelperInterface >& xParent,
const uno::Reference< uno::XComponentContext > & xContext,
const uno::Reference< frame::XModel >& xModel,
const uno::Reference< container::XEnumeration >& xEnumeration ) : mxParent( xParent ), mxContext( xContext ), mxModel( xModel ), mxEnumeration( xEnumeration )
241 virtual sal_Bool SAL_CALL hasMoreElements( )
override
243 return mxEnumeration->hasMoreElements();
245 virtual uno::Any SAL_CALL nextElement( )
override
247 if ( !hasMoreElements() )
248 throw container::NoSuchElementException();
249 return lcl_createField( mxParent, mxContext, mxModel, mxEnumeration->nextElement() );
253 class FieldCollectionHelper :
public ::cppu::WeakImplHelper< container::XIndexAccess,
254 container::XEnumerationAccess >
256 uno::Reference< XHelperInterface > mxParent;
257 uno::Reference< uno::XComponentContext > mxContext;
258 uno::Reference< frame::XModel > mxModel;
259 uno::Reference< container::XEnumerationAccess > mxEnumerationAccess;
262 FieldCollectionHelper(
const uno::Reference< XHelperInterface >& xParent,
const uno::Reference< uno::XComponentContext >& xContext,
const uno::Reference< frame::XModel >& xModel ) : mxParent( xParent ), mxContext( xContext ), mxModel( xModel )
264 uno::Reference< text::XTextFieldsSupplier > xSupp( xModel, uno::UNO_QUERY_THROW );
265 mxEnumerationAccess.set( xSupp->getTextFields(), uno::UNO_SET_THROW );
268 virtual uno::Type SAL_CALL getElementType( )
override {
return mxEnumerationAccess->getElementType(); }
269 virtual sal_Bool SAL_CALL hasElements( )
override {
return mxEnumerationAccess->hasElements(); }
271 virtual ::sal_Int32 SAL_CALL getCount( )
override
273 uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
275 while( xEnumeration->hasMoreElements() )
278 xEnumeration->nextElement();
282 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32
Index )
override
285 throw lang::IndexOutOfBoundsException();
287 uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
288 sal_Int32 nCount = 0;
289 while( xEnumeration->hasMoreElements() )
291 if( nCount == Index )
293 return xEnumeration->nextElement();
297 throw lang::IndexOutOfBoundsException();
300 virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( )
override
302 uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
303 return uno::Reference< container::XEnumeration >(
new FieldEnumeration( mxParent, mxContext, mxModel, xEnumeration ) );
309 SwVbaFields::SwVbaFields(
const uno::Reference< XHelperInterface >& xParent,
const uno::Reference< uno::XComponentContext > & xContext,
const uno::Reference< frame::XModel >& xModel ) :
SwVbaFields_BASE( xParent, xContext ,
uno::
Reference< container::XIndexAccess >( new FieldCollectionHelper( xParent, xContext, xModel ) ) ), mxModel( xModel )
311 mxMSF.set( mxModel, uno::UNO_QUERY_THROW );
314 uno::Reference< word::XField > SAL_CALL
315 SwVbaFields::Add(
const css::uno::Reference< ::ooo::vba::word::XRange >&
Range,
const css::uno::Any&
Type,
const css::uno::Any& Text,
const css::uno::Any& )
317 sal_Int32
nType = word::WdFieldType::wdFieldEmpty;
323 if( ( nType == word::WdFieldType::wdFieldEmpty ) && !sText.isEmpty() )
325 SwVbaReadFieldParams aReadParam(sText);
326 sFieldName = aReadParam.GetFieldName();
327 SAL_INFO(
"sw.vba",
"the field name is " << sFieldName );
330 uno::Reference< text::XTextContent > xTextField;
331 if( nType == word::WdFieldType::wdFieldFileName || sFieldName.equalsIgnoreAsciiCase(
"FILENAME") )
335 else if( nType == word::WdFieldType::wdFieldDocProperty || sFieldName.equalsIgnoreAsciiCase(
"DOCPROPERTY") )
341 throw uno::RuntimeException(
"Not implemented" );
345 uno::Reference< text::XTextRange > xTextRange = rVbaRange.
getXTextRange();
346 uno::Reference< text::XText > xText = xTextRange->getText();
347 xText->insertTextContent( xTextRange, xTextField,
true );
348 return uno::Reference< word::XField >(
new SwVbaField( mxParent, mxContext, uno::Reference< text::XTextField >( xTextField, uno::UNO_QUERY_THROW ) ) );
353 uno::Reference< text::XTextField > xTextField(
mxMSF->createInstance(
"com.sun.star.text.TextField.FileName"), uno::UNO_QUERY_THROW );
354 sal_Int16 nFileFormat = text::FilenameDisplayFormat::NAME_AND_EXT;
355 if( !_text.isEmpty() )
358 SwVbaReadFieldParams aReadParam( _text );
359 while (-1 != (nRet = aReadParam.SkipToNextToken()))
364 nFileFormat = text::FilenameDisplayFormat::FULL;
368 aReadParam.SkipToNextToken();
377 uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW );
378 xProps->setPropertyValue(
"FileFormat", uno::makeAny( nFileFormat ) );
385 struct DocPropertyTable
387 const char* sDocPropertyName;
388 const char* sFieldService;
395 {
"Author",
"com.sun.star.text.textfield.docinfo.CreateAuthor" },
396 {
"Bytes",
nullptr },
397 {
"Category",
nullptr },
398 {
"Characters",
nullptr },
399 {
"CharactersWithSpaces",
nullptr },
400 {
"Comments",
"com.sun.star.text.textfield.docinfo.Description" },
401 {
"Company",
nullptr },
402 {
"CreateTime",
"com.sun.star.text.textfield.docinfo.CreateDateTime" },
403 {
"HyperlinkBase",
nullptr },
404 {
"Keywords",
"com.sun.star.text.textfield.docinfo.Keywords" },
405 {
"LastPrinted",
"com.sun.star.text.textfield.docinfo.PrintDateTime" },
406 {
"LastSavedBy",
"com.sun.star.text.textfield.docinfo.ChangeAuthor" },
407 {
"LastSavedTime",
"com.sun.star.text.textfield.docinfo.ChangeDateTime" },
408 {
"Lines",
nullptr },
409 {
"Manager",
nullptr },
410 {
"NameofApplication",
nullptr },
411 {
"ODMADocID",
nullptr },
412 {
"Pages",
"com.sun.star.text.textfield.PageCount" },
413 {
"Paragraphs",
"com.sun.star.text.textfield.ParagraphCount" },
414 {
"RevisionNumber",
"com.sun.star.text.textfield.docinfo.Revision" },
415 {
"Security",
nullptr },
416 {
"Subject",
"com.sun.star.text.textfield.docinfo.Subject" },
417 {
"Template",
"com.sun.star.text.textfield.TemplateName" },
418 {
"Title",
"com.sun.star.text.textfield.docinfo.Title" },
419 {
"TotalEditingTime",
"com.sun.star.text.textfield.docinfo.EditTime" },
420 {
"Words",
"com.sun.star.text.textfield.WordCount" },
426 OUString aDocProperty;
427 SwVbaReadFieldParams aReadParam( _text );
429 while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
434 if( aDocProperty.isEmpty() )
435 aDocProperty = aReadParam.GetResult();
439 aReadParam.SkipToNextToken();
443 aDocProperty = aDocProperty.replaceAll(
"\"",
"");
444 SAL_INFO(
"sw.vba",
"SwVbaFields::Create_Field_DocProperty, the document property name is " << aDocProperty );
445 if( aDocProperty.isEmpty() )
447 throw uno::RuntimeException();
451 OUString sFieldService;
453 for(
const DocPropertyTable* pTable = aDocPropertyTables; pTable->sDocPropertyName !=
nullptr; pTable++ )
455 if( aDocProperty.equalsIgnoreAsciiCaseAscii( pTable->sDocPropertyName ) )
457 if( pTable->sFieldService !=
nullptr )
458 sFieldService = OUString::createFromAscii(pTable->sFieldService);
466 sFieldService =
"com.sun.star.text.textfield.docinfo.Custom";
468 else if( sFieldService.isEmpty() )
470 throw uno::RuntimeException(
"Not implemented" );
473 uno::Reference< text::XTextField > xTextField(
mxMSF->createInstance( sFieldService ), uno::UNO_QUERY_THROW );
477 uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW );
478 xProps->setPropertyValue(
"Name", uno::makeAny( aDocProperty ) );
484 uno::Reference< container::XEnumeration > SAL_CALL
487 uno::Reference< container::XEnumerationAccess > xEnumerationAccess(
m_xIndexAccess, uno::UNO_QUERY_THROW );
488 return xEnumerationAccess->createEnumeration();
500 sal_Int32 nUpdate = 1;
503 uno::Reference< text::XTextFieldsSupplier > xSupp( mxModel, uno::UNO_QUERY_THROW );
504 uno::Reference< util::XRefreshable > xRef( xSupp->getTextFields(), uno::UNO_QUERY_THROW );
508 catch(
const uno::Exception&)
519 return "SwVbaFields";
529 uno::Sequence<OUString>
534 "ooo.vba.word.Fields"
#define ERRCODE_BASIC_BAD_ARGUMENT
css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess
WeakReference< XInterface > mxParent
css::uno::Reference< css::frame::XModel2 > mxModel
Sequence< OUString > aServiceNames
virtual OUString getServiceImplName() override
SwVbaFields(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel > &xModel)
static const DocPropertyTable aDocPropertyTables[]
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
css::uno::Reference< css::text::XTextField > Create_Field_FileName(const OUString &rText)
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getXTextRange() override
css::uno::Reference< css::text::XTextField > Create_Field_DocProperty(const OUString &_text)
virtual css::uno::Type SAL_CALL getElementType() override
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
css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF
virtual sal_Int32 SAL_CALL Update() override
css::uno::Type const & get()
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
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)
virtual css::uno::Sequence< OUString > getServiceNames() override
#define SAL_INFO(area, stream)
void copy(const fs::path &src, const fs::path &dest)
double getLength(const B2DPolygon &rCandidate)
virtual sal_Bool SAL_CALL Update() override
virtual css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
virtual css::uno::Sequence< OUString > getServiceNames() override
Reference< XComponentContext > mxContext