1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewling.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
38 #define _SVSTDARR_STRINGSDTOR
39 #include <svtools/svstdarr.hxx>
41 #include <com/sun/star/lang/Locale.hpp>
42 #include <com/sun/star/linguistic2/XThesaurus.hpp>
43 #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
44 #include <com/sun/star/i18n/TextConversionOption.hpp>
45 #include <linguistic/lngprops.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
48 #include <vcl/msgbox.hxx>
49 #include <svtools/ehdl.hxx>
50 #include <svtools/stritem.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include <sfx2/request.hxx>
53 #include <svx/dlgutil.hxx>
54 #include <svx/dialmgr.hxx>
55 #include <svx/langitem.hxx>
56 #include <svx/svxerr.hxx>
57 #include <svx/unolingu.hxx>
58 #include <svx/thesdlg.hxx>
59 #include <svx/SpellPortions.hxx>
60 #include <swmodule.hxx>
62 #include <initui.hxx> // fuer SpellPointer
72 #include <docsh.hxx> // CheckSpellChanges
74 #include <viewopt.hxx> // Viewoptions
75 #include <swundo.hxx> // fuer Undo-Ids
76 #include <hyp.hxx> // Trennung
77 #include <olmenu.hxx> // PopupMenu fuer OnlineSpelling
78 #include <pam.hxx> // Spelling: Multiselektion
80 #include <crsskip.hxx>
87 #include <globals.hrc>
90 #include <comcore.hrc> // STR_MULT_INTERACT_SPELL_WARN
96 #include <com/sun/star/frame/XStorable.hpp>
98 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
99 #include <com/sun/star/lang/XInitialization.hpp>
100 #include <com/sun/star/frame/XDispatch.hpp>
101 #include <com/sun/star/frame/XDispatchProvider.hpp>
102 #include <com/sun/star/frame/XFrame.hpp>
103 #include <com/sun/star/util/URL.hpp>
104 #include <com/sun/star/beans/PropertyValue.hpp>
105 #include <com/sun/star/util/XURLTransformer.hpp>
107 #include <unotools/processfactory.hxx>
109 #include <vcl/svapp.hxx>
110 #include <rtl/ustring.hxx>
112 #include <cppuhelper/bootstrap.hxx>
113 #include "stmenu.hxx" // PopupMenu for smarttags
114 #include <svx/dialogs.hrc>
118 #include <ecmaflds.hxx>
122 using namespace sw::mark
;
123 using ::rtl::OUString
;
124 using namespace ::com::sun::star
;
125 using namespace ::com::sun::star::beans
;
126 using namespace ::com::sun::star::uno
;
127 using namespace ::com::sun::star::linguistic2
;
128 using namespace ::com::sun::star::smarttags
;
130 /*--------------------------------------------------------------------
131 Beschreibung: Lingu-Dispatcher
132 --------------------------------------------------------------------*/
135 void SwView::ExecLingu(SfxRequest
&rReq
)
137 switch(rReq
.GetSlot())
139 case FN_THESAURUS_DLG
:
143 case SID_HANGUL_HANJA_CONVERSION
:
144 StartTextConversion( LANGUAGE_KOREAN
, LANGUAGE_KOREAN
, NULL
,
145 i18n::TextConversionOption::CHARACTER_BY_CHARACTER
, sal_True
);
147 case SID_CHINESE_CONVERSION
:
149 //open ChineseTranslationDialog
150 Reference
< XComponentContext
> xContext(
151 ::cppu::defaultBootstrap_InitialComponentContext() ); //@todo get context from calc if that has one
154 Reference
< lang::XMultiComponentFactory
> xMCF( xContext
->getServiceManager() );
157 Reference
< ui::dialogs::XExecutableDialog
> xDialog(
158 xMCF
->createInstanceWithContext(
159 rtl::OUString::createFromAscii("com.sun.star.linguistic2.ChineseTranslationDialog")
160 , xContext
), UNO_QUERY
);
161 Reference
< lang::XInitialization
> xInit( xDialog
, UNO_QUERY
);
165 Reference
< awt::XWindow
> xDialogParentWindow(0);
166 Sequence
<Any
> aSeq(1);
167 Any
* pArray
= aSeq
.getArray();
168 PropertyValue aParam
;
169 aParam
.Name
= rtl::OUString::createFromAscii("ParentWindow");
170 aParam
.Value
<<= makeAny(xDialogParentWindow
);
171 pArray
[0] <<= makeAny(aParam
);
172 xInit
->initialize( aSeq
);
175 sal_Int16 nDialogRet
= xDialog
->execute();
176 if( RET_OK
== nDialogRet
)
178 //get some parameters from the dialog
179 sal_Bool bToSimplified
= sal_True
;
180 sal_Bool bUseVariants
= sal_True
;
181 sal_Bool bCommonTerms
= sal_True
;
182 Reference
< beans::XPropertySet
> xProp( xDialog
, UNO_QUERY
);
187 xProp
->getPropertyValue( C2U("IsDirectionToSimplified") ) >>= bToSimplified
;
188 xProp
->getPropertyValue( C2U("IsUseCharacterVariants") ) >>= bUseVariants
;
189 xProp
->getPropertyValue( C2U("IsTranslateCommonTerms") ) >>= bCommonTerms
;
196 //execute translation
197 sal_Int16 nSourceLang
= bToSimplified
? LANGUAGE_CHINESE_TRADITIONAL
: LANGUAGE_CHINESE_SIMPLIFIED
;
198 sal_Int16 nTargetLang
= bToSimplified
? LANGUAGE_CHINESE_SIMPLIFIED
: LANGUAGE_CHINESE_TRADITIONAL
;
199 sal_Int32 nOptions
= bUseVariants
? i18n::TextConversionOption::USE_CHARACTER_VARIANTS
: 0;
201 nOptions
= nOptions
| i18n::TextConversionOption::CHARACTER_BY_CHARACTER
;
203 Font aTargetFont
= GetEditWin().GetDefaultFont( DEFAULTFONT_CJK_TEXT
,
204 nTargetLang
, DEFAULTFONT_FLAGS_ONLYONE
);
206 // disallow formatting, updating the view, ... while
207 // converting the document. (saves time)
208 // Also remember the current view and cursor position for later
209 pWrtShell
->StartAction();
211 // remember cursor position data for later restoration of the cursor
212 const SwPosition
*pPoint
= pWrtShell
->GetCrsr()->GetPoint();
213 sal_Bool bRestoreCursor
= pPoint
->nNode
.GetNode().IsTxtNode();
214 const SwNodeIndex
aPointNodeIndex( pPoint
->nNode
);
215 xub_StrLen nPointIndex
= pPoint
->nContent
.GetIndex();;
217 // since this conversion is not interactive the whole converted
218 // document should be undone in a single undo step.
219 pWrtShell
->StartUndo( UNDO_OVERWRITE
);
221 StartTextConversion( nSourceLang
, nTargetLang
, &aTargetFont
, nOptions
, sal_False
);
223 pWrtShell
->EndUndo( UNDO_OVERWRITE
);
227 SwTxtNode
*pTxtNode
= aPointNodeIndex
.GetNode().GetTxtNode();
228 // check for unexpected error case
229 DBG_ASSERT( pTxtNode
&& pTxtNode
->GetTxt().Len() >= nPointIndex
,
230 "text missing: corrupted node?" );
231 if (!pTxtNode
|| pTxtNode
->GetTxt().Len() < nPointIndex
)
233 // restore cursor to its original position
234 pWrtShell
->GetCrsr()->GetPoint()->nContent
.Assign( pTxtNode
, nPointIndex
);
237 // enable all, restore view and cursor position
238 pWrtShell
->EndAction();
241 Reference
< lang::XComponent
> xComponent( xDialog
, UNO_QUERY
);
242 if( xComponent
.is() )
243 xComponent
->dispose();
248 case FN_HYPHENATE_OPT_DLG
:
252 ASSERT(!this, falscher Dispatcher
);
257 /*--------------------------------------------------------------------
258 Description: start language specific text conversion
259 --------------------------------------------------------------------*/
261 void SwView::StartTextConversion(
262 LanguageType nSourceLang
,
263 LanguageType nTargetLang
,
264 const Font
*pTargetFont
,
266 sal_Bool bIsInteractive
)
268 // do not do text conversion if it is active elsewhere
269 if (GetWrtShell().HasConvIter())
271 // MessBox( 0, WB_OK, String( SW_RES( STR_SPELL_TITLE ) ),
272 // String( SW_RES( STR_MULT_INTERACT_SPELL_WARN ) ) ).Execute();
276 SfxErrorContext aContext( ERRCTX_SVX_LINGU_SPELLING, aEmptyStr, pEditWin,
277 RID_SVXERRCTX, DIALOG_MGR() );
279 Reference< XSpellChecker1 > xSpell = ::GetSpellChecker();
281 { // keine Arme keine Kekse
282 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS );
286 SpellKontext(sal_True
);
288 SwViewOption
* pVOpt
= (SwViewOption
*)pWrtShell
->GetViewOptions();
289 sal_Bool bOldIdle
= pVOpt
->IsIdle();
290 pVOpt
->SetIdle( sal_False
);
292 sal_Bool bOldIns
= pWrtShell
->IsInsMode();
293 pWrtShell
->SetInsMode( sal_True
);
297 sal_Bool bSelection
= ((SwCrsrShell
*)pWrtShell
)->HasSelection() ||
298 pWrtShell
->GetCrsr() != pWrtShell
->GetCrsr()->GetNext();
300 // sal_Bool bIsSpellSpecial = sal_True;
302 sal_Bool bStart
= bSelection
|| pWrtShell
->IsStartOfDoc();
303 sal_Bool bOther
= !bSelection
&& !(pWrtShell
->GetFrmType(0,sal_True
) & FRMTYPE_BODY
);
306 if( bOther && !bIsSpellSpecial )
307 // kein Sonderbereich eingeschaltet
309 // Ich will auch in Sonderbereichen trennen
310 QueryBox aBox( &GetEditWin(), SW_RES( DLG_SPECIAL_FORCED ) );
311 if( aBox.Execute() == RET_YES && xProp.is())
313 sal_Bool bTrue = sal_True;
314 Any aTmp(&bTrue, ::getBooleanCppuType());
315 xProp->setPropertyValue( C2U(UPN_IS_SPELL_SPECIAL), aTmp );
318 return; // Nein Es wird nicht gespellt
322 const uno::Reference
< lang::XMultiServiceFactory
> xMgr(
323 comphelper::getProcessServiceFactory() );
324 SwHHCWrapper
aWrap( this, xMgr
, nSourceLang
, nTargetLang
, pTargetFont
,
325 nOptions
, bIsInteractive
,
326 bStart
, bOther
, bSelection
);
331 pWrtShell
->SetInsMode( bOldIns
);
332 pVOpt
->SetIdle( bOldIdle
);
333 SpellKontext(sal_False
);
336 /*--------------------------------------------------------------------
337 spellcheck and text conversion related stuff
338 --------------------------------------------------------------------*/
340 void SwView::SpellStart( SvxSpellArea eWhich
,
341 sal_Bool bStartDone
, sal_Bool bEndDone
,
342 SwConversionArgs
*pConvArgs
)
344 Reference
< beans::XPropertySet
> xProp( ::GetLinguPropertySet() );
345 sal_Bool bIsWrapReverse
= (!pConvArgs
&& xProp
.is()) ?
346 *(sal_Bool
*)xProp
->getPropertyValue( C2U(UPN_IS_WRAP_REVERSE
) ).getValue() : sal_False
;
348 SwDocPositions eStart
= DOCPOS_START
;
349 SwDocPositions eEnde
= DOCPOS_END
;
350 SwDocPositions eCurr
= DOCPOS_CURR
;
357 eCurr
= DOCPOS_START
;
359 case SVX_SPELL_BODY_END
:
363 eStart
= DOCPOS_CURR
;
366 else if( bStartDone
)
367 eCurr
= DOCPOS_START
;
369 case SVX_SPELL_BODY_START
:
370 if( !bIsWrapReverse
)
374 eCurr
= DOCPOS_START
;
379 case SVX_SPELL_OTHER
:
382 eStart
= DOCPOS_OTHERSTART
;
383 eEnde
= DOCPOS_OTHEREND
;
384 eCurr
= DOCPOS_OTHEREND
;
388 eStart
= DOCPOS_OTHERSTART
;
389 eEnde
= DOCPOS_OTHEREND
;
390 eCurr
= DOCPOS_OTHERSTART
;
394 ASSERT( !this, "SpellStart with unknown Area" );
396 pWrtShell
->SpellStart( eStart
, eEnde
, eCurr
, pConvArgs
);
399 /*--------------------------------------------------------------------
400 Beschreibung: Fehlermeldung beim Spelling
401 --------------------------------------------------------------------*/
404 // Der uebergebene Pointer nLang ist selbst der Wert
405 IMPL_LINK( SwView
, SpellError
, LanguageType
*, pLang
)
407 #if OSL_DEBUG_LEVEL > 1
408 sal_Bool bFocus
= GetEditWin().HasFocus();
410 sal_uInt16 nPend
= 0;
412 if ( pWrtShell
->ActionPend() )
415 pWrtShell
->ClearMark();
418 pWrtShell
->EndAction();
421 while( pWrtShell
->ActionPend() );
423 LanguageType eLang
= pLang
? *pLang
: LANGUAGE_NONE
;
424 String
aErr(::GetLanguageString( eLang
) );
426 SwEditWin
&rEditWin
= GetEditWin();
427 #if OSL_DEBUG_LEVEL > 1
428 bFocus
= rEditWin
.HasFocus();
430 sal_uInt16 nWaitCnt
= 0;
431 while( rEditWin
.IsWait() )
433 rEditWin
.LeaveWait();
436 if ( LANGUAGE_NONE
== eLang
)
437 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_NOLANGUAGE
);
439 ErrorHandler::HandleError( *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS
, aErr
) );
443 rEditWin
.EnterWait();
446 #if OSL_DEBUG_LEVEL > 1
447 bFocus
= GetEditWin().HasFocus();
453 pWrtShell
->StartAction();
454 pWrtShell
->Combine();
456 #if OSL_DEBUG_LEVEL > 1
458 GetEditWin().GrabFocus();
464 /*--------------------------------------------------------------------
465 Beschreibung: Spelling beenden und Cursor wiederherstellen
466 --------------------------------------------------------------------*/
469 void SwView::SpellEnd( SwConversionArgs
*pConvArgs
)
471 pWrtShell
->SpellEnd( pConvArgs
);
472 if( pWrtShell
->IsExtMode() )
473 pWrtShell
->SetMark();
477 void SwView::HyphStart( SvxSpellArea eWhich
)
482 pWrtShell
->HyphStart( DOCPOS_START
, DOCPOS_END
);
484 case SVX_SPELL_BODY_END
:
485 pWrtShell
->HyphStart( DOCPOS_CURR
, DOCPOS_END
);
487 case SVX_SPELL_BODY_START
:
488 pWrtShell
->HyphStart( DOCPOS_START
, DOCPOS_CURR
);
490 case SVX_SPELL_OTHER
:
491 pWrtShell
->HyphStart( DOCPOS_OTHERSTART
, DOCPOS_OTHEREND
);
494 ASSERT( !this, "HyphStart with unknown Area" );
498 /*--------------------------------------------------------------------
499 Beschreibung: Interaktive Trennung
500 --------------------------------------------------------------------*/
503 void SwView::HyphenateDocument()
505 // do not hyphenate if interactive hyphenationg is active elsewhere
506 if (GetWrtShell().HasHyphIter())
508 MessBox( 0, WB_OK
, String( SW_RES( STR_HYPH_TITLE
) ),
509 String( SW_RES( STR_MULT_INTERACT_HYPH_WARN
) ) ).Execute();
513 SfxErrorContext
aContext( ERRCTX_SVX_LINGU_HYPHENATION
, aEmptyStr
, pEditWin
,
514 RID_SVXERRCTX
, &DIALOG_MGR() );
516 Reference
< XHyphenator
> xHyph( ::GetHyphenator() );
519 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS
);
523 if (pWrtShell
->GetSelectionType() & (nsSelectionType::SEL_DRW_TXT
|nsSelectionType::SEL_DRW
))
525 // Silbentrennung in einem Draw-Objekt
530 SwViewOption
* pVOpt
= (SwViewOption
*)pWrtShell
->GetViewOptions();
531 sal_Bool bOldIdle
= pVOpt
->IsIdle();
532 pVOpt
->SetIdle( sal_False
);
534 Reference
< beans::XPropertySet
> xProp( ::GetLinguPropertySet() );
537 pWrtShell
->StartUndo(UNDO_INSATTR
); // spaeter gueltig
539 sal_Bool bHyphSpecial
= xProp
.is() ?
540 *(sal_Bool
*)xProp
->getPropertyValue( C2U(UPN_IS_HYPH_SPECIAL
) ).getValue() : sal_False
;
541 sal_Bool bSelection
= ((SwCrsrShell
*)pWrtShell
)->HasSelection() ||
542 pWrtShell
->GetCrsr() != pWrtShell
->GetCrsr()->GetNext();
543 sal_Bool bOther
= pWrtShell
->HasOtherCnt() && bHyphSpecial
&& !bSelection
;
544 sal_Bool bStart
= bSelection
|| ( !bOther
&& pWrtShell
->IsStartOfDoc() );
545 sal_Bool bStop
= sal_False
;
546 if( !bOther
&& !(pWrtShell
->GetFrmType(0,sal_True
) & FRMTYPE_BODY
) && !bSelection
)
547 // kein Sonderbereich eingeschaltet
549 // Ich will auch in Sonderbereichen trennen
550 QueryBox
aBox( &GetEditWin(), SW_RES( DLG_SPECIAL_FORCED
) );
551 if( aBox
.Execute() == RET_YES
)
556 sal_Bool bTrue
= sal_True
;
557 Any
aTmp(&bTrue
, ::getBooleanCppuType());
558 xProp
->setPropertyValue( C2U(UPN_IS_HYPH_SPECIAL
), aTmp
);
562 bStop
= sal_True
; // Nein Es wird nicht getrennt
567 SwHyphWrapper
aWrap( this, xHyph
, bStart
, bOther
, bSelection
);
568 aWrap
.SpellDocument();
569 pWrtShell
->EndUndo(UNDO_INSATTR
);
571 pVOpt
->SetIdle( bOldIdle
);
575 /*--------------------------------------------------------------------
576 Beschreibung: Thesaurus starten
577 --------------------------------------------------------------------*/
580 void SwView::StartThesaurus()
582 if( pWrtShell
->GetCrsr() != pWrtShell
->GetCrsr()->GetNext() )
584 sal_Bool bSelection
= ((SwCrsrShell
*)pWrtShell
)->HasSelection();
585 if( bSelection
&& !pWrtShell
->IsSelOnePara() )
588 SfxErrorContext
aContext( ERRCTX_SVX_LINGU_THESAURUS
, aEmptyStr
, pEditWin
,
589 RID_SVXERRCTX
, &DIALOG_MGR() );
593 LanguageType eLang
= pWrtShell
->GetCurLang();
594 if( LANGUAGE_SYSTEM
== eLang
)
595 eLang
= GetAppLanguage();
597 if( eLang
== LANGUAGE_DONTKNOW
|| eLang
== LANGUAGE_NONE
)
599 LanguageType nLanguage
= LANGUAGE_NONE
;
600 SpellError( &nLanguage
);
604 SwViewOption
* pVOpt
= (SwViewOption
*)pWrtShell
->GetViewOptions();
605 sal_Bool bOldIdle
= pVOpt
->IsIdle();
606 pVOpt
->SetIdle( sal_False
);
609 //!!! hier mu� noch was getan werden... (Umsetzung der Funktionalitaet)
610 // ErrorLink setzen, alten merken
611 Link aOldLnk
= pSpell
->ChgErrorLink(LINK(this, SwView
, SpellError
));
615 // get initial LookUp text
616 String aTmp
= bSelection
?
617 pWrtShell
->GetSelTxt() : pWrtShell
->GetCurWord();
619 Reference
< XThesaurus
> xThes( ::GetThesaurus() );
620 SvxThesaurusDialog
*pDlg
= NULL
;
622 if ( !xThes
.is() || !xThes
->hasLocale( SvxCreateLocale( eLang
) ) )
624 SpellError( &eLang
);
629 { //Scope for SwWait-Object
630 SwWait
aWait( *GetDocShell(), sal_True
);
631 pDlg
= new SvxThesaurusDialog( &GetEditWin(),
632 xThes
, aTmp
, eLang
);
636 // Hier wird der Thesaurus-Dialog im Applikationsfenster zentriert,
637 // und zwar oberhalb oder unterhalb der Cursorposition, je nachdem,
638 // wo mehr Platz ist.
641 SwRect
aRect( pWrtShell
->GetCharRect() );
642 Point aTopPos
= aRect
.Pos();
643 Point
aBtmPos( aTopPos
.X(), aRect
.Bottom() );
644 aTopPos
= GetEditWin().LogicToPixel( aTopPos
);
645 aTopPos
= GetEditWin().OutputToScreenPixel( aTopPos
);
646 aBtmPos
= GetEditWin().LogicToPixel( aBtmPos
);
647 aBtmPos
= GetEditWin().OutputToScreenPixel( aBtmPos
);
649 Rectangle aRct
= GetEditWin().GetDesktopRectPixel();
650 Point
aWinTop( aRct
.TopLeft() );
651 Point
aWinBtm( aRct
.BottomRight() );
652 if ( aTopPos
.Y() - aWinTop
.Y() > aWinBtm
.Y() - aBtmPos
.Y() )
653 aWinBtm
.Y() = aTopPos
.Y();
655 aWinTop
.Y() = aBtmPos
.Y();
657 Size aSz
= pDlg
->GetSizePixel();
658 if ( aWinBtm
.Y() - aWinTop
.Y() > aSz
.Height() )
660 aWinTop
.X() = ( aWinTop
.X() + aWinBtm
.X() - aSz
.Width() ) / 2;
661 aWinTop
.Y() = ( aWinTop
.Y() + aWinBtm
.Y() - aSz
.Height() ) / 2;
662 pDlg
->SetPosPixel( aWinTop
);
666 if ( pDlg
->Execute()== RET_OK
)
668 sal_Bool bOldIns
= pWrtShell
->IsInsMode();
669 pWrtShell
->SetInsMode( sal_True
);
671 pWrtShell
->StartAllAction();
672 pWrtShell
->StartUndo(UNDO_DELETE
);
676 if(pWrtShell
->IsEndWrd())
677 pWrtShell
->Left(CRSR_SKIP_CELLS
, FALSE
, 1, FALSE
);
681 // make sure the selection build later from the
682 // data below does not include footnotes and other
683 // "in word" character to the left and right in order
684 // to preserve those. Therefore count those "in words"
685 // in order to modify the selection accordingly.
686 const sal_Unicode
* pChar
= aTmp
.GetBuffer();
687 xub_StrLen nLeft
= 0;
688 while (pChar
&& *pChar
++ == CH_TXTATR_INWORD
)
690 pChar
= aTmp
.Len() ? aTmp
.GetBuffer() + aTmp
.Len() - 1 : 0;
691 xub_StrLen nRight
= 0;
692 while (pChar
&& *pChar
-- == CH_TXTATR_INWORD
)
695 // adjust existing selection
696 SwPaM
*pCrsr
= pWrtShell
->GetCrsr();
697 pCrsr
->GetPoint()->nContent
/*.nIndex*/ -= nRight
;
698 pCrsr
->GetMark()->nContent
/*.nIndex*/ += nLeft
;
701 pWrtShell
->Insert( pDlg
->GetWord() );
703 pWrtShell
->EndUndo(UNDO_DELETE
);
704 pWrtShell
->EndAllAction();
706 pWrtShell
->SetInsMode( bOldIns
);
713 pVOpt
->SetIdle( bOldIdle
);
717 /*--------------------------------------------------------------------
718 Beschreibung: Online-Vorschlaege anbieten
719 *--------------------------------------------------------------------*/
721 //!! Start of extra code for context menu modifying extensions
724 uno::Reference
< frame::XDispatch
> xDispatch
;
725 util::URL aTargetURL
;
726 uno::Sequence
< PropertyValue
> aArgs
;
732 DECL_STATIC_LINK( AsyncExecute
, ExecuteHdl_Impl
, ExecuteInfo
* );
735 IMPL_STATIC_LINK_NOINSTANCE( AsyncExecute
, ExecuteHdl_Impl
, ExecuteInfo
*, pExecuteInfo
)
737 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
740 // Asynchronous execution as this can lead to our own destruction!
741 // Framework can recycle our current frame and the layout manager disposes all user interface
742 // elements if a component gets detached from its frame!
743 pExecuteInfo
->xDispatch
->dispatch( pExecuteInfo
->aTargetURL
, pExecuteInfo
->aArgs
);
749 Application::AcquireSolarMutex( nRef
);
753 //!! End of extra code for context menu modifying extensions
755 sal_Bool
SwView::ExecSpellPopup(const Point
& rPt
)
757 sal_Bool bRet
= sal_False
;
758 const SwViewOption
* pVOpt
= pWrtShell
->GetViewOptions();
759 if( pVOpt
->IsOnlineSpell() &&
760 !pWrtShell
->IsSelection())
762 if (pWrtShell
->GetSelectionType() & nsSelectionType::SEL_DRW_TXT
)
763 bRet
= ExecDrwTxtSpellPopup(rPt
);
764 else if (!pWrtShell
->IsSelFrmMode())
766 const sal_Bool bOldViewLock
= pWrtShell
->IsViewLocked();
767 pWrtShell
->LockView( sal_True
);
771 // decide which variant of the context menu to use...
772 // if neither spell checking nor grammar checking provides suggestions use the
773 // default context menu.
774 bool bUseGrammarContext
= false;
775 Reference
< XSpellAlternatives
> xAlt( pWrtShell
->GetCorrection(&rPt
, aToFill
) );
776 /*linguistic2::*/ProofreadingResult aGrammarCheckRes
;
777 sal_Int32 nErrorPosInText
= -1;
778 sal_Int32 nErrorInResult
= -1;
779 uno::Sequence
< rtl::OUString
> aSuggestions
;
780 bool bCorrectionRes
= false;
781 if (!xAlt
.is() || xAlt
->getAlternatives().getLength() == 0)
783 bCorrectionRes
= pWrtShell
->GetGrammarCorrection( aGrammarCheckRes
, nErrorPosInText
, nErrorInResult
, aSuggestions
, &rPt
, aToFill
);
784 ::rtl::OUString aMessageText
;
785 if (nErrorInResult
>= 0)
786 aMessageText
= aGrammarCheckRes
.aErrors
[ nErrorInResult
].aShortComment
;
787 // we like to use the grammar checking context menu if we either get
788 // some suggestions or at least a comment about the error found...
789 bUseGrammarContext
= bCorrectionRes
&&
790 (aSuggestions
.getLength() > 0 || aMessageText
.getLength() > 0);
793 // open respective context menu for spell check or grammar errors with correction suggestions...
794 if ((!bUseGrammarContext
&& xAlt
.is()) ||
795 (bUseGrammarContext
&& bCorrectionRes
&& aGrammarCheckRes
.aErrors
.getLength() > 0))
797 // get paragraph text
799 SwPosition
aPoint( *pWrtShell
->GetCrsr()->GetPoint() );
800 const SwTxtNode
*pNode
= dynamic_cast< const SwTxtNode
* >(
801 &aPoint
.nNode
.GetNode() );
803 aParaText
= pNode
->GetTxt(); // this may include hidden text but that should be Ok
806 DBG_ERROR( "text node expected but not found" );
810 pWrtShell
->SttSelect();
811 std::auto_ptr
< SwSpellPopup
> pPopup
;
812 if (bUseGrammarContext
)
814 sal_Int32 nPos
= aPoint
.nContent
.GetIndex();
816 pPopup
= std::auto_ptr
< SwSpellPopup
>(new SwSpellPopup( pWrtShell
, aGrammarCheckRes
, nErrorInResult
, aSuggestions
, aParaText
));
819 pPopup
= std::auto_ptr
< SwSpellPopup
>(new SwSpellPopup( pWrtShell
, xAlt
, aParaText
));
820 ui::ContextMenuExecuteEvent aEvent
;
821 const Point aPixPos
= GetEditWin().LogicToPixel( rPt
);
823 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( pEditWin
);
824 aEvent
.ExecutePosition
.X
= aPixPos
.X();
825 aEvent
.ExecutePosition
.Y
= aPixPos
.Y();
828 ::rtl::OUString sMenuName
= ::rtl::OUString::createFromAscii(
829 bUseGrammarContext
? "private:resource/GrammarContextMenu" : "private:resource/SpellContextMenu");
830 if(TryContextMenuInterception( *pPopup
, sMenuName
, pMenu
, aEvent
))
833 //! happy hacking for context menu modifying extensions of this
834 //! 'custom made' menu... *sigh* (code copied from sfx2 and framework)
837 OUString
aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
838 USHORT nId
= ((PopupMenu
*)pMenu
)->Execute(pEditWin
, aPixPos
);
839 OUString aCommand
= ((PopupMenu
*)pMenu
)->GetItemCommand(nId
);
840 if (aCommand
.getLength() == 0 )
842 if(!ExecuteMenuCommand( *dynamic_cast<PopupMenu
*>(pMenu
), *GetViewFrame(), nId
))
843 pPopup
->Execute(nId
);
847 SfxViewFrame
*pSfxViewFrame
= GetViewFrame();
848 SfxFrame
*pSfxFrame
= pSfxViewFrame
? pSfxViewFrame
->GetFrame() : 0;
849 uno::Reference
< frame::XFrame
> xFrame
;
851 xFrame
= pSfxFrame
->GetFrameInterface();
852 com::sun::star::util::URL aURL
;
853 uno::Reference
< frame::XDispatchProvider
> xDispatchProvider( xFrame
, UNO_QUERY
);
854 uno::Reference
< lang::XMultiServiceFactory
> xMgr( utl::getProcessServiceFactory(), uno::UNO_QUERY
);
858 uno::Reference
< frame::XDispatch
> xDispatch
;
859 uno::Reference
< util::XURLTransformer
> xURLTransformer
;
862 xURLTransformer
= uno::Reference
< util::XURLTransformer
>( xMgr
->createInstance(
863 C2U("com.sun.star.util.URLTransformer")), UNO_QUERY
);
866 aURL
.Complete
= aCommand
;
867 xURLTransformer
->parseStrict(aURL
);
868 uno::Sequence
< beans::PropertyValue
> aArgs
;
869 xDispatch
= xDispatchProvider
->queryDispatch( aURL
, rtl::OUString(), 0 );
874 // Execute dispatch asynchronously
875 ExecuteInfo
* pExecuteInfo
= new ExecuteInfo
;
876 pExecuteInfo
->xDispatch
= xDispatch
;
877 pExecuteInfo
->aTargetURL
= aURL
;
878 pExecuteInfo
->aArgs
= aArgs
;
879 Application::PostUserEvent( STATIC_LINK(0, AsyncExecute
, ExecuteHdl_Impl
), pExecuteInfo
);
889 pPopup
->Execute( aToFill
.SVRect(), pEditWin
);
894 pWrtShell
->Pop( sal_False
);
895 pWrtShell
->LockView( bOldViewLock
);
901 /** Function: ExecSmartTagPopup
903 This function shows the popup menu for smarttag
907 sal_Bool
SwView::ExecSmartTagPopup( const Point
& rPt
)
909 sal_Bool bRet
= sal_False
;
910 const sal_Bool bOldViewLock
= pWrtShell
->IsViewLocked();
911 pWrtShell
->LockView( sal_True
);
915 // get word that was clicked on
916 // This data structure maps a smart tag type string to the property bag
918 Sequence
< rtl::OUString
> aSmartTagTypes
;
919 Sequence
< Reference
< container::XStringKeyMap
> > aStringKeyMaps
;
920 Reference
<text::XTextRange
> xRange
;
922 pWrtShell
->GetSmartTagTerm( rPt
, aToFill
, aSmartTagTypes
, aStringKeyMaps
, xRange
);
923 if ( xRange
.is() && aSmartTagTypes
.getLength() )
926 pWrtShell
->SttSelect();
927 SwSmartTagPopup
aPopup( this, aSmartTagTypes
, aStringKeyMaps
, xRange
);
928 aPopup
.Execute( aToFill
.SVRect(), pEditWin
);
931 pWrtShell
->Pop( sal_False
);
932 pWrtShell
->LockView( bOldViewLock
);
939 class SwFieldPopup
: public PopupMenu
943 InsertItem(1, ::rtl::OUString::createFromAscii("Hello"));
947 class SwFieldListBox
: public ListBox
950 SwFieldListBox(Window
* pParent
) : ListBox(pParent
/*, WB_DROPDOWN*/) {
954 return NULL
; //FIXME!!!
959 virtual void LoseFocus() {
960 // printf("ListBox: lose focus!!\n");
961 ListBox::LoseFocus();
964 virtual void Select() {
965 // printf("SELECT!!! IsTravelSelect=%i\n", IsTravelSelect());
970 class SwFieldDialog
: public Dialog
973 SwFieldListBox aListBox
;
977 DECL_LINK( MyListBoxHandler
, ListBox
* );
980 SwFieldDialog(Window
* parent
, IFieldmark
*fieldBM
) : Dialog(parent
, WB_BORDER
| WB_SYSTEMWINDOW
| WB_NOSHADOW
), aListBox(this), aText(this, WB_RIGHT
| WB_READONLY
), selection(-1) {
982 assert(fieldBM
!=NULL
);
984 int items
=fieldBM
->getNumOfParams();
985 for(int i
=0;i
<items
;i
++) {
986 IFieldmark::ParamPair_t p
=fieldBM
->getParam(i
);
987 if (p
.first
.compareToAscii(ECMA_FORMDROPDOWN_LISTENTRY
)==0) {
988 aListBox
.InsertEntry(p
.second
);
992 Size lbSize
=aListBox
.GetOptimalSize(WINDOWSIZE_PREFERRED
);
995 aListBox
.SetSizePixel(lbSize
);
996 aListBox
.SetSelectHdl( LINK( this, SwFieldDialog
, MyListBoxHandler
) );
998 aText
.SetText(rtl::OUString::createFromAscii("Cancel"));
999 Size tSize
=aText
.GetOptimalSize(WINDOWSIZE_PREFERRED
);
1000 aText
.SetSizePixel(Size(lbSize
.Width(), tSize
.Height()));
1001 aText
.SetPosPixel(Point(0, lbSize
.Height()));
1003 SetSizePixel(Size(lbSize
.Width(), lbSize
.Height()+tSize
.Height()));
1004 // SetSizePixel(Size(200, 200));
1007 int getSelection() {
1012 virtual void LoseFocus() {
1013 printf("lose focus!!\n");
1014 Dialog::LoseFocus();
1020 virtual long PreNotify( NotifyEvent
& rNEvt
) {
1021 if (rNEvt
.GetType() == EVENT_LOSEFOCUS
&& aListBox
.GetImplWin()==rNEvt
.GetWindow()) {
1025 if (rNEvt
.GetType() == EVENT_KEYINPUT
) {
1026 // printf("PreNotify::KEYINPUT\n");
1028 return Dialog::PreNotify(rNEvt
);
1032 IMPL_LINK( SwFieldDialog
, MyListBoxHandler
, ListBox
*, pBox
)
1034 // printf("### DROP DOWN SELECT... IsTravelSelect=%i\n", pBox->IsTravelSelect());
1035 if (pBox
->IsTravelSelect()) {
1038 this->selection
=pBox
->GetSelectEntryPos();
1039 EndDialog(9); //@TODO have meaningfull returns...
1045 BOOL
SwView::ExecFieldPopup( const Point
& rPt
, IFieldmark
*fieldBM
)
1047 sal_Bool bRet
= sal_False
;
1048 const sal_Bool bOldViewLock
= pWrtShell
->IsViewLocked();
1049 pWrtShell
->LockView( sal_True
);
1053 const Point aPixPos
= GetEditWin().LogicToPixel( rPt
);
1055 SwFieldDialog
aFldDlg(pEditWin
, fieldBM
);
1056 aFldDlg
.SetPosPixel(pEditWin
->OutputToScreenPixel(aPixPos
));
1058 short ret
=aFldDlg
.Execute();
1059 int selection
=aFldDlg
.getSelection();
1061 fieldBM
->addParam(ECMA_FORMDROPDOWN_RESULT
, selection
);
1064 pWrtShell
->Pop( sal_False
);
1065 pWrtShell
->LockView( bOldViewLock
);