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