update dev300-m58
[ooovba.git] / sw / source / ui / uiview / viewling.cxx
blob39d1595c3d8ddb9822c9aa1e19af5a12a0dbef33
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewling.cxx,v $
10 * $Revision: 1.38 $
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>
37 #ifndef _SVSTDARR_HXX
38 #define _SVSTDARR_STRINGSDTOR
39 #include <svtools/svstdarr.hxx>
40 #endif
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>
61 #include <swwait.hxx>
62 #include <initui.hxx> // fuer SpellPointer
63 #include <uitool.hxx>
64 #ifndef _VIEW_HXX
65 #include <view.hxx>
66 #endif
67 #include <wrtsh.hxx>
68 #ifndef _BASESH_HXX
69 #include <basesh.hxx>
70 #endif
71 #ifndef _DOCSH_HXX
72 #include <docsh.hxx> // CheckSpellChanges
73 #endif
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
79 #include <edtwin.hxx>
80 #include <crsskip.hxx>
81 #include <ndtxt.hxx>
83 #ifndef _CMDID_H
84 #include <cmdid.h>
85 #endif
86 #ifndef _GLOBALS_HRC
87 #include <globals.hrc>
88 #endif
89 #ifndef _COMCORE_HRC
90 #include <comcore.hrc> // STR_MULT_INTERACT_SPELL_WARN
91 #endif
92 #ifndef _VIEW_HRC
93 #include <view.hrc>
94 #endif
95 #include <hhcwrp.hxx>
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>
116 #include <unomid.h>
117 #include <IMark.hxx>
118 #include <ecmaflds.hxx>
120 #include <memory>
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:
140 StartThesaurus();
141 rReq.Ignore();
142 break;
143 case SID_HANGUL_HANJA_CONVERSION:
144 StartTextConversion( LANGUAGE_KOREAN, LANGUAGE_KOREAN, NULL,
145 i18n::TextConversionOption::CHARACTER_BY_CHARACTER, sal_True );
146 break;
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
152 if(xContext.is())
154 Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
155 if(xMCF.is())
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 );
162 if( xInit.is() )
164 // initialize dialog
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 );
174 //execute dialog
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 );
183 if( xProp.is() )
187 xProp->getPropertyValue( C2U("IsDirectionToSimplified") ) >>= bToSimplified;
188 xProp->getPropertyValue( C2U("IsUseCharacterVariants") ) >>= bUseVariants;
189 xProp->getPropertyValue( C2U("IsTranslateCommonTerms") ) >>= bCommonTerms;
191 catch( Exception& )
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;
200 if( !bCommonTerms )
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 );
225 if (bRestoreCursor)
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)
232 nPointIndex = 0;
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();
246 break;
248 case FN_HYPHENATE_OPT_DLG:
249 HyphenateDocument();
250 break;
251 default:
252 ASSERT(!this, falscher Dispatcher);
253 return;
257 /*--------------------------------------------------------------------
258 Description: start language specific text conversion
259 --------------------------------------------------------------------*/
261 void SwView::StartTextConversion(
262 LanguageType nSourceLang,
263 LanguageType nTargetLang,
264 const Font *pTargetFont,
265 sal_Int32 nOptions,
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();
273 return;
276 SfxErrorContext aContext( ERRCTX_SVX_LINGU_SPELLING, aEmptyStr, pEditWin,
277 RID_SVXERRCTX, DIALOG_MGR() );
279 Reference< XSpellChecker1 > xSpell = ::GetSpellChecker();
280 if(!xSpell.is())
281 { // keine Arme keine Kekse
282 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS );
283 return;
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 );
317 else
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 );
327 aWrap.Convert();
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;
351 switch ( eWhich )
353 case SVX_SPELL_BODY:
354 if( bIsWrapReverse )
355 eCurr = DOCPOS_END;
356 else
357 eCurr = DOCPOS_START;
358 break;
359 case SVX_SPELL_BODY_END:
360 if( bIsWrapReverse )
362 if( bStartDone )
363 eStart = DOCPOS_CURR;
364 eCurr = DOCPOS_END;
366 else if( bStartDone )
367 eCurr = DOCPOS_START;
368 break;
369 case SVX_SPELL_BODY_START:
370 if( !bIsWrapReverse )
372 if( bEndDone )
373 eEnde = DOCPOS_CURR;
374 eCurr = DOCPOS_START;
376 else if( bEndDone )
377 eCurr = DOCPOS_END;
378 break;
379 case SVX_SPELL_OTHER:
380 if( bIsWrapReverse )
382 eStart = DOCPOS_OTHERSTART;
383 eEnde = DOCPOS_OTHEREND;
384 eCurr = DOCPOS_OTHEREND;
386 else
388 eStart = DOCPOS_OTHERSTART;
389 eEnde = DOCPOS_OTHEREND;
390 eCurr = DOCPOS_OTHERSTART;
392 break;
393 default:
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();
409 #endif
410 sal_uInt16 nPend = 0;
412 if ( pWrtShell->ActionPend() )
414 pWrtShell->Push();
415 pWrtShell->ClearMark();
418 pWrtShell->EndAction();
419 ++nPend;
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();
429 #endif
430 sal_uInt16 nWaitCnt = 0;
431 while( rEditWin.IsWait() )
433 rEditWin.LeaveWait();
434 ++nWaitCnt;
436 if ( LANGUAGE_NONE == eLang )
437 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_NOLANGUAGE );
438 else
439 ErrorHandler::HandleError( *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
441 while( nWaitCnt )
443 rEditWin.EnterWait();
444 --nWaitCnt;
446 #if OSL_DEBUG_LEVEL > 1
447 bFocus = GetEditWin().HasFocus();
448 #endif
450 if ( nPend )
452 while( nPend-- )
453 pWrtShell->StartAction();
454 pWrtShell->Combine();
456 #if OSL_DEBUG_LEVEL > 1
457 if( !bFocus )
458 GetEditWin().GrabFocus();
459 #endif
461 return 0;
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 )
479 switch ( eWhich )
481 case SVX_SPELL_BODY:
482 pWrtShell->HyphStart( DOCPOS_START, DOCPOS_END );
483 break;
484 case SVX_SPELL_BODY_END:
485 pWrtShell->HyphStart( DOCPOS_CURR, DOCPOS_END );
486 break;
487 case SVX_SPELL_BODY_START:
488 pWrtShell->HyphStart( DOCPOS_START, DOCPOS_CURR );
489 break;
490 case SVX_SPELL_OTHER:
491 pWrtShell->HyphStart( DOCPOS_OTHERSTART, DOCPOS_OTHEREND );
492 break;
493 default:
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();
510 return;
513 SfxErrorContext aContext( ERRCTX_SVX_LINGU_HYPHENATION, aEmptyStr, pEditWin,
514 RID_SVXERRCTX, &DIALOG_MGR() );
516 Reference< XHyphenator > xHyph( ::GetHyphenator() );
517 if (!xHyph.is())
519 ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS );
520 return;
523 if (pWrtShell->GetSelectionType() & (nsSelectionType::SEL_DRW_TXT|nsSelectionType::SEL_DRW))
525 // Silbentrennung in einem Draw-Objekt
526 HyphenateDrawText();
528 else
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 )
553 bOther = sal_True;
554 if (xProp.is())
556 sal_Bool bTrue = sal_True;
557 Any aTmp(&bTrue, ::getBooleanCppuType());
558 xProp->setPropertyValue( C2U(UPN_IS_HYPH_SPECIAL), aTmp );
561 else
562 bStop = sal_True; // Nein Es wird nicht getrennt
565 if( !bStop )
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() )
583 return;
584 sal_Bool bSelection = ((SwCrsrShell*)pWrtShell)->HasSelection();
585 if( bSelection && !pWrtShell->IsSelOnePara() )
586 return;
588 SfxErrorContext aContext( ERRCTX_SVX_LINGU_THESAURUS, aEmptyStr, pEditWin,
589 RID_SVXERRCTX, &DIALOG_MGR() );
591 // Sprache rausholen
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 );
601 return;
604 SwViewOption* pVOpt = (SwViewOption*)pWrtShell->GetViewOptions();
605 sal_Bool bOldIdle = pVOpt->IsIdle();
606 pVOpt->SetIdle( sal_False );
608 #ifdef TL_NEVER
609 //!!! hier mu� noch was getan werden... (Umsetzung der Funktionalitaet)
610 // ErrorLink setzen, alten merken
611 Link aOldLnk = pSpell->ChgErrorLink(LINK(this, SwView, SpellError));
612 #endif
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 );
626 else
628 // create dialog
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.
640 // Current Word:
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 );
648 // ::frame::Desktop:
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();
654 else
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);
674 if( !bSelection )
676 if(pWrtShell->IsEndWrd())
677 pWrtShell->Left(CRSR_SKIP_CELLS, FALSE, 1, FALSE );
679 pWrtShell->SelWrd();
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)
689 ++nLeft;
690 pChar = aTmp.Len() ? aTmp.GetBuffer() + aTmp.Len() - 1 : 0;
691 xub_StrLen nRight = 0;
692 while (pChar && *pChar-- == CH_TXTATR_INWORD)
693 ++nRight;
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 );
711 delete pDlg;
713 pVOpt->SetIdle( bOldIdle );
717 /*--------------------------------------------------------------------
718 Beschreibung: Online-Vorschlaege anbieten
719 *--------------------------------------------------------------------*/
721 //!! Start of extra code for context menu modifying extensions
722 struct ExecuteInfo
724 uno::Reference< frame::XDispatch > xDispatch;
725 util::URL aTargetURL;
726 uno::Sequence< PropertyValue > aArgs;
729 class AsyncExecute
731 public:
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 );
745 catch ( Exception& )
749 Application::AcquireSolarMutex( nRef );
750 delete pExecuteInfo;
751 return 0;
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 );
768 pWrtShell->Push();
769 SwRect aToFill;
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
798 String aParaText;
799 SwPosition aPoint( *pWrtShell->GetCrsr()->GetPoint() );
800 const SwTxtNode *pNode = dynamic_cast< const SwTxtNode * >(
801 &aPoint.nNode.GetNode() );
802 if (pNode)
803 aParaText = pNode->GetTxt(); // this may include hidden text but that should be Ok
804 else
806 DBG_ERROR( "text node expected but not found" );
809 bRet = sal_True;
810 pWrtShell->SttSelect();
811 std::auto_ptr< SwSpellPopup > pPopup;
812 if (bUseGrammarContext)
814 sal_Int32 nPos = aPoint.nContent.GetIndex();
815 (void) nPos;
816 pPopup = std::auto_ptr< SwSpellPopup >(new SwSpellPopup( pWrtShell, aGrammarCheckRes, nErrorInResult, aSuggestions, aParaText ));
818 else
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();
826 Menu* pMenu = 0;
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)
835 if ( pMenu )
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);
845 else
847 SfxViewFrame *pSfxViewFrame = GetViewFrame();
848 SfxFrame *pSfxFrame = pSfxViewFrame? pSfxViewFrame->GetFrame() : 0;
849 uno::Reference< frame::XFrame > xFrame;
850 if (pSfxFrame)
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;
860 if (xMgr.is())
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 );
872 if (xDispatch.is())
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 );
882 catch (Exception &)
887 else
889 pPopup->Execute( aToFill.SVRect(), pEditWin );
894 pWrtShell->Pop( sal_False );
895 pWrtShell->LockView( bOldViewLock );
898 return bRet;
901 /** Function: ExecSmartTagPopup
903 This function shows the popup menu for smarttag
904 actions.
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 );
912 pWrtShell->Push();
915 // get word that was clicked on
916 // This data structure maps a smart tag type string to the property bag
917 SwRect aToFill;
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() )
925 bRet = sal_True;
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 );
934 return bRet;
939 class SwFieldPopup : public PopupMenu
941 public:
942 SwFieldPopup() {
943 InsertItem(1, ::rtl::OUString::createFromAscii("Hello"));
947 class SwFieldListBox : public ListBox
949 public:
950 SwFieldListBox(Window* pParent) : ListBox(pParent /*, WB_DROPDOWN*/) {
953 void *GetImplWin() {
954 return NULL; //FIXME!!!
955 // return mpImplWin;
958 protected:
959 virtual void LoseFocus() {
960 // printf("ListBox: lose focus!!\n");
961 ListBox::LoseFocus();
964 virtual void Select() {
965 // printf("SELECT!!! IsTravelSelect=%i\n", IsTravelSelect());
966 ListBox::Select();
970 class SwFieldDialog : public Dialog
972 private:
973 SwFieldListBox aListBox;
974 Edit aText;
975 int selection;
977 DECL_LINK( MyListBoxHandler, ListBox * );
979 public:
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);
983 if (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);
993 lbSize.Width()+=50;
994 lbSize.Height()+=20;
995 aListBox.SetSizePixel(lbSize);
996 aListBox.SetSelectHdl( LINK( this, SwFieldDialog, MyListBoxHandler ) );
997 aListBox.Show();
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()));
1002 aText.Show();
1003 SetSizePixel(Size(lbSize.Width(), lbSize.Height()+tSize.Height()));
1004 // SetSizePixel(Size(200, 200));
1007 int getSelection() {
1008 return selection;
1010 protected:
1012 virtual void LoseFocus() {
1013 printf("lose focus!!\n");
1014 Dialog::LoseFocus();
1015 printf("close:\n");
1016 EndDialog(8);
1020 virtual long PreNotify( NotifyEvent& rNEvt ) {
1021 if (rNEvt.GetType() == EVENT_LOSEFOCUS && aListBox.GetImplWin()==rNEvt.GetWindow()) {
1022 EndDialog(8);
1023 return 1;
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()) {
1036 return 0;
1037 } else {
1038 this->selection=pBox->GetSelectEntryPos();
1039 EndDialog(9); //@TODO have meaningfull returns...
1040 return 1;
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 );
1050 pWrtShell->Push();
1052 bRet=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();
1060 if (selection>=0) {
1061 fieldBM->addParam(ECMA_FORMDROPDOWN_RESULT, selection);
1064 pWrtShell->Pop( sal_False );
1065 pWrtShell->LockView( bOldViewLock );
1067 return bRet;