1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #include "vbabookmarks.hxx" 28 #include "vbabookmark.hxx" 29 #include <com/sun/star/container/XNamed.hpp> 30 #include <com/sun/star/text/XTextDocument.hpp> 31 #include <com/sun/star/text/XTextViewCursor.hpp> 32 #include <com/sun/star/text/XTextViewCursorSupplier.hpp> 33 #include <ooo/vba/word/WdBookmarkSortBy.hpp> 34 #include "vbarange.hxx" 35 #include "wordvbahelper.hxx" 36 #include <cppuhelper/implbase2.hxx> 37 38 using namespace ::ooo::vba; 39 using namespace ::com::sun::star; 40 41 class BookmarksEnumeration : public EnumerationHelperImpl 42 { 43 uno::Reference< frame::XModel > mxModel; 44 public: 45 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 ) {} 46 47 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 48 { 49 uno::Reference< container::XNamed > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); 50 rtl::OUString aName = xNamed->getName(); 51 return uno::makeAny( uno::Reference< word::XBookmark > ( new SwVbaBookmark( m_xParent, m_xContext, mxModel, aName ) ) ); 52 } 53 54 }; 55 56 // Bookmarks use case-insensitive name lookup in MS Word. 57 typedef ::cppu::WeakImplHelper2< container::XNameAccess, container::XIndexAccess > BookmarkCollectionHelper_BASE; 58 class BookmarkCollectionHelper : public BookmarkCollectionHelper_BASE 59 { 60 private: 61 uno::Reference< container::XNameAccess > mxNameAccess; 62 uno::Reference< container::XIndexAccess > mxIndexAccess; 63 uno::Any cachePos; 64 public: 65 BookmarkCollectionHelper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) throw (uno::RuntimeException) : mxIndexAccess( xIndexAccess ) 66 { 67 mxNameAccess.set( mxIndexAccess, uno::UNO_QUERY_THROW ); 68 } 69 // XElementAccess 70 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) { return mxIndexAccess->getElementType(); } 71 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException) { return mxIndexAccess->hasElements(); } 72 // XNameAcess 73 virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 74 { 75 if ( !hasByName(aName) ) 76 throw container::NoSuchElementException(); 77 return cachePos; 78 } 79 virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException) 80 { 81 return mxNameAccess->getElementNames(); 82 } 83 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException) 84 { 85 if( mxNameAccess->hasByName( aName ) ) 86 { 87 cachePos = mxNameAccess->getByName( aName ); 88 return sal_True; 89 } 90 else 91 { 92 for( sal_Int32 nIndex = 0; nIndex < mxIndexAccess->getCount(); nIndex++ ) 93 { 94 uno::Reference< container::XNamed > xNamed( mxIndexAccess->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); 95 rtl::OUString aBookmarkName = xNamed->getName(); 96 if( aName.equalsIgnoreAsciiCase( aBookmarkName ) ) 97 { 98 cachePos <<= xNamed; 99 return sal_True; 100 } 101 } 102 } 103 return sal_False; 104 } 105 // XIndexAccess 106 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) 107 { 108 return mxIndexAccess->getCount(); 109 } 110 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException ) 111 { 112 return mxIndexAccess->getByIndex( Index ); 113 } 114 }; 115 116 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 ) 117 { 118 mxBookmarksSupplier.set( mxModel, uno::UNO_QUERY_THROW ); 119 uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW ); 120 // use view cursor to insert bookmark, or it will fail if insert bookmark in table 121 // mxText = xDocument->getText(); 122 mxText = word::getXTextViewCursor( mxModel )->getText(); 123 } 124 // XEnumerationAccess 125 uno::Type 126 SwVbaBookmarks::getElementType() throw (uno::RuntimeException) 127 { 128 return word::XBookmark::static_type(0); 129 } 130 uno::Reference< container::XEnumeration > 131 SwVbaBookmarks::createEnumeration() throw (uno::RuntimeException) 132 { 133 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); 134 return new BookmarksEnumeration( getParent(), mxContext,xEnumAccess->createEnumeration(), mxModel ); 135 } 136 137 uno::Any 138 SwVbaBookmarks::createCollectionObject( const css::uno::Any& aSource ) 139 { 140 uno::Reference< container::XNamed > xNamed( aSource, uno::UNO_QUERY_THROW ); 141 rtl::OUString aName = xNamed->getName(); 142 return uno::makeAny( uno::Reference< word::XBookmark > ( new SwVbaBookmark( getParent(), mxContext, mxModel, aName ) ) ); 143 } 144 145 void SwVbaBookmarks::removeBookmarkByName( const rtl::OUString& rName ) throw (uno::RuntimeException) 146 { 147 uno::Reference< text::XTextContent > xBookmark( m_xNameAccess->getByName( rName ), uno::UNO_QUERY_THROW ); 148 mxText->removeTextContent( xBookmark ); 149 } 150 151 void SwVbaBookmarks::addBookmarkByName( const rtl::OUString& rName, const uno::Reference< text::XTextRange >& rTextRange ) throw (uno::RuntimeException) 152 { 153 uno::Reference< lang::XMultiServiceFactory > xDocMSF( mxModel, uno::UNO_QUERY_THROW ); 154 uno::Reference< text::XTextContent > xBookmark( xDocMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Bookmark")) ), uno::UNO_QUERY_THROW ); 155 uno::Reference< container::XNamed > xNamed( xBookmark, uno::UNO_QUERY_THROW ); 156 xNamed->setName( rName ); 157 mxText->insertTextContent( rTextRange, xBookmark, sal_False ); 158 } 159 160 uno::Any SAL_CALL 161 SwVbaBookmarks::Add( const rtl::OUString& rName, const uno::Any& rRange ) throw (uno::RuntimeException) 162 { 163 uno::Reference< text::XTextRange > xTextRange; 164 uno::Reference< word::XRange > xRange; 165 if( rRange >>= xRange ) 166 { 167 SwVbaRange* pRange = dynamic_cast< SwVbaRange* >( xRange.get() ); 168 if( pRange ) 169 xTextRange = pRange->getXTextRange(); 170 } 171 else 172 { 173 // FIXME: insert the bookmark into current view cursor 174 xTextRange.set( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW ); 175 } 176 177 // remove the exist bookmark 178 // rtl::OUString aName = rName.toAsciiLowerCase(); 179 rtl::OUString aName = rName; 180 if( m_xNameAccess->hasByName( aName ) ) 181 removeBookmarkByName( aName ); 182 183 addBookmarkByName( aName, xTextRange ); 184 185 return uno::makeAny( uno::Reference< word::XBookmark >( new SwVbaBookmark( getParent(), mxContext, mxModel, aName ) ) ); 186 } 187 188 sal_Int32 SAL_CALL 189 SwVbaBookmarks::getDefaultSorting() throw (css::uno::RuntimeException) 190 { 191 return word::WdBookmarkSortBy::wdSortByName; 192 } 193 194 void SAL_CALL 195 SwVbaBookmarks::setDefaultSorting( sal_Int32/* _type*/ ) throw (css::uno::RuntimeException) 196 { 197 // not support in Writer 198 } 199 200 sal_Bool SAL_CALL 201 SwVbaBookmarks::getShowHidden() throw (css::uno::RuntimeException) 202 { 203 return sal_True; 204 } 205 206 void SAL_CALL 207 SwVbaBookmarks::setShowHidden( sal_Bool /*_hidden*/ ) throw (css::uno::RuntimeException) 208 { 209 // not support in Writer 210 } 211 212 sal_Bool SAL_CALL 213 SwVbaBookmarks::Exists( const rtl::OUString& rName ) throw (css::uno::RuntimeException) 214 { 215 sal_Bool bExist = m_xNameAccess->hasByName( rName ); 216 return bExist; 217 } 218 219 rtl::OUString& 220 SwVbaBookmarks::getServiceImplName() 221 { 222 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBookmarks") ); 223 return sImplName; 224 } 225 226 css::uno::Sequence<rtl::OUString> 227 SwVbaBookmarks::getServiceNames() 228 { 229 static uno::Sequence< rtl::OUString > sNames; 230 if ( sNames.getLength() == 0 ) 231 { 232 sNames.realloc( 1 ); 233 sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Bookmarks") ); 234 } 235 return sNames; 236 } 237