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 #ifdef PRECOMPILED
27 #include "ui_pch.hxx"
28 #endif
29
30
31 #include <hintids.hxx>
32 #ifndef _VIEW_HXX
33 #include <view.hxx>
34 #endif
35 #include <wrtsh.hxx>
36 #include <swundo.hxx> // fuer Undo-Ids
37 #ifndef _GLOBALS_HRC
38 #include <globals.hrc>
39 #endif
40 #include <splargs.hxx>
41
42
43 #ifndef _MSGBOX_HXX //autogen
44 #include <vcl/msgbox.hxx>
45 #endif
46 #include <editeng/unolingu.hxx>
47 #include <editeng/langitem.hxx>
48 #include <editeng/fontitem.hxx>
49 #include <rtl/ustring.hxx>
50 #include <com/sun/star/text/RubyAdjust.hpp>
51 #include <hhcwrp.hxx>
52 #include <sdrhhcwrap.hxx>
53 #include <doc.hxx>
54 #include <docsh.hxx>
55 #include <txatritr.hxx>
56 #include <mdiexp.hxx> // Progress
57 #include <edtwin.hxx>
58 #include <crsskip.hxx>
59 #include <index.hxx>
60 #include <pam.hxx>
61 #include <swcrsr.hxx>
62 #include <viscrs.hxx>
63 #include <ndtxt.hxx>
64 #include <fmtruby.hxx>
65 #include <breakit.hxx>
66 #include <docsh.hxx>
67
68 #ifndef _OLMENU_HRC
69 #include <olmenu.hrc>
70 #endif
71
72 #include <unomid.h>
73
74 using ::rtl::OUString;
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::text;
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::linguistic2;
79 using namespace ::com::sun::star::i18n;
80
81 #define CHAR_PAR_BRK ((sal_Char) 0x0D)
82
83 //////////////////////////////////////////////////////////////////////
84 // Beschreibung: Ggf. Rahmen/Objektshell abschalten
85
lcl_ActivateTextShell(SwWrtShell & rWrtSh)86 static void lcl_ActivateTextShell( SwWrtShell & rWrtSh )
87 {
88 if( rWrtSh.IsSelFrmMode() || rWrtSh.IsObjSelected() )
89 rWrtSh.EnterStdMode();
90 }
91
92 //////////////////////////////////////////////////////////////////////
93
94 class SwKeepConversionDirectionStateContext
95 {
96 public:
SwKeepConversionDirectionStateContext()97 SwKeepConversionDirectionStateContext()
98 {
99 //!! hack to transport the current conversion direction state settings
100 //!! into the next incarnation that iterates over the drawing objets
101 //!! ( see SwHHCWrapper::~SwHHCWrapper() )
102 editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_True );
103 }
104
~SwKeepConversionDirectionStateContext()105 ~SwKeepConversionDirectionStateContext()
106 {
107 editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_False );
108 }
109 };
110
111 //////////////////////////////////////////////////////////////////////
112
SwHHCWrapper(SwView * pSwView,const uno::Reference<lang::XMultiServiceFactory> & rxMSF,LanguageType nSourceLanguage,LanguageType nTargetLanguage,const Font * pTargetFont,sal_Int32 nConvOptions,sal_Bool bIsInteractive,sal_Bool bStart,sal_Bool bOther,sal_Bool bSelection)113 SwHHCWrapper::SwHHCWrapper(
114 SwView* pSwView,
115 const uno::Reference< lang::XMultiServiceFactory >& rxMSF,
116 LanguageType nSourceLanguage,
117 LanguageType nTargetLanguage,
118 const Font *pTargetFont,
119 sal_Int32 nConvOptions,
120 sal_Bool bIsInteractive,
121 sal_Bool bStart, sal_Bool bOther, sal_Bool bSelection ) :
122 editeng::HangulHanjaConversion( &pSwView->GetEditWin(), rxMSF,
123 SvxCreateLocale( nSourceLanguage ),
124 SvxCreateLocale( nTargetLanguage ),
125 pTargetFont,
126 nConvOptions,
127 bIsInteractive ),
128 rWrtShell( pSwView->GetWrtShell() )
129 {
130 pConvArgs = 0;
131 nLastPos = 0;
132 nUnitOffset = 0;
133
134 pView = pSwView;
135 pWin = &pSwView->GetEditWin();
136 bIsDrawObj = sal_False;
137 bIsStart = bStart;
138 bIsOtherCntnt = bStartChk = bOther;
139 bIsConvSpecial = sal_True;
140 bIsSelection = bSelection;
141 bInfoBox = sal_False;
142 bStartDone = bOther || bStart;
143 bEndDone = sal_False;
144 // bLastRet = sal_True;
145 nPageCount = nPageStart = 0;
146 }
147
148
~SwHHCWrapper()149 SwHHCWrapper::~SwHHCWrapper()
150 {
151 delete pConvArgs;
152
153 rWrtShell.SetCareWin( NULL );
154
155 // check for existence of a draw view which means that there are
156 // (or previously were) draw objects present in the document.
157 // I.e. we like to check those too.
158 if ( IsDrawObj() /*&& bLastRet*/ && pView->GetWrtShell().HasDrawView() )
159 {
160 Cursor *pSave = pView->GetWindow()->GetCursor();
161 {
162 SwKeepConversionDirectionStateContext aContext;
163
164 SdrHHCWrapper aSdrConvWrap( pView, GetSourceLanguage(),
165 GetTargetLanguage(), GetTargetFont(),
166 GetConversionOptions(), IsInteractive() );
167 aSdrConvWrap.StartTextConversion();
168 }
169 pView->GetWindow()->SetCursor( pSave );
170 }
171
172 if( nPageCount )
173 ::EndProgress( pView->GetDocShell() );
174
175 // finally for chinese translation we need to change the documents
176 // default language and font to the new ones to be used.
177 LanguageType nTargetLang = GetTargetLanguage();
178 if (IsChinese( nTargetLang ))
179 {
180 SwDoc *pDoc = pView->GetDocShell()->GetDoc();
181
182 //!! Note: This also effects the default language of text boxes (EditEngine/EditView) !!
183 pDoc->SetDefault( SvxLanguageItem( nTargetLang, RES_CHRATR_CJK_LANGUAGE ) );
184 //
185 const Font *pFont = GetTargetFont();
186 if (pFont)
187 {
188 SvxFontItem aFontItem( pFont->GetFamily(), pFont->GetName(),
189 pFont->GetStyleName(), pFont->GetPitch(),
190 pFont->GetCharSet(), RES_CHRATR_CJK_FONT );
191 pDoc->SetDefault( aFontItem );
192 }
193
194 }
195
196 /*
197 if( bInfoBox )
198 InfoBox(&pView->GetEditWin(), String(SW_RES(STR_SPELL_OK)) ).Execute();
199 */
200 }
201
202
GetNextPortion(::rtl::OUString & rNextPortion,LanguageType & rLangOfPortion,sal_Bool bAllowChanges)203 void SwHHCWrapper::GetNextPortion(
204 ::rtl::OUString& rNextPortion,
205 LanguageType& rLangOfPortion,
206 sal_Bool bAllowChanges )
207 {
208 pConvArgs->bAllowImplicitChangesForNotConvertibleText = bAllowChanges;
209
210 FindConvText_impl();
211 rNextPortion = pConvArgs->aConvText;
212 rLangOfPortion = pConvArgs->nConvTextLang;
213
214 nUnitOffset = 0;
215
216 // build last pos from currently selected text
217 SwPaM* pCrsr = rWrtShell.GetCrsr();
218 nLastPos = pCrsr->Start()->nContent.GetIndex();
219 }
220
221
SelectNewUnit_impl(sal_Int32 nUnitStart,sal_Int32 nUnitEnd)222 void SwHHCWrapper::SelectNewUnit_impl( sal_Int32 nUnitStart, sal_Int32 nUnitEnd )
223 {
224 SwPaM *pCrsr = rWrtShell.GetCrsr();
225 pCrsr->GetPoint()->nContent = nLastPos;
226 pCrsr->DeleteMark();
227
228 rWrtShell.Right( CRSR_SKIP_CHARS, /*bExpand*/ sal_False,
229 (sal_uInt16) (nUnitOffset + nUnitStart), sal_True );
230 pCrsr->SetMark();
231 rWrtShell.Right( CRSR_SKIP_CHARS, /*bExpand*/ sal_True,
232 (sal_uInt16) (nUnitEnd - nUnitStart), sal_True );
233 // end selection now. Otherwise SHIFT+HOME (extending the selection)
234 // won't work when the dialog is closed without any replacement.
235 // (see #116346#)
236 rWrtShell.EndSelect();
237 }
238
239
HandleNewUnit(const sal_Int32 nUnitStart,const sal_Int32 nUnitEnd)240 void SwHHCWrapper::HandleNewUnit(
241 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd )
242 {
243 DBG_ASSERT( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" );
244 if (!(0 <= nUnitStart && nUnitStart <= nUnitEnd))
245 return;
246
247 lcl_ActivateTextShell( rWrtShell );
248
249 rWrtShell.StartAllAction();
250
251 // select current unit
252 SelectNewUnit_impl( nUnitStart, nUnitEnd );
253
254 rWrtShell.EndAllAction();
255 }
256
257
ChangeText(const String & rNewText,const OUString & rOrigText,const uno::Sequence<sal_Int32> * pOffsets,SwPaM * pCrsr)258 void SwHHCWrapper::ChangeText( const String &rNewText,
259 const OUString& rOrigText,
260 const uno::Sequence< sal_Int32 > *pOffsets,
261 SwPaM *pCrsr )
262 {
263 //!! please see also TextConvWrapper::ChangeText with is a modified
264 //!! copy of this code
265
266 DBG_ASSERT( rNewText.Len() != 0, "unexpected empty string" );
267 if (rNewText.Len() == 0)
268 return;
269
270 if (pOffsets && pCrsr) // try to keep as much attributation as possible ?
271 {
272 // remember cursor start position for later setting of the cursor
273 const SwPosition *pStart = pCrsr->Start();
274 const xub_StrLen nStartIndex = pStart->nContent.GetIndex();
275 const SwNodeIndex aStartNodeIndex = pStart->nNode;
276 SwTxtNode *pStartTxtNode = aStartNodeIndex.GetNode().GetTxtNode();
277
278 const sal_Int32 nIndices = pOffsets->getLength();
279 const sal_Int32 *pIndices = pOffsets->getConstArray();
280 xub_StrLen nConvTextLen = rNewText.Len();
281 xub_StrLen nPos = 0;
282 xub_StrLen nChgPos = STRING_NOTFOUND;
283 xub_StrLen nChgLen = 0;
284 xub_StrLen nConvChgPos = STRING_NOTFOUND;
285 xub_StrLen nConvChgLen = 0;
286
287 // offset to calculate the position in the text taking into
288 // account that text may have been replaced with new text of
289 // different length. Negative values allowed!
290 long nCorrectionOffset = 0;
291
292 DBG_ASSERT(nIndices == 0 || nIndices == nConvTextLen,
293 "mismatch between string length and sequence length!" );
294
295 // find all substrings that need to be replaced (and only those)
296 while (sal_True)
297 {
298 // get index in original text that matches nPos in new text
299 xub_StrLen nIndex;
300 if (nPos < nConvTextLen)
301 nIndex = (sal_Int32) nPos < nIndices ? (xub_StrLen) pIndices[nPos] : nPos;
302 else
303 {
304 nPos = nConvTextLen;
305 nIndex = static_cast< xub_StrLen >( rOrigText.getLength() );
306 }
307
308 if (rOrigText.getStr()[nIndex] == rNewText.GetChar(nPos) ||
309 nPos == nConvTextLen /* end of string also terminates non-matching char sequence */)
310 {
311 // substring that needs to be replaced found?
312 if (nChgPos != STRING_NOTFOUND && nConvChgPos != STRING_NOTFOUND)
313 {
314 nChgLen = nIndex - nChgPos;
315 nConvChgLen = nPos - nConvChgPos;
316 #ifdef DEBUG
317 String aInOrig( rOrigText.copy( nChgPos, nChgLen ) );
318 #endif
319 String aInNew( rNewText.Copy( nConvChgPos, nConvChgLen ) );
320
321 // set selection to sub string to be replaced in original text
322 xub_StrLen nChgInNodeStartIndex = static_cast< xub_StrLen >( nStartIndex + nCorrectionOffset + nChgPos );
323 DBG_ASSERT( rWrtShell.GetCrsr()->HasMark(), "cursor misplaced (nothing selected)" );
324 rWrtShell.GetCrsr()->GetMark()->nContent.Assign( pStartTxtNode, nChgInNodeStartIndex );
325 rWrtShell.GetCrsr()->GetPoint()->nContent.Assign( pStartTxtNode, nChgInNodeStartIndex + nChgLen );
326 #ifdef DEBUG
327 String aSelTxt1( rWrtShell.GetSelTxt() );
328 #endif
329
330 // replace selected sub string with the corresponding
331 // sub string from the new text while keeping as
332 // much from the attributes as possible
333 ChangeText_impl( aInNew, sal_True );
334
335 nCorrectionOffset += nConvChgLen - nChgLen;
336
337 nChgPos = STRING_NOTFOUND;
338 nConvChgPos = STRING_NOTFOUND;
339 }
340 }
341 else
342 {
343 // begin of non-matching char sequence found ?
344 if (nChgPos == STRING_NOTFOUND && nConvChgPos == STRING_NOTFOUND)
345 {
346 nChgPos = nIndex;
347 nConvChgPos = nPos;
348 }
349 }
350 if (nPos >= nConvTextLen)
351 break;
352 ++nPos;
353 }
354
355 // set cursor to the end of all the new text
356 // (as it would happen after ChangeText_impl (Delete and Insert)
357 // of the whole text in the 'else' branch below)
358 rWrtShell.ClearMark();
359 rWrtShell.GetCrsr()->Start()->nContent.Assign( pStartTxtNode, nStartIndex + nConvTextLen );
360 }
361 else
362 {
363 ChangeText_impl( rNewText, sal_False );
364 }
365 }
366
367
ChangeText_impl(const String & rNewText,sal_Bool bKeepAttributes)368 void SwHHCWrapper::ChangeText_impl( const String &rNewText, sal_Bool bKeepAttributes )
369 {
370 if (bKeepAttributes)
371 {
372 // get item set with all relevant attributes
373 sal_uInt16 aRanges[] = {
374 RES_CHRATR_BEGIN, RES_FRMATR_END,
375 0, 0, 0 };
376 SfxItemSet aItemSet( rWrtShell.GetAttrPool(), aRanges );
377 // get all attributes spanning the whole selection in order to
378 // restore those for the new text
379 rWrtShell.GetCurAttr( aItemSet );
380
381 #ifdef DEBUG
382 String aSelTxt1( rWrtShell.GetSelTxt() );
383 #endif
384 rWrtShell.Delete();
385 rWrtShell.Insert( rNewText );
386
387 // select new inserted text (currently the Point is right after the new text)
388 if (!rWrtShell.GetCrsr()->HasMark())
389 rWrtShell.GetCrsr()->SetMark();
390 SwPosition *pMark = rWrtShell.GetCrsr()->GetMark();
391 pMark->nContent = pMark->nContent.GetIndex() - rNewText.Len();
392 #ifdef DEBUG
393 String aSelTxt2( rWrtShell.GetSelTxt() );
394 #endif
395
396 // since 'SetAttr' below functions like merging with the attributes
397 // from the itemset with any existing ones we have to get rid of all
398 // all attributes now. (Those attributes that may take effect left
399 // to the position where the new text gets inserted after the old text
400 // was deleted)
401 rWrtShell.ResetAttr();
402 // apply previously saved attributes to new text
403 rWrtShell.SetAttrSet( aItemSet );
404 }
405 else
406 {
407 rWrtShell.Delete();
408 rWrtShell.Insert( rNewText );
409 }
410 }
411
412
ReplaceUnit(const sal_Int32 nUnitStart,const sal_Int32 nUnitEnd,const::rtl::OUString & rOrigText,const OUString & rReplaceWith,const uno::Sequence<sal_Int32> & rOffsets,ReplacementAction eAction,LanguageType * pNewUnitLanguage)413 void SwHHCWrapper::ReplaceUnit(
414 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd,
415 const ::rtl::OUString& rOrigText,
416 const OUString& rReplaceWith,
417 const uno::Sequence< sal_Int32 > &rOffsets,
418 ReplacementAction eAction,
419 LanguageType *pNewUnitLanguage )
420 {
421 static OUString aBracketedStart( C2U( "(" ) );
422 static OUString aBracketedEnd( C2U( ")" ) );
423
424 DBG_ASSERT( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" );
425 if (!(nUnitStart >= 0 && nUnitEnd >= nUnitStart))
426 return;
427
428 lcl_ActivateTextShell( rWrtShell );
429
430 // Das aktuelle Wort austauschen
431 rWrtShell.StartAllAction();
432
433 // select current unit
434 SelectNewUnit_impl( nUnitStart, nUnitEnd );
435
436 OUString aOrigTxt( rWrtShell.GetSelTxt() );
437 OUString aNewTxt( rReplaceWith );
438 DBG_ASSERT( aOrigTxt == rOrigText, "!! text mismatch !!" );
439 SwFmtRuby *pRuby = 0;
440 sal_Bool bRubyBelow = sal_False;
441 String aNewOrigText;
442 switch (eAction)
443 {
444 case eExchange :
445 break;
446 case eReplacementBracketed :
447 {
448 (((aNewTxt = aOrigTxt) += aBracketedStart) += rReplaceWith) += aBracketedEnd;
449 }
450 break;
451 case eOriginalBracketed :
452 {
453 (((aNewTxt = rReplaceWith) += aBracketedStart) += aOrigTxt) += aBracketedEnd;
454 }
455 break;
456 case eReplacementAbove :
457 {
458 pRuby = new SwFmtRuby( rReplaceWith );
459 }
460 break;
461 case eOriginalAbove :
462 {
463 pRuby = new SwFmtRuby( aOrigTxt );
464 aNewOrigText = rReplaceWith;
465 }
466 break;
467 case eReplacementBelow :
468 {
469 pRuby = new SwFmtRuby( rReplaceWith );
470 bRubyBelow = sal_True;
471 }
472 break;
473 case eOriginalBelow :
474 {
475 pRuby = new SwFmtRuby( aOrigTxt );
476 aNewOrigText = rReplaceWith;
477 bRubyBelow = sal_True;
478 }
479 break;
480 default:
481 DBG_ERROR( "unexpected case" );
482 }
483 nUnitOffset += nUnitStart + aNewTxt.getLength();
484
485 if (pRuby)
486 {
487 rWrtShell.StartUndo( UNDO_SETRUBYATTR );
488 if (aNewOrigText.Len())
489 {
490 // according to FT we currently should not bother about keeping
491 // attributes in Hangul/Hanja conversion
492 ChangeText( aNewOrigText, rOrigText, NULL, NULL );
493
494 //!! since Delete, Insert in 'ChangeText' do not set the WrtShells
495 //!! bInSelect flag
496 //!! back to false we do it now manually in order for the selection
497 //!! to be done properly in the following call to Left.
498 // We didn't fix it in Delete and Insert since it is currently
499 // unclear if someone depends on this incorrect behvaiour
500 // of the flag.
501 rWrtShell.EndSelect();
502
503 rWrtShell.Left( 0, sal_True, aNewOrigText.Len(), sal_True, sal_True );
504 }
505
506 pRuby->SetPosition( bRubyBelow );
507 pRuby->SetAdjustment( RubyAdjust_CENTER );
508 //!! the following seem not to be needed
509 //pRuby->SetCharFmtName( const String& rNm );
510 //pRuby->SetCharFmtId( sal_uInt16 nNew );
511 #ifdef DEBUG
512 SwPaM *pPaM = rWrtShell.GetCrsr();
513 (void)pPaM;
514 #endif
515 rWrtShell.SetAttrItem(*pRuby);
516 delete pRuby;
517 rWrtShell.EndUndo( UNDO_SETRUBYATTR );
518 }
519 else
520 {
521 rWrtShell.StartUndo( UNDO_OVERWRITE );
522
523 // according to FT we should currently not bother about keeping
524 // attributes in Hangul/Hanja conversion and leave that untouched.
525 // Thus we do this only for Chinese translation...
526 sal_Bool bIsChineseConversion = IsChinese( GetSourceLanguage() );
527 if (bIsChineseConversion)
528 ChangeText( aNewTxt, rOrigText, &rOffsets, rWrtShell.GetCrsr() );
529 else
530 ChangeText( aNewTxt, rOrigText, NULL, NULL );
531
532 // change language and font if necessary
533 if (bIsChineseConversion)
534 {
535 rWrtShell.SetMark();
536 rWrtShell.GetCrsr()->GetMark()->nContent -= (xub_StrLen) aNewTxt.getLength();
537
538 DBG_ASSERT( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL,
539 "SwHHCWrapper::ReplaceUnit : unexpected target language" );
540
541 sal_uInt16 aRanges[] = {
542 RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
543 RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
544 0, 0, 0 };
545
546 SfxItemSet aSet( rWrtShell.GetAttrPool(), aRanges );
547 if (pNewUnitLanguage)
548 {
549 //DBG_ASSERT(!IsSimilarChinese( *pNewUnitLanguage, nOldLang ),
550 // "similar language should not be changed!");
551 aSet.Put( SvxLanguageItem( *pNewUnitLanguage, RES_CHRATR_CJK_LANGUAGE ) );
552 }
553
554 const Font *pTargetFont = GetTargetFont();
555 DBG_ASSERT( pTargetFont, "target font missing?" );
556 if (pTargetFont && pNewUnitLanguage)
557 {
558 SvxFontItem aFontItem = (SvxFontItem&) aSet.Get( RES_CHRATR_CJK_FONT );
559 aFontItem.SetFamilyName( pTargetFont->GetName());
560 aFontItem.SetFamily( pTargetFont->GetFamily());
561 aFontItem.SetStyleName( pTargetFont->GetStyleName());
562 aFontItem.SetPitch( pTargetFont->GetPitch());
563 aFontItem.SetCharSet( pTargetFont->GetCharSet() );
564 aSet.Put( aFontItem );
565 }
566
567 rWrtShell.SetAttrSet( aSet );
568
569 rWrtShell.ClearMark();
570 }
571
572 rWrtShell.EndUndo( UNDO_OVERWRITE );
573 }
574
575 rWrtShell.EndAllAction();
576 }
577
578
HasRubySupport() const579 sal_Bool SwHHCWrapper::HasRubySupport() const
580 {
581 return sal_True;
582 }
583
584
Convert()585 void SwHHCWrapper::Convert()
586 {
587 DBG_ASSERT( pConvArgs == 0, "NULL pointer expected" );
588 {
589 SwPaM *pCrsr = pView->GetWrtShell().GetCrsr();
590 SwPosition* pSttPos = pCrsr->Start();
591 SwPosition* pEndPos = pCrsr->End();
592
593
594 if (pSttPos->nNode.GetNode().IsTxtNode() &&
595 pEndPos->nNode.GetNode().IsTxtNode())
596 {
597 pConvArgs = new SwConversionArgs( GetSourceLanguage(),
598 pSttPos->nNode.GetNode().GetTxtNode(), pSttPos->nContent,
599 pEndPos->nNode.GetNode().GetTxtNode(), pEndPos->nContent );
600 }
601 else // we are not in the text (maybe a graphic or OLE object is selected) let's start from the top
602 {
603 // get PaM that points to the start of the document
604 SwNode& rNode = pView->GetDocShell()->GetDoc()->GetNodes().GetEndOfContent();
605 SwPaM aPam(rNode);
606 aPam.Move( fnMoveBackward, fnGoDoc ); // move to start of document
607
608 pSttPos = aPam.GetPoint(); //! using a PaM here makes sure we will get only text nodes
609 SwTxtNode *pTxtNode = pSttPos->nNode.GetNode().GetTxtNode();
610 // just in case we check anyway...
611 if (!pTxtNode || !pTxtNode->IsTxtNode())
612 return;
613 pConvArgs = new SwConversionArgs( GetSourceLanguage(),
614 pTxtNode, pSttPos->nContent,
615 pTxtNode, pSttPos->nContent );
616 }
617 DBG_ASSERT( pConvArgs->pStartNode && pConvArgs->pStartNode->IsTxtNode(),
618 "failed to get proper start text node" );
619 DBG_ASSERT( pConvArgs->pEndNode && pConvArgs->pEndNode->IsTxtNode(),
620 "failed to get proper end text node" );
621
622 // chinese conversion specific settings
623 DBG_ASSERT( IsChinese( GetSourceLanguage() ) == IsChinese( GetTargetLanguage() ),
624 "source and target language mismatch?" );
625 if (IsChinese( GetTargetLanguage() ))
626 {
627 pConvArgs->nConvTargetLang = GetTargetLanguage();
628 pConvArgs->pTargetFont = GetTargetFont();
629 pConvArgs->bAllowImplicitChangesForNotConvertibleText = sal_True;
630 }
631
632 // if it is not just a selection and we are about to begin
633 // with the current conversion for the very first time
634 // we need to find the start of the current (initial)
635 // convertible unit in order for the text conversion to give
636 // the correct result for that. Since it is easier to obtain
637 // the start of the word we use that though.
638 if (!pCrsr->HasMark()) // is not a selection?
639 {
640 // since #118246 / #117803 still occurs if the cursor is placed
641 // between the two chinese characters to be converted (because both
642 // of them are words on their own!) using the word boundary here does
643 // not work. Thus since chinese conversion is not interactive we start
644 // at the begin of the paragraph to solve the problem, i.e. have the
645 // TextConversion service get those charcters together in the same call.
646 xub_StrLen nStartIdx = STRING_MAXLEN;
647 if (editeng::HangulHanjaConversion::IsChinese( GetSourceLanguage() ) )
648 nStartIdx = 0;
649 else
650 {
651 OUString aText( pConvArgs->pStartNode->GetTxt() );
652 long nPos = pConvArgs->pStartIdx->GetIndex();
653 Boundary aBoundary( pBreakIt->GetBreakIter()->
654 getWordBoundary( aText, nPos, pBreakIt->GetLocale( pConvArgs->nConvSrcLang ),
655 WordType::DICTIONARY_WORD, sal_True ) );
656
657 // valid result found?
658 if (aBoundary.startPos < aText.getLength() &&
659 aBoundary.startPos != aBoundary.endPos)
660 {
661 nStartIdx = static_cast< xub_StrLen >(aBoundary.startPos );
662 }
663 }
664
665 if (STRING_MAXLEN != nStartIdx)
666 *pConvArgs->pStartIdx = nStartIdx;
667 }
668 }
669
670 if ( bIsOtherCntnt )
671 ConvStart_impl( pConvArgs, SVX_SPELL_OTHER );
672 else
673 {
674 bStartChk = sal_False;
675 ConvStart_impl( pConvArgs, SVX_SPELL_BODY_END );
676 }
677
678 ConvertDocument();
679
680 ConvEnd_impl( pConvArgs );
681 }
682
683
ConvNext_impl()684 sal_Bool SwHHCWrapper::ConvNext_impl( )
685 {
686 //! modified version of SvxSpellWrapper::SpellNext
687
688 // Keine Richtungsaenderung, also ist der gewuenschte Bereich ( bStartChk )
689 // vollstaendig abgearbeitet.
690 if( bStartChk )
691 bStartDone = sal_True;
692 else
693 bEndDone = sal_True;
694
695 if( bIsOtherCntnt && bStartDone && bEndDone ) // Dokument komplett geprueft?
696 {
697 bInfoBox = sal_True;
698 return sal_False;
699 }
700
701 //ResMgr* pMgr = DIALOG_MGR();
702 sal_Bool bGoOn = sal_False;
703
704 if ( bIsOtherCntnt )
705 {
706 bStartChk = sal_False;
707 ConvStart_impl( pConvArgs, SVX_SPELL_BODY );
708 bGoOn = sal_True;
709 }
710 else if ( bStartDone && bEndDone )
711 {
712 // Bodybereich erledigt, Frage nach Sonderbereich
713 if( bIsConvSpecial && HasOtherCnt_impl() )
714 {
715 ConvStart_impl( pConvArgs, SVX_SPELL_OTHER );
716 bIsOtherCntnt = bGoOn = sal_True;
717 }
718 else
719 bInfoBox = sal_True;
720 }
721 else
722 {
723 // Ein BODY_Bereich erledigt, Frage nach dem anderen BODY_Bereich
724 /*
725 //pWin->LeaveWait();
726
727 sal_uInt16 nResId = RID_SVXQB_CONTINUE;
728 QueryBox aBox( pWin, ResId( nResId, pMgr ) );
729 if ( aBox.Execute() != RET_YES )
730 {
731 // Verzicht auf den anderen Bereich, ggf. Frage nach Sonderbereich
732 //pWin->EnterWait();
733 bStartDone = bEndDone = sal_True;
734 return SpellNext();
735 }
736 else
737 {
738 */
739 bStartChk = !bStartDone;
740 ConvStart_impl( pConvArgs, bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
741 bGoOn = sal_True;
742 /*
743 }
744 pWin->EnterWait();
745 */
746 }
747 return bGoOn;
748 }
749
750
FindConvText_impl()751 sal_Bool SwHHCWrapper::FindConvText_impl()
752 {
753 //! modified version of SvxSpellWrapper::FindSpellError
754
755 //ShowLanguageErrors();
756
757 sal_Bool bFound = sal_False;
758
759 pWin->EnterWait();
760 sal_Bool bConv = sal_True;
761
762 while ( bConv )
763 {
764 bFound = ConvContinue_impl( pConvArgs );
765 if (bFound)
766 {
767 bConv = sal_False;
768 }
769 else
770 {
771 ConvEnd_impl( pConvArgs );
772 bConv = ConvNext_impl();
773 }
774 }
775 pWin->LeaveWait();
776 return bFound;
777 }
778
779
HasOtherCnt_impl()780 sal_Bool SwHHCWrapper::HasOtherCnt_impl()
781 {
782 return bIsSelection ? sal_False : rWrtShell.HasOtherCnt();
783 }
784
785
ConvStart_impl(SwConversionArgs * pConversionArgs,SvxSpellArea eArea)786 void SwHHCWrapper::ConvStart_impl( SwConversionArgs /* [out] */ *pConversionArgs, SvxSpellArea eArea )
787 {
788 SetDrawObj( SVX_SPELL_OTHER == eArea );
789 pView->SpellStart( eArea, bStartDone, bEndDone, /* [out] */ pConversionArgs );
790 }
791
792
ConvEnd_impl(SwConversionArgs * pConversionArgs)793 void SwHHCWrapper::ConvEnd_impl( SwConversionArgs *pConversionArgs )
794 {
795 pView->SpellEnd( pConversionArgs );
796 //ShowLanguageErrors();
797 }
798
799
ConvContinue_impl(SwConversionArgs * pConversionArgs)800 sal_Bool SwHHCWrapper::ConvContinue_impl( SwConversionArgs *pConversionArgs )
801 {
802 sal_Bool bProgress = !bIsDrawObj && !bIsSelection;
803 // bLastRet = aConvText.getLength() == 0;
804 pConversionArgs->aConvText = OUString();
805 pConversionArgs->nConvTextLang = LANGUAGE_NONE;
806 uno::Any aRet = bProgress ?
807 pView->GetWrtShell().SpellContinue( &nPageCount, &nPageStart, pConversionArgs ) :
808 pView->GetWrtShell().SpellContinue( &nPageCount, NULL, pConversionArgs );
809 //aRet >>= aConvText;
810 return pConversionArgs->aConvText.getLength() != 0;
811 }
812
813 //////////////////////////////////////////////////////////////////////
814
815