summaryrefslogtreecommitdiff
path: root/sw/source/core/uibase/lingu
diff options
context:
space:
mode:
authorroopak12345 <mailstorpk@gmail.com>2014-03-09 21:40:44 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-03-09 21:53:34 +0100
commita652ea0fc4cc789f715b461819127ee80afa9e6f (patch)
tree0858def8201a45024721f4a98b537cd3274ac4c5 /sw/source/core/uibase/lingu
parentf4dfd811344604e119670eb7cdda0ab2e85bcea5 (diff)
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
Diffstat (limited to 'sw/source/core/uibase/lingu')
-rw-r--r--sw/source/core/uibase/lingu/hhcwrp.cxx720
-rw-r--r--sw/source/core/uibase/lingu/hyp.cxx132
-rw-r--r--sw/source/core/uibase/lingu/olmenu.cxx891
-rw-r--r--sw/source/core/uibase/lingu/olmenu.hrc89
-rw-r--r--sw/source/core/uibase/lingu/olmenu.src131
-rw-r--r--sw/source/core/uibase/lingu/sdrhhcwrap.cxx175
-rw-r--r--sw/source/core/uibase/lingu/sdrhhcwrap.hxx56
7 files changed, 2194 insertions, 0 deletions
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 <hintids.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <swundo.hxx>
+#include <globals.hrc>
+#include <splargs.hxx>
+
+#include <vcl/msgbox.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/text/RubyAdjust.hpp>
+#include <hhcwrp.hxx>
+#include <sdrhhcwrap.hxx>
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <mdiexp.hxx>
+#include <edtwin.hxx>
+#include <crsskip.hxx>
+#include <index.hxx>
+#include <pam.hxx>
+#include <swcrsr.hxx>
+#include <viscrs.hxx>
+#include <ndtxt.hxx>
+#include <fmtruby.hxx>
+#include <breakit.hxx>
+
+#include <olmenu.hrc>
+
+#include <unomid.h>
+
+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<sal_uInt16>(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 <vcl/msgbox.hxx>
+#include <vcl/wrkwin.hxx>
+#include <linguistic/lngprops.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+#include <swwait.hxx>
+
+#include "hyp.hxx"
+#include "mdiexp.hxx"
+#include "olmenu.hrc"
+
+#include <unomid.h>
+
+#include <boost/scoped_ptr.hpp>
+
+#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<SwWait> 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 <comphelper/anytostring.hxx>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/splwrap.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/editview.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <linguistic/lngprops.hxx>
+#include <linguistic/misc.hxx>
+#include <osl/file.hxx>
+#include <rtl/string.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/imagemgr.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <svl/itemset.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/langtab.hxx>
+#include <svx/dlgutil.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <vcl/layout.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/macros.h>
+
+#include <map>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/document/XDocumentLanguages.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/linguistic2/SingleProofreadingError.hpp>
+#include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/system/SystemShellExecute.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+
+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<linguistic2::XSearchableDictionaryList> 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 <hintids.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/editdata.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdogrp.hxx>
+#include <sfx2/printer.hxx>
+#include <svx/svdmodel.hxx>
+#include <editeng/langitem.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <linguistic/lngprops.hxx>
+#include <sfx2/sfxuno.hxx>
+#include <svx/svdview.hxx>
+#include <editeng/unolingu.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <sdrhhcwrap.hxx>
+#include <frmfmt.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <dcontact.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <edtwin.hxx>
+
+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<SdrTextObj*> aTextObjs;
+ SwDrawContact::GetTextObjectsFromFmt( aTextObjs, pView->GetDocShell()->GetDoc() );
+ for ( std::list<SdrTextObj*>::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 <svx/svdoutl.hxx>
+
+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: */