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_editeng.hxx"
26
27 #include <vcl/wrkwin.hxx>
28 #include <vcl/dialog.hxx>
29 #include <vcl/msgbox.hxx>
30 #include <vcl/svapp.hxx>
31
32 #include <impedit.hxx>
33 #include <editeng/editview.hxx>
34 #include <editeng/editeng.hxx>
35 #include <editeng/unolingu.hxx>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/lang/Locale.hpp>
38 #include <editeng/langitem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <textconv.hxx>
41
42
43 using ::rtl::OUString;
44 using namespace com::sun::star;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::beans;
47 using namespace com::sun::star::lang;
48 using namespace com::sun::star::linguistic2;
49
50 #define C2U(cChar) OUString::createFromAscii(cChar)
51
52 //////////////////////////////////////////////////////////////////////
53
TextConvWrapper(Window * pWindow,const Reference<XMultiServiceFactory> & rxMSF,const Locale & rSourceLocale,const Locale & rTargetLocale,const Font * pTargetFont,sal_Int32 nOptions,sal_Bool bIsInteractive,sal_Bool bIsStart,EditView * pView)54 TextConvWrapper::TextConvWrapper( Window* pWindow,
55 const Reference< XMultiServiceFactory >& rxMSF,
56 const Locale& rSourceLocale,
57 const Locale& rTargetLocale,
58 const Font* pTargetFont,
59 sal_Int32 nOptions,
60 sal_Bool bIsInteractive,
61 sal_Bool bIsStart,
62 EditView* pView ) :
63 HangulHanjaConversion( pWindow, rxMSF, rSourceLocale, rTargetLocale, pTargetFont, nOptions, bIsInteractive )
64 {
65 DBG_ASSERT( pWindow, "TextConvWrapper: window missing" );
66
67 nConvTextLang = LANGUAGE_NONE;
68 nUnitOffset = 0;
69
70 bStartChk = sal_False;
71 bStartDone = bIsStart;
72 bEndDone = sal_False;
73 pWin = pWindow;
74 pEditView = pView;
75
76 aConvSel = pEditView->GetSelection();
77 aConvSel.Adjust(); // make Start <= End
78
79 bAllowChange = sal_False;
80 }
81
82
~TextConvWrapper()83 TextConvWrapper::~TextConvWrapper()
84 {
85 }
86
87
ConvNext_impl()88 sal_Bool TextConvWrapper::ConvNext_impl()
89 {
90 // modified version of SvxSpellWrapper::SpellNext
91
92 if( bStartChk )
93 bStartDone = sal_True;
94 else
95 bEndDone = sal_True;
96
97 if ( bStartDone && bEndDone )
98 {
99 if ( ConvMore_impl() ) // ein weiteres Dokument pruefen?
100 {
101 bStartDone = sal_True;
102 bEndDone = sal_False;
103 ConvStart_impl( SVX_SPELL_BODY );
104 return sal_True;
105 }
106 return sal_False;
107
108 }
109
110 //ResMgr* pMgr = DIALOG_MGR();
111 sal_Bool bGoOn = sal_False;
112
113 if ( bStartDone && bEndDone )
114 {
115 if ( ConvMore_impl() ) // ein weiteres Dokument pruefen?
116 {
117 bStartDone = sal_True;
118 bEndDone = sal_False;
119 ConvStart_impl( SVX_SPELL_BODY );
120 return sal_True;
121 }
122 }
123 else
124 {
125 // Ein BODY_Bereich erledigt, Frage nach dem anderen BODY_Bereich
126 /*
127 pWin->LeaveWait();
128
129 sal_uInt16 nResId = bReverse ? RID_SVXQB_BW_CONTINUE : RID_SVXQB_CONTINUE;
130 QueryBox aBox( pWin, ResId( nResId, pMgr ) );
131 if ( aBox.Execute() != RET_YES )
132 {
133 // Verzicht auf den anderen Bereich, ggf. Frage nach Sonderbereich
134 pWin->EnterWait();
135 bStartDone = bEndDone = sal_True;
136 return ConvNext_impl();
137 }
138 else
139 {
140 */
141 if (!aConvSel.HasRange())
142 {
143 bStartChk = !bStartDone;
144 ConvStart_impl( bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
145 bGoOn = sal_True;
146 }
147 /*
148 }
149 pWin->EnterWait();
150 */
151 }
152 return bGoOn;
153 }
154
155
FindConvText_impl()156 sal_Bool TextConvWrapper::FindConvText_impl()
157 {
158 // modified version of SvxSpellWrapper::FindSpellError
159
160 //ShowLanguageErrors();
161
162 sal_Bool bFound = sal_False;
163
164 pWin->EnterWait();
165 sal_Bool bConvert = sal_True;
166
167 while ( bConvert )
168 {
169 bFound = ConvContinue_impl();
170 if (bFound)
171 {
172 bConvert = sal_False;
173 }
174 else
175 {
176 ConvEnd_impl();
177 bConvert = ConvNext_impl();
178 }
179 }
180 pWin->LeaveWait();
181 return bFound;
182 }
183
184
ConvMore_impl()185 sal_Bool TextConvWrapper::ConvMore_impl()
186 {
187 // modified version of SvxSpellWrapper::SpellMore
188
189 sal_Bool bMore = sal_False;
190 ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
191 ConvInfo* pConvInfo = pImpEE->GetConvInfo();
192 if ( pConvInfo->bMultipleDoc )
193 {
194 bMore = pImpEE->GetEditEnginePtr()->ConvertNextDocument();
195 if ( bMore )
196 {
197 // Der Text wurde in diese Engine getreten...
198 pEditView->GetImpEditView()->SetEditSelection(
199 pImpEE->GetEditDoc().GetStartPaM() );
200 }
201 }
202 return bMore;
203 }
204
205
ConvStart_impl(SvxSpellArea eArea)206 void TextConvWrapper::ConvStart_impl( SvxSpellArea eArea )
207 {
208 // modified version of EditSpellWrapper::SpellStart
209
210 ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
211 ConvInfo* pConvInfo = pImpEE->GetConvInfo();
212
213 if ( eArea == SVX_SPELL_BODY_START )
214 {
215 // Wird gerufen, wenn Spell-Forwad am Ende angekomment ist
216 // und soll von vorne beginnen
217 if ( bEndDone )
218 {
219 pConvInfo->bConvToEnd = sal_False;
220 pConvInfo->aConvTo = pConvInfo->aConvStart;
221 pConvInfo->aConvContinue = EPaM( 0, 0 );
222 pEditView->GetImpEditView()->SetEditSelection(
223 pImpEE->GetEditDoc().GetStartPaM() );
224 }
225 else
226 {
227 pConvInfo->bConvToEnd = sal_True;
228 pConvInfo->aConvTo = pImpEE->CreateEPaM(
229 pImpEE->GetEditDoc().GetStartPaM() );
230 }
231 }
232 else if ( eArea == SVX_SPELL_BODY_END )
233 {
234 // Wird gerufen, wenn Spell-Forwad gestartet wird
235 pConvInfo->bConvToEnd = sal_True;
236 if (aConvSel.HasRange())
237 {
238 // user selection: convert to end of selection
239 pConvInfo->aConvTo.nPara = aConvSel.nEndPara;
240 pConvInfo->aConvTo.nIndex = aConvSel.nEndPos;
241 pConvInfo->bConvToEnd = sal_False;
242 }
243 else
244 {
245 // nothing selected: convert to end of document
246 pConvInfo->aConvTo = pImpEE->CreateEPaM(
247 pImpEE->GetEditDoc().GetEndPaM() );
248 }
249 }
250 else if ( eArea == SVX_SPELL_BODY )
251 {
252 // called by ConvNext_impl...
253 pConvInfo->aConvContinue = pConvInfo->aConvStart;
254 pConvInfo->aConvTo = pImpEE->CreateEPaM(
255 pImpEE->GetEditDoc().GetEndPaM() );
256 // pSpellInfo->bSpellToEnd = sal_True;
257 }
258 else
259 {
260 DBG_ERROR( "ConvStart_impl: Unknown Area!" );
261 }
262 }
263
264
ConvEnd_impl()265 void TextConvWrapper::ConvEnd_impl()
266 {
267 }
268
269
ConvContinue_impl()270 sal_Bool TextConvWrapper::ConvContinue_impl()
271 {
272 // modified version of EditSpellWrapper::SpellContinue
273
274 // get next convertible text portion and its language
275 aConvText = rtl::OUString();
276 nConvTextLang = LANGUAGE_NONE;
277 pEditView->GetImpEditEngine()->ImpConvert( aConvText, nConvTextLang,
278 pEditView, GetSourceLanguage(), aConvSel,
279 bAllowChange, GetTargetLanguage(), GetTargetFont() );
280 return aConvText.getLength() != 0;
281 }
282
283
SetLanguageAndFont(const ESelection & rESel,LanguageType nLang,sal_uInt16 nLangWhichId,const Font * pFont,sal_uInt16 nFontWhichId)284 void TextConvWrapper::SetLanguageAndFont( const ESelection &rESel,
285 LanguageType nLang, sal_uInt16 nLangWhichId,
286 const Font *pFont, sal_uInt16 nFontWhichId )
287 {
288 ESelection aOldSel = pEditView->GetSelection();
289 pEditView->SetSelection( rESel );
290
291 // set new language attribute
292 SfxItemSet aNewSet( pEditView->GetEmptyItemSet() );
293 aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
294
295 // new font to be set?
296 DBG_ASSERT( pFont, "target font missing?" );
297 if (pFont)
298 {
299 // set new font attribute
300 SvxFontItem aFontItem = (SvxFontItem&) aNewSet.Get( nFontWhichId );
301 aFontItem.SetFamilyName( pFont->GetName());
302 aFontItem.SetFamily( pFont->GetFamily());
303 aFontItem.SetStyleName( pFont->GetStyleName());
304 aFontItem.SetPitch( pFont->GetPitch());
305 aFontItem.SetCharSet(pFont->GetCharSet());
306 aNewSet.Put( aFontItem );
307 }
308
309 // apply new attributes
310 pEditView->SetAttribs( aNewSet );
311
312 pEditView->SetSelection( aOldSel );
313 }
314
315
SelectNewUnit_impl(const sal_Int32 nUnitStart,const sal_Int32 nUnitEnd)316 void TextConvWrapper::SelectNewUnit_impl(
317 const sal_Int32 nUnitStart,
318 const sal_Int32 nUnitEnd )
319 {
320 sal_Bool bOK = 0 <= nUnitStart && 0 <= nUnitEnd && nUnitStart <= nUnitEnd;
321 DBG_ASSERT( bOK, "invalid arguments" );
322 if (!bOK)
323 return;
324
325 ESelection aSelection = pEditView->GetSelection();
326 DBG_ASSERT( aSelection.nStartPara == aSelection.nEndPara,
327 "paragraph mismatch in selection" );
328 aSelection.nStartPos = (sal_uInt16) (nLastPos + nUnitOffset + nUnitStart);
329 aSelection.nEndPos = (sal_uInt16) (nLastPos + nUnitOffset + nUnitEnd);
330 pEditView->SetSelection( aSelection );
331 }
332
333
GetNextPortion(::rtl::OUString & rNextPortion,LanguageType & rLangOfPortion,sal_Bool _bAllowImplicitChangesForNotConvertibleText)334 void TextConvWrapper::GetNextPortion(
335 ::rtl::OUString& /* [out] */ rNextPortion,
336 LanguageType& /* [out] */ rLangOfPortion,
337 sal_Bool /* [in] */ _bAllowImplicitChangesForNotConvertibleText )
338 {
339 bAllowChange = _bAllowImplicitChangesForNotConvertibleText;
340
341 FindConvText_impl();
342 rNextPortion = aConvText;
343 rLangOfPortion = nConvTextLang;
344 nUnitOffset = 0;
345
346 ESelection aSelection = pEditView->GetSelection();
347 DBG_ASSERT( aSelection.nStartPara == aSelection.nEndPara,
348 "paragraph mismatch in selection" );
349 DBG_ASSERT( aSelection.nStartPos <= aSelection.nEndPos,
350 "start pos > end pos" );
351 nLastPos = aSelection.nStartPos;
352 }
353
354
HandleNewUnit(const sal_Int32 nUnitStart,const sal_Int32 nUnitEnd)355 void TextConvWrapper::HandleNewUnit(
356 const sal_Int32 nUnitStart,
357 const sal_Int32 nUnitEnd )
358 {
359 SelectNewUnit_impl( nUnitStart, nUnitEnd );
360 }
361
362
ReplaceUnit(const sal_Int32 nUnitStart,const sal_Int32 nUnitEnd,const::rtl::OUString & rOrigText,const::rtl::OUString & rReplaceWith,const::com::sun::star::uno::Sequence<sal_Int32> & rOffsets,ReplacementAction eAction,LanguageType * pNewUnitLanguage)363 void TextConvWrapper::ReplaceUnit(
364 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd,
365 const ::rtl::OUString& rOrigText,
366 const ::rtl::OUString& rReplaceWith,
367 const ::com::sun::star::uno::Sequence< sal_Int32 > &rOffsets,
368 ReplacementAction eAction,
369 LanguageType *pNewUnitLanguage )
370 {
371 sal_Bool bOK = 0 <= nUnitStart && 0 <= nUnitEnd && nUnitStart <= nUnitEnd;
372 DBG_ASSERT( bOK, "invalid arguments" );
373 if (!bOK)
374 return;
375
376 static OUString aBracketedStart( C2U( "(" ) );
377 static OUString aBracketedEnd( C2U( ")" ) );
378
379 // select current unit
380 SelectNewUnit_impl( nUnitStart, nUnitEnd );
381
382 OUString aOrigTxt( pEditView->GetSelected() );
383 OUString aNewTxt( rReplaceWith );
384 String aNewOrigText;
385 switch (eAction)
386 {
387 case eExchange :
388 break;
389 case eReplacementBracketed :
390 (((aNewTxt = aOrigTxt) += aBracketedStart) += rReplaceWith) += aBracketedEnd;
391 break;
392 case eOriginalBracketed :
393 (((aNewTxt = rReplaceWith) += aBracketedStart) += aOrigTxt) += aBracketedEnd;
394 break;
395 case eReplacementAbove :
396 case eOriginalAbove :
397 case eReplacementBelow :
398 case eOriginalBelow :
399 DBG_ERROR( "Rubies not supported" );
400 break;
401 default:
402 DBG_ERROR( "unexpected case" );
403 }
404 nUnitOffset = sal::static_int_cast< sal_uInt16 >(
405 nUnitOffset + nUnitStart + aNewTxt.getLength());
406
407 // remember current original language for kater use
408 ImpEditEngine *pImpEditEng = pEditView->GetImpEditEngine();
409 ESelection _aOldSel = pEditView->GetSelection();
410 //EditSelection aOldEditSel = pEditView->GetImpEditView()->GetEditSelection();
411
412 #ifdef DBG_UTIL
413 LanguageType nOldLang = pImpEditEng->GetLanguage( pImpEditEng->CreateSel( _aOldSel ).Min() );
414 #endif
415
416 pImpEditEng->UndoActionStart( EDITUNDO_INSERT );
417
418 // according to FT we should currently not bother about keeping
419 // attributes in Hangul/Hanja conversion and leave that untouched.
420 // Thus we do this only for Chinese translation...
421 sal_Bool bIsChineseConversion = IsChinese( GetSourceLanguage() );
422 if (bIsChineseConversion)
423 ChangeText( aNewTxt, rOrigText, &rOffsets, &_aOldSel );
424 else
425 ChangeText( aNewTxt, rOrigText, NULL, NULL );
426
427 // change language and font if necessary
428 if (bIsChineseConversion)
429 {
430 DBG_ASSERT( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL,
431 "TextConvWrapper::ReplaceUnit : unexpected target language" );
432
433 ESelection aOldSel = pEditView->GetSelection();
434 ESelection aNewSel( aOldSel );
435 aNewSel.nStartPos = sal::static_int_cast< xub_StrLen >(
436 aNewSel.nStartPos - aNewTxt.getLength());
437 // DBG_ASSERT( aOldSel.nEndPos >= 0, "error while building selection" );
438
439 if (pNewUnitLanguage)
440 {
441 DBG_ASSERT(!IsSimilarChinese( *pNewUnitLanguage, nOldLang ),
442 "similar language should not be changed!");
443 SetLanguageAndFont( aNewSel, *pNewUnitLanguage, EE_CHAR_LANGUAGE_CJK,
444 GetTargetFont(), EE_CHAR_FONTINFO_CJK );
445 }
446 }
447
448 pImpEditEng->UndoActionEnd( EDITUNDO_INSERT );
449
450 // adjust ConvContinue / ConvTo if necessary
451 ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
452 ConvInfo* pConvInfo = pImpEE->GetConvInfo();
453 sal_Int32 nDelta = aNewTxt.getLength() - aOrigTxt.getLength();
454 if (nDelta != 0)
455 {
456 // Note: replacement is always done in the current paragraph
457 // which is the one ConvContinue points to
458 pConvInfo->aConvContinue.nIndex = sal::static_int_cast< sal_uInt16 >(
459 pConvInfo->aConvContinue.nIndex + nDelta);
460
461 // if that is the same as the one where the conversions ends
462 // the end needs to be updated also
463 if (pConvInfo->aConvTo.nPara == pConvInfo->aConvContinue.nPara)
464 pConvInfo->aConvTo.nIndex = sal::static_int_cast< sal_uInt16 >(
465 pConvInfo->aConvTo.nIndex + nDelta);
466 }
467 }
468
469
ChangeText(const String & rNewText,const OUString & rOrigText,const uno::Sequence<sal_Int32> * pOffsets,ESelection * pESelection)470 void TextConvWrapper::ChangeText( const String &rNewText,
471 const OUString& rOrigText,
472 const uno::Sequence< sal_Int32 > *pOffsets,
473 ESelection *pESelection )
474 {
475 //!! code is a modifed copy of SwHHCWrapper::ChangeText from sw !!
476
477 DBG_ASSERT( rNewText.Len() != 0, "unexpected empty string" );
478 if (rNewText.Len() == 0)
479 return;
480
481 if (pOffsets && pESelection) // try to keep as much attributation as possible ?
482 {
483 pESelection->Adjust();
484
485 // remember cursor start position for later setting of the cursor
486 const xub_StrLen nStartIndex = pESelection->nStartPos;
487
488 const sal_Int32 nIndices = pOffsets->getLength();
489 const sal_Int32 *pIndices = pOffsets->getConstArray();
490 xub_StrLen nConvTextLen = rNewText.Len();
491 xub_StrLen nPos = 0;
492 xub_StrLen nChgPos = STRING_NOTFOUND;
493 xub_StrLen nChgLen = 0;
494 xub_StrLen nConvChgPos = STRING_NOTFOUND;
495 xub_StrLen nConvChgLen = 0;
496
497 // offset to calculate the position in the text taking into
498 // account that text may have been replaced with new text of
499 // different length. Negative values allowed!
500 long nCorrectionOffset = 0;
501
502 DBG_ASSERT(nIndices == 0 || nIndices == nConvTextLen,
503 "mismatch between string length and sequence length!" );
504
505 // find all substrings that need to be replaced (and only those)
506 while (sal_True)
507 {
508 // get index in original text that matches nPos in new text
509 xub_StrLen nIndex;
510 if (nPos < nConvTextLen)
511 nIndex = (sal_Int32) nPos < nIndices ? (xub_StrLen) pIndices[nPos] : nPos;
512 else
513 {
514 nPos = nConvTextLen;
515 nIndex = static_cast< xub_StrLen >( rOrigText.getLength() );
516 }
517
518 if (rOrigText.getStr()[nIndex] == rNewText.GetChar(nPos) ||
519 nPos == nConvTextLen /* end of string also terminates non-matching char sequence */)
520 {
521 // substring that needs to be replaced found?
522 if (nChgPos != STRING_NOTFOUND && nConvChgPos != STRING_NOTFOUND)
523 {
524 nChgLen = nIndex - nChgPos;
525 nConvChgLen = nPos - nConvChgPos;
526 #ifdef DEBUG
527 String aInOrig( rOrigText.copy( nChgPos, nChgLen ) );
528 #endif
529 String aInNew( rNewText.Copy( nConvChgPos, nConvChgLen ) );
530
531 // set selection to sub string to be replaced in original text
532 ESelection aSel( *pESelection );
533 xub_StrLen nChgInNodeStartIndex = static_cast< xub_StrLen >( nStartIndex + nCorrectionOffset + nChgPos );
534 aSel.nStartPos = nChgInNodeStartIndex;
535 aSel.nEndPos = nChgInNodeStartIndex + nChgLen;
536 pEditView->SetSelection( aSel );
537 #ifdef DEBUG
538 String aSelTxt1( pEditView->GetSelected() );
539 #endif
540
541 // replace selected sub string with the corresponding
542 // sub string from the new text while keeping as
543 // much from the attributes as possible
544 ChangeText_impl( aInNew, sal_True );
545
546 nCorrectionOffset += nConvChgLen - nChgLen;
547
548 nChgPos = STRING_NOTFOUND;
549 nConvChgPos = STRING_NOTFOUND;
550 }
551 }
552 else
553 {
554 // begin of non-matching char sequence found ?
555 if (nChgPos == STRING_NOTFOUND && nConvChgPos == STRING_NOTFOUND)
556 {
557 nChgPos = nIndex;
558 nConvChgPos = nPos;
559 }
560 }
561 if (nPos >= nConvTextLen)
562 break;
563 ++nPos;
564 }
565
566 // set cursor to the end of the inserted text
567 // (as it would happen after ChangeText_impl (Delete and Insert)
568 // of the whole text in the 'else' branch below)
569 pESelection->nStartPos = pESelection->nEndPos = nStartIndex + nConvTextLen;
570 }
571 else
572 {
573 ChangeText_impl( rNewText, sal_False );
574 }
575 }
576
577
ChangeText_impl(const String & rNewText,sal_Bool bKeepAttributes)578 void TextConvWrapper::ChangeText_impl( const String &rNewText, sal_Bool bKeepAttributes )
579 {
580 if (bKeepAttributes)
581 {
582 // save attributes to be restored
583 SfxItemSet aSet( pEditView->GetAttribs() );
584
585 #ifdef DEBUG
586 String aSelTxt1( pEditView->GetSelected() );
587 #endif
588 // replace old text and select new text
589 pEditView->InsertText( rNewText, sal_True );
590 #ifdef DEBUG
591 String aSelTxt2( pEditView->GetSelected() );
592 #endif
593
594 // since 'SetAttribs' below function like merging with the attributes
595 // from the itemset with any existing ones we have to get rid of all
596 // all attributes now. (Those attributes that may take effect left
597 // to the position where the new text gets inserted after the old text
598 // was deleted)
599 pEditView->RemoveAttribs();
600 // apply saved attributes to new inserted text
601 pEditView->SetAttribs( aSet );
602 }
603 else
604 {
605 pEditView->InsertText( rNewText );
606 }
607 }
608
609
Convert()610 void TextConvWrapper::Convert()
611 {
612 bStartChk = sal_False;
613 ConvStart_impl( SVX_SPELL_BODY_END );
614 ConvertDocument();
615 ConvEnd_impl();
616 }
617
618
HasRubySupport() const619 sal_Bool TextConvWrapper::HasRubySupport() const
620 {
621 return sal_False;
622 }
623
624 //////////////////////////////////////////////////////////////////////
625
626