1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <com/sun/star/lang/Locale.hpp>
23 #include <com/sun/star/linguistic2/XThesaurus.hpp>
24 #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
25 #include <com/sun/star/i18n/TextConversionOption.hpp>
26 #include <linguistic/lngprops.hxx>
27 #include <comphelper/processfactory.hxx>
28 #include <toolkit/helper/vclunohelper.hxx>
29 #include <vcl/msgbox.hxx>
30 #include <svtools/ehdl.hxx>
31 #include <svl/stritem.hxx>
32 #include <sfx2/viewfrm.hxx>
33 #include <sfx2/request.hxx>
34 #include <svx/dlgutil.hxx>
35 #include <svx/dialmgr.hxx>
36 #include <editeng/langitem.hxx>
37 #include <svx/svxerr.hxx>
38 #include <editeng/unolingu.hxx>
39 #include <svx/svxdlg.hxx>
40 #include <editeng/SpellPortions.hxx>
41 #include <swmodule.hxx>
43 #include <initui.hxx> // fuer SpellPointer
48 #include <docsh.hxx> // CheckSpellChanges
49 #include <viewopt.hxx> // Viewoptions
50 #include <swundo.hxx> // fuer Undo-Ids
51 #include <hyp.hxx> // Trennung
52 #include <olmenu.hxx> // PopupMenu fuer OnlineSpelling
53 #include <pam.hxx> // Spelling: Multiselektion
55 #include <crsskip.hxx>
57 #include <vcl/lstbox.hxx>
59 #include <globals.hrc>
60 #include <comcore.hrc> // STR_MULT_INTERACT_SPELL_WARN
63 #include <com/sun/star/frame/XStorable.hpp>
65 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
66 #include <com/sun/star/lang/XInitialization.hpp>
67 #include <com/sun/star/frame/XDispatch.hpp>
68 #include <com/sun/star/frame/XDispatchProvider.hpp>
69 #include <com/sun/star/frame/XFrame.hpp>
70 #include <com/sun/star/util/URL.hpp>
71 #include <com/sun/star/beans/PropertyValue.hpp>
72 #include <com/sun/star/util/URLTransformer.hpp>
73 #include <com/sun/star/util/XURLTransformer.hpp>
75 #include <vcl/svapp.hxx>
76 #include <rtl/ustring.hxx>
78 #include <cppuhelper/bootstrap.hxx>
79 #include "stmenu.hxx" // PopupMenu for smarttags
80 #include <svx/dialogs.hrc>
81 #include <svtools/langtab.hxx>
84 #include <xmloff/odffields.hxx>
87 #include <editeng/editerr.hxx>
89 using namespace sw::mark
;
90 using namespace ::com::sun::star
;
91 using namespace ::com::sun::star::beans
;
92 using namespace ::com::sun::star::uno
;
93 using namespace ::com::sun::star::linguistic2
;
94 using namespace ::com::sun::star::smarttags
;
96 /*--------------------------------------------------------------------
97 Beschreibung: Lingu-Dispatcher
98 --------------------------------------------------------------------*/
99 void SwView::ExecLingu(SfxRequest
&rReq
)
101 switch(rReq
.GetSlot())
107 case SID_HANGUL_HANJA_CONVERSION
:
108 StartTextConversion( LANGUAGE_KOREAN
, LANGUAGE_KOREAN
, NULL
,
109 i18n::TextConversionOption::CHARACTER_BY_CHARACTER
, sal_True
);
111 case SID_CHINESE_CONVERSION
:
113 //open ChineseTranslationDialog
114 Reference
< XComponentContext
> xContext(
115 ::cppu::defaultBootstrap_InitialComponentContext() ); //@todo get context from calc if that has one
118 Reference
< lang::XMultiComponentFactory
> xMCF( xContext
->getServiceManager() );
121 Reference
< ui::dialogs::XExecutableDialog
> xDialog(
122 xMCF
->createInstanceWithContext(
123 OUString("com.sun.star.linguistic2.ChineseTranslationDialog")
124 , xContext
), UNO_QUERY
);
125 Reference
< lang::XInitialization
> xInit( xDialog
, UNO_QUERY
);
129 Reference
< awt::XWindow
> xDialogParentWindow(0);
130 Sequence
<Any
> aSeq(1);
131 Any
* pArray
= aSeq
.getArray();
132 PropertyValue aParam
;
133 aParam
.Name
= OUString("ParentWindow");
134 aParam
.Value
<<= makeAny(xDialogParentWindow
);
135 pArray
[0] <<= makeAny(aParam
);
136 xInit
->initialize( aSeq
);
139 sal_Int16 nDialogRet
= xDialog
->execute();
140 if( RET_OK
== nDialogRet
)
142 //get some parameters from the dialog
143 sal_Bool bToSimplified
= sal_True
;
144 sal_Bool bUseVariants
= sal_True
;
145 sal_Bool bCommonTerms
= sal_True
;
146 Reference
< beans::XPropertySet
> xProp( xDialog
, UNO_QUERY
);
151 xProp
->getPropertyValue( "IsDirectionToSimplified" ) >>= bToSimplified
;
152 xProp
->getPropertyValue( "IsUseCharacterVariants" ) >>= bUseVariants
;
153 xProp
->getPropertyValue( "IsTranslateCommonTerms" ) >>= bCommonTerms
;
155 catch (const Exception
&)
160 //execute translation
161 sal_Int16 nSourceLang
= bToSimplified
? LANGUAGE_CHINESE_TRADITIONAL
: LANGUAGE_CHINESE_SIMPLIFIED
;
162 sal_Int16 nTargetLang
= bToSimplified
? LANGUAGE_CHINESE_SIMPLIFIED
: LANGUAGE_CHINESE_TRADITIONAL
;
163 sal_Int32 nOptions
= bUseVariants
? i18n::TextConversionOption::USE_CHARACTER_VARIANTS
: 0;
165 nOptions
= nOptions
| i18n::TextConversionOption::CHARACTER_BY_CHARACTER
;
167 Font aTargetFont
= GetEditWin().GetDefaultFont( DEFAULTFONT_CJK_TEXT
,
168 nTargetLang
, DEFAULTFONT_FLAGS_ONLYONE
);
170 // disallow formatting, updating the view, ... while
171 // converting the document. (saves time)
172 // Also remember the current view and cursor position for later
173 m_pWrtShell
->StartAction();
175 // remember cursor position data for later restoration of the cursor
176 const SwPosition
*pPoint
= m_pWrtShell
->GetCrsr()->GetPoint();
177 sal_Bool bRestoreCursor
= pPoint
->nNode
.GetNode().IsTxtNode();
178 const SwNodeIndex
aPointNodeIndex( pPoint
->nNode
);
179 xub_StrLen nPointIndex
= pPoint
->nContent
.GetIndex();
181 // since this conversion is not interactive the whole converted
182 // document should be undone in a single undo step.
183 m_pWrtShell
->StartUndo( UNDO_OVERWRITE
);
185 StartTextConversion( nSourceLang
, nTargetLang
, &aTargetFont
, nOptions
, sal_False
);
187 m_pWrtShell
->EndUndo( UNDO_OVERWRITE
);
191 SwTxtNode
*pTxtNode
= aPointNodeIndex
.GetNode().GetTxtNode();
192 // check for unexpected error case
193 OSL_ENSURE(pTxtNode
&& pTxtNode
->GetTxt().getLength() >= nPointIndex
,
194 "text missing: corrupted node?" );
195 if (!pTxtNode
|| pTxtNode
->GetTxt().getLength() < nPointIndex
)
197 // restore cursor to its original position
198 m_pWrtShell
->GetCrsr()->GetPoint()->nContent
.Assign( pTxtNode
, nPointIndex
);
201 // enable all, restore view and cursor position
202 m_pWrtShell
->EndAction();
205 Reference
< lang::XComponent
> xComponent( xDialog
, UNO_QUERY
);
206 if( xComponent
.is() )
207 xComponent
->dispose();
212 case FN_HYPHENATE_OPT_DLG
:
216 OSL_ENSURE(!this, "wrong Dispatcher");
221 /*--------------------------------------------------------------------
222 Description: start language specific text conversion
223 --------------------------------------------------------------------*/
224 void SwView::StartTextConversion(
225 LanguageType nSourceLang
,
226 LanguageType nTargetLang
,
227 const Font
*pTargetFont
,
229 sal_Bool bIsInteractive
)
231 // do not do text conversion if it is active elsewhere
232 if (GetWrtShell().HasConvIter())
237 SpellKontext(sal_True
);
239 const SwViewOption
* pVOpt
= m_pWrtShell
->GetViewOptions();
240 const sal_Bool bOldIdle
= pVOpt
->IsIdle();
241 pVOpt
->SetIdle( sal_False
);
243 sal_Bool bOldIns
= m_pWrtShell
->IsInsMode();
244 m_pWrtShell
->SetInsMode( sal_True
);
246 const bool bSelection
= ((SwCrsrShell
*)m_pWrtShell
)->HasSelection() ||
247 m_pWrtShell
->GetCrsr() != m_pWrtShell
->GetCrsr()->GetNext();
249 const bool bStart
= bSelection
|| m_pWrtShell
->IsStartOfDoc();
250 const bool bOther
= !bSelection
&& !(m_pWrtShell
->GetFrmType(0,sal_True
) & FRMTYPE_BODY
);
253 const uno::Reference
< uno::XComponentContext
> xContext(
254 comphelper::getProcessComponentContext() );
255 SwHHCWrapper
aWrap( this, xContext
, nSourceLang
, nTargetLang
, pTargetFont
,
256 nOptions
, bIsInteractive
,
257 bStart
, bOther
, bSelection
);
261 m_pWrtShell
->SetInsMode( bOldIns
);
262 pVOpt
->SetIdle( bOldIdle
);
263 SpellKontext(sal_False
);
266 /*--------------------------------------------------------------------
267 spellcheck and text conversion related stuff
268 --------------------------------------------------------------------*/
269 void SwView::SpellStart( SvxSpellArea eWhich
,
270 bool bStartDone
, bool bEndDone
,
271 SwConversionArgs
*pConvArgs
)
273 Reference
< XLinguProperties
> xProp
= ::GetLinguPropertySet();
274 sal_Bool bIsWrapReverse
= (!pConvArgs
&& xProp
.is()) ? xProp
->getIsWrapReverse() : sal_False
;
276 SwDocPositions eStart
= DOCPOS_START
;
277 SwDocPositions eEnde
= DOCPOS_END
;
278 SwDocPositions eCurr
= DOCPOS_CURR
;
285 eCurr
= DOCPOS_START
;
287 case SVX_SPELL_BODY_END
:
291 eStart
= DOCPOS_CURR
;
294 else if( bStartDone
)
295 eCurr
= DOCPOS_START
;
297 case SVX_SPELL_BODY_START
:
298 if( !bIsWrapReverse
)
302 eCurr
= DOCPOS_START
;
307 case SVX_SPELL_OTHER
:
310 eStart
= DOCPOS_OTHERSTART
;
311 eEnde
= DOCPOS_OTHEREND
;
312 eCurr
= DOCPOS_OTHEREND
;
316 eStart
= DOCPOS_OTHERSTART
;
317 eEnde
= DOCPOS_OTHEREND
;
318 eCurr
= DOCPOS_OTHERSTART
;
322 OSL_ENSURE( !this, "SpellStart with unknown Area" );
324 m_pWrtShell
->SpellStart( eStart
, eEnde
, eCurr
, pConvArgs
);
327 /*--------------------------------------------------------------------
328 Beschreibung: Fehlermeldung beim Spelling
329 --------------------------------------------------------------------*/
330 // Der uebergebene Pointer nLang ist selbst der Wert
331 void SwView::SpellError(LanguageType eLang
)
333 #if OSL_DEBUG_LEVEL > 1
334 sal_Bool bFocus
= GetEditWin().HasFocus();
336 sal_uInt16 nPend
= 0;
338 if ( m_pWrtShell
->ActionPend() )
341 m_pWrtShell
->ClearMark();
344 m_pWrtShell
->EndAction();
347 while( m_pWrtShell
->ActionPend() );
349 String
aErr(SvtLanguageTable::GetLanguageString( eLang
) );
351 SwEditWin
&rEditWin
= GetEditWin();
352 #if OSL_DEBUG_LEVEL > 1
353 bFocus
= rEditWin
.HasFocus();
355 sal_uInt16 nWaitCnt
= 0;
356 while( rEditWin
.IsWait() )
358 rEditWin
.LeaveWait();
361 if ( LANGUAGE_NONE
== eLang
)
362 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_NOLANGUAGE
);
364 ErrorHandler::HandleError( *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS
, aErr
) );
368 rEditWin
.EnterWait();
371 #if OSL_DEBUG_LEVEL > 1
372 bFocus
= GetEditWin().HasFocus();
378 m_pWrtShell
->StartAction();
379 m_pWrtShell
->Combine();
381 #if OSL_DEBUG_LEVEL > 1
383 GetEditWin().GrabFocus();
388 /*--------------------------------------------------------------------
389 Beschreibung: Spelling beenden und Cursor wiederherstellen
390 --------------------------------------------------------------------*/
391 void SwView::SpellEnd( SwConversionArgs
*pConvArgs
)
393 m_pWrtShell
->SpellEnd( pConvArgs
);
394 if( m_pWrtShell
->IsExtMode() )
395 m_pWrtShell
->SetMark();
398 void SwView::HyphStart( SvxSpellArea eWhich
)
403 m_pWrtShell
->HyphStart( DOCPOS_START
, DOCPOS_END
);
405 case SVX_SPELL_BODY_END
:
406 m_pWrtShell
->HyphStart( DOCPOS_CURR
, DOCPOS_END
);
408 case SVX_SPELL_BODY_START
:
409 m_pWrtShell
->HyphStart( DOCPOS_START
, DOCPOS_CURR
);
411 case SVX_SPELL_OTHER
:
412 m_pWrtShell
->HyphStart( DOCPOS_OTHERSTART
, DOCPOS_OTHEREND
);
415 OSL_ENSURE( !this, "HyphStart with unknown Area" );
419 /*--------------------------------------------------------------------
420 Beschreibung: Interaktive Trennung
421 --------------------------------------------------------------------*/
422 void SwView::HyphenateDocument()
424 // do not hyphenate if interactive hyphenationg is active elsewhere
425 if (GetWrtShell().HasHyphIter())
427 MessBox( 0, WB_OK
, String( SW_RES( STR_HYPH_TITLE
) ),
428 String( SW_RES( STR_MULT_INTERACT_HYPH_WARN
) ) ).Execute();
432 SfxErrorContext
aContext( ERRCTX_SVX_LINGU_HYPHENATION
, aEmptyStr
, m_pEditWin
,
433 RID_SVXERRCTX
, &DIALOG_MGR() );
435 Reference
< XHyphenator
> xHyph( ::GetHyphenator() );
438 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS
);
442 if (m_pWrtShell
->GetSelectionType() & (nsSelectionType::SEL_DRW_TXT
|nsSelectionType::SEL_DRW
))
444 // Silbentrennung in einem Draw-Objekt
449 SwViewOption
* pVOpt
= (SwViewOption
*)m_pWrtShell
->GetViewOptions();
450 sal_Bool bOldIdle
= pVOpt
->IsIdle();
451 pVOpt
->SetIdle( sal_False
);
453 Reference
< XLinguProperties
> xProp( ::GetLinguPropertySet() );
456 m_pWrtShell
->StartUndo(UNDO_INSATTR
); // spaeter gueltig
458 sal_Bool bHyphSpecial
= xProp
.is() ? xProp
->getIsHyphSpecial() : sal_False
;
459 sal_Bool bSelection
= ((SwCrsrShell
*)m_pWrtShell
)->HasSelection() ||
460 m_pWrtShell
->GetCrsr() != m_pWrtShell
->GetCrsr()->GetNext();
461 sal_Bool bOther
= m_pWrtShell
->HasOtherCnt() && bHyphSpecial
&& !bSelection
;
462 sal_Bool bStart
= bSelection
|| ( !bOther
&& m_pWrtShell
->IsStartOfDoc() );
464 if( !bOther
&& !(m_pWrtShell
->GetFrmType(0,sal_True
) & FRMTYPE_BODY
) && !bSelection
)
465 // kein Sonderbereich eingeschaltet
467 // Ich will auch in Sonderbereichen trennen
468 QueryBox
aBox( &GetEditWin(), SW_RES( DLG_SPECIAL_FORCED
) );
469 if( aBox
.Execute() == RET_YES
)
474 xProp
->setIsHyphSpecial( sal_True
);
478 bStop
= true; // Nein Es wird nicht getrennt
483 SwHyphWrapper
aWrap( this, xHyph
, bStart
, bOther
, bSelection
);
484 aWrap
.SpellDocument();
485 m_pWrtShell
->EndUndo(UNDO_INSATTR
);
487 pVOpt
->SetIdle( bOldIdle
);
491 bool SwView::IsValidSelectionForThesaurus() const
493 // must not be a multi-selection, and if it is a selection it needs
494 // to be within a single paragraph
496 const bool bMultiSel
= m_pWrtShell
->GetCrsr() != m_pWrtShell
->GetCrsr()->GetNext();
497 const sal_Bool bSelection
= ((SwCrsrShell
*)m_pWrtShell
)->HasSelection();
498 return !bMultiSel
&& (!bSelection
|| m_pWrtShell
->IsSelOnePara() );
501 String
SwView::GetThesaurusLookUpText( bool bSelection
) const
503 return bSelection
? m_pWrtShell
->GetSelTxt() : m_pWrtShell
->GetCurWord();
506 void SwView::InsertThesaurusSynonym( const String
&rSynonmText
, const String
&rLookUpText
, bool bSelection
)
508 sal_Bool bOldIns
= m_pWrtShell
->IsInsMode();
509 m_pWrtShell
->SetInsMode( sal_True
);
511 m_pWrtShell
->StartAllAction();
512 m_pWrtShell
->StartUndo(UNDO_DELETE
);
516 if(m_pWrtShell
->IsEndWrd())
517 m_pWrtShell
->Left(CRSR_SKIP_CELLS
, sal_False
, 1, sal_False
);
519 m_pWrtShell
->SelWrd();
521 // make sure the selection build later from the data below does not
522 // include "in word" character to the left and right in order to
523 // preserve those. Therefore count those "in words" in order to modify
524 // the selection accordingly.
525 const sal_Unicode
* pChar
= rLookUpText
.GetBuffer();
526 xub_StrLen nLeft
= 0;
527 while (pChar
&& *pChar
++ == CH_TXTATR_INWORD
)
529 pChar
= rLookUpText
.Len() ? rLookUpText
.GetBuffer() + rLookUpText
.Len() - 1 : 0;
530 xub_StrLen nRight
= 0;
531 while (pChar
&& *pChar
-- == CH_TXTATR_INWORD
)
534 // adjust existing selection
535 SwPaM
*pCrsr
= m_pWrtShell
->GetCrsr();
536 pCrsr
->GetPoint()->nContent
-= nRight
;
537 pCrsr
->GetMark()->nContent
+= nLeft
;
540 m_pWrtShell
->Insert( rSynonmText
);
542 m_pWrtShell
->EndUndo(UNDO_DELETE
);
543 m_pWrtShell
->EndAllAction();
545 m_pWrtShell
->SetInsMode( bOldIns
);
548 /*--------------------------------------------------------------------
549 Beschreibung: Thesaurus starten
550 --------------------------------------------------------------------*/
551 void SwView::StartThesaurus()
553 if (!IsValidSelectionForThesaurus())
556 SfxErrorContext
aContext( ERRCTX_SVX_LINGU_THESAURUS
, aEmptyStr
, m_pEditWin
,
557 RID_SVXERRCTX
, &DIALOG_MGR() );
561 LanguageType eLang
= m_pWrtShell
->GetCurLang();
562 if( LANGUAGE_SYSTEM
== eLang
)
563 eLang
= GetAppLanguage();
565 if( eLang
== LANGUAGE_DONTKNOW
|| eLang
== LANGUAGE_NONE
)
567 SpellError( LANGUAGE_NONE
);
571 SwViewOption
* pVOpt
= (SwViewOption
*)m_pWrtShell
->GetViewOptions();
572 sal_Bool bOldIdle
= pVOpt
->IsIdle();
573 pVOpt
->SetIdle( sal_False
);
575 // get initial LookUp text
576 const sal_Bool bSelection
= ((SwCrsrShell
*)m_pWrtShell
)->HasSelection();
577 String aTmp
= GetThesaurusLookUpText( bSelection
);
579 Reference
< XThesaurus
> xThes( ::GetThesaurus() );
580 AbstractThesaurusDialog
*pDlg
= NULL
;
582 if ( !xThes
.is() || !xThes
->hasLocale( LanguageTag( eLang
).getLocale() ) )
587 { //Scope for SwWait-Object
588 SwWait
aWait( *GetDocShell(), sal_True
);
589 // load library with dialog only on demand ...
590 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
591 pDlg
= pFact
->CreateThesaurusDialog( &GetEditWin(), xThes
, aTmp
, eLang
);
594 if ( pDlg
->Execute()== RET_OK
)
595 InsertThesaurusSynonym( pDlg
->GetWord(), aTmp
, bSelection
);
600 pVOpt
->SetIdle( bOldIdle
);
603 /*--------------------------------------------------------------------
604 Beschreibung: Online-Vorschlaege anbieten
605 *--------------------------------------------------------------------*/
606 //!! Start of extra code for context menu modifying extensions
609 uno::Reference
< frame::XDispatch
> xDispatch
;
610 util::URL aTargetURL
;
611 uno::Sequence
< PropertyValue
> aArgs
;
617 DECL_STATIC_LINK( AsyncExecute
, ExecuteHdl_Impl
, ExecuteInfo
* );
620 IMPL_STATIC_LINK_NOINSTANCE( AsyncExecute
, ExecuteHdl_Impl
, ExecuteInfo
*, pExecuteInfo
)
622 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
625 // Asynchronous execution as this can lead to our own destruction!
626 // Framework can recycle our current frame and the layout manager disposes all user interface
627 // elements if a component gets detached from its frame!
628 pExecuteInfo
->xDispatch
->dispatch( pExecuteInfo
->aTargetURL
, pExecuteInfo
->aArgs
);
630 catch (const Exception
&)
634 Application::AcquireSolarMutex( nRef
);
638 //!! End of extra code for context menu modifying extensions
640 sal_Bool
SwView::ExecSpellPopup(const Point
& rPt
)
642 sal_Bool bRet
= sal_False
;
643 const SwViewOption
* pVOpt
= m_pWrtShell
->GetViewOptions();
644 if( pVOpt
->IsOnlineSpell() &&
645 !m_pWrtShell
->IsSelection())
647 if (m_pWrtShell
->GetSelectionType() & nsSelectionType::SEL_DRW_TXT
)
648 bRet
= ExecDrwTxtSpellPopup(rPt
);
649 else if (!m_pWrtShell
->IsSelFrmMode())
651 const sal_Bool bOldViewLock
= m_pWrtShell
->IsViewLocked();
652 m_pWrtShell
->LockView( sal_True
);
656 // decide which variant of the context menu to use...
657 // if neither spell checking nor grammar checking provides suggestions use the
658 // default context menu.
659 bool bUseGrammarContext
= false;
660 Reference
< XSpellAlternatives
> xAlt( m_pWrtShell
->GetCorrection(&rPt
, aToFill
) );
661 ProofreadingResult aGrammarCheckRes
;
662 sal_Int32 nErrorInResult
= -1;
663 uno::Sequence
< OUString
> aSuggestions
;
664 bool bCorrectionRes
= false;
665 if (!xAlt
.is() || xAlt
->getAlternatives().getLength() == 0)
667 sal_Int32 nErrorPosInText
= -1;
668 bCorrectionRes
= m_pWrtShell
->GetGrammarCorrection( aGrammarCheckRes
, nErrorPosInText
, nErrorInResult
, aSuggestions
, &rPt
, aToFill
);
669 OUString aMessageText
;
670 if (nErrorInResult
>= 0)
671 aMessageText
= aGrammarCheckRes
.aErrors
[ nErrorInResult
].aShortComment
;
672 // we like to use the grammar checking context menu if we either get
673 // some suggestions or at least a comment about the error found...
674 bUseGrammarContext
= bCorrectionRes
&&
675 (aSuggestions
.getLength() > 0 || !aMessageText
.isEmpty());
678 // open respective context menu for spell check or grammar errors with correction suggestions...
679 if ((!bUseGrammarContext
&& xAlt
.is()) ||
680 (bUseGrammarContext
&& bCorrectionRes
&& aGrammarCheckRes
.aErrors
.getLength() > 0))
682 // get paragraph text
684 SwPosition
aPoint( *m_pWrtShell
->GetCrsr()->GetPoint() );
685 const SwTxtNode
*pNode
= dynamic_cast< const SwTxtNode
* >(
686 &aPoint
.nNode
.GetNode() );
688 aParaText
= pNode
->GetTxt(); // this may include hidden text but that should be Ok
691 OSL_FAIL("text node expected but not found" );
695 m_pWrtShell
->SttSelect();
696 std::auto_ptr
< SwSpellPopup
> pPopup
;
697 if (bUseGrammarContext
)
699 sal_Int32 nPos
= aPoint
.nContent
.GetIndex();
701 pPopup
= std::auto_ptr
< SwSpellPopup
>(new SwSpellPopup( m_pWrtShell
, aGrammarCheckRes
, nErrorInResult
, aSuggestions
, aParaText
));
704 pPopup
= std::auto_ptr
< SwSpellPopup
>(new SwSpellPopup( m_pWrtShell
, xAlt
, aParaText
));
705 ui::ContextMenuExecuteEvent aEvent
;
706 const Point aPixPos
= GetEditWin().LogicToPixel( rPt
);
708 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( m_pEditWin
);
709 aEvent
.ExecutePosition
.X
= aPixPos
.X();
710 aEvent
.ExecutePosition
.Y
= aPixPos
.Y();
713 OUString sMenuName
= bUseGrammarContext
?
714 OUString("private:resource/GrammarContextMenu") : OUString("private:resource/SpellContextMenu");
715 if(TryContextMenuInterception( *pPopup
, sMenuName
, pMenu
, aEvent
))
718 //! happy hacking for context menu modifying extensions of this
719 //! 'custom made' menu... *sigh* (code copied from sfx2 and framework)
722 sal_uInt16 nId
= ((PopupMenu
*)pMenu
)->Execute(m_pEditWin
, aPixPos
);
723 OUString aCommand
= ((PopupMenu
*)pMenu
)->GetItemCommand(nId
);
724 if (aCommand
.isEmpty() )
726 if(!ExecuteMenuCommand( *dynamic_cast<PopupMenu
*>(pMenu
), *GetViewFrame(), nId
))
727 pPopup
->Execute(nId
);
731 SfxViewFrame
*pSfxViewFrame
= GetViewFrame();
732 uno::Reference
< frame::XFrame
> xFrame
;
734 xFrame
= pSfxViewFrame
->GetFrame().GetFrameInterface();
735 com::sun::star::util::URL aURL
;
736 uno::Reference
< frame::XDispatchProvider
> xDispatchProvider( xFrame
, UNO_QUERY
);
740 uno::Reference
< frame::XDispatch
> xDispatch
;
741 uno::Reference
< util::XURLTransformer
> xURLTransformer
= util::URLTransformer::create(comphelper::getProcessComponentContext());
743 aURL
.Complete
= aCommand
;
744 xURLTransformer
->parseStrict(aURL
);
745 uno::Sequence
< beans::PropertyValue
> aArgs
;
746 xDispatch
= xDispatchProvider
->queryDispatch( aURL
, OUString(), 0 );
751 // Execute dispatch asynchronously
752 ExecuteInfo
* pExecuteInfo
= new ExecuteInfo
;
753 pExecuteInfo
->xDispatch
= xDispatch
;
754 pExecuteInfo
->aTargetURL
= aURL
;
755 pExecuteInfo
->aArgs
= aArgs
;
756 Application::PostUserEvent( STATIC_LINK(0, AsyncExecute
, ExecuteHdl_Impl
), pExecuteInfo
);
759 catch (const Exception
&)
766 pPopup
->Execute( aToFill
.SVRect(), m_pEditWin
);
771 m_pWrtShell
->Pop( sal_False
);
772 m_pWrtShell
->LockView( bOldViewLock
);
778 /** Function: ExecSmartTagPopup
780 This function shows the popup menu for smarttag
783 sal_Bool
SwView::ExecSmartTagPopup( const Point
& rPt
)
785 sal_Bool bRet
= sal_False
;
786 const sal_Bool bOldViewLock
= m_pWrtShell
->IsViewLocked();
787 m_pWrtShell
->LockView( sal_True
);
791 // get word that was clicked on
792 // This data structure maps a smart tag type string to the property bag
794 Sequence
< OUString
> aSmartTagTypes
;
795 Sequence
< Reference
< container::XStringKeyMap
> > aStringKeyMaps
;
796 Reference
<text::XTextRange
> xRange
;
798 m_pWrtShell
->GetSmartTagTerm( rPt
, aToFill
, aSmartTagTypes
, aStringKeyMaps
, xRange
);
799 if ( xRange
.is() && aSmartTagTypes
.getLength() )
802 m_pWrtShell
->SttSelect();
803 SwSmartTagPopup
aPopup( this, aSmartTagTypes
, aStringKeyMaps
, xRange
);
804 aPopup
.Execute( aToFill
.SVRect(), m_pEditWin
);
807 m_pWrtShell
->Pop( sal_False
);
808 m_pWrtShell
->LockView( bOldViewLock
);
813 class SwFieldDialog
: public FloatingWindow
817 IFieldmark
*pFieldmark
;
819 DECL_LINK( MyListBoxHandler
, ListBox
* );
822 SwFieldDialog( SwEditWin
* parent
, IFieldmark
*fieldBM
);
825 SwFieldDialog::SwFieldDialog( SwEditWin
* parent
, IFieldmark
*fieldBM
) :
826 FloatingWindow( parent
, WB_BORDER
| WB_SYSTEMWINDOW
),
828 pFieldmark( fieldBM
)
830 if ( fieldBM
!= NULL
)
832 const IFieldmark::parameter_map_t
* const pParameters
= fieldBM
->GetParameters();
834 OUString sListKey
= OUString( ODF_FORMDROPDOWN_LISTENTRY
);
835 IFieldmark::parameter_map_t::const_iterator pListEntries
= pParameters
->find( sListKey
);
836 if(pListEntries
!= pParameters
->end())
838 Sequence
< OUString
> vListEntries
;
839 pListEntries
->second
>>= vListEntries
;
840 for( OUString
* pCurrent
= vListEntries
.getArray();
841 pCurrent
!= vListEntries
.getArray() + vListEntries
.getLength();
844 aListBox
.InsertEntry(*pCurrent
);
848 // Select the current one
849 OUString sResultKey
= OUString( ODF_FORMDROPDOWN_RESULT
);
850 IFieldmark::parameter_map_t::const_iterator pResult
= pParameters
->find( sResultKey
);
851 if ( pResult
!= pParameters
->end() )
853 sal_Int32 nSelection
= -1;
854 pResult
->second
>>= nSelection
;
855 aListBox
.SelectEntryPos( nSelection
);
859 Size
lbSize(aListBox
.GetOptimalSize());
862 aListBox
.SetSizePixel(lbSize
);
863 aListBox
.SetSelectHdl( LINK( this, SwFieldDialog
, MyListBoxHandler
) );
866 SetSizePixel( lbSize
);
869 IMPL_LINK( SwFieldDialog
, MyListBoxHandler
, ListBox
*, pBox
)
872 if ( !pBox
->IsTravelSelect() )
874 sal_Int32 selection
= pBox
->GetSelectEntryPos();
875 if ( selection
>= 0 )
877 OUString sKey
= OUString( ODF_FORMDROPDOWN_RESULT
);
878 (*pFieldmark
->GetParameters())[ sKey
] = makeAny(selection
);
879 pFieldmark
->Invalidate();
880 SwView
& rView
= ( ( SwEditWin
* )GetParent() )->GetView();
881 rView
.GetDocShell()->SetModified( sal_True
);
890 IMPL_LINK_NOARG(SwView
, FieldPopupModeEndHdl
)
894 delete m_pFieldPopup
;
895 m_pFieldPopup
= NULL
;
900 void SwView::ExecFieldPopup( const Point
& rPt
, IFieldmark
*fieldBM
)
902 const Point aPixPos
= GetEditWin().LogicToPixel( rPt
);
904 m_pFieldPopup
= new SwFieldDialog( m_pEditWin
, fieldBM
);
905 m_pFieldPopup
->SetPopupModeEndHdl( LINK( this, SwView
, FieldPopupModeEndHdl
) );
907 Rectangle
aRect( m_pEditWin
->OutputToScreenPixel( aPixPos
), Size( 0, 0 ) );
908 m_pFieldPopup
->StartPopupMode( aRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
911 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */