update credits
[LibreOffice.git] / sw / source / ui / uiview / viewling.cxx
blob98d0dfc306f9eab923672c9e6eeac339a39fe9f1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
42 #include <swwait.hxx>
43 #include <initui.hxx> // fuer SpellPointer
44 #include <uitool.hxx>
45 #include <view.hxx>
46 #include <wrtsh.hxx>
47 #include <basesh.hxx>
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
54 #include <edtwin.hxx>
55 #include <crsskip.hxx>
56 #include <ndtxt.hxx>
57 #include <vcl/lstbox.hxx>
58 #include <cmdid.h>
59 #include <globals.hrc>
60 #include <comcore.hrc> // STR_MULT_INTERACT_SPELL_WARN
61 #include <view.hrc>
62 #include <hhcwrp.hxx>
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>
82 #include <unomid.h>
83 #include <IMark.hxx>
84 #include <xmloff/odffields.hxx>
86 #include <memory>
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())
103 case SID_THESAURUS:
104 StartThesaurus();
105 rReq.Ignore();
106 break;
107 case SID_HANGUL_HANJA_CONVERSION:
108 StartTextConversion( LANGUAGE_KOREAN, LANGUAGE_KOREAN, NULL,
109 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, sal_True );
110 break;
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
116 if(xContext.is())
118 Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
119 if(xMCF.is())
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 );
126 if( xInit.is() )
128 // initialize dialog
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 );
138 //execute dialog
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 );
147 if( xProp.is() )
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;
164 if( !bCommonTerms )
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 );
189 if (bRestoreCursor)
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)
196 nPointIndex = 0;
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();
210 break;
212 case FN_HYPHENATE_OPT_DLG:
213 HyphenateDocument();
214 break;
215 default:
216 OSL_ENSURE(!this, "wrong Dispatcher");
217 return;
221 /*--------------------------------------------------------------------
222 Description: start language specific text conversion
223 --------------------------------------------------------------------*/
224 void SwView::StartTextConversion(
225 LanguageType nSourceLang,
226 LanguageType nTargetLang,
227 const Font *pTargetFont,
228 sal_Int32 nOptions,
229 sal_Bool bIsInteractive )
231 // do not do text conversion if it is active elsewhere
232 if (GetWrtShell().HasConvIter())
234 return;
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 );
258 aWrap.Convert();
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;
279 switch ( eWhich )
281 case SVX_SPELL_BODY:
282 if( bIsWrapReverse )
283 eCurr = DOCPOS_END;
284 else
285 eCurr = DOCPOS_START;
286 break;
287 case SVX_SPELL_BODY_END:
288 if( bIsWrapReverse )
290 if( bStartDone )
291 eStart = DOCPOS_CURR;
292 eCurr = DOCPOS_END;
294 else if( bStartDone )
295 eCurr = DOCPOS_START;
296 break;
297 case SVX_SPELL_BODY_START:
298 if( !bIsWrapReverse )
300 if( bEndDone )
301 eEnde = DOCPOS_CURR;
302 eCurr = DOCPOS_START;
304 else if( bEndDone )
305 eCurr = DOCPOS_END;
306 break;
307 case SVX_SPELL_OTHER:
308 if( bIsWrapReverse )
310 eStart = DOCPOS_OTHERSTART;
311 eEnde = DOCPOS_OTHEREND;
312 eCurr = DOCPOS_OTHEREND;
314 else
316 eStart = DOCPOS_OTHERSTART;
317 eEnde = DOCPOS_OTHEREND;
318 eCurr = DOCPOS_OTHERSTART;
320 break;
321 default:
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();
335 #endif
336 sal_uInt16 nPend = 0;
338 if ( m_pWrtShell->ActionPend() )
340 m_pWrtShell->Push();
341 m_pWrtShell->ClearMark();
344 m_pWrtShell->EndAction();
345 ++nPend;
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();
354 #endif
355 sal_uInt16 nWaitCnt = 0;
356 while( rEditWin.IsWait() )
358 rEditWin.LeaveWait();
359 ++nWaitCnt;
361 if ( LANGUAGE_NONE == eLang )
362 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_NOLANGUAGE );
363 else
364 ErrorHandler::HandleError( *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
366 while( nWaitCnt )
368 rEditWin.EnterWait();
369 --nWaitCnt;
371 #if OSL_DEBUG_LEVEL > 1
372 bFocus = GetEditWin().HasFocus();
373 #endif
375 if ( nPend )
377 while( nPend-- )
378 m_pWrtShell->StartAction();
379 m_pWrtShell->Combine();
381 #if OSL_DEBUG_LEVEL > 1
382 if( !bFocus )
383 GetEditWin().GrabFocus();
384 #endif
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 )
400 switch ( eWhich )
402 case SVX_SPELL_BODY:
403 m_pWrtShell->HyphStart( DOCPOS_START, DOCPOS_END );
404 break;
405 case SVX_SPELL_BODY_END:
406 m_pWrtShell->HyphStart( DOCPOS_CURR, DOCPOS_END );
407 break;
408 case SVX_SPELL_BODY_START:
409 m_pWrtShell->HyphStart( DOCPOS_START, DOCPOS_CURR );
410 break;
411 case SVX_SPELL_OTHER:
412 m_pWrtShell->HyphStart( DOCPOS_OTHERSTART, DOCPOS_OTHEREND );
413 break;
414 default:
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();
429 return;
432 SfxErrorContext aContext( ERRCTX_SVX_LINGU_HYPHENATION, aEmptyStr, m_pEditWin,
433 RID_SVXERRCTX, &DIALOG_MGR() );
435 Reference< XHyphenator > xHyph( ::GetHyphenator() );
436 if (!xHyph.is())
438 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS );
439 return;
442 if (m_pWrtShell->GetSelectionType() & (nsSelectionType::SEL_DRW_TXT|nsSelectionType::SEL_DRW))
444 // Silbentrennung in einem Draw-Objekt
445 HyphenateDrawText();
447 else
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() );
463 bool bStop = false;
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 )
471 bOther = sal_True;
472 if (xProp.is())
474 xProp->setIsHyphSpecial( sal_True );
477 else
478 bStop = true; // Nein Es wird nicht getrennt
481 if( !bStop )
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);
514 if( !bSelection )
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)
528 ++nLeft;
529 pChar = rLookUpText.Len() ? rLookUpText.GetBuffer() + rLookUpText.Len() - 1 : 0;
530 xub_StrLen nRight = 0;
531 while (pChar && *pChar-- == CH_TXTATR_INWORD)
532 ++nRight;
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())
554 return;
556 SfxErrorContext aContext( ERRCTX_SVX_LINGU_THESAURUS, aEmptyStr, m_pEditWin,
557 RID_SVXERRCTX, &DIALOG_MGR() );
559 // Sprache rausholen
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 );
568 return;
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() ) )
583 SpellError( eLang );
584 else
586 // create dialog
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 );
598 delete pDlg;
600 pVOpt->SetIdle( bOldIdle );
603 /*--------------------------------------------------------------------
604 Beschreibung: Online-Vorschlaege anbieten
605 *--------------------------------------------------------------------*/
606 //!! Start of extra code for context menu modifying extensions
607 struct ExecuteInfo
609 uno::Reference< frame::XDispatch > xDispatch;
610 util::URL aTargetURL;
611 uno::Sequence< PropertyValue > aArgs;
614 class AsyncExecute
616 public:
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 );
635 delete pExecuteInfo;
636 return 0;
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 );
653 m_pWrtShell->Push();
654 SwRect aToFill;
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
683 String aParaText;
684 SwPosition aPoint( *m_pWrtShell->GetCrsr()->GetPoint() );
685 const SwTxtNode *pNode = dynamic_cast< const SwTxtNode * >(
686 &aPoint.nNode.GetNode() );
687 if (pNode)
688 aParaText = pNode->GetTxt(); // this may include hidden text but that should be Ok
689 else
691 OSL_FAIL("text node expected but not found" );
694 bRet = sal_True;
695 m_pWrtShell->SttSelect();
696 std::auto_ptr< SwSpellPopup > pPopup;
697 if (bUseGrammarContext)
699 sal_Int32 nPos = aPoint.nContent.GetIndex();
700 (void) nPos;
701 pPopup = std::auto_ptr< SwSpellPopup >(new SwSpellPopup( m_pWrtShell, aGrammarCheckRes, nErrorInResult, aSuggestions, aParaText ));
703 else
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();
711 Menu* pMenu = 0;
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)
720 if ( pMenu )
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);
729 else
731 SfxViewFrame *pSfxViewFrame = GetViewFrame();
732 uno::Reference< frame::XFrame > xFrame;
733 if ( pSfxViewFrame )
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 );
749 if (xDispatch.is())
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&)
764 else
766 pPopup->Execute( aToFill.SVRect(), m_pEditWin );
771 m_pWrtShell->Pop( sal_False );
772 m_pWrtShell->LockView( bOldViewLock );
775 return bRet;
778 /** Function: ExecSmartTagPopup
780 This function shows the popup menu for smarttag
781 actions.
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 );
788 m_pWrtShell->Push();
791 // get word that was clicked on
792 // This data structure maps a smart tag type string to the property bag
793 SwRect aToFill;
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() )
801 bRet = sal_True;
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 );
810 return bRet;
813 class SwFieldDialog : public FloatingWindow
815 private:
816 ListBox aListBox;
817 IFieldmark *pFieldmark;
819 DECL_LINK( MyListBoxHandler, ListBox * );
821 public:
822 SwFieldDialog( SwEditWin* parent, IFieldmark *fieldBM );
825 SwFieldDialog::SwFieldDialog( SwEditWin* parent, IFieldmark *fieldBM ) :
826 FloatingWindow( parent, WB_BORDER | WB_SYSTEMWINDOW ),
827 aListBox(this),
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();
842 ++pCurrent)
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());
860 lbSize.Width()+=50;
861 lbSize.Height()+=20;
862 aListBox.SetSizePixel(lbSize);
863 aListBox.SetSelectHdl( LINK( this, SwFieldDialog, MyListBoxHandler ) );
864 aListBox.Show();
866 SetSizePixel( lbSize );
869 IMPL_LINK( SwFieldDialog, MyListBoxHandler, ListBox *, pBox )
871 short res = 0;
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 );
884 EndPopupMode();
885 res = 1;
887 return res;
890 IMPL_LINK_NOARG(SwView, FieldPopupModeEndHdl)
892 if ( m_pFieldPopup )
894 delete m_pFieldPopup;
895 m_pFieldPopup = NULL;
897 return 0;
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: */