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