| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| #include "vbafind.hxx" |
| #include <vbahelper/vbahelper.hxx> |
| #include <tools/diagnose_ex.h> |
| #include "vbareplacement.hxx" |
| #include <ooo/vba/word/WdFindWrap.hpp> |
| #include <ooo/vba/word/WdReplace.hpp> |
| #include <com/sun/star/text/XTextRangeCompare.hpp> |
| #include "wordvbahelper.hxx" |
| |
| using namespace ::ooo::vba; |
| using namespace ::com::sun::star; |
| |
| SwVbaFind::SwVbaFind( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ) throw ( uno::RuntimeException ) : |
| SwVbaFind_BASE( rParent, rContext ), mxModel( xModel ), mxTextRange( xTextRange ), mbReplace( sal_False ), mnReplaceType( word::WdReplace::wdReplaceOne ), mnWrap( word::WdFindWrap::wdFindStop ) |
| { |
| mxReplaceable.set( mxModel, uno::UNO_QUERY_THROW ); |
| mxPropertyReplace.set( mxReplaceable->createReplaceDescriptor(), uno::UNO_QUERY_THROW ); |
| mxTVC = word::getXTextViewCursor( mxModel ); |
| mxSelSupp.set( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); |
| } |
| |
| SwVbaFind::~SwVbaFind() |
| { |
| } |
| |
| sal_Bool SwVbaFind::InRange( const uno::Reference< text::XTextRange >& xCurrentRange ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW ); |
| if( xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) >= 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) <= 0 ) |
| return sal_True; |
| return sal_False; |
| } |
| |
| sal_Bool SwVbaFind::InEqualRange( const uno::Reference< text::XTextRange >& xCurrentRange ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW ); |
| if( xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) == 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) == 0 ) |
| return sal_True; |
| return sal_False; |
| } |
| |
| void SwVbaFind::SetReplaceWith( const rtl::OUString& rText ) throw (uno::RuntimeException) |
| { |
| mxPropertyReplace->setReplaceString( rText ); |
| mbReplace = sal_True; |
| } |
| |
| rtl::OUString SwVbaFind::GetReplaceWith() throw (uno::RuntimeException) |
| { |
| return mxPropertyReplace->getReplaceString(); |
| } |
| void SwVbaFind::SetReplace( sal_Int32 type ) |
| { |
| mnReplaceType = type; |
| mbReplace = sal_True; |
| } |
| #ifdef TOMORROW |
| rtl::OUString SwVbaFind::ReplaceWildcards( const rtl::OUString& /*rText*/ ) throw ( uno::RuntimeException ) |
| { |
| // TODO: |
| return rtl::OUString(); |
| } |
| #endif |
| uno::Reference< text::XTextRange > SwVbaFind::FindOneElement() throw ( uno::RuntimeException ) |
| { |
| uno::Reference< text::XTextRange > xFoundOne; |
| if( mxTVC->getString().getLength() > 0 ) |
| { |
| if( getForward() ) |
| { |
| xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); |
| } |
| else |
| { |
| xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); |
| } |
| |
| if( xFoundOne.is() && InEqualRange( xFoundOne ) ) |
| { |
| xFoundOne.set( mxReplaceable->findNext( xFoundOne, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); |
| } |
| else if( xFoundOne.is() && !InRange( xFoundOne ) ) |
| { |
| xFoundOne = uno::Reference< text::XTextRange >(); |
| } |
| } |
| else |
| { |
| xFoundOne.set( mxReplaceable->findNext( mxTextRange, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); |
| } |
| |
| if( !xFoundOne.is() && ( getWrap() == word::WdFindWrap::wdFindContinue || getWrap() == word::WdFindWrap::wdFindAsk ) ) |
| { |
| if( getForward() ) |
| { |
| mxTVC->gotoStart(sal_False); |
| xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); |
| } |
| else |
| { |
| mxTVC->gotoEnd( sal_False ); |
| xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); |
| |
| } |
| } |
| return xFoundOne; |
| } |
| |
| sal_Bool SwVbaFind::SearchReplace() throw (uno::RuntimeException) |
| { |
| sal_Bool result = sal_False; |
| |
| // TODO: map wildcards in area to OOo wildcards |
| |
| if( mbReplace ) |
| { |
| switch( mnReplaceType ) |
| { |
| case word::WdReplace::wdReplaceNone: |
| { |
| result = sal_True; |
| break; |
| } |
| case word::WdReplace::wdReplaceOne: |
| { |
| uno::Reference< text::XTextRange > xFindOne = FindOneElement(); |
| if( xFindOne.is() ) |
| { |
| xFindOne->setString( GetReplaceWith() ); |
| result = mxSelSupp->select( uno::makeAny( xFindOne ) ); |
| } |
| break; |
| } |
| case word::WdReplace::wdReplaceAll: |
| { |
| uno::Reference< container::XIndexAccess > xIndexAccess = mxReplaceable->findAll( uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ); |
| if( xIndexAccess->getCount() > 0 ) |
| { |
| for( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ ) |
| { |
| uno::Reference< text::XTextRange > xTextRange( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW ); |
| if( mnWrap == word::WdFindWrap::wdFindContinue || mnWrap == word::WdFindWrap::wdFindAsk || InRange( xTextRange ) ) |
| { |
| xTextRange->setString( GetReplaceWith() ); |
| result = sal_True; |
| } |
| } |
| } |
| break; |
| } |
| default: |
| { |
| result = sal_False; |
| } |
| } |
| } |
| else |
| { |
| uno::Reference< text::XTextRange > xFindOne = FindOneElement(); |
| if( xFindOne.is() ) |
| result = mxSelSupp->select( uno::makeAny( xFindOne ) ); |
| } |
| |
| return result; |
| } |
| |
| ::rtl::OUString SAL_CALL SwVbaFind::getText() throw (uno::RuntimeException) |
| { |
| return mxPropertyReplace->getSearchString(); |
| } |
| |
| void SAL_CALL SwVbaFind::setText( const ::rtl::OUString& _text ) throw (uno::RuntimeException) |
| { |
| mxPropertyReplace->setSearchString( _text ); |
| } |
| |
| uno::Any SAL_CALL SwVbaFind::getReplacement() throw (uno::RuntimeException) |
| { |
| return uno::makeAny( uno::Reference< word::XReplacement >( new SwVbaReplacement( this, mxContext, mxPropertyReplace ) ) ); |
| } |
| |
| void SAL_CALL SwVbaFind::setReplacement( const uno::Any& /*_replacement */ ) throw (uno::RuntimeException) |
| { |
| throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getForward() throw (uno::RuntimeException) |
| { |
| sal_Bool bBackward = sal_False; |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchBackwards") ) ) >>= bBackward; |
| return !bBackward; |
| } |
| |
| void SAL_CALL SwVbaFind::setForward( ::sal_Bool _forward ) throw (uno::RuntimeException) |
| { |
| sal_Bool bBackward = !_forward; |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchBackwards") ), uno::makeAny( bBackward ) ); |
| } |
| |
| ::sal_Int32 SAL_CALL SwVbaFind::getWrap() throw (uno::RuntimeException) |
| { |
| // seems not supported in Writer |
| return mnWrap; |
| } |
| |
| void SAL_CALL SwVbaFind::setWrap( ::sal_Int32 _wrap ) throw (uno::RuntimeException) |
| { |
| // seems not supported in Writer |
| mnWrap = _wrap; |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getFormat() throw (uno::RuntimeException) |
| { |
| return mxPropertyReplace->getValueSearch(); |
| } |
| |
| void SAL_CALL SwVbaFind::setFormat( ::sal_Bool _format ) throw (uno::RuntimeException) |
| { |
| mxPropertyReplace->setValueSearch( _format ); |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getMatchCase() throw (uno::RuntimeException) |
| { |
| sal_Bool value = sal_False; |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchCaseSensitive") ) ) >>= value; |
| return value; |
| } |
| |
| void SAL_CALL SwVbaFind::setMatchCase( ::sal_Bool _matchcase ) throw (uno::RuntimeException) |
| { |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchCaseSensitive") ), uno::makeAny( _matchcase ) ); |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getMatchWholeWord() throw (uno::RuntimeException) |
| { |
| sal_Bool value = sal_False; |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchWords") ) ) >>= value; |
| return value; |
| } |
| |
| void SAL_CALL SwVbaFind::setMatchWholeWord( ::sal_Bool _matchwholeword ) throw (uno::RuntimeException) |
| { |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchWords") ), uno::makeAny( _matchwholeword ) ); |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getMatchWildcards() throw (uno::RuntimeException) |
| { |
| sal_Bool value = sal_False; |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchRegularExpression") ) ) >>= value; |
| return value; |
| } |
| |
| void SAL_CALL SwVbaFind::setMatchWildcards( ::sal_Bool _matchwildcards ) throw (uno::RuntimeException) |
| { |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchRegularExpression") ), uno::makeAny( _matchwildcards ) ); |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getMatchSoundsLike() throw (uno::RuntimeException) |
| { |
| sal_Bool value = sal_False; |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ) ) >>= value; |
| return value; |
| } |
| |
| void SAL_CALL SwVbaFind::setMatchSoundsLike( ::sal_Bool _matchsoundslike ) throw (uno::RuntimeException) |
| { |
| // seems not accurate |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ), uno::makeAny( _matchsoundslike ) ); |
| } |
| |
| ::sal_Bool SAL_CALL SwVbaFind::getMatchAllWordForms() throw (uno::RuntimeException) |
| { |
| sal_Bool value = sal_False; |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ) ) >>= value; |
| if( value ) |
| mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarityRelax") ) ) >>= value; |
| return value; |
| } |
| |
| void SAL_CALL SwVbaFind::setMatchAllWordForms( ::sal_Bool _matchallwordforms ) throw (uno::RuntimeException) |
| { |
| // seems not accurate |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ), uno::makeAny( _matchallwordforms ) ); |
| mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarityRelax") ), uno::makeAny( _matchallwordforms ) ); |
| } |
| |
| uno::Any SAL_CALL SwVbaFind::getStyle() throw (uno::RuntimeException) |
| { |
| throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); |
| } |
| |
| void SAL_CALL SwVbaFind::setStyle( const uno::Any& /*_style */ ) throw (uno::RuntimeException) |
| { |
| throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); |
| } |
| |
| sal_Bool SAL_CALL |
| SwVbaFind::Execute( const uno::Any& FindText, const uno::Any& MatchCase, const uno::Any& MatchWholeWord, const uno::Any& MatchWildcards, const uno::Any& MatchSoundsLike, const uno::Any& MatchAllWordForms, const uno::Any& Forward, const uno::Any& Wrap, const uno::Any& Format, const uno::Any& ReplaceWith, const uno::Any& Replace, const uno::Any& /*MatchKashida*/, const uno::Any& /*MatchDiacritics*/, const uno::Any& /*MatchAlefHamza*/, const uno::Any& /*MatchControl*/, const uno::Any& /*MatchPrefix*/, const uno::Any& /*MatchSuffix*/, const uno::Any& /*MatchPhrase*/, const uno::Any& /*IgnoreSpace*/, const uno::Any& /*IgnorePunct*/ ) throw (uno::RuntimeException) |
| { |
| sal_Bool result = sal_False; |
| if( FindText.hasValue() ) |
| { |
| rtl::OUString sText; |
| FindText >>= sText; |
| setText( sText ); |
| } |
| |
| sal_Bool bValue = sal_False; |
| if( MatchCase.hasValue() ) |
| { |
| MatchCase >>= bValue; |
| setMatchCase( bValue ); |
| } |
| |
| if( MatchWholeWord.hasValue() ) |
| { |
| MatchWholeWord >>= bValue; |
| setMatchWholeWord( bValue ); |
| } |
| |
| if( MatchWildcards.hasValue() ) |
| { |
| MatchWildcards >>= bValue; |
| setMatchWildcards( bValue ); |
| } |
| |
| if( MatchSoundsLike.hasValue() ) |
| { |
| MatchSoundsLike >>= bValue; |
| setMatchSoundsLike( bValue ); |
| } |
| |
| if( MatchAllWordForms.hasValue() ) |
| { |
| MatchAllWordForms >>= bValue; |
| setMatchAllWordForms( bValue ); |
| } |
| |
| if( Forward.hasValue() ) |
| { |
| Forward >>= bValue; |
| setForward( bValue ); |
| } |
| |
| if( Wrap.hasValue() ) |
| { |
| sal_Int32 nWrapType = 0; |
| Wrap >>= nWrapType; |
| setWrap( nWrapType ); |
| } |
| |
| if( Format.hasValue() ) |
| { |
| Format >>= bValue; |
| setFormat( bValue ); |
| } |
| |
| if( ReplaceWith.hasValue() ) |
| { |
| rtl::OUString sValue; |
| ReplaceWith >>= sValue; |
| SetReplaceWith( sValue ); |
| } |
| |
| if( Replace.hasValue() ) |
| { |
| sal_Int32 nValue(0); |
| Replace >>= nValue; |
| SetReplace( nValue ); |
| } |
| |
| result = SearchReplace(); |
| |
| return result; |
| } |
| |
| void SAL_CALL |
| SwVbaFind::ClearFormatting( ) throw (uno::RuntimeException) |
| { |
| uno::Sequence< beans::PropertyValue > aSearchAttribs; |
| mxPropertyReplace->setSearchAttributes( aSearchAttribs ); |
| } |
| |
| rtl::OUString& |
| SwVbaFind::getServiceImplName() |
| { |
| static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaFind") ); |
| return sImplName; |
| } |
| |
| uno::Sequence< rtl::OUString > |
| SwVbaFind::getServiceNames() |
| { |
| static uno::Sequence< rtl::OUString > aServiceNames; |
| if ( aServiceNames.getLength() == 0 ) |
| { |
| aServiceNames.realloc( 1 ); |
| aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Find" ) ); |
| } |
| return aServiceNames; |
| } |
| |