From a652ea0fc4cc789f715b461819127ee80afa9e6f Mon Sep 17 00:00:00 2001 From: roopak12345 Date: Sun, 9 Mar 2014 21:40:44 +0100 Subject: fdo#70422 Moved the linked files from sw/source/ui to a new core/uibase dir Moved the files linked in sw/Library_sw.mk from sw/source/ui to sw/source/core/uibase and modified the make files as per the new directory location. Reviewed on: https://gerrit.libreoffice.org/8447 Change-Id: I05f6ccdeee5e76fb0ae477d16721d9ddc6eaff32 --- sw/source/core/uibase/lingu/hhcwrp.cxx | 720 +++++++++++++++++++++++ sw/source/core/uibase/lingu/hyp.cxx | 132 +++++ sw/source/core/uibase/lingu/olmenu.cxx | 891 +++++++++++++++++++++++++++++ sw/source/core/uibase/lingu/olmenu.hrc | 89 +++ sw/source/core/uibase/lingu/olmenu.src | 131 +++++ sw/source/core/uibase/lingu/sdrhhcwrap.cxx | 175 ++++++ sw/source/core/uibase/lingu/sdrhhcwrap.hxx | 56 ++ 7 files changed, 2194 insertions(+) create mode 100644 sw/source/core/uibase/lingu/hhcwrp.cxx create mode 100644 sw/source/core/uibase/lingu/hyp.cxx create mode 100644 sw/source/core/uibase/lingu/olmenu.cxx create mode 100644 sw/source/core/uibase/lingu/olmenu.hrc create mode 100644 sw/source/core/uibase/lingu/olmenu.src create mode 100644 sw/source/core/uibase/lingu/sdrhhcwrap.cxx create mode 100644 sw/source/core/uibase/lingu/sdrhhcwrap.hxx (limited to 'sw/source/core/uibase/lingu') diff --git a/sw/source/core/uibase/lingu/hhcwrp.cxx b/sw/source/core/uibase/lingu/hhcwrp.cxx new file mode 100644 index 000000000000..b5d1950f24f3 --- /dev/null +++ b/sw/source/core/uibase/lingu/hhcwrp.cxx @@ -0,0 +1,720 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::linguistic2; +using namespace ::com::sun::star::i18n; + +// Description: Turn off frame/object shell if applicable + +static void lcl_ActivateTextShell( SwWrtShell & rWrtSh ) +{ + if( rWrtSh.IsSelFrmMode() || rWrtSh.IsObjSelected() ) + rWrtSh.EnterStdMode(); +} + +class SwKeepConversionDirectionStateContext +{ +public: + SwKeepConversionDirectionStateContext() + { + //!! hack to transport the current conversion direction state settings + //!! into the next incarnation that iterates over the drawing objets + //!! ( see SwHHCWrapper::~SwHHCWrapper() ) + editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( true ); + } + + ~SwKeepConversionDirectionStateContext() + { + editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( false ); + } +}; + +SwHHCWrapper::SwHHCWrapper( + SwView* pSwView, + const uno::Reference< uno::XComponentContext >& rxContext, + LanguageType nSourceLanguage, + LanguageType nTargetLanguage, + const Font *pTargetFont, + sal_Int32 nConvOptions, + bool bIsInteractive, + bool bStart, bool bOther, bool bSelection ) + : editeng::HangulHanjaConversion( &pSwView->GetEditWin(), rxContext, + LanguageTag::convertToLocale( nSourceLanguage ), + LanguageTag::convertToLocale( nTargetLanguage ), + pTargetFont, + nConvOptions, + bIsInteractive ) + , m_pView( pSwView ) + , m_pWin( &pSwView->GetEditWin() ) + , m_rWrtShell( pSwView->GetWrtShell() ) + , m_pConvArgs( 0 ) + , m_nLastPos( 0 ) + , m_nUnitOffset( 0 ) + , m_nPageCount( 0 ) + , m_nPageStart( 0 ) + , m_bIsDrawObj( false ) + , m_bIsOtherCntnt( bOther ) + , m_bStartChk( bOther ) + , m_bIsSelection( bSelection ) + , m_bStartDone( bOther || bStart ) + , m_bEndDone( false ) +{ +} + +SwHHCWrapper::~SwHHCWrapper() +{ + delete m_pConvArgs; + + m_rWrtShell.SetCareWin( NULL ); + + // check for existence of a draw view which means that there are + // (or previously were) draw objects present in the document. + // I.e. we like to check those too. + if ( IsDrawObj() /*&& bLastRet*/ && m_pView->GetWrtShell().HasDrawView() ) + { + Cursor *pSave = m_pView->GetWindow()->GetCursor(); + { + SwKeepConversionDirectionStateContext aContext; + + SdrHHCWrapper aSdrConvWrap( m_pView, GetSourceLanguage(), + GetTargetLanguage(), GetTargetFont(), + GetConversionOptions(), IsInteractive() ); + aSdrConvWrap.StartTextConversion(); + } + m_pView->GetWindow()->SetCursor( pSave ); + } + + if( m_nPageCount ) + ::EndProgress( m_pView->GetDocShell() ); + + // finally for chinese translation we need to change the documents + // default language and font to the new ones to be used. + LanguageType nTargetLang = GetTargetLanguage(); + if (IsChinese( nTargetLang )) + { + SwDoc *pDoc = m_pView->GetDocShell()->GetDoc(); + + //!! Note: This also effects the default language of text boxes (EditEngine/EditView) !! + pDoc->SetDefault( SvxLanguageItem( nTargetLang, RES_CHRATR_CJK_LANGUAGE ) ); + + const Font *pFont = GetTargetFont(); + if (pFont) + { + SvxFontItem aFontItem( pFont->GetFamily(), pFont->GetName(), + pFont->GetStyleName(), pFont->GetPitch(), + pFont->GetCharSet(), RES_CHRATR_CJK_FONT ); + pDoc->SetDefault( aFontItem ); + } + + } +} + +void SwHHCWrapper::GetNextPortion( + OUString& rNextPortion, + LanguageType& rLangOfPortion, + bool bAllowChanges ) +{ + m_pConvArgs->bAllowImplicitChangesForNotConvertibleText = bAllowChanges; + + FindConvText_impl(); + rNextPortion = m_pConvArgs->aConvText; + rLangOfPortion = m_pConvArgs->nConvTextLang; + + m_nUnitOffset = 0; + + // build last pos from currently selected text + SwPaM* pCrsr = m_rWrtShell.GetCrsr(); + m_nLastPos = pCrsr->Start()->nContent.GetIndex(); +} + +void SwHHCWrapper::SelectNewUnit_impl( sal_Int32 nUnitStart, sal_Int32 nUnitEnd ) +{ + SwPaM *pCrsr = m_rWrtShell.GetCrsr(); + pCrsr->GetPoint()->nContent = m_nLastPos; + pCrsr->DeleteMark(); + + m_rWrtShell.Right( CRSR_SKIP_CHARS, /*bExpand*/ sal_False, + (sal_uInt16) (m_nUnitOffset + nUnitStart), sal_True ); + pCrsr->SetMark(); + m_rWrtShell.Right( CRSR_SKIP_CHARS, /*bExpand*/ sal_True, + (sal_uInt16) (nUnitEnd - nUnitStart), sal_True ); + // end selection now. Otherwise SHIFT+HOME (extending the selection) + // won't work when the dialog is closed without any replacement. + // (see #116346#) + m_rWrtShell.EndSelect(); +} + +void SwHHCWrapper::HandleNewUnit( + const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd ) +{ + OSL_ENSURE( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" ); + if (!(0 <= nUnitStart && nUnitStart <= nUnitEnd)) + return; + + lcl_ActivateTextShell( m_rWrtShell ); + + m_rWrtShell.StartAllAction(); + + // select current unit + SelectNewUnit_impl( nUnitStart, nUnitEnd ); + + m_rWrtShell.EndAllAction(); +} + +void SwHHCWrapper::ChangeText( const OUString &rNewText, + const OUString& rOrigText, + const uno::Sequence< sal_Int32 > *pOffsets, + SwPaM *pCrsr ) +{ + //!! please see also TextConvWrapper::ChangeText with is a modified + //!! copy of this code + + OSL_ENSURE( !rNewText.isEmpty(), "unexpected empty string" ); + if (rNewText.isEmpty()) + return; + + if (pOffsets && pCrsr) // try to keep as much attributation as possible ? + { + // remember cursor start position for later setting of the cursor + const SwPosition *pStart = pCrsr->Start(); + const sal_Int32 nStartIndex = pStart->nContent.GetIndex(); + const SwNodeIndex aStartNodeIndex = pStart->nNode; + SwTxtNode *pStartTxtNode = aStartNodeIndex.GetNode().GetTxtNode(); + + const sal_Int32 nIndices = pOffsets->getLength(); + const sal_Int32 *pIndices = pOffsets->getConstArray(); + sal_Int32 nConvTextLen = rNewText.getLength(); + sal_Int32 nPos = 0; + sal_Int32 nChgPos = -1; + sal_Int32 nChgLen = 0; + sal_Int32 nConvChgPos = -1; + sal_Int32 nConvChgLen = 0; + + // offset to calculate the position in the text taking into + // account that text may have been replaced with new text of + // different length. Negative values allowed! + long nCorrectionOffset = 0; + + OSL_ENSURE(nIndices == 0 || nIndices == nConvTextLen, + "mismatch between string length and sequence length!" ); + + // find all substrings that need to be replaced (and only those) + while (true) + { + // get index in original text that matches nPos in new text + sal_Int32 nIndex; + if (nPos < nConvTextLen) + nIndex = nPos < nIndices ? pIndices[nPos] : nPos; + else + { + nPos = nConvTextLen; + nIndex = rOrigText.getLength(); + } + + if (rOrigText[nIndex] == rNewText[nPos] || + nPos == nConvTextLen /* end of string also terminates non-matching char sequence */) + { + // substring that needs to be replaced found? + if (nChgPos != -1 && nConvChgPos != -1) + { + nChgLen = nIndex - nChgPos; + nConvChgLen = nPos - nConvChgPos; +#if OSL_DEBUG_LEVEL > 1 + OUString aInOrig( rOrigText.copy( nChgPos, nChgLen ) ); +#endif + OUString aInNew( rNewText.copy( nConvChgPos, nConvChgLen ) ); + + // set selection to sub string to be replaced in original text + sal_Int32 nChgInNodeStartIndex = nStartIndex + nCorrectionOffset + nChgPos; + OSL_ENSURE( m_rWrtShell.GetCrsr()->HasMark(), "cursor misplaced (nothing selected)" ); + m_rWrtShell.GetCrsr()->GetMark()->nContent.Assign( pStartTxtNode, nChgInNodeStartIndex ); + m_rWrtShell.GetCrsr()->GetPoint()->nContent.Assign( pStartTxtNode, nChgInNodeStartIndex + nChgLen ); +#if OSL_DEBUG_LEVEL > 1 + OUString aSelTxt1( m_rWrtShell.GetSelTxt() ); +#endif + + // replace selected sub string with the corresponding + // sub string from the new text while keeping as + // much from the attributes as possible + ChangeText_impl( aInNew, true ); + + nCorrectionOffset += nConvChgLen - nChgLen; + + nChgPos = -1; + nConvChgPos = -1; + } + } + else + { + // begin of non-matching char sequence found ? + if (nChgPos == -1 && nConvChgPos == -1) + { + nChgPos = nIndex; + nConvChgPos = nPos; + } + } + if (nPos >= nConvTextLen) + break; + ++nPos; + } + + // set cursor to the end of all the new text + // (as it would happen after ChangeText_impl (Delete and Insert) + // of the whole text in the 'else' branch below) + m_rWrtShell.ClearMark(); + m_rWrtShell.GetCrsr()->Start()->nContent.Assign( pStartTxtNode, nStartIndex + nConvTextLen ); + } + else + { + ChangeText_impl( rNewText, false ); + } +} + +void SwHHCWrapper::ChangeText_impl( const OUString &rNewText, bool bKeepAttributes ) +{ + if (bKeepAttributes) + { + // get item set with all relevant attributes + sal_uInt16 aRanges[] = { + RES_CHRATR_BEGIN, RES_FRMATR_END, + 0, 0, 0 }; + SfxItemSet aItemSet( m_rWrtShell.GetAttrPool(), aRanges ); + // get all attributes spanning the whole selection in order to + // restore those for the new text + m_rWrtShell.GetCurAttr( aItemSet ); + +#if OSL_DEBUG_LEVEL > 1 + OUString aSelTxt1( m_rWrtShell.GetSelTxt() ); +#endif + m_rWrtShell.Delete(); + m_rWrtShell.Insert( rNewText ); + + // select new inserted text (currently the Point is right after the new text) + if (!m_rWrtShell.GetCrsr()->HasMark()) + m_rWrtShell.GetCrsr()->SetMark(); + SwPosition *pMark = m_rWrtShell.GetCrsr()->GetMark(); + pMark->nContent = pMark->nContent.GetIndex() - rNewText.getLength(); +#if OSL_DEBUG_LEVEL > 1 + OUString aSelTxt2( m_rWrtShell.GetSelTxt() ); +#endif + + // since 'SetAttr' below functions like merging with the attributes + // from the itemset with any existing ones we have to get rid of all + // all attributes now. (Those attributes that may take effect left + // to the position where the new text gets inserted after the old text + // was deleted) + m_rWrtShell.ResetAttr(); + // apply previously saved attributes to new text + m_rWrtShell.SetAttrSet( aItemSet ); + } + else + { + m_rWrtShell.Delete(); + m_rWrtShell.Insert( rNewText ); + } +} + +void SwHHCWrapper::ReplaceUnit( + const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd, + const OUString& rOrigText, + const OUString& rReplaceWith, + const uno::Sequence< sal_Int32 > &rOffsets, + ReplacementAction eAction, + LanguageType *pNewUnitLanguage ) +{ + OSL_ENSURE( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" ); + if (!(nUnitStart >= 0 && nUnitEnd >= nUnitStart)) + return; + + lcl_ActivateTextShell( m_rWrtShell ); + + // replace the current word + m_rWrtShell.StartAllAction(); + + // select current unit + SelectNewUnit_impl( nUnitStart, nUnitEnd ); + + OUString aOrigTxt( m_rWrtShell.GetSelTxt() ); + OUString aNewTxt( rReplaceWith ); + OSL_ENSURE( aOrigTxt == rOrigText, "!! text mismatch !!" ); + SwFmtRuby *pRuby = 0; + bool bRubyBelow = false; + OUString aNewOrigText; + switch (eAction) + { + case eExchange : + break; + case eReplacementBracketed : + { + aNewTxt = aOrigTxt + "(" + rReplaceWith + ")"; + } + break; + case eOriginalBracketed : + { + aNewTxt = rReplaceWith + "(" + aOrigTxt + ")"; + } + break; + case eReplacementAbove : + { + pRuby = new SwFmtRuby( rReplaceWith ); + } + break; + case eOriginalAbove : + { + pRuby = new SwFmtRuby( aOrigTxt ); + aNewOrigText = rReplaceWith; + } + break; + case eReplacementBelow : + { + pRuby = new SwFmtRuby( rReplaceWith ); + bRubyBelow = true; + } + break; + case eOriginalBelow : + { + pRuby = new SwFmtRuby( aOrigTxt ); + aNewOrigText = rReplaceWith; + bRubyBelow = true; + } + break; + default: + OSL_FAIL("unexpected case" ); + } + m_nUnitOffset += nUnitStart + aNewTxt.getLength(); + + if (pRuby) + { + m_rWrtShell.StartUndo( UNDO_SETRUBYATTR ); + if (!aNewOrigText.isEmpty()) + { + // according to FT we currently should not bother about keeping + // attributes in Hangul/Hanja conversion + ChangeText( aNewOrigText, rOrigText, NULL, NULL ); + + //!! since Delete, Insert in 'ChangeText' do not set the WrtShells + //!! bInSelect flag + //!! back to false we do it now manually in order for the selection + //!! to be done properly in the following call to Left. + // We didn't fix it in Delete and Insert since it is currently + // unclear if someone depends on this incorrect behvaiour + // of the flag. + m_rWrtShell.EndSelect(); + + m_rWrtShell.Left( 0, sal_True, aNewOrigText.getLength(), sal_True, sal_True ); + } + + pRuby->SetPosition( static_cast(bRubyBelow) ); + pRuby->SetAdjustment( RubyAdjust_CENTER ); + +#if OSL_DEBUG_LEVEL > 1 + SwPaM *pPaM = m_rWrtShell.GetCrsr(); + (void)pPaM; +#endif + m_rWrtShell.SetAttrItem(*pRuby); + delete pRuby; + m_rWrtShell.EndUndo( UNDO_SETRUBYATTR ); + } + else + { + m_rWrtShell.StartUndo( UNDO_OVERWRITE ); + + // according to FT we should currently not bother about keeping + // attributes in Hangul/Hanja conversion and leave that untouched. + // Thus we do this only for Chinese translation... + const bool bIsChineseConversion = IsChinese( GetSourceLanguage() ); + if (bIsChineseConversion) + ChangeText( aNewTxt, rOrigText, &rOffsets, m_rWrtShell.GetCrsr() ); + else + ChangeText( aNewTxt, rOrigText, NULL, NULL ); + + // change language and font if necessary + if (bIsChineseConversion) + { + m_rWrtShell.SetMark(); + m_rWrtShell.GetCrsr()->GetMark()->nContent -= aNewTxt.getLength(); + + OSL_ENSURE( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL, + "SwHHCWrapper::ReplaceUnit : unexpected target language" ); + + sal_uInt16 aRanges[] = { + RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, + RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT, + 0, 0, 0 }; + + SfxItemSet aSet( m_rWrtShell.GetAttrPool(), aRanges ); + if (pNewUnitLanguage) + { + aSet.Put( SvxLanguageItem( *pNewUnitLanguage, RES_CHRATR_CJK_LANGUAGE ) ); + } + + const Font *pTargetFont = GetTargetFont(); + OSL_ENSURE( pTargetFont, "target font missing?" ); + if (pTargetFont && pNewUnitLanguage) + { + SvxFontItem aFontItem = (SvxFontItem&) aSet.Get( RES_CHRATR_CJK_FONT ); + aFontItem.SetFamilyName( pTargetFont->GetName()); + aFontItem.SetFamily( pTargetFont->GetFamily()); + aFontItem.SetStyleName( pTargetFont->GetStyleName()); + aFontItem.SetPitch( pTargetFont->GetPitch()); + aFontItem.SetCharSet( pTargetFont->GetCharSet() ); + aSet.Put( aFontItem ); + } + + m_rWrtShell.SetAttrSet( aSet ); + + m_rWrtShell.ClearMark(); + } + + m_rWrtShell.EndUndo( UNDO_OVERWRITE ); + } + + m_rWrtShell.EndAllAction(); +} + +bool SwHHCWrapper::HasRubySupport() const +{ + return true; +} + +void SwHHCWrapper::Convert() +{ + OSL_ENSURE( m_pConvArgs == 0, "NULL pointer expected" ); + { + SwPaM *pCrsr = m_pView->GetWrtShell().GetCrsr(); + SwPosition* pSttPos = pCrsr->Start(); + SwPosition* pEndPos = pCrsr->End(); + + if (pSttPos->nNode.GetNode().IsTxtNode() && + pEndPos->nNode.GetNode().IsTxtNode()) + { + m_pConvArgs = new SwConversionArgs( GetSourceLanguage(), + pSttPos->nNode.GetNode().GetTxtNode(), pSttPos->nContent, + pEndPos->nNode.GetNode().GetTxtNode(), pEndPos->nContent ); + } + else // we are not in the text (maybe a graphic or OLE object is selected) let's start from the top + { + // get PaM that points to the start of the document + SwNode& rNode = m_pView->GetDocShell()->GetDoc()->GetNodes().GetEndOfContent(); + SwPaM aPam(rNode); + aPam.Move( fnMoveBackward, fnGoDoc ); // move to start of document + + pSttPos = aPam.GetPoint(); //! using a PaM here makes sure we will get only text nodes + SwTxtNode *pTxtNode = pSttPos->nNode.GetNode().GetTxtNode(); + // just in case we check anyway... + if (!pTxtNode || !pTxtNode->IsTxtNode()) + return; + m_pConvArgs = new SwConversionArgs( GetSourceLanguage(), + pTxtNode, pSttPos->nContent, + pTxtNode, pSttPos->nContent ); + } + OSL_ENSURE( m_pConvArgs->pStartNode && m_pConvArgs->pStartNode->IsTxtNode(), + "failed to get proper start text node" ); + OSL_ENSURE( m_pConvArgs->pEndNode && m_pConvArgs->pEndNode->IsTxtNode(), + "failed to get proper end text node" ); + + // chinese conversion specific settings + OSL_ENSURE( IsChinese( GetSourceLanguage() ) == IsChinese( GetTargetLanguage() ), + "source and target language mismatch?" ); + if (IsChinese( GetTargetLanguage() )) + { + m_pConvArgs->nConvTargetLang = GetTargetLanguage(); + m_pConvArgs->pTargetFont = GetTargetFont(); + m_pConvArgs->bAllowImplicitChangesForNotConvertibleText = true; + } + + // if it is not just a selection and we are about to begin + // with the current conversion for the very first time + // we need to find the start of the current (initial) + // convertible unit in order for the text conversion to give + // the correct result for that. Since it is easier to obtain + // the start of the word we use that though. + if (!pCrsr->HasMark()) // is not a selection? + { + // since #118246 / #117803 still occurs if the cursor is placed + // between the two chinese characters to be converted (because both + // of them are words on their own!) using the word boundary here does + // not work. Thus since chinese conversion is not interactive we start + // at the begin of the paragraph to solve the problem, i.e. have the + // TextConversion service get those characters together in the same call. + sal_Int32 nStartIdx = -1; + if (editeng::HangulHanjaConversion::IsChinese( GetSourceLanguage() ) ) + nStartIdx = 0; + else + { + OUString aText( m_pConvArgs->pStartNode->GetTxt() ); + const sal_Int32 nPos = m_pConvArgs->pStartIdx->GetIndex(); + Boundary aBoundary( g_pBreakIt->GetBreakIter()-> + getWordBoundary( aText, nPos, g_pBreakIt->GetLocale( m_pConvArgs->nConvSrcLang ), + WordType::DICTIONARY_WORD, sal_True ) ); + + // valid result found? + if (aBoundary.startPos < aText.getLength() && + aBoundary.startPos != aBoundary.endPos) + { + nStartIdx = aBoundary.startPos; + } + } + + if (nStartIdx != -1) + *m_pConvArgs->pStartIdx = nStartIdx; + } + } + + if ( m_bIsOtherCntnt ) + ConvStart_impl( m_pConvArgs, SVX_SPELL_OTHER ); + else + { + m_bStartChk = false; + ConvStart_impl( m_pConvArgs, SVX_SPELL_BODY_END ); + } + + ConvertDocument(); + + ConvEnd_impl( m_pConvArgs ); +} + +bool SwHHCWrapper::ConvNext_impl( ) +{ + //! modified version of SvxSpellWrapper::SpellNext + + // no change of direction so the desired region is fully processed + if( m_bStartChk ) + m_bStartDone = true; + else + m_bEndDone = true; + + if( m_bIsOtherCntnt && m_bStartDone && m_bEndDone ) // document completely checked? + { + return false; + } + + bool bGoOn = false; + + if ( m_bIsOtherCntnt ) + { + m_bStartChk = false; + ConvStart_impl( m_pConvArgs, SVX_SPELL_BODY ); + bGoOn = true; + } + else if ( m_bStartDone && m_bEndDone ) + { + // body region done, ask about special region + if( HasOtherCnt_impl() ) + { + ConvStart_impl( m_pConvArgs, SVX_SPELL_OTHER ); + m_bIsOtherCntnt = bGoOn = true; + } + } + else + { + m_bStartChk = !m_bStartDone; + ConvStart_impl( m_pConvArgs, m_bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END ); + bGoOn = true; + } + return bGoOn; +} + +bool SwHHCWrapper::FindConvText_impl() +{ + //! modified version of SvxSpellWrapper::FindSpellError + + bool bFound = false; + + m_pWin->EnterWait(); + bool bConv = true; + + while ( bConv ) + { + bFound = ConvContinue_impl( m_pConvArgs ); + if (bFound) + { + bConv = false; + } + else + { + ConvEnd_impl( m_pConvArgs ); + bConv = ConvNext_impl(); + } + } + m_pWin->LeaveWait(); + return bFound; +} + +bool SwHHCWrapper::HasOtherCnt_impl() +{ + return m_bIsSelection ? false : m_rWrtShell.HasOtherCnt(); +} + +void SwHHCWrapper::ConvStart_impl( SwConversionArgs /* [out] */ *pConversionArgs, SvxSpellArea eArea ) +{ + SetDrawObj( SVX_SPELL_OTHER == eArea ); + m_pView->SpellStart( eArea, m_bStartDone, m_bEndDone, /* [out] */ pConversionArgs ); +} + +void SwHHCWrapper::ConvEnd_impl( SwConversionArgs *pConversionArgs ) +{ + m_pView->SpellEnd( pConversionArgs ); +} + +bool SwHHCWrapper::ConvContinue_impl( SwConversionArgs *pConversionArgs ) +{ + bool bProgress = !m_bIsDrawObj && !m_bIsSelection; + pConversionArgs->aConvText = OUString(); + pConversionArgs->nConvTextLang = LANGUAGE_NONE; + m_pView->GetWrtShell().SpellContinue( &m_nPageCount, bProgress ? &m_nPageStart : NULL, pConversionArgs ); + return !pConversionArgs->aConvText.isEmpty(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/uibase/lingu/hyp.cxx b/sw/source/core/uibase/lingu/hyp.cxx new file mode 100644 index 000000000000..73de46c7aeb8 --- /dev/null +++ b/sw/source/core/uibase/lingu/hyp.cxx @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "initui.hxx" +#include "view.hxx" +#include "edtwin.hxx" +#include "wrtsh.hxx" +#include "globals.hrc" +#include +#include +#include +#include +#include +#include + +#include "hyp.hxx" +#include "mdiexp.hxx" +#include "olmenu.hrc" + +#include + +#include + +#define PSH (&pView->GetWrtShell()) + +using namespace ::com::sun::star; + +/*-------------------------------------------------------------------- + Description: interactive separation + --------------------------------------------------------------------*/ + +SwHyphWrapper::SwHyphWrapper( SwView* pVw, + uno::Reference< linguistic2::XHyphenator > &rxHyph, + sal_Bool bStart, sal_Bool bOther, sal_Bool bSelect ) : + SvxSpellWrapper( &pVw->GetEditWin(), rxHyph, bStart, bOther ), + pView( pVw ), + xHyph( rxHyph ), + nPageCount( 0 ), + nPageStart( 0 ), + bInSelection( bSelect ), + bInfoBox( sal_False ) +{ + uno::Reference< linguistic2::XLinguProperties > xProp( GetLinguPropertySet() ); + bAutomatic = xProp.is() ? xProp->getIsHyphAuto() : sal_False; + SetHyphen(); +} + +void SwHyphWrapper::SpellStart( SvxSpellArea eSpell ) +{ + if( SVX_SPELL_OTHER == eSpell && nPageCount ) + { + ::EndProgress( pView->GetDocShell() ); + nPageCount = 0; + nPageStart = 0; + } + pView->HyphStart( eSpell ); +} + +bool SwHyphWrapper::SpellContinue() +{ + // for automatic separation, make actions visible only at the end + boost::scoped_ptr pWait; + if( bAutomatic ) + { + PSH->StartAllAction(); + pWait.reset(new SwWait( *pView->GetDocShell(), true )); + } + + uno::Reference< uno::XInterface > xHyphWord = bInSelection ? + PSH->HyphContinue( NULL, NULL ) : + PSH->HyphContinue( &nPageCount, &nPageStart ); + SetLast( xHyphWord ); + + // for automatic separation, make actions visible only at the end + if( bAutomatic ) + { + PSH->EndAllAction(); + pWait.reset(); + } + + return GetLast().is(); +} + +void SwHyphWrapper::SpellEnd() +{ + PSH->HyphEnd(); + SvxSpellWrapper::SpellEnd(); +} + +bool SwHyphWrapper::SpellMore() +{ + PSH->Push(); + bInfoBox = sal_True; + PSH->Combine(); + return false; +} + +void SwHyphWrapper::InsertHyphen( const sal_uInt16 nPos ) +{ + if( nPos) + PSH->InsertSoftHyph( nPos + 1); // does nPos == 1 really mean + // insert hyphen after first char? + // (instead of nPos == 0) + else + PSH->HyphIgnore(); +} + +SwHyphWrapper::~SwHyphWrapper() +{ + if( nPageCount ) + ::EndProgress( pView->GetDocShell() ); + if( bInfoBox ) + InfoBox( &pView->GetEditWin(), SW_RESSTR(STR_HYP_OK) ).Execute(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/uibase/lingu/olmenu.cxx b/sw/source/core/uibase/lingu/olmenu.cxx new file mode 100644 index 000000000000..f5909da430d1 --- /dev/null +++ b/sw/source/core/uibase/lingu/olmenu.cxx @@ -0,0 +1,891 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "SwRewriter.hxx" +#include "chrdlg.hrc" +#include "cmdid.h" +#include "comcore.hrc" +#include "crsskip.hxx" +#include "doc.hxx" +#include "docsh.hxx" +#include "edtwin.hxx" +#include "helpid.h" +#include "hintids.hxx" +#include "langhelper.hxx" +#include "ndtxt.hxx" +#include "olmenu.hrc" +#include "olmenu.hxx" +#include "swabstdlg.hxx" +#include "swmodule.hxx" +#include "swtypes.hxx" +#include "swundo.hxx" +#include "uitool.hxx" +#include "unomid.h" +#include "view.hxx" +#include "viewopt.hxx" +#include "wrtsh.hxx" +#include "wview.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; + +extern void sw_CharDialog( SwWrtShell &rWrtSh, bool bUseDialog, sal_uInt16 nSlot,const SfxItemSet *pArgs, SfxRequest *pReq ); + +/// @returns : the language for the selected text that is set for the +/// specified attribute (script type). +/// If there are more than one languages used LANGUAGE_DONTKNOW will be returned. +/// @param nLangWhichId : one of +/// RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE, +/// @returns: the language in use for the selected text. +/// 'In use' means the language(s) matching the script type(s) of the +/// selected text. Or in other words, the language a spell checker would use. +/// If there is more than one language LANGUAGE_DONTKNOW will be returned. +// check if nScriptType includes the script type associated to nLang +static inline bool lcl_checkScriptType( sal_Int16 nScriptType, LanguageType nLang ) +{ + return 0 != (nScriptType & SvtLanguageOptions::GetScriptTypeOfLanguage( nLang )); +} + +void SwSpellPopup::fillLangPopupMenu( + PopupMenu *pPopupMenu, + sal_uInt16 nLangItemIdStart, + uno::Sequence< OUString > aSeq, + SwWrtShell* pWrtSh, + std::map< sal_Int16, OUString > &rLangTable ) +{ + if (!pPopupMenu) + return; + + SvtLanguageTable aLanguageTable; + + // set of languages to be displayed in the sub menus + std::set< OUString > aLangItems; + + OUString aCurLang( aSeq[0] ); + sal_uInt16 nScriptType = static_cast< sal_Int16 >(aSeq[1].toInt32()); + OUString aKeyboardLang( aSeq[2] ); + OUString aGuessedTextLang( aSeq[3] ); + + if (!aCurLang.isEmpty() && + LANGUAGE_DONTKNOW != aLanguageTable.GetType( aCurLang )) + aLangItems.insert( aCurLang ); + + //2--System + const AllSettings& rAllSettings = Application::GetSettings(); + LanguageType rSystemLanguage = rAllSettings.GetLanguageTag().getLanguageType(); + if (rSystemLanguage != LANGUAGE_DONTKNOW) + { + if (lcl_checkScriptType( nScriptType, rSystemLanguage )) + aLangItems.insert( aLanguageTable.GetString(rSystemLanguage) ); + } + + //3--UI + LanguageType rUILanguage = rAllSettings.GetUILanguageTag().getLanguageType(); + if (rUILanguage != LANGUAGE_DONTKNOW) + { + if (lcl_checkScriptType(nScriptType, rUILanguage )) + aLangItems.insert( aLanguageTable.GetString(rUILanguage) ); + } + + //4--guessed language + if (!aGuessedTextLang.isEmpty()) + { + if (lcl_checkScriptType(nScriptType, aLanguageTable.GetType(aGuessedTextLang))) + aLangItems.insert( aGuessedTextLang ); + } + + //5--keyboard language + if (!aKeyboardLang.isEmpty()) + { + if (lcl_checkScriptType(nScriptType, aLanguageTable.GetType(aKeyboardLang))) + aLangItems.insert( aKeyboardLang ); + } + + //6--all languages used in current document + uno::Reference< com::sun::star::frame::XModel > xModel; + uno::Reference< com::sun::star::frame::XController > xController( pWrtSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface()->getController(), uno::UNO_QUERY ); + if ( xController.is() ) + xModel = xController->getModel(); + uno::Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, uno::UNO_QUERY ); + /*the description of nScriptType flags + LATIN : 0x0001 + ASIAN : 0x0002 + COMPLEX: 0x0004 + */ + const sal_Int16 nMaxCount = 7; + if (xDocumentLanguages.is()) + { + uno::Sequence< lang::Locale > rLocales( xDocumentLanguages->getDocumentLanguages( nScriptType, nMaxCount ) ); + if (rLocales.getLength() > 0) + { + for (sal_uInt16 i = 0; i < rLocales.getLength(); ++i) + { + if (aLangItems.size() == (size_t)nMaxCount) + break; + const lang::Locale& rLocale = rLocales[i]; + if (lcl_checkScriptType( nScriptType, aLanguageTable.GetType( rLocale.Language ))) + aLangItems.insert( rLocale.Language ); + } + } + } + + sal_uInt16 nItemId = nLangItemIdStart; + std::set< OUString >::const_iterator it; + for (it = aLangItems.begin(); it != aLangItems.end(); ++it) + { + OUString aEntryTxt( *it ); + if (aEntryTxt != OUString( aLanguageTable.GetString( LANGUAGE_NONE ) )&& + aEntryTxt != "*" && // multiple languages in current selection + !aEntryTxt.isEmpty()) // 'no language found' from language guessing + { + OSL_ENSURE( nLangItemIdStart <= nItemId && nItemId <= nLangItemIdStart + MN_MAX_NUM_LANG, + "nItemId outside of expected range!" ); + pPopupMenu->InsertItem( nItemId, aEntryTxt, MIB_RADIOCHECK ); + if (aEntryTxt == aCurLang) + { + //make a check mark for the current language + pPopupMenu->CheckItem( nItemId, true ); + } + rLangTable[ nItemId ] = aEntryTxt; + ++nItemId; + } + } + + pPopupMenu->InsertItem( nLangItemIdStart + MN_NONE_OFFSET, OUString(SW_RES( STR_LANGSTATUS_NONE )), MIB_RADIOCHECK ); + if ( aLanguageTable.GetString( LANGUAGE_NONE ) == aCurLang ) + pPopupMenu->CheckItem( nLangItemIdStart + MN_NONE_OFFSET, true ); + + pPopupMenu->InsertItem( nLangItemIdStart + MN_RESET_OFFSET, OUString(SW_RES( STR_RESET_TO_DEFAULT_LANGUAGE )), 0 ); + pPopupMenu->InsertItem( nLangItemIdStart + MN_MORE_OFFSET, OUString(SW_RES( STR_LANGSTATUS_MORE )), 0 ); +} + +OUString RetrieveLabelFromCommand( const OUString& aCmdURL ) +{ + OUString aLabel; + if ( !aCmdURL.isEmpty() ) + { + try + { + uno::Reference< container::XNameAccess > const xNameAccess( + frame::theUICommandDescription::get( + ::comphelper::getProcessComponentContext() ), + uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xUICommandLabels; + uno::Any a = xNameAccess->getByName( "com.sun.star.text.TextDocument" ); + uno::Reference< container::XNameAccess > xUICommands; + a >>= xUICommandLabels; + OUString aStr; + uno::Sequence< beans::PropertyValue > aPropSeq; + a = xUICommandLabels->getByName( aCmdURL ); + if ( a >>= aPropSeq ) + { + for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) + { + if ( aPropSeq[i].Name == "Name" ) + { + aPropSeq[i].Value >>= aStr; + break; + } + } + } + aLabel = aStr; + } + catch (const uno::Exception&) + { + } + } + + return aLabel; +} + +SwSpellPopup::SwSpellPopup( + SwWrtShell* pWrtSh, + const uno::Reference< linguistic2::XSpellAlternatives > &xAlt, + const OUString &rParaText +) : PopupMenu( SW_RES(MN_SPELL_POPUP) ) + , m_pSh( pWrtSh ) + , m_xSpellAlt(xAlt) + , m_bGrammarResults(false) +{ + OSL_ENSURE(m_xSpellAlt.is(), "no spelling alternatives available"); + + SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS); + bool bUseImagesInMenus = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus(); + + m_nCheckedLanguage = LANGUAGE_NONE; + if (m_xSpellAlt.is()) + { + m_nCheckedLanguage = LanguageTag( m_xSpellAlt->getLocale() ).getLanguageType(); + m_aSuggestions = m_xSpellAlt->getAlternatives(); + } + sal_Int16 nStringCount = static_cast< sal_Int16 >( m_aSuggestions.getLength() ); + + SvtLinguConfig aCfg; + + PopupMenu *pMenu = GetPopupMenu(MN_AUTOCORR); + pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS); + sal_Bool bEnable = sal_False; + if( nStringCount ) + { + Image aImage; + OUString aSuggestionImageUrl; + + if (bUseImagesInMenus) + { + uno::Reference< container::XNamed > xNamed( m_xSpellAlt, uno::UNO_QUERY ); + if (xNamed.is()) + { + aSuggestionImageUrl = aCfg.GetSpellAndGrammarContextSuggestionImage( xNamed->getName() ); + aImage = Image( aSuggestionImageUrl ); + } + } + + InsertSeparator(OString(), 0); + bEnable = sal_True; + sal_uInt16 nAutoCorrItemId = MN_AUTOCORR_START; + sal_uInt16 nItemId = MN_SUGGESTION_START; + for (sal_uInt16 i = 0; i < nStringCount; ++i) + { + const OUString aEntry = m_aSuggestions[ i ]; + InsertItem(nItemId, aEntry, 0, OString(), i); + SetHelpId( nItemId, HID_LINGU_REPLACE); + if (!aSuggestionImageUrl.isEmpty()) + SetItemImage( nItemId, aImage ); + + pMenu->InsertItem( nAutoCorrItemId, aEntry ); + pMenu->SetHelpId( nAutoCorrItemId, HID_LINGU_AUTOCORR); + + ++nAutoCorrItemId; + ++nItemId; + } + } + + OUString aIgnoreSelection( SW_RES( STR_IGNORE_SELECTION ) ); + OUString aSpellingAndGrammar = RetrieveLabelFromCommand( ".uno:SpellingAndGrammarDialog" ); + SetItemText( MN_SPELLING_DLG, aSpellingAndGrammar ); + sal_uInt16 nItemPos = GetItemPos( MN_IGNORE_WORD ); + InsertItem(MN_IGNORE_SELECTION, aIgnoreSelection, 0, OString(), nItemPos); + SetHelpId( MN_IGNORE_SELECTION, HID_LINGU_IGNORE_SELECTION); + + EnableItem( MN_AUTOCORR, bEnable ); + + uno::Reference< linguistic2::XLanguageGuessing > xLG = SW_MOD()->GetLanguageGuesser(); + m_nGuessLangWord = LANGUAGE_NONE; + m_nGuessLangPara = LANGUAGE_NONE; + if (m_xSpellAlt.is() && xLG.is()) + { + m_nGuessLangWord = EditView::CheckLanguage( m_xSpellAlt->getWord(), ::GetSpellChecker(), xLG, false ); + m_nGuessLangPara = EditView::CheckLanguage( rParaText, ::GetSpellChecker(), xLG, true ); + } + if (m_nGuessLangWord != LANGUAGE_NONE || m_nGuessLangPara != LANGUAGE_NONE) + { + // make sure LANGUAGE_NONE gets not used as menu entry + if (m_nGuessLangWord == LANGUAGE_NONE) + m_nGuessLangWord = m_nGuessLangPara; + if (m_nGuessLangPara == LANGUAGE_NONE) + m_nGuessLangPara = m_nGuessLangWord; + } + + pMenu = GetPopupMenu(MN_ADD_TO_DIC); + pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS); //! necessary to retrieve the correct dictionary name in 'Execute' below + uno::Reference< linguistic2::XSearchableDictionaryList > xDicList( SvxGetDictionaryList() ); + sal_uInt16 nItemId = MN_DICTIONARIES_START; + if (xDicList.is()) + { + // add the default positive dictionary to dic-list (if not already done). + // This is to ensure that there is at least one dictionary to which + // words could be added. + uno::Reference< linguistic2::XDictionary > xDic( SvxGetOrCreatePosDic( xDicList ) ); + if (xDic.is()) + xDic->setActive( sal_True ); + + m_aDics = xDicList->getDictionaries(); + const uno::Reference< linguistic2::XDictionary > *pDic = m_aDics.getConstArray(); + sal_uInt16 nDicCount = static_cast< sal_uInt16 >(m_aDics.getLength()); + + for( sal_uInt16 i = 0; i < nDicCount; i++ ) + { + uno::Reference< linguistic2::XDictionary > xDicTmp( pDic[i], uno::UNO_QUERY ); + if (!xDicTmp.is() || SvxGetIgnoreAllList() == xDicTmp) + continue; + + uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY ); + LanguageType nActLanguage = LanguageTag( xDicTmp->getLocale() ).getLanguageType(); + if( xDicTmp->isActive() + && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE + && (m_nCheckedLanguage == nActLanguage || LANGUAGE_NONE == nActLanguage ) + && (!xStor.is() || !xStor->isReadonly()) ) + { + // the extra 1 is because of the (possible) external + // linguistic entry above + pMenu->InsertItem( nItemId, xDicTmp->getName() ); + m_aDicNameSingle = xDicTmp->getName(); + + if (bUseImagesInMenus) + { + uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY ); + if (xSvcInfo.is()) + { + OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage( + xSvcInfo->getImplementationName() ) ); + if (!aDictionaryImageUrl.isEmpty()) + { + Image aImage( aDictionaryImageUrl ); + pMenu->SetItemImage( nItemId, aImage ); + } + } + } + + ++nItemId; + } + } + } + EnableItem( MN_ADD_TO_DIC, ((nItemId - MN_DICTIONARIES_START) > 1)?sal_True:sal_False ); + EnableItem( MN_ADD_TO_DIC_SINGLE, ((nItemId - MN_DICTIONARIES_START) == 1)?sal_True:sal_False ); + + //ADD NEW LANGUAGE MENU ITEM + + OUString aScriptTypesInUse( OUString::number( pWrtSh->GetScriptType() ) ); + SvtLanguageTable aLanguageTable; + + // get keyboard language + OUString aKeyboardLang; + SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin(); + LanguageType nLang = rEditWin.GetInputLanguage(); + if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM) + aKeyboardLang = aLanguageTable.GetString( nLang ); + + // get the language that is in use + OUString aCurrentLang("*"); + nLang = SwLangHelper::GetCurrentLanguage( *pWrtSh ); + if (nLang != LANGUAGE_DONTKNOW) + aCurrentLang = aLanguageTable.GetString( nLang ); + + // build sequence for status value + uno::Sequence< OUString > aSeq( 4 ); + aSeq[0] = aCurrentLang; + aSeq[1] = aScriptTypesInUse; + aSeq[2] = aKeyboardLang; + aSeq[3] = aLanguageTable.GetString(m_nGuessLangWord); + + pMenu = GetPopupMenu(MN_SET_LANGUAGE_SELECTION); + fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_SELECTION_START, aSeq, pWrtSh, m_aLangTable_Text ); + EnableItem( MN_SET_LANGUAGE_SELECTION, true ); + + pMenu = GetPopupMenu(MN_SET_LANGUAGE_PARAGRAPH); + fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_PARAGRAPH_START, aSeq, pWrtSh, m_aLangTable_Paragraph ); + EnableItem( MN_SET_LANGUAGE_PARAGRAPH, true ); + + if (bUseImagesInMenus) + { + uno::Reference< frame::XFrame > xFrame = pWrtSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface(); + Image rImg = ::GetImage( xFrame, ".uno:SpellingAndGrammarDialog", false ); + SetItemImage( MN_SPELLING_DLG, rImg ); + } + + checkRedline(); + RemoveDisabledEntries( true, true ); +} + +SwSpellPopup::SwSpellPopup( + SwWrtShell *pWrtSh, + const linguistic2::ProofreadingResult &rResult, + sal_Int32 nErrorInResult, + const uno::Sequence< OUString > &rSuggestions, + const OUString &rParaText ) : +PopupMenu( SW_RES(MN_SPELL_POPUP) ), +m_pSh( pWrtSh ), +m_xGrammarResult( rResult ), +m_aSuggestions( rSuggestions ), +m_sExplanationLink( ), +m_bGrammarResults( true ), +m_aInfo16( SW_RES(IMG_INFO_16) ) +{ + m_nCheckedLanguage = LanguageTag::convertToLanguageType( rResult.aLocale ); + m_nGrammarError = nErrorInResult; + bool bUseImagesInMenus = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus(); + + sal_uInt16 nPos = 0; + OUString aMessageText( rResult.aErrors[ nErrorInResult ].aShortComment ); + InsertSeparator(OString(), nPos++); + InsertItem(MN_SHORT_COMMENT, aMessageText, MIB_NOSELECT, OString(), nPos++); + if (bUseImagesInMenus) + SetItemImage( MN_SHORT_COMMENT, m_aInfo16 ); + + // Add an item to show detailled infos if the FullCommentURL property is defined + beans::PropertyValues aProperties = rResult.aErrors[ nErrorInResult ].aProperties; + { + sal_Int32 i = 0; + while ( m_sExplanationLink.isEmpty() && i < aProperties.getLength() ) + { + if ( aProperties[i].Name == "FullCommentURL" ) + { + uno::Any aValue = aProperties[i].Value; + aValue >>= m_sExplanationLink; + } + ++i; + } + } + + if ( !m_sExplanationLink.isEmpty( ) ) + { + InsertItem(MN_EXPLANATION_LINK, SW_RESSTR(STR_EXPLANATION_LINK), MIB_TEXT | MIB_HELP, OString(), nPos++); + } + + SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS); + + InsertSeparator(OString(), nPos++); + sal_Int32 nStringCount = m_aSuggestions.getLength(); + if ( nStringCount ) // suggestions available... + { + Image aImage; + OUString aSuggestionImageUrl; + + if (bUseImagesInMenus) + { + uno::Reference< lang::XServiceInfo > xInfo( rResult.xProofreader, uno::UNO_QUERY ); + if (xInfo.is()) + { + aSuggestionImageUrl = SvtLinguConfig().GetSpellAndGrammarContextSuggestionImage( xInfo->getImplementationName() ); + aImage = Image( aSuggestionImageUrl ); + } + } + + sal_uInt16 nItemId = MN_SUGGESTION_START; + for (sal_uInt16 i = 0; i < nStringCount; ++i) + { + const OUString aEntry = m_aSuggestions[ i ]; + InsertItem(nItemId, aEntry, 0, OString(), nPos++); + SetHelpId( nItemId, HID_LINGU_REPLACE ); + if (!aSuggestionImageUrl.isEmpty()) + SetItemImage( nItemId, aImage ); + + ++nItemId; + } + InsertSeparator(OString(), nPos++); + } + + OUString aIgnoreSelection( SW_RES( STR_IGNORE_SELECTION ) ); + OUString aSpellingAndGrammar = RetrieveLabelFromCommand( ".uno:SpellingAndGrammarDialog" ); + SetItemText( MN_SPELLING_DLG, aSpellingAndGrammar ); + sal_uInt16 nItemPos = GetItemPos( MN_IGNORE_WORD ); + InsertItem( MN_IGNORE_SELECTION, aIgnoreSelection, 0, OString(), nItemPos ); + SetHelpId( MN_IGNORE_SELECTION, HID_LINGU_IGNORE_SELECTION); + + EnableItem( MN_AUTOCORR, false ); + + uno::Reference< linguistic2::XLanguageGuessing > xLG = SW_MOD()->GetLanguageGuesser(); + m_nGuessLangWord = LANGUAGE_NONE; + m_nGuessLangPara = LANGUAGE_NONE; + if (xLG.is()) + { + m_nGuessLangPara = EditView::CheckLanguage( rParaText, ::GetSpellChecker(), xLG, true ); + } + if (m_nGuessLangWord != LANGUAGE_NONE || m_nGuessLangPara != LANGUAGE_NONE) + { + // make sure LANGUAGE_NONE gets not used as menu entry + if (m_nGuessLangWord == LANGUAGE_NONE) + m_nGuessLangWord = m_nGuessLangPara; + if (m_nGuessLangPara == LANGUAGE_NONE) + m_nGuessLangPara = m_nGuessLangWord; + } + + EnableItem( MN_ADD_TO_DIC, false ); + EnableItem( MN_ADD_TO_DIC_SINGLE, false ); + + //ADD NEW LANGUAGE MENU ITEM + + OUString aScriptTypesInUse( OUString::number( pWrtSh->GetScriptType() ) ); + SvtLanguageTable aLanguageTable; + + // get keyboard language + OUString aKeyboardLang; + SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin(); + LanguageType nLang = rEditWin.GetInputLanguage(); + if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM) + aKeyboardLang = aLanguageTable.GetString( nLang ); + + // get the language that is in use + OUString aCurrentLang("*"); + nLang = SwLangHelper::GetCurrentLanguage( *pWrtSh ); + if (nLang != LANGUAGE_DONTKNOW) + aCurrentLang = aLanguageTable.GetString( nLang ); + + // build sequence for status value + uno::Sequence< OUString > aSeq( 4 ); + aSeq[0] = aCurrentLang; + aSeq[1] = aScriptTypesInUse; + aSeq[2] = aKeyboardLang; + aSeq[3] = aLanguageTable.GetString(m_nGuessLangWord); + + PopupMenu *pMenu = GetPopupMenu(MN_SET_LANGUAGE_SELECTION); + fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_SELECTION_START, aSeq, pWrtSh, m_aLangTable_Text ); + EnableItem( MN_SET_LANGUAGE_SELECTION, true ); + + pMenu = GetPopupMenu(MN_SET_LANGUAGE_PARAGRAPH); + fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_PARAGRAPH_START, aSeq, pWrtSh, m_aLangTable_Paragraph ); + EnableItem( MN_SET_LANGUAGE_PARAGRAPH, true ); + + if (bUseImagesInMenus) + { + uno::Reference< frame::XFrame > xFrame = pWrtSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface(); + Image rImg = ::GetImage( xFrame, ".uno:SpellingAndGrammarDialog", false ); + SetItemImage( MN_SPELLING_DLG, rImg ); + } + + checkRedline(); + RemoveDisabledEntries( true, true ); +} + +void SwSpellPopup::checkRedline() +{ + // Let SwView::GetState() already has the logic on when to disable the + // accept/reject and the next/prev change items, let it do the decision. + + // Build an item set that contains a void item for each menu entry. The + // WhichId of each item is set, so SwView may clear it. + static const sal_uInt16 pRedlineIds[] = { + FN_REDLINE_ACCEPT_DIRECT, + FN_REDLINE_REJECT_DIRECT, + FN_REDLINE_NEXT_CHANGE, + FN_REDLINE_PREV_CHANGE + }; + SwDoc *pDoc = m_pSh->GetDoc(); + SfxItemSet aSet(pDoc->GetAttrPool(), FN_REDLINE_ACCEPT_DIRECT, FN_REDLINE_PREV_CHANGE); + for (size_t i = 0; i < SAL_N_ELEMENTS(pRedlineIds); ++i) + { + const sal_uInt16 nWhich = pRedlineIds[i]; + aSet.Put(SfxVoidItem(nWhich), nWhich); + } + m_pSh->GetView().GetState(aSet); + + // Enable/disable items based on if the which id of the void items are + // cleared or not. + for (size_t i = 0; i < SAL_N_ELEMENTS(pRedlineIds); ++i) + { + const sal_uInt16 nWhich = pRedlineIds[i]; + EnableItem(nWhich, aSet.Get(nWhich).Which()); + } +} + +sal_uInt16 SwSpellPopup::Execute( const Rectangle& rWordPos, Window* pWin ) +{ + sal_uInt16 nRet = PopupMenu::Execute(pWin, pWin->LogicToPixel(rWordPos)); + Execute( nRet ); + return nRet; +} + +void SwSpellPopup::Execute( sal_uInt16 nId ) +{ + if (nId == USHRT_MAX) + return; + + if (/*m_bGrammarResults && */nId == MN_SHORT_COMMENT) + return; // nothing to do since it is the error message (short comment) + + if ((MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) || + (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)) + { + sal_Int32 nAltIdx = (MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) ? + nId - MN_SUGGESTION_START : nId - MN_AUTOCORR_START; + OSL_ENSURE( 0 <= nAltIdx && nAltIdx < m_aSuggestions.getLength(), "index out of range" ); + if (0 <= nAltIdx && nAltIdx < m_aSuggestions.getLength() && (m_bGrammarResults || m_xSpellAlt.is())) + { + sal_Bool bOldIns = m_pSh->IsInsMode(); + m_pSh->SetInsMode( sal_True ); + + OUString aTmp( m_aSuggestions[ nAltIdx ] ); + OUString aOrig( m_bGrammarResults ? OUString() : m_xSpellAlt->getWord() ); + + // if original word has a trailing . (likely the end of a sentence) + // and the replacement text hasn't, then add it to the replacement + if (!aTmp.isEmpty() && !aOrig.isEmpty() && + aOrig.endsWith(".") && /* !IsAlphaNumeric ??*/ + !aTmp.endsWith(".")) + { + aTmp += "."; + } + + // #111827# + SwRewriter aRewriter; + + aRewriter.AddRule(UndoArg1, m_pSh->GetCrsrDescr()); + aRewriter.AddRule(UndoArg2, OUString(SW_RES(STR_YIELDS))); + + OUString aTmpStr( SW_RES(STR_START_QUOTE) ); + aTmpStr += aTmp; + aTmpStr += OUString(SW_RES(STR_END_QUOTE)); + aRewriter.AddRule(UndoArg3, aTmpStr); + + m_pSh->StartUndo(UNDO_UI_REPLACE, &aRewriter); + m_pSh->StartAction(); + m_pSh->DelLeft(); + + m_pSh->Insert( aTmp ); + + /* #102505# EndAction/EndUndo moved down since insertion + of temporary auto correction is now undoable two and + must reside in the same undo group.*/ + + // record only if it's NOT already present in autocorrection + SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect(); + + OUString aOrigWord( m_bGrammarResults ? OUString() : m_xSpellAlt->getWord() ) ; + OUString aNewWord( m_aSuggestions[ nAltIdx ] ); + SvxPrepareAutoCorrect( aOrigWord, aNewWord ); + + if (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END) + pACorr->PutText( aOrigWord, aNewWord, m_nCheckedLanguage ); + + /* #102505# EndAction/EndUndo moved down since insertion + of temporary auto correction is now undoable two and + must reside in the same undo group.*/ + m_pSh->EndAction(); + m_pSh->EndUndo(); + + m_pSh->SetInsMode( bOldIns ); + } + } + else if (nId == MN_SPELLING_DLG) + { + if (m_bGrammarResults) + { + SvtLinguConfig().SetProperty( UPN_IS_GRAMMAR_INTERACTIVE, uno::makeAny( sal_True )); + } + m_pSh->Left(CRSR_SKIP_CHARS, sal_False, 1, sal_False ); + { + uno::Reference xDictionaryList( SvxGetDictionaryList() ); + SvxDicListChgClamp aClamp( xDictionaryList ); + m_pSh->GetView().GetViewFrame()->GetDispatcher()-> + Execute( FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON ); + } + } + else if (nId == MN_IGNORE_SELECTION) + { + SwPaM *pPaM = m_pSh->GetCrsr(); + if (pPaM) + m_pSh->IgnoreGrammarErrorAt( *pPaM ); + } + else if (nId == MN_IGNORE_WORD) + { + uno::Reference< linguistic2::XDictionary > xDictionary( SvxGetIgnoreAllList(), uno::UNO_QUERY ); + if (m_bGrammarResults) { + try + { + m_xGrammarResult.xProofreader->ignoreRule( + m_xGrammarResult.aErrors[ m_nGrammarError ].aRuleIdentifier, + m_xGrammarResult.aLocale ); + // refresh the layout of the actual paragraph (faster) + SwPaM *pPaM = m_pSh->GetCrsr(); + if (pPaM) + m_pSh->IgnoreGrammarErrorAt( *pPaM ); + // refresh the layout of all paragraphs (workaround to launch a dictionary event) + xDictionary->setActive(sal_False); + xDictionary->setActive(sal_True); + } + catch( const uno::Exception& ) + { + } + } else { + linguistic::AddEntryToDic( xDictionary, + m_xSpellAlt->getWord(), sal_False, OUString(), LANGUAGE_NONE ); + } + } + else if ((MN_DICTIONARIES_START <= nId && nId <= MN_DICTIONARIES_END) || nId == MN_ADD_TO_DIC_SINGLE) + { + OUString aWord( m_xSpellAlt->getWord() ); + OUString aDicName; + + if (MN_DICTIONARIES_START <= nId && nId <= MN_DICTIONARIES_END) + { + PopupMenu *pMenu = GetPopupMenu(MN_ADD_TO_DIC); + aDicName = pMenu->GetItemText(nId); + } + else + aDicName = m_aDicNameSingle; + + uno::Reference< linguistic2::XDictionary > xDic; + uno::Reference< linguistic2::XSearchableDictionaryList > xDicList( SvxGetDictionaryList() ); + if (xDicList.is()) + xDic = xDicList->getDictionaryByName( aDicName ); + + if (xDic.is()) + { + sal_Int16 nAddRes = linguistic::AddEntryToDic( xDic, aWord, sal_False, OUString(), LANGUAGE_NONE ); + // save modified user-dictionary if it is persistent + uno::Reference< frame::XStorable > xSavDic( xDic, uno::UNO_QUERY ); + if (xSavDic.is()) + xSavDic->store(); + + if (DIC_ERR_NONE != nAddRes + && !xDic->getEntry( aWord ).is()) + { + SvxDicError( + &m_pSh->GetView().GetViewFrame()->GetWindow(), + nAddRes ); + } + } + } + else if ( nId == MN_EXPLANATION_LINK && !m_sExplanationLink.isEmpty() ) + { + try + { + uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute( + com::sun::star::system::SystemShellExecute::create( ::comphelper::getProcessComponentContext() ) ); + xSystemShellExecute->execute( m_sExplanationLink, OUString(), + com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY ); + } + catch (const uno::Exception&) + { + uno::Any exc( ::cppu::getCaughtException() ); + OUString msg( ::comphelper::anyToString( exc ) ); + const SolarMutexGuard guard; + MessageDialog aErrorBox(NULL, msg); + aErrorBox.SetText( "Explanations" ); + aErrorBox.Execute(); + } + } + else if (nId == FN_REDLINE_ACCEPT_DIRECT || nId == FN_REDLINE_REJECT_DIRECT + || nId == FN_REDLINE_NEXT_CHANGE || nId == FN_REDLINE_PREV_CHANGE) + { + // Let SwView::Execute() handle the redline actions. + SfxRequest aReq(m_pSh->GetView().GetViewFrame(), nId); + m_pSh->GetView().Execute(aReq); + } + else + { + // Set language for selection or for paragraph... + + SfxItemSet aCoreSet( m_pSh->GetView().GetPool(), + RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE, + RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, + RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE, + 0 ); + OUString aNewLangTxt; + + if (MN_SET_LANGUAGE_SELECTION_START <= nId && nId <= MN_SET_LANGUAGE_SELECTION_END) + { + //Set language for current selection + aNewLangTxt = m_aLangTable_Text[nId]; + SwLangHelper::SetLanguage( *m_pSh, aNewLangTxt, true, aCoreSet ); + } + else if (nId == MN_SET_SELECTION_NONE) + { + //Set Language_None for current selection + SwLangHelper::SetLanguage_None( *m_pSh, true, aCoreSet ); + } + else if (nId == MN_SET_SELECTION_RESET) + { + //reset languages for current selection + SwLangHelper::ResetLanguages( *m_pSh, true ); + } + else if (nId == MN_SET_SELECTION_MORE) + { + //Open Format/Character Dialog + sw_CharDialog( *m_pSh, true, nId, 0, 0 ); + } + else if (MN_SET_LANGUAGE_PARAGRAPH_START <= nId && nId <= MN_SET_LANGUAGE_PARAGRAPH_END) + { + //Set language for current paragraph + aNewLangTxt = m_aLangTable_Paragraph[nId]; + m_pSh->Push(); // save cursor + SwLangHelper::SelectCurrentPara( *m_pSh ); + SwLangHelper::SetLanguage( *m_pSh, aNewLangTxt, true, aCoreSet ); + m_pSh->Pop( sal_False ); // restore cursor + } + else if (nId == MN_SET_PARA_NONE) + { + //Set Language_None for current paragraph + m_pSh->Push(); // save cursor + SwLangHelper::SelectCurrentPara( *m_pSh ); + SwLangHelper::SetLanguage_None( *m_pSh, true, aCoreSet ); + m_pSh->Pop( sal_False ); // restore cursor + } + else if (nId == MN_SET_PARA_RESET) + { + //reset languages for current paragraph + m_pSh->Push(); // save cursor + SwLangHelper::SelectCurrentPara( *m_pSh ); + SwLangHelper::ResetLanguages( *m_pSh, true ); + m_pSh->Pop( sal_False ); // restore cursor + } + else if (nId == MN_SET_PARA_MORE) + { + m_pSh->Push(); // save cursor + SwLangHelper::SelectCurrentPara( *m_pSh ); + //Open Format/Character Dialog + sw_CharDialog( *m_pSh, true, nId, 0, 0 ); + m_pSh->Pop( sal_False ); // restore cursor + } + } + + m_pSh->EnterStdMode(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/uibase/lingu/olmenu.hrc b/sw/source/core/uibase/lingu/olmenu.hrc new file mode 100644 index 000000000000..0a8ae91cec6e --- /dev/null +++ b/sw/source/core/uibase/lingu/olmenu.hrc @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef _OLMENU_HRC +#define _OLMENU_HRC + +#include "rcid.hrc" + +#define MN_SPELL_POPUP (RC_LINGU_BEGIN + 1) +#define STR_SPELL_OK (RC_LINGU_BEGIN + 2) +#define STR_HYP_OK (RC_LINGU_BEGIN + 3) +#define STR_WORD (RC_LINGU_BEGIN + 4) +#define STR_PARAGRAPH (RC_LINGU_BEGIN + 5) +#define STR_LANGSTATUS_NONE (RC_LINGU_BEGIN + 6) +#define STR_LANGSTATUS_MORE (RC_LINGU_BEGIN + 7) +#define STR_IGNORE_SELECTION (RC_LINGU_BEGIN + 8) +#define STR_RESET_TO_DEFAULT_LANGUAGE (RC_LINGU_BEGIN + 9) +#define STR_EXPLANATION_LINK (RC_LINGU_BEGIN + 10) + +#define IMG_INFO_16 (RC_LINGU_BEGIN + 100) + +//! Don't change these values. You may break context menu modifying extensions! +#define MN_SPELLING_DLG 200 +#define MN_IGNORE_SELECTION 201 +#define MN_IGNORE_WORD 202 +#define MN_ADD_TO_DIC 203 +#define MN_AUTOCORR 204 +#define MN_SET_LANGUAGE_SELECTION 205 +#define MN_SET_LANGUAGE_PARAGRAPH 206 +#define MN_SET_LANGUAGE_ALL_TEXT 207 +#define MN_SHORT_COMMENT 208 +#define MN_EXPLANATION_LINK 209 +#define MN_ADD_TO_DIC_SINGLE 210 + +// id range for dictionaries sub menu +#define MN_DICTIONARIES_START 300 +#define MN_DICTIONARIES_END (MN_DICTIONARIES_START + 99) + +// id range for suggestions from spell and grammar checker +#define MN_SUGGESTION_START 500 +#define MN_SUGGESTION_END (MN_SUGGESTION_START + MN_MAX_NUM_LANG) + +// id range for auto correction sub menu entries +#define MN_AUTOCORR_START 700 +#define MN_AUTOCORR_END (MN_AUTOCORR_START + MN_MAX_NUM_LANG) + +// max number of language entries sub menus +#define MN_MAX_NUM_LANG 99 + +#define MN_NONE_OFFSET (MN_MAX_NUM_LANG + 1) +#define MN_RESET_OFFSET (MN_MAX_NUM_LANG + 2) +#define MN_MORE_OFFSET (MN_MAX_NUM_LANG + 3) + +// id range for 'set language for selection' sub menu entries +#define MN_SET_LANGUAGE_SELECTION_START 900 +#define MN_SET_LANGUAGE_SELECTION_END (MN_SET_LANGUAGE_SELECTION_START + MN_MAX_NUM_LANG) +#define MN_SET_SELECTION_NONE (MN_SET_LANGUAGE_SELECTION_START + MN_NONE_OFFSET) +#define MN_SET_SELECTION_RESET (MN_SET_LANGUAGE_SELECTION_START + MN_RESET_OFFSET) +#define MN_SET_SELECTION_MORE (MN_SET_LANGUAGE_SELECTION_START + MN_MORE_OFFSET) + +// id range for 'set language for paragraph' sub menu entries +#define MN_SET_LANGUAGE_PARAGRAPH_START 1100 +#define MN_SET_LANGUAGE_PARAGRAPH_END (MN_SET_LANGUAGE_PARAGRAPH_START + MN_MAX_NUM_LANG) +#define MN_SET_PARA_NONE (MN_SET_LANGUAGE_PARAGRAPH_START + MN_NONE_OFFSET) +#define MN_SET_PARA_RESET (MN_SET_LANGUAGE_PARAGRAPH_START + MN_RESET_OFFSET) +#define MN_SET_PARA_MORE (MN_SET_LANGUAGE_PARAGRAPH_START + MN_MORE_OFFSET) + +// id range for 'set language for all text' sub menu entries +#define MN_SET_LANGUAGE_ALL_TEXT_START 1300 + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/uibase/lingu/olmenu.src b/sw/source/core/uibase/lingu/olmenu.src new file mode 100644 index 000000000000..293d8043c7db --- /dev/null +++ b/sw/source/core/uibase/lingu/olmenu.src @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +/* StarView resource file */ + +#include "olmenu.hrc" +#include "helpid.h" +#include "redline.hrc" + +#define MASKCOLOR MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; }; +#define SEPARATOR MenuItem { Separator = TRUE; }; + +Menu MN_SPELL_POPUP +{ + ItemList = + { + MenuItem + { + Identifier = MN_IGNORE_WORD ; + HelpID = HID_LINGU_IGNORE_WORD ; + Text [ en-US ] = "Ignore All" ; + }; + MenuItem + { + Identifier = MN_ADD_TO_DIC ; + HelpID = HID_LINGU_ADD_WORD ; + SubMenu = Menu + { + }; + Text [ en-US ] = "~Add to Dictionary" ; + }; + MenuItem + { + Identifier = MN_ADD_TO_DIC_SINGLE ; + HelpID = HID_LINGU_ADD_WORD ; + Text [ en-US ] = "~Add to Dictionary" ; + }; + MenuItem + { + Identifier = MN_AUTOCORR ; + HelpID = HID_LINGU_AUTOCORR ; + SubMenu = Menu + { + }; + Text [ en-US ] = "Always correct to" ; + }; + MenuItem + { + Identifier = MN_SPELLING_DLG ; + HelpID = HID_LINGU_SPELLING_DLG ; + Text [ en-US ] = "~Spellcheck..." ; + }; + SEPARATOR + MenuItem + { + Identifier = MN_SET_LANGUAGE_SELECTION ; + SubMenu = Menu + { + }; + Text [ en-US ] = "Set Language for Selection" ; + }; + MenuItem + { + Identifier = MN_SET_LANGUAGE_PARAGRAPH ; + SubMenu = Menu + { + }; + Text [ en-US ] = "Set Language for Paragraph" ; + }; + SEPARATOR + MN_EDIT_REDLINE + }; +}; +String STR_WORD +{ + Text [ en-US ] = "Word is " ; +}; +String STR_PARAGRAPH +{ + Text [ en-US ] = "Paragraph is " ; +}; +String STR_SPELL_OK +{ + Text [ en-US ] = "The spellcheck is complete." ; +}; +String STR_HYP_OK +{ + Text [ en-US ] = "Hyphenation completed" ; +}; +String STR_LANGSTATUS_NONE +{ + Text [ en-US ] = "None (Do not check spelling)" ; +}; +String STR_RESET_TO_DEFAULT_LANGUAGE +{ + Text [ en-US ] = "Reset to Default Language" ; +}; +String STR_LANGSTATUS_MORE +{ + Text [ en-US ] = "More..." ; +}; +String STR_IGNORE_SELECTION +{ + Text [ en-US ] = "Ignore" ; +}; +String STR_EXPLANATION_LINK +{ + Text [ en-US ] = "Explanations..." ; +}; +Image IMG_INFO_16 +{ + ImageBitmap = Bitmap { File = "info_16.png" ; }; + MASKCOLOR +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/uibase/lingu/sdrhhcwrap.cxx b/sw/source/core/uibase/lingu/sdrhhcwrap.cxx new file mode 100644 index 000000000000..3a05a06b3328 --- /dev/null +++ b/sw/source/core/uibase/lingu/sdrhhcwrap.cxx @@ -0,0 +1,175 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; + +SdrHHCWrapper::SdrHHCWrapper( SwView* pVw, + LanguageType nSourceLanguage, LanguageType nTargetLanguage, + const Font* pTargetFnt, + sal_Int32 nConvOptions, + bool bInteractive ) : + SdrOutliner(pVw->GetDocShell()->GetDoc()->GetDrawModel()-> + GetDrawOutliner().GetEmptyItemSet().GetPool(), + OUTLINERMODE_TEXTOBJECT ), + pView( pVw ), + pTextObj( NULL ), + pOutlView( NULL ), + nOptions( nConvOptions ), + nDocIndex( 0 ), + nSourceLang( nSourceLanguage ), + nTargetLang( nTargetLanguage ), + pTargetFont( pTargetFnt ), + bIsInteractive( bInteractive ) +{ + SetRefDevice( pView->GetDocShell()->GetDoc()->getPrinter( false ) ); + + MapMode aMapMode (MAP_TWIP); + SetRefMapMode(aMapMode); + + Size aSize( 1, 1 ); + SetPaperSize( aSize ); + + pOutlView = new OutlinerView( this, &(pView->GetEditWin()) ); + pOutlView->GetOutliner()->SetRefDevice(pView->GetWrtShell().getIDocumentDeviceAccess()->getPrinter( false )); + + // Hack: all SdrTextObj attributes should be transferred to EditEngine + pOutlView->SetBackgroundColor( Color( COL_WHITE ) ); + + InsertView( pOutlView ); + Point aPoint( 0, 0 ); + Rectangle aRect( aPoint, aSize ); + pOutlView->SetOutputArea( aRect ); +// SetText( NULL ); + ClearModifyFlag(); +} + +SdrHHCWrapper::~SdrHHCWrapper() +{ + if (pTextObj) + { + SdrView *pSdrView = pView->GetWrtShell().GetDrawView(); + OSL_ENSURE( pSdrView, "SdrHHCWrapper without DrawView?" ); + pSdrView->SdrEndTextEdit( sal_True ); + SetUpdateMode(false); + pOutlView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) ); + } + RemoveView( pOutlView ); + delete pOutlView; +} + +void SdrHHCWrapper::StartTextConversion() +{ + pOutlView->StartTextConversion( nSourceLang, nTargetLang, pTargetFont, nOptions, bIsInteractive, true ); +} + +bool SdrHHCWrapper::ConvertNextDocument() +{ + bool bNextDoc = false; + + if ( pTextObj ) + { + SdrView *pSdrView = pView->GetWrtShell().GetDrawView(); + OSL_ENSURE( pSdrView, "SdrHHCWrapper without DrawView?" ); + pSdrView->SdrEndTextEdit( sal_True ); + SetUpdateMode(false); + pOutlView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) ); + SetPaperSize( Size(1, 1) ); + Clear(); + pTextObj = NULL; + } + + sal_uInt16 n = nDocIndex; + + std::list aTextObjs; + SwDrawContact::GetTextObjectsFromFmt( aTextObjs, pView->GetDocShell()->GetDoc() ); + for ( std::list::iterator aIt = aTextObjs.begin(); aIt != aTextObjs.end(); ++aIt ) + { + pTextObj = (*aIt); + if ( pTextObj ) + { + OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); + if ( pParaObj ) + { + SetPaperSize( pTextObj->GetLogicRect().GetSize() ); + SetText( *pParaObj ); + + ClearModifyFlag(); + + //!! update mode needs to be set to true otherwise + //!! the call to 'HasConvertibleTextPortion' will not always + //!! work correctly because the document may not be properly + //!! formatted when some information is accessed, and thus + //!! incorrect results get returned. + SetUpdateMode(true); + if (HasConvertibleTextPortion( nSourceLang )) + { + SdrView *pSdrView = pView->GetWrtShell().GetDrawView(); + OSL_ENSURE( pSdrView, "SdrHHCWrapper without DrawView?" ); + SdrPageView* pPV = pSdrView->GetSdrPageView(); + nDocIndex = n; + bNextDoc = true; + pOutlView->SetOutputArea( Rectangle( Point(), Size(1,1))); + SetPaperSize( pTextObj->GetLogicRect().GetSize() ); + SetUpdateMode(true); + pView->GetWrtShell().MakeVisible(pTextObj->GetLogicRect()); + + pSdrView->SdrBeginTextEdit(pTextObj, pPV, &pView->GetEditWin(), sal_False, this, pOutlView, sal_True, sal_True); + } + else + SetUpdateMode(false); + } + + if ( !bNextDoc ) + pTextObj = NULL; + else + break; + } + } + + ClearModifyFlag(); + + return bNextDoc; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/uibase/lingu/sdrhhcwrap.hxx b/sw/source/core/uibase/lingu/sdrhhcwrap.hxx new file mode 100644 index 000000000000..d6befe334b44 --- /dev/null +++ b/sw/source/core/uibase/lingu/sdrhhcwrap.hxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_LINGU_SDRHHCWRAP_HXX +#define INCLUDED_SW_SOURCE_UI_LINGU_SDRHHCWRAP_HXX + +#include + +class SwView; +class SdrTextObj; +class OutlinerView; + +class SdrHHCWrapper : public SdrOutliner +{ + // modified version of SdrSpeller + + SwView* pView; + SdrTextObj* pTextObj; + OutlinerView* pOutlView; + sal_Int32 nOptions; + sal_uInt16 nDocIndex; + LanguageType nSourceLang; + LanguageType nTargetLang; + const Font* pTargetFont; + bool bIsInteractive; + +public: + SdrHHCWrapper( SwView* pVw, + LanguageType nSourceLanguage, LanguageType nTargetLanguage, + const Font* pTargetFnt, + sal_Int32 nConvOptions, bool bInteractive ); + + virtual ~SdrHHCWrapper(); + + virtual bool ConvertNextDocument(); + void StartTextConversion(); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3