xref: /AOO41X/main/sw/source/ui/uiview/viewling.cxx (revision 8ef2f12b1aeba1404ab3c221e6e26281826cc4fc)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <hintids.hxx>
29 
30 #ifndef _SVSTDARR_HXX
31 #define _SVSTDARR_STRINGSDTOR
32 #include <svl/svstdarr.hxx>
33 #endif
34 #include <com/sun/star/lang/Locale.hpp>
35 #include <com/sun/star/linguistic2/XThesaurus.hpp>
36 #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
37 #include <com/sun/star/i18n/TextConversionOption.hpp>
38 #include <linguistic/lngprops.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <svtools/ehdl.hxx>
43 #include <svl/stritem.hxx>
44 #include <sfx2/viewfrm.hxx>
45 #include <sfx2/request.hxx>
46 #include <svx/dlgutil.hxx>
47 #include <svx/dialmgr.hxx>
48 #include <editeng/langitem.hxx>
49 #include <svx/svxerr.hxx>
50 #include <editeng/unolingu.hxx>
51 #include <svx/svxdlg.hxx>
52 #include <editeng/SpellPortions.hxx>
53 #include <swmodule.hxx>
54 #include <swwait.hxx>
55 #include <initui.hxx>               // fuer SpellPointer
56 #include <uitool.hxx>
57 #include <view.hxx>
58 #include <wrtsh.hxx>
59 #include <basesh.hxx>
60 #include <docsh.hxx>                // CheckSpellChanges
61 #include <viewopt.hxx>              // Viewoptions
62 #include <swundo.hxx>               // fuer Undo-Ids
63 #include <hyp.hxx>                  // Trennung
64 #include <olmenu.hxx>               // PopupMenu fuer OnlineSpelling
65 #include <pam.hxx>                  // Spelling: Multiselektion
66 #include <edtwin.hxx>
67 #include <crsskip.hxx>
68 #include <ndtxt.hxx>
69 #include <vcl/lstbox.hxx>
70 #include <cmdid.h>
71 #include <globals.hrc>
72 #include <comcore.hrc>              // STR_MULT_INTERACT_SPELL_WARN
73 #include <view.hrc>
74 #include <hhcwrp.hxx>
75 #include <com/sun/star/frame/XStorable.hpp>
76 
77 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
78 #include <com/sun/star/lang/XInitialization.hpp>
79 #include <com/sun/star/frame/XDispatch.hpp>
80 #include <com/sun/star/frame/XDispatchProvider.hpp>
81 #include <com/sun/star/frame/XFrame.hpp>
82 #include <com/sun/star/util/URL.hpp>
83 #include <com/sun/star/beans/PropertyValue.hpp>
84 #include <com/sun/star/util/XURLTransformer.hpp>
85 
86 #include <unotools/processfactory.hxx>
87 
88 #include <vcl/svapp.hxx>
89 #include <rtl/ustring.hxx>
90 
91 #include <cppuhelper/bootstrap.hxx>
92 #include "stmenu.hxx"              // PopupMenu for smarttags
93 #include <svx/dialogs.hrc>
94 #include <svtools/langtab.hxx>
95 #include <unomid.h>
96 #include <IMark.hxx>
97 #include <xmloff/odffields.hxx>
98 
99 #include <memory>
100 #include <editeng/editerr.hxx>
101 
102 using namespace sw::mark;
103 using ::rtl::OUString;
104 using namespace ::com::sun::star;
105 using namespace ::com::sun::star::beans;
106 using namespace ::com::sun::star::uno;
107 using namespace ::com::sun::star::linguistic2;
108 using namespace ::com::sun::star::smarttags;
109 
110 /*--------------------------------------------------------------------
111     Beschreibung:   Lingu-Dispatcher
112  --------------------------------------------------------------------*/
113 
114 
ExecLingu(SfxRequest & rReq)115 void SwView::ExecLingu(SfxRequest &rReq)
116 {
117     switch(rReq.GetSlot())
118     {
119         case SID_THESAURUS:
120             StartThesaurus();
121             rReq.Ignore();
122             break;
123         case SID_HANGUL_HANJA_CONVERSION:
124             StartTextConversion( LANGUAGE_KOREAN, LANGUAGE_KOREAN, NULL,
125                     i18n::TextConversionOption::CHARACTER_BY_CHARACTER, sal_True );
126             break;
127         case SID_CHINESE_CONVERSION:
128         {
129             //open ChineseTranslationDialog
130             Reference< XComponentContext > xContext(
131                 ::cppu::defaultBootstrap_InitialComponentContext() ); //@todo get context from calc if that has one
132             if(xContext.is())
133             {
134                 Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
135                 if(xMCF.is())
136                 {
137                     Reference< ui::dialogs::XExecutableDialog > xDialog(
138                             xMCF->createInstanceWithContext(
139                                 rtl::OUString::createFromAscii("com.sun.star.linguistic2.ChineseTranslationDialog")
140                                 , xContext), UNO_QUERY);
141                     Reference< lang::XInitialization > xInit( xDialog, UNO_QUERY );
142                     if( xInit.is() )
143                     {
144                         //  initialize dialog
145                         Reference< awt::XWindow > xDialogParentWindow(0);
146                         Sequence<Any> aSeq(1);
147                         Any* pArray = aSeq.getArray();
148                         PropertyValue aParam;
149                         aParam.Name = rtl::OUString::createFromAscii("ParentWindow");
150                         aParam.Value <<= makeAny(xDialogParentWindow);
151                         pArray[0] <<= makeAny(aParam);
152                         xInit->initialize( aSeq );
153 
154                         //execute dialog
155                         sal_Int16 nDialogRet = xDialog->execute();
156                         if( RET_OK == nDialogRet )
157                         {
158                             //get some parameters from the dialog
159                             sal_Bool bToSimplified = sal_True;
160                             sal_Bool bUseVariants = sal_True;
161                             sal_Bool bCommonTerms = sal_True;
162                             Reference< beans::XPropertySet >  xProp( xDialog, UNO_QUERY );
163                             if( xProp.is() )
164                             {
165                                 try
166                                 {
167                                     xProp->getPropertyValue( C2U("IsDirectionToSimplified") ) >>= bToSimplified;
168                                     xProp->getPropertyValue( C2U("IsUseCharacterVariants") ) >>= bUseVariants;
169                                     xProp->getPropertyValue( C2U("IsTranslateCommonTerms") ) >>= bCommonTerms;
170                                 }
171                                 catch( Exception& )
172                                 {
173                                 }
174                             }
175 
176                             //execute translation
177                             sal_Int16 nSourceLang = bToSimplified ? LANGUAGE_CHINESE_TRADITIONAL : LANGUAGE_CHINESE_SIMPLIFIED;
178                             sal_Int16 nTargetLang = bToSimplified ? LANGUAGE_CHINESE_SIMPLIFIED : LANGUAGE_CHINESE_TRADITIONAL;
179                             sal_Int32 nOptions    = bUseVariants ? i18n::TextConversionOption::USE_CHARACTER_VARIANTS : 0;
180                             if( !bCommonTerms )
181                                 nOptions = nOptions | i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
182 
183                             Font aTargetFont = GetEditWin().GetDefaultFont( DEFAULTFONT_CJK_TEXT,
184                                                     nTargetLang, DEFAULTFONT_FLAGS_ONLYONE );
185 
186                             // disallow formatting, updating the view, ... while
187                             // converting the document. (saves time)
188                             // Also remember the current view and cursor position for later
189                             pWrtShell->StartAction();
190 
191                             // remember cursor position data for later restoration of the cursor
192                             const SwPosition *pPoint = pWrtShell->GetCrsr()->GetPoint();
193                             sal_Bool bRestoreCursor = pPoint->nNode.GetNode().IsTxtNode();
194                             const SwNodeIndex aPointNodeIndex( pPoint->nNode );
195                             xub_StrLen nPointIndex = pPoint->nContent.GetIndex();;
196 
197                             // since this conversion is not interactive the whole converted
198                             // document should be undone in a single undo step.
199                             pWrtShell->StartUndo( UNDO_OVERWRITE );
200 
201                             StartTextConversion( nSourceLang, nTargetLang, &aTargetFont, nOptions, sal_False );
202 
203                             pWrtShell->EndUndo( UNDO_OVERWRITE );
204 
205                             if (bRestoreCursor)
206                             {
207                                 SwTxtNode *pTxtNode = aPointNodeIndex.GetNode().GetTxtNode();
208                                 // check for unexpected error case
209                                 DBG_ASSERT( pTxtNode && pTxtNode->GetTxt().Len() >= nPointIndex,
210                                     "text missing: corrupted node?" );
211                                 if (!pTxtNode || pTxtNode->GetTxt().Len() < nPointIndex)
212                                     nPointIndex = 0;
213                                 // restore cursor to its original position
214                                 pWrtShell->GetCrsr()->GetPoint()->nContent.Assign( pTxtNode, nPointIndex );
215                             }
216 
217                             // enable all, restore view and cursor position
218                             pWrtShell->EndAction();
219                         }
220                     }
221                     Reference< lang::XComponent > xComponent( xDialog, UNO_QUERY );
222                     if( xComponent.is() )
223                         xComponent->dispose();
224                 }
225             }
226             break;
227         }
228         case FN_HYPHENATE_OPT_DLG:
229             HyphenateDocument();
230             break;
231         default:
232             ASSERT(!this, falscher Dispatcher);
233             return;
234     }
235 }
236 
237 /*--------------------------------------------------------------------
238     Description: start language specific text conversion
239  --------------------------------------------------------------------*/
240 
StartTextConversion(LanguageType nSourceLang,LanguageType nTargetLang,const Font * pTargetFont,sal_Int32 nOptions,sal_Bool bIsInteractive)241 void SwView::StartTextConversion(
242         LanguageType nSourceLang,
243         LanguageType nTargetLang,
244         const Font *pTargetFont,
245         sal_Int32 nOptions,
246         sal_Bool bIsInteractive )
247 {
248     // do not do text conversion if it is active elsewhere
249     if (GetWrtShell().HasConvIter())
250     {
251         return;
252     }
253 
254     SpellKontext(sal_True);
255 
256     const SwViewOption* pVOpt = pWrtShell->GetViewOptions();
257     const sal_Bool bOldIdle = pVOpt->IsIdle();
258     pVOpt->SetIdle( sal_False );
259 
260     sal_Bool bOldIns = pWrtShell->IsInsMode();
261     pWrtShell->SetInsMode( sal_True );
262 
263     sal_Bool bSelection = ((SwCrsrShell*)pWrtShell)->HasSelection() ||
264         pWrtShell->GetCrsr() != pWrtShell->GetCrsr()->GetNext();
265 
266     sal_Bool    bStart = bSelection || pWrtShell->IsStartOfDoc();
267     sal_Bool    bOther = !bSelection && !(pWrtShell->GetFrmType(0,sal_True) & FRMTYPE_BODY);
268 
269     {
270         const uno::Reference< lang::XMultiServiceFactory > xMgr(
271                     comphelper::getProcessServiceFactory() );
272         SwHHCWrapper aWrap( this, xMgr, nSourceLang, nTargetLang, pTargetFont,
273                             nOptions, bIsInteractive,
274                             bStart, bOther, bSelection );
275         aWrap.Convert();
276     }
277 
278     pWrtShell->SetInsMode( bOldIns );
279     pVOpt->SetIdle( bOldIdle );
280     SpellKontext(sal_False);
281 }
282 
283 /*--------------------------------------------------------------------
284      spellcheck and text conversion related stuff
285  --------------------------------------------------------------------*/
286 
SpellStart(SvxSpellArea eWhich,sal_Bool bStartDone,sal_Bool bEndDone,SwConversionArgs * pConvArgs)287 void SwView::SpellStart( SvxSpellArea eWhich,
288         sal_Bool bStartDone, sal_Bool bEndDone,
289         SwConversionArgs *pConvArgs )
290 {
291     Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
292     sal_Bool bIsWrapReverse = (!pConvArgs && xProp.is()) ?
293             *(sal_Bool*)xProp->getPropertyValue( C2U(UPN_IS_WRAP_REVERSE) ).getValue() : sal_False;
294 
295     SwDocPositions eStart = DOCPOS_START;
296     SwDocPositions eEnde  = DOCPOS_END;
297     SwDocPositions eCurr  = DOCPOS_CURR;
298     switch ( eWhich )
299     {
300         case SVX_SPELL_BODY:
301             if( bIsWrapReverse )
302                 eCurr = DOCPOS_END;
303             else
304                 eCurr = DOCPOS_START;
305             break;
306         case SVX_SPELL_BODY_END:
307             if( bIsWrapReverse )
308             {
309                 if( bStartDone )
310                     eStart = DOCPOS_CURR;
311                 eCurr = DOCPOS_END;
312             }
313             else if( bStartDone )
314                 eCurr = DOCPOS_START;
315             break;
316         case SVX_SPELL_BODY_START:
317             if( !bIsWrapReverse )
318             {
319                 if( bEndDone )
320                     eEnde = DOCPOS_CURR;
321                 eCurr = DOCPOS_START;
322             }
323             else if( bEndDone )
324                 eCurr = DOCPOS_END;
325             break;
326         case SVX_SPELL_OTHER:
327             if( bIsWrapReverse )
328             {
329                 eStart = DOCPOS_OTHERSTART;
330                 eEnde  = DOCPOS_OTHEREND;
331                 eCurr = DOCPOS_OTHEREND;
332             }
333             else
334             {
335                 eStart = DOCPOS_OTHERSTART;
336                 eEnde  = DOCPOS_OTHEREND;
337                 eCurr = DOCPOS_OTHERSTART;
338             }
339             break;
340         default:
341             ASSERT( !this, "SpellStart with unknown Area" );
342     }
343     pWrtShell->SpellStart( eStart, eEnde, eCurr, pConvArgs );
344 }
345 
346 /*--------------------------------------------------------------------
347     Beschreibung: Fehlermeldung beim Spelling
348  --------------------------------------------------------------------*/
349 
350 
351 // Der uebergebene Pointer nLang ist selbst der Wert
IMPL_LINK(SwView,SpellError,LanguageType *,pLang)352 IMPL_LINK( SwView, SpellError, LanguageType *, pLang )
353 {
354 #if OSL_DEBUG_LEVEL > 1
355     sal_Bool bFocus = GetEditWin().HasFocus();
356 #endif
357     sal_uInt16 nPend = 0;
358 
359     if ( pWrtShell->ActionPend() )
360     {
361         pWrtShell->Push();
362         pWrtShell->ClearMark();
363         do
364         {
365             pWrtShell->EndAction();
366             ++nPend;
367         }
368         while( pWrtShell->ActionPend() );
369     }
370     LanguageType eLang = pLang ? *pLang : LANGUAGE_NONE;
371     String aErr(SvtLanguageTable::GetLanguageString( eLang ) );
372 
373     SwEditWin &rEditWin = GetEditWin();
374 #if OSL_DEBUG_LEVEL > 1
375     bFocus = rEditWin.HasFocus();
376 #endif
377     sal_uInt16 nWaitCnt = 0;
378     while( rEditWin.IsWait() )
379     {
380         rEditWin.LeaveWait();
381         ++nWaitCnt;
382     }
383     if ( LANGUAGE_NONE == eLang )
384         ErrorHandler::HandleError( ERRCODE_SVX_LINGU_NOLANGUAGE );
385     else
386         ErrorHandler::HandleError( *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
387 
388     while( nWaitCnt )
389     {
390         rEditWin.EnterWait();
391         --nWaitCnt;
392     }
393 #if OSL_DEBUG_LEVEL > 1
394     bFocus = GetEditWin().HasFocus();
395 #endif
396 
397     if ( nPend )
398     {
399         while( nPend-- )
400             pWrtShell->StartAction();
401         pWrtShell->Combine();
402     }
403 #if OSL_DEBUG_LEVEL > 1
404     if( !bFocus )
405         GetEditWin().GrabFocus();
406 #endif
407 
408     return 0;
409 }
410 
411 /*--------------------------------------------------------------------
412      Beschreibung: Spelling beenden und Cursor wiederherstellen
413  --------------------------------------------------------------------*/
414 
415 
SpellEnd(SwConversionArgs * pConvArgs)416 void SwView::SpellEnd( SwConversionArgs *pConvArgs )
417 {
418     pWrtShell->SpellEnd( pConvArgs );
419     if( pWrtShell->IsExtMode() )
420         pWrtShell->SetMark();
421 }
422 
423 
HyphStart(SvxSpellArea eWhich)424 void SwView::HyphStart( SvxSpellArea eWhich )
425 {
426     switch ( eWhich )
427     {
428         case SVX_SPELL_BODY:
429             pWrtShell->HyphStart( DOCPOS_START, DOCPOS_END );
430             break;
431         case SVX_SPELL_BODY_END:
432             pWrtShell->HyphStart( DOCPOS_CURR, DOCPOS_END );
433             break;
434         case SVX_SPELL_BODY_START:
435             pWrtShell->HyphStart( DOCPOS_START, DOCPOS_CURR );
436             break;
437         case SVX_SPELL_OTHER:
438             pWrtShell->HyphStart( DOCPOS_OTHERSTART, DOCPOS_OTHEREND );
439             break;
440         default:
441             ASSERT( !this, "HyphStart with unknown Area" );
442     }
443 }
444 
445 /*--------------------------------------------------------------------
446      Beschreibung: Interaktive Trennung
447  --------------------------------------------------------------------*/
448 
449 
HyphenateDocument()450 void SwView::HyphenateDocument()
451 {
452     // do not hyphenate if interactive hyphenationg is active elsewhere
453     if (GetWrtShell().HasHyphIter())
454     {
455         MessBox( 0, WB_OK, String( SW_RES( STR_HYPH_TITLE ) ),
456                 String( SW_RES( STR_MULT_INTERACT_HYPH_WARN ) ) ).Execute();
457         return;
458     }
459 
460     SfxErrorContext aContext( ERRCTX_SVX_LINGU_HYPHENATION, aEmptyStr, pEditWin,
461          RID_SVXERRCTX, &DIALOG_MGR() );
462 
463     Reference< XHyphenator >  xHyph( ::GetHyphenator() );
464     if (!xHyph.is())
465     {
466         ErrorHandler::HandleError( ERRCODE_SVX_LINGU_LINGUNOTEXISTS );
467         return;
468     }
469 
470     if (pWrtShell->GetSelectionType() & (nsSelectionType::SEL_DRW_TXT|nsSelectionType::SEL_DRW))
471     {
472         // Silbentrennung in einem Draw-Objekt
473         HyphenateDrawText();
474     }
475     else
476     {
477         SwViewOption* pVOpt = (SwViewOption*)pWrtShell->GetViewOptions();
478         sal_Bool bOldIdle = pVOpt->IsIdle();
479         pVOpt->SetIdle( sal_False );
480 
481         Reference< beans::XPropertySet >  xProp( ::GetLinguPropertySet() );
482 
483 
484         pWrtShell->StartUndo(UNDO_INSATTR);         // spaeter gueltig
485 
486         sal_Bool bHyphSpecial = xProp.is() ?
487                 *(sal_Bool*)xProp->getPropertyValue( C2U(UPN_IS_HYPH_SPECIAL) ).getValue() : sal_False;
488         sal_Bool bSelection = ((SwCrsrShell*)pWrtShell)->HasSelection() ||
489             pWrtShell->GetCrsr() != pWrtShell->GetCrsr()->GetNext();
490         sal_Bool bOther = pWrtShell->HasOtherCnt() && bHyphSpecial && !bSelection;
491         sal_Bool bStart = bSelection || ( !bOther && pWrtShell->IsStartOfDoc() );
492         sal_Bool bStop = sal_False;
493         if( !bOther && !(pWrtShell->GetFrmType(0,sal_True) & FRMTYPE_BODY) && !bSelection )
494         // kein Sonderbereich eingeschaltet
495         {
496             // Ich will auch in Sonderbereichen trennen
497             QueryBox aBox( &GetEditWin(), SW_RES( DLG_SPECIAL_FORCED ) );
498             if( aBox.Execute() == RET_YES )
499             {
500                 bOther = sal_True;
501                 if (xProp.is())
502                 {
503                     sal_Bool bTrue = sal_True;
504                     Any aTmp(&bTrue, ::getBooleanCppuType());
505                     xProp->setPropertyValue( C2U(UPN_IS_HYPH_SPECIAL), aTmp );
506                 }
507             }
508             else
509                 bStop = sal_True; // Nein Es wird nicht getrennt
510         }
511 
512         if( !bStop )
513         {
514             SwHyphWrapper aWrap( this, xHyph, bStart, bOther, bSelection );
515             aWrap.SpellDocument();
516             pWrtShell->EndUndo(UNDO_INSATTR);
517         }
518         pVOpt->SetIdle( bOldIdle );
519     }
520 }
521 
522 /*--------------------------------------------------------------------
523  --------------------------------------------------------------------*/
524 
IsValidSelectionForThesaurus() const525 bool SwView::IsValidSelectionForThesaurus() const
526 {
527     // must not be a multi-selection, and if it is a selection it needs
528     // to be within a single paragraph
529 
530     const bool bMultiSel = pWrtShell->GetCrsr() != pWrtShell->GetCrsr()->GetNext();
531     const sal_Bool bSelection = ((SwCrsrShell*)pWrtShell)->HasSelection();
532     return !bMultiSel && (!bSelection || pWrtShell->IsSelOnePara() );
533 }
534 
535 
GetThesaurusLookUpText(bool bSelection) const536 String SwView::GetThesaurusLookUpText( bool bSelection ) const
537 {
538     return bSelection ? pWrtShell->GetSelTxt() : pWrtShell->GetCurWord();
539 }
540 
541 
InsertThesaurusSynonym(const String & rSynonmText,const String & rLookUpText,bool bSelection)542 void SwView::InsertThesaurusSynonym( const String &rSynonmText, const String &rLookUpText, bool bSelection )
543 {
544     sal_Bool bOldIns = pWrtShell->IsInsMode();
545     pWrtShell->SetInsMode( sal_True );
546 
547     pWrtShell->StartAllAction();
548     pWrtShell->StartUndo(UNDO_DELETE);
549 
550     if( !bSelection )
551     {
552         if(pWrtShell->IsEndWrd())
553             pWrtShell->Left(CRSR_SKIP_CELLS, sal_False, 1, sal_False );
554 
555         pWrtShell->SelWrd();
556 
557         // make sure the selection build later from the
558         // data below does not include footnotes and other
559         // "in word" character to the left and right in order
560         // to preserve those. Therefore count those "in words"
561         // in order to modify the selection accordingly.
562         const sal_Unicode* pChar = rLookUpText.GetBuffer();
563         xub_StrLen nLeft = 0;
564         while (pChar && *pChar++ == CH_TXTATR_INWORD)
565             ++nLeft;
566         pChar = rLookUpText.Len() ? rLookUpText.GetBuffer() + rLookUpText.Len() - 1 : 0;
567         xub_StrLen nRight = 0;
568         while (pChar && *pChar-- == CH_TXTATR_INWORD)
569             ++nRight;
570 
571         // adjust existing selection
572         SwPaM *pCrsr = pWrtShell->GetCrsr();
573         pCrsr->GetPoint()->nContent/*.nIndex*/ -= nRight;
574         pCrsr->GetMark()->nContent/*.nIndex*/ += nLeft;
575     }
576 
577     pWrtShell->Insert( rSynonmText );
578 
579     pWrtShell->EndUndo(UNDO_DELETE);
580     pWrtShell->EndAllAction();
581 
582     pWrtShell->SetInsMode( bOldIns );
583 }
584 
585 
586 /*--------------------------------------------------------------------
587     Beschreibung:   Thesaurus starten
588  --------------------------------------------------------------------*/
589 
590 
StartThesaurus()591 void SwView::StartThesaurus()
592 {
593     if (!IsValidSelectionForThesaurus())
594         return;
595 
596     SfxErrorContext aContext( ERRCTX_SVX_LINGU_THESAURUS, aEmptyStr, pEditWin,
597          RID_SVXERRCTX, &DIALOG_MGR() );
598 
599     // Sprache rausholen
600     //
601     LanguageType eLang = pWrtShell->GetCurLang();
602     if( LANGUAGE_SYSTEM == eLang )
603        eLang = GetAppLanguage();
604 
605     if( eLang == LANGUAGE_DONTKNOW || eLang == LANGUAGE_NONE )
606     {
607         LanguageType nLanguage = LANGUAGE_NONE;
608         SpellError( &nLanguage );
609         return;
610     }
611 
612     SwViewOption* pVOpt = (SwViewOption*)pWrtShell->GetViewOptions();
613     sal_Bool bOldIdle = pVOpt->IsIdle();
614     pVOpt->SetIdle( sal_False );
615 
616     // get initial LookUp text
617     const sal_Bool bSelection = ((SwCrsrShell*)pWrtShell)->HasSelection();
618     String aTmp = GetThesaurusLookUpText( bSelection );
619 
620     Reference< XThesaurus >  xThes( ::GetThesaurus() );
621     AbstractThesaurusDialog *pDlg = NULL;
622 
623     if ( !xThes.is() || !xThes->hasLocale( SvxCreateLocale( eLang ) ) )
624         SpellError( &eLang );
625     else
626     {
627         // create dialog
628         {   //Scope for SwWait-Object
629             SwWait aWait( *GetDocShell(), true );
630             // load library with dialog only on demand ...
631             SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
632             pDlg = pFact->CreateThesaurusDialog( &GetEditWin(), xThes, aTmp, eLang );
633         }
634 
635         if ( pDlg->Execute()== RET_OK )
636             InsertThesaurusSynonym( pDlg->GetWord(), aTmp, bSelection );
637     }
638 
639     delete pDlg;
640 
641     pVOpt->SetIdle( bOldIdle );
642 }
643 
644 /*--------------------------------------------------------------------
645     Beschreibung:   Online-Vorschlaege anbieten
646  *--------------------------------------------------------------------*/
647 
648 //!! Start of extra code for context menu modifying extensions
649 struct ExecuteInfo
650 {
651     uno::Reference< frame::XDispatch >  xDispatch;
652     util::URL                           aTargetURL;
653     uno::Sequence< PropertyValue >      aArgs;
654 };
655 
656 class AsyncExecute
657 {
658 public:
659     DECL_STATIC_LINK( AsyncExecute, ExecuteHdl_Impl, ExecuteInfo* );
660 };
661 
IMPL_STATIC_LINK_NOINSTANCE(AsyncExecute,ExecuteHdl_Impl,ExecuteInfo *,pExecuteInfo)662 IMPL_STATIC_LINK_NOINSTANCE( AsyncExecute, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
663 {
664     const sal_uInt32 nRef = Application::ReleaseSolarMutex();
665     try
666     {
667         // Asynchronous execution as this can lead to our own destruction!
668         // Framework can recycle our current frame and the layout manager disposes all user interface
669         // elements if a component gets detached from its frame!
670         pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
671     }
672     catch ( Exception& )
673     {
674     }
675 
676     Application::AcquireSolarMutex( nRef );
677     delete pExecuteInfo;
678     return 0;
679 }
680 //!! End of extra code for context menu modifying extensions
681 
ExecSpellPopup(const Point & rPt)682 sal_Bool SwView::ExecSpellPopup(const Point& rPt)
683 {
684     sal_Bool bRet = sal_False;
685     const SwViewOption* pVOpt = pWrtShell->GetViewOptions();
686     if( pVOpt->IsOnlineSpell() &&
687         !pWrtShell->IsSelection())
688     {
689         if (pWrtShell->GetSelectionType() & nsSelectionType::SEL_DRW_TXT)
690             bRet = ExecDrwTxtSpellPopup(rPt);
691         else if (!pWrtShell->IsSelFrmMode())
692         {
693             const sal_Bool bOldViewLock = pWrtShell->IsViewLocked();
694             pWrtShell->LockView( sal_True );
695             pWrtShell->Push();
696             SwRect aToFill;
697 
698             // decide which variant of the context menu to use...
699             // if neither spell checking nor grammar checking provides suggestions use the
700             // default context menu.
701             bool bUseGrammarContext = false;
702             Reference< XSpellAlternatives >  xAlt( pWrtShell->GetCorrection(&rPt, aToFill) );
703             /*linguistic2::*/ProofreadingResult aGrammarCheckRes;
704             sal_Int32 nErrorPosInText = -1;
705             sal_Int32 nErrorInResult = -1;
706             uno::Sequence< rtl::OUString > aSuggestions;
707             bool bCorrectionRes = false;
708             if (!xAlt.is() || xAlt->getAlternatives().getLength() == 0)
709             {
710                 bCorrectionRes = pWrtShell->GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, &rPt, aToFill );
711                 ::rtl::OUString aMessageText;
712                 if (nErrorInResult >= 0)
713                     aMessageText = aGrammarCheckRes.aErrors[ nErrorInResult ].aShortComment;
714                 // we like to use the grammar checking context menu if we either get
715                 // some suggestions or at least a comment about the error found...
716                 bUseGrammarContext = bCorrectionRes &&
717                         (aSuggestions.getLength() > 0 || aMessageText.getLength() > 0);
718             }
719 
720             // open respective context menu for spell check or grammar errors with correction suggestions...
721             if ((!bUseGrammarContext && xAlt.is()) ||
722                 (bUseGrammarContext && bCorrectionRes && aGrammarCheckRes.aErrors.getLength() > 0))
723             {
724                 // get paragraph text
725                 String aParaText;
726                 SwPosition aPoint( *pWrtShell->GetCrsr()->GetPoint() );
727                 const SwTxtNode *pNode = dynamic_cast< const SwTxtNode * >(
728                                             &aPoint.nNode.GetNode() );
729                 if (pNode)
730                     aParaText = pNode->GetTxt();    // this may include hidden text but that should be Ok
731                 else
732                 {
733                     DBG_ERROR( "text node expected but not found" );
734                 }
735 
736                 bRet = sal_True;
737                 pWrtShell->SttSelect();
738                 std::auto_ptr< SwSpellPopup > pPopup;
739                 if (bUseGrammarContext)
740                 {
741                     sal_Int32 nPos = aPoint.nContent.GetIndex();
742                     (void) nPos;
743                     pPopup = std::auto_ptr< SwSpellPopup >(new SwSpellPopup( pWrtShell, aGrammarCheckRes, nErrorInResult, aSuggestions, aParaText ));
744                 }
745                 else
746                     pPopup = std::auto_ptr< SwSpellPopup >(new SwSpellPopup( pWrtShell, xAlt, aParaText ));
747                 ui::ContextMenuExecuteEvent aEvent;
748                 const Point aPixPos = GetEditWin().LogicToPixel( rPt );
749 
750                 aEvent.SourceWindow = VCLUnoHelper::GetInterface( pEditWin );
751                 aEvent.ExecutePosition.X = aPixPos.X();
752                 aEvent.ExecutePosition.Y = aPixPos.Y();
753                 Menu* pMenu = 0;
754 
755                 ::rtl::OUString sMenuName = ::rtl::OUString::createFromAscii(
756                     bUseGrammarContext ? "private:resource/GrammarContextMenu" : "private:resource/SpellContextMenu");
757                 if(TryContextMenuInterception( *pPopup, sMenuName, pMenu, aEvent ))
758                 {
759 
760                     //! happy hacking for context menu modifying extensions of this
761                     //! 'custom made' menu... *sigh* (code copied from sfx2 and framework)
762                     if ( pMenu )
763                     {
764                         OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
765                         sal_uInt16 nId = ((PopupMenu*)pMenu)->Execute(pEditWin, aPixPos);
766                         OUString aCommand = ((PopupMenu*)pMenu)->GetItemCommand(nId);
767                         if (aCommand.getLength() == 0 )
768                         {
769                             if(!ExecuteMenuCommand( *dynamic_cast<PopupMenu*>(pMenu), *GetViewFrame(), nId ))
770                                 pPopup->Execute(nId);
771                         }
772                         else
773                         {
774                             SfxViewFrame *pSfxViewFrame = GetViewFrame();
775                             uno::Reference< frame::XFrame > xFrame;
776                             if ( pSfxViewFrame )
777                                 xFrame = pSfxViewFrame->GetFrame().GetFrameInterface();
778                             com::sun::star::util::URL aURL;
779                             uno::Reference< frame::XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY );
780                             uno::Reference< lang::XMultiServiceFactory > xMgr( utl::getProcessServiceFactory(), uno::UNO_QUERY );
781 
782                             try
783                             {
784                                 uno::Reference< frame::XDispatch > xDispatch;
785                                 uno::Reference< util::XURLTransformer > xURLTransformer;
786                                 if (xMgr.is())
787                                 {
788                                     xURLTransformer = uno::Reference< util::XURLTransformer >( xMgr->createInstance(
789                                             C2U("com.sun.star.util.URLTransformer")), UNO_QUERY);
790                                 }
791 
792                                 aURL.Complete = aCommand;
793                                 xURLTransformer->parseStrict(aURL);
794                                 uno::Sequence< beans::PropertyValue > aArgs;
795                                 xDispatch = xDispatchProvider->queryDispatch( aURL, rtl::OUString(), 0 );
796 
797 
798                                 if (xDispatch.is())
799                                 {
800                                     // Execute dispatch asynchronously
801                                     ExecuteInfo* pExecuteInfo   = new ExecuteInfo;
802                                     pExecuteInfo->xDispatch     = xDispatch;
803                                     pExecuteInfo->aTargetURL    = aURL;
804                                     pExecuteInfo->aArgs         = aArgs;
805                                     Application::PostUserEvent( STATIC_LINK(0, AsyncExecute , ExecuteHdl_Impl), pExecuteInfo );
806                                 }
807                             }
808                             catch (Exception &)
809                             {
810                             }
811                         }
812                     }
813                     else
814                     {
815                         pPopup->Execute( aToFill.SVRect(), pEditWin );
816                     }
817                 }
818             }
819 
820             pWrtShell->Pop( sal_False );
821             pWrtShell->LockView( bOldViewLock );
822         }
823     }
824     return bRet;
825 }
826 
827 /** Function: ExecSmartTagPopup
828 
829    This function shows the popup menu for smarttag
830    actions.
831 */
832 
ExecSmartTagPopup(const Point & rPt)833 sal_Bool SwView::ExecSmartTagPopup( const Point& rPt )
834 {
835     sal_Bool bRet = sal_False;
836     const sal_Bool bOldViewLock = pWrtShell->IsViewLocked();
837     pWrtShell->LockView( sal_True );
838     pWrtShell->Push();
839 
840 
841     // get word that was clicked on
842     // This data structure maps a smart tag type string to the property bag
843     SwRect aToFill;
844     Sequence< rtl::OUString > aSmartTagTypes;
845     Sequence< Reference< container::XStringKeyMap > > aStringKeyMaps;
846     Reference<text::XTextRange> xRange;
847 
848     pWrtShell->GetSmartTagTerm( rPt, aToFill, aSmartTagTypes, aStringKeyMaps, xRange);
849     if ( xRange.is() && aSmartTagTypes.getLength() )
850     {
851         bRet = sal_True;
852         pWrtShell->SttSelect();
853         SwSmartTagPopup aPopup( this, aSmartTagTypes, aStringKeyMaps, xRange );
854         aPopup.Execute( aToFill.SVRect(), pEditWin );
855     }
856 
857     pWrtShell->Pop( sal_False );
858     pWrtShell->LockView( bOldViewLock );
859 
860     return bRet;
861 }
862 
863 
864 
865 class SwFieldPopup : public PopupMenu
866 {
867 public:
SwFieldPopup()868     SwFieldPopup()  {
869     InsertItem(1, ::rtl::OUString::createFromAscii("Hello"));
870     }
871 };
872 
873 class SwFieldListBox : public ListBox
874 {
875 public:
SwFieldListBox(Window * pParent)876     SwFieldListBox(Window* pParent) : ListBox(pParent /*, WB_DROPDOWN*/) {
877     }
878 
GetImplWin()879     void *GetImplWin() {
880     return NULL; //FIXME!!!
881 //  return mpImplWin;
882     }
883 
884 protected:
LoseFocus()885     virtual void LoseFocus() {
886 //  printf("ListBox: lose focus!!\n");
887     ListBox::LoseFocus();
888     }
889 
Select()890     virtual void Select() {
891 //  printf("SELECT!!! IsTravelSelect=%i\n", IsTravelSelect());
892     ListBox::Select();
893     }
894 };
895 
896 class SwFieldDialog : public Dialog
897 {
898 private:
899     SwFieldListBox aListBox;
900     Edit aText;
901     int selection;
902 
903     DECL_LINK( MyListBoxHandler, ListBox * );
904 
905 public:
SwFieldDialog(Window * parent,IFieldmark * fieldBM)906     SwFieldDialog(Window* parent, IFieldmark *fieldBM) : Dialog(parent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW ), aListBox(this), aText(this, WB_RIGHT | WB_READONLY), selection(-1) {
907 
908     assert(fieldBM!=NULL);
909     if (fieldBM!=NULL) {
910         const IFieldmark::parameter_map_t* const pParameters = fieldBM->GetParameters();
911         IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find(::rtl::OUString::createFromAscii(ODF_FORMDROPDOWN_LISTENTRY));
912         if(pListEntries != pParameters->end())
913         {
914             Sequence< ::rtl::OUString> vListEntries;
915             pListEntries->second >>= vListEntries;
916             for( ::rtl::OUString* pCurrent = vListEntries.getArray();
917                 pCurrent != vListEntries.getArray() + vListEntries.getLength();
918                 ++pCurrent)
919             {
920                 aListBox.InsertEntry(*pCurrent);
921             }
922         }
923     }
924     Size lbSize=aListBox.GetOptimalSize(WINDOWSIZE_PREFERRED);
925     lbSize.Width()+=50;
926     lbSize.Height()+=20;
927     aListBox.SetSizePixel(lbSize);
928     aListBox.SetSelectHdl( LINK( this, SwFieldDialog, MyListBoxHandler ) );
929     aListBox.Show();
930     aText.SetText(rtl::OUString::createFromAscii("Cancel"));
931     Size tSize=aText.GetOptimalSize(WINDOWSIZE_PREFERRED);
932     aText.SetSizePixel(Size(lbSize.Width(), tSize.Height()));
933     aText.SetPosPixel(Point(0, lbSize.Height()));
934     aText.Show();
935     SetSizePixel(Size(lbSize.Width(), lbSize.Height()+tSize.Height()));
936 //  SetSizePixel(Size(200, 200));
937     }
938 
getSelection()939     int getSelection() {
940     return selection;
941     }
942 protected:
943     /*
944     virtual void LoseFocus() {
945     printf("lose focus!!\n");
946     Dialog::LoseFocus();
947     printf("close:\n");
948     EndDialog(8);
949     }
950     */
951 
PreNotify(NotifyEvent & rNEvt)952     virtual long PreNotify( NotifyEvent& rNEvt ) {
953     if (rNEvt.GetType() == EVENT_LOSEFOCUS && aListBox.GetImplWin()==rNEvt.GetWindow()) {
954         EndDialog(8);
955         return 1;
956     }
957     if (rNEvt.GetType() == EVENT_KEYINPUT) {
958 //      printf("PreNotify::KEYINPUT\n");
959     }
960     return Dialog::PreNotify(rNEvt);
961     }
962 };
963 
IMPL_LINK(SwFieldDialog,MyListBoxHandler,ListBox *,pBox)964 IMPL_LINK( SwFieldDialog, MyListBoxHandler, ListBox *, pBox )
965 {
966 //    printf("### DROP DOWN SELECT... IsTravelSelect=%i\n", pBox->IsTravelSelect());
967     if (pBox->IsTravelSelect()) {
968     return 0;
969     } else {
970     this->selection=pBox->GetSelectEntryPos();
971     EndDialog(9); //@TODO have meaningfull returns...
972     return 1;
973     }
974 }
975 
976 
ExecFieldPopup(const Point & rPt,IFieldmark * fieldBM)977 sal_Bool SwView::ExecFieldPopup( const Point& rPt, IFieldmark *fieldBM )
978 {
979     sal_Bool bRet = sal_False;
980     const sal_Bool bOldViewLock = pWrtShell->IsViewLocked();
981     pWrtShell->LockView( sal_True );
982     pWrtShell->Push();
983 
984     bRet=sal_True;
985     const Point aPixPos = GetEditWin().LogicToPixel( rPt );
986 
987     SwFieldDialog aFldDlg(pEditWin, fieldBM);
988     aFldDlg.SetPosPixel(pEditWin->OutputToScreenPixel(aPixPos));
989 
990     /*short ret=*/aFldDlg.Execute();
991     sal_Int32 selection=aFldDlg.getSelection();
992     if (selection>=0) {
993         (*fieldBM->GetParameters())[::rtl::OUString::createFromAscii(ODF_FORMDROPDOWN_RESULT)] = makeAny(selection);
994     }
995 
996     pWrtShell->Pop( sal_False );
997     pWrtShell->LockView( bOldViewLock );
998 
999     return bRet;
1000 }
1001 
1002