1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #include "vbabookmarks.hxx" 24 #include "vbabookmark.hxx" 25 #include <com/sun/star/container/XNamed.hpp> 26 #include <com/sun/star/text/XTextDocument.hpp> 27 #include <com/sun/star/text/XTextViewCursor.hpp> 28 #include <com/sun/star/text/XTextViewCursorSupplier.hpp> 29 #include <ooo/vba/word/WdBookmarkSortBy.hpp> 30 #include "vbarange.hxx" 31 #include "wordvbahelper.hxx" 32 #include <cppuhelper/implbase2.hxx> 33 34 using namespace ::ooo::vba; 35 using namespace ::com::sun::star; 36 37 class BookmarksEnumeration : public EnumerationHelperImpl 38 { 39 uno::Reference< frame::XModel > mxModel; 40 public: 41 BookmarksEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel( xModel ) {} 42 43 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 44 { 45 uno::Reference< container::XNamed > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); 46 rtl::OUString aName = xNamed->getName(); 47 return uno::makeAny( uno::Reference< word::XBookmark > ( new SwVbaBookmark( m_xParent, m_xContext, mxModel, aName ) ) ); 48 } 49 50 }; 51 52 // Bookmarks use case-insensitive name lookup in MS Word. 53 typedef ::cppu::WeakImplHelper2< container::XNameAccess, container::XIndexAccess > BookmarkCollectionHelper_BASE; 54 class BookmarkCollectionHelper : public BookmarkCollectionHelper_BASE 55 { 56 private: 57 uno::Reference< container::XNameAccess > mxNameAccess; 58 uno::Reference< container::XIndexAccess > mxIndexAccess; 59 uno::Any cachePos; 60 public: 61 BookmarkCollectionHelper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) throw (uno::RuntimeException) : mxIndexAccess( xIndexAccess ) 62 { 63 mxNameAccess.set( mxIndexAccess, uno::UNO_QUERY_THROW ); 64 } 65 // XElementAccess 66 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) { return mxIndexAccess->getElementType(); } 67 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException) { return mxIndexAccess->hasElements(); } 68 // XNameAcess 69 virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 70 { 71 if ( !hasByName(aName) ) 72 throw container::NoSuchElementException(); 73 return cachePos; 74 } 75 virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException) 76 { 77 return mxNameAccess->getElementNames(); 78 } 79 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException) 80 { 81 if( mxNameAccess->hasByName( aName ) ) 82 { 83 cachePos = mxNameAccess->getByName( aName ); 84 return sal_True; 85 } 86 else 87 { 88 for( sal_Int32 nIndex = 0; nIndex < mxIndexAccess->getCount(); nIndex++ ) 89 { 90 uno::Reference< container::XNamed > xNamed( mxIndexAccess->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); 91 rtl::OUString aBookmarkName = xNamed->getName(); 92 if( aName.equalsIgnoreAsciiCase( aBookmarkName ) ) 93 { 94 cachePos <<= xNamed; 95 return sal_True; 96 } 97 } 98 } 99 return sal_False; 100 } 101 // XIndexAccess 102 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) 103 { 104 return mxIndexAccess->getCount(); 105 } 106 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException ) 107 { 108 return mxIndexAccess->getByIndex( Index ); 109 } 110 }; 111 112 SwVbaBookmarks::SwVbaBookmarks( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xBookmarks, const uno::Reference< frame::XModel >& xModel ): SwVbaBookmarks_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new BookmarkCollectionHelper( xBookmarks ) ) ), mxModel( xModel ) 113 { 114 mxBookmarksSupplier.set( mxModel, uno::UNO_QUERY_THROW ); 115 uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW ); 116 // use view cursor to insert bookmark, or it will fail if insert bookmark in table 117 // mxText = xDocument->getText(); 118 mxText = word::getXTextViewCursor( mxModel )->getText(); 119 } 120 // XEnumerationAccess 121 uno::Type 122 SwVbaBookmarks::getElementType() throw (uno::RuntimeException) 123 { 124 return word::XBookmark::static_type(0); 125 } 126 uno::Reference< container::XEnumeration > 127 SwVbaBookmarks::createEnumeration() throw (uno::RuntimeException) 128 { 129 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); 130 return new BookmarksEnumeration( getParent(), mxContext,xEnumAccess->createEnumeration(), mxModel ); 131 } 132 133 uno::Any 134 SwVbaBookmarks::createCollectionObject( const css::uno::Any& aSource ) 135 { 136 uno::Reference< container::XNamed > xNamed( aSource, uno::UNO_QUERY_THROW ); 137 rtl::OUString aName = xNamed->getName(); 138 return uno::makeAny( uno::Reference< word::XBookmark > ( new SwVbaBookmark( getParent(), mxContext, mxModel, aName ) ) ); 139 } 140 141 void SwVbaBookmarks::removeBookmarkByName( const rtl::OUString& rName ) throw (uno::RuntimeException) 142 { 143 uno::Reference< text::XTextContent > xBookmark( m_xNameAccess->getByName( rName ), uno::UNO_QUERY_THROW ); 144 mxText->removeTextContent( xBookmark ); 145 } 146 147 void SwVbaBookmarks::addBookmarkByName( const rtl::OUString& rName, const uno::Reference< text::XTextRange >& rTextRange ) throw (uno::RuntimeException) 148 { 149 uno::Reference< lang::XMultiServiceFactory > xDocMSF( mxModel, uno::UNO_QUERY_THROW ); 150 uno::Reference< text::XTextContent > xBookmark( xDocMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Bookmark")) ), uno::UNO_QUERY_THROW ); 151 uno::Reference< container::XNamed > xNamed( xBookmark, uno::UNO_QUERY_THROW ); 152 xNamed->setName( rName ); 153 mxText->insertTextContent( rTextRange, xBookmark, sal_False ); 154 } 155 156 uno::Any SAL_CALL 157 SwVbaBookmarks::Add( const rtl::OUString& rName, const uno::Any& rRange ) throw (uno::RuntimeException) 158 { 159 uno::Reference< text::XTextRange > xTextRange; 160 uno::Reference< word::XRange > xRange; 161 if( rRange >>= xRange ) 162 { 163 SwVbaRange* pRange = dynamic_cast< SwVbaRange* >( xRange.get() ); 164 if( pRange ) 165 xTextRange = pRange->getXTextRange(); 166 } 167 else 168 { 169 // FIXME: insert the bookmark into current view cursor 170 xTextRange.set( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW ); 171 } 172 173 // remove the exist bookmark 174 // rtl::OUString aName = rName.toAsciiLowerCase(); 175 rtl::OUString aName = rName; 176 if( m_xNameAccess->hasByName( aName ) ) 177 removeBookmarkByName( aName ); 178 179 addBookmarkByName( aName, xTextRange ); 180 181 return uno::makeAny( uno::Reference< word::XBookmark >( new SwVbaBookmark( getParent(), mxContext, mxModel, aName ) ) ); 182 } 183 184 sal_Int32 SAL_CALL 185 SwVbaBookmarks::getDefaultSorting() throw (css::uno::RuntimeException) 186 { 187 return word::WdBookmarkSortBy::wdSortByName; 188 } 189 190 void SAL_CALL 191 SwVbaBookmarks::setDefaultSorting( sal_Int32/* _type*/ ) throw (css::uno::RuntimeException) 192 { 193 // not support in Writer 194 } 195 196 sal_Bool SAL_CALL 197 SwVbaBookmarks::getShowHidden() throw (css::uno::RuntimeException) 198 { 199 return sal_True; 200 } 201 202 void SAL_CALL 203 SwVbaBookmarks::setShowHidden( sal_Bool /*_hidden*/ ) throw (css::uno::RuntimeException) 204 { 205 // not support in Writer 206 } 207 208 sal_Bool SAL_CALL 209 SwVbaBookmarks::Exists( const rtl::OUString& rName ) throw (css::uno::RuntimeException) 210 { 211 sal_Bool bExist = m_xNameAccess->hasByName( rName ); 212 return bExist; 213 } 214 215 rtl::OUString& 216 SwVbaBookmarks::getServiceImplName() 217 { 218 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBookmarks") ); 219 return sImplName; 220 } 221 222 css::uno::Sequence<rtl::OUString> 223 SwVbaBookmarks::getServiceNames() 224 { 225 static uno::Sequence< rtl::OUString > sNames; 226 if ( sNames.getLength() == 0 ) 227 { 228 sNames.realloc( 1 ); 229 sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Bookmarks") ); 230 } 231 return sNames; 232 } 233