1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hyphen.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 // include ---------------------------------------------------------------
35 #include <tools/shl.hxx>
36 #include <tools/list.hxx>
37 #include <com/sun/star/linguistic2/XPossibleHyphens.hpp>
38 #include <vcl/msgbox.hxx>
41 #define _SVX_HYPHEN_CXX
43 #include <svx/dialogs.hrc>
46 #include <svx/svxenum.hxx>
48 #include <svx/splwrap.hxx>
49 #include "dlgutil.hxx"
50 #include <svx/dialmgr.hxx>
51 #include <unolingu.hxx>
52 #ifndef _USR_USTRING_HXX
53 //#include <usr/ustring.hxx>
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::beans
;
59 using namespace ::com::sun::star::linguistic2
;
63 //#define S2U(s) StringToOUString(s, CHARSET_SYSTEM)
64 //#define U2S(s) OUStringToString(s, CHARSET_SYSTEM)
66 // define ----------------------------------------------------------------
69 #define CONTINUE_HYPH USHRT_MAX
71 // Dies ist nur ein Hack, weil an dieser Stelle das extern char aus hmwrap
72 // nicht bekannt ist, wird demnaechst in hmwrap durch ein define ersetzt.
73 #define SW_SOFT_HYPHEN '='
75 // class SvxHyphenEdit ---------------------------------------------------
77 SvxHyphenEdit::SvxHyphenEdit( Window
* pParent
, const ResId
& rResId
) :
79 Edit( pParent
, rResId
)
83 // -----------------------------------------------------------------------
85 void SvxHyphenEdit::KeyInput( const KeyEvent
& rKEvt
)
87 // sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier();
88 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
93 ( (SvxHyphenWordDialog
*)GetParent() )->SelLeft();
97 ( (SvxHyphenWordDialog
*)GetParent() )->SelRight();
103 Edit::KeyInput(rKEvt
);
106 Control::KeyInput( rKEvt
); // An den Dialog weiterleiten
111 // class SvxHyphenWordDialog ---------------------------------------------
113 SvxHyphenWordDialog::SvxHyphenWordDialog( const String
&rWord
, LanguageType nLang
,
115 Reference
< XHyphenator
> &xHyphen
,
116 SvxSpellWrapper
* pWrapper
) :
117 SfxModalDialog( pParent
, SVX_RES( RID_SVXDLG_HYPHENATE
) ),
119 aWordFT ( this, SVX_RES( FT_WORD
) ),
120 aWordEdit ( this, SVX_RES( ED_WORD
) ),
121 aLeftBtn ( this, SVX_RES( BTN_LEFT
) ),
122 aRightBtn ( this, SVX_RES( BTN_RIGHT
) ),
123 aOkBtn ( this, SVX_RES( BTN_HYPH_CUT
) ),
124 aCancelBtn ( this, SVX_RES( BTN_HYPH_CANCEL
) ),
125 aContBtn ( this, SVX_RES( BTN_HYPH_CONTINUE
) ),
126 aDelBtn ( this, SVX_RES( BTN_HYPH_DELETE
) ),
127 aHelpBtn ( this, SVX_RES( BTN_HYPH_HELP
) ),
128 aLabel ( GetText() ),
129 pHyphWrapper ( pWrapper
),
130 xHyphenator ( xHyphen
),
132 nActLanguage ( nLang
),
137 aContBtn
.SetClickHdl(
138 LINK( this, SvxHyphenWordDialog
, ContinueHdl_Impl
) );
139 aOkBtn
.SetClickHdl( LINK( this, SvxHyphenWordDialog
, CutHdl_Impl
) );
140 aDelBtn
.SetClickHdl( LINK( this, SvxHyphenWordDialog
, DeleteHdl_Impl
) );
141 aCancelBtn
.SetClickHdl(
142 LINK( this, SvxHyphenWordDialog
, CancelHdl_Impl
) );
143 aLeftBtn
.SetClickHdl( LINK( this, SvxHyphenWordDialog
, Left_Impl
) );
144 aRightBtn
.SetClickHdl( LINK( this, SvxHyphenWordDialog
, Right_Impl
) );
146 aWordEdit
.SetGetFocusHdl(
147 LINK( this, SvxHyphenWordDialog
, GetFocusHdl_Impl
) );
149 Reference
< XHyphenatedWord
> xHyphWord( pWrapper
?
150 pWrapper
->GetLast() : Reference
< XInterface
> () , UNO_QUERY
);
151 DBG_ASSERT(xHyphWord
.is(), "missing hyphenated word");
152 nMaxHyphenationPos
= xHyphWord
.is() ? xHyphWord
->getHyphenationPos() : 0;
153 SetLabel_Impl( nLang
);
156 aWordEdit
.GrabFocus();
160 // disable controls if service is not available
161 if (!xHyphenator
.is())
165 // -----------------------------------------------------------------------
167 void SvxHyphenWordDialog::SelLeft()
169 String
aTxt( aWordEdit
.GetText() );
171 for ( xub_StrLen i
= nOldPos
+ 1; i
-- > 0 ; )
173 DBG_ASSERT(i
<= aTxt
.Len(), "index out of range");
174 if( aTxt
.GetChar( i
) == sal_Unicode( SW_SOFT_HYPHEN
) )
176 aTxt
.SetChar( i
, sal_Unicode( HYPHHERE
) );
178 if ( nOldPos
!= 0 && nOldPos
!= aTxt
.Len() )
179 aTxt
.SetChar( nOldPos
, sal_Unicode( SW_SOFT_HYPHEN
) );
181 aWordEdit
.SetText( aTxt
);
182 aWordEdit
.GrabFocus();
183 aWordEdit
.SetSelection( Selection( i
, i
+ 1 ) );
187 nHyphPos
= GetHyphIndex_Impl();
191 // -----------------------------------------------------------------------
193 void SvxHyphenWordDialog::SelRight()
195 String
aTxt( aWordEdit
.GetText() );
197 for ( xub_StrLen i
= nOldPos
+ 1; i
< aTxt
.Len(); ++i
)
199 if( aTxt
.GetChar( i
) == sal_Unicode( SW_SOFT_HYPHEN
) )
201 aTxt
.SetChar( i
, sal_Unicode( HYPHHERE
) );
203 if ( nOldPos
!= 0 && nOldPos
!= aTxt
.Len() )
204 aTxt
.SetChar( nOldPos
, sal_Unicode( SW_SOFT_HYPHEN
) );
206 aWordEdit
.SetText( aTxt
);
207 aWordEdit
.GrabFocus();
208 aWordEdit
.SetSelection( Selection( i
, i
+ 1 ) );
212 nHyphPos
= GetHyphIndex_Impl();
216 // -----------------------------------------------------------------------
218 void SvxHyphenWordDialog::EnableLRBtn_Impl()
220 String
aTxt( aWordEdit
.GetText() );
221 xub_StrLen nLen
= aTxt
.Len();
225 for ( i
= nOldPos
+ 2; i
< nLen
; ++i
)
227 if ( aTxt
.GetChar( i
) == sal_Unicode( SW_SOFT_HYPHEN
) )
234 DBG_ASSERT(nOldPos
< aTxt
.Len(), "nOldPos out of range");
235 if (nOldPos
>= aTxt
.Len())
236 nOldPos
= aTxt
.Len() - 1;
238 for ( i
= nOldPos
; i
-- > 0; )
240 if ( aTxt
.GetChar( i
) == sal_Unicode( SW_SOFT_HYPHEN
) )
248 // -----------------------------------------------------------------------
251 void SvxHyphenWordDialog::SetLabel_Impl( LanguageType nLang
)
253 String
aLangStr( ::GetLanguageString( nLang
) );
254 String
aTmp( aLabel
);
255 aTmp
.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) );
256 aTmp
.Append( aLangStr
);
257 aTmp
.Append( sal_Unicode( ')' ) );
261 // -----------------------------------------------------------------------
263 String
SvxHyphenWordDialog::EraseUnusableHyphens_Impl(
264 Reference
< XPossibleHyphens
> &rxPossHyph
,
265 sal_uInt16 _nMaxHyphenationPos
)
267 // returns a String showing only those hyphen positions which will result
268 // in a line break if hyphenation is done there
271 DBG_ASSERT(rxPossHyph
.is(), "missing possible hyphens");
274 aTxt
= String( rxPossHyph
->getPossibleHyphens() );
276 Sequence
< sal_Int16
> aHyphenationPositions(
277 rxPossHyph
->getHyphenationPositions() );
278 sal_Int32 nLen
= aHyphenationPositions
.getLength();
279 const sal_Int16
*pHyphenationPos
= aHyphenationPositions
.getConstArray();
281 // find position nIdx after which all hyphen positions are unusable
282 xub_StrLen nIdx
= STRING_NOTFOUND
,
286 xub_StrLen nStart
= 0;
287 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
289 if (pHyphenationPos
[i
] > _nMaxHyphenationPos
)
293 // find corresponding hyphen pos in string
294 nPos
= aTxt
.Search( sal_Unicode( SW_SOFT_HYPHEN
), nStart
);
296 if (nStart
== STRING_NOTFOUND
)
306 DBG_ASSERT(nIdx
!= STRING_NOTFOUND
, "no usable hyphenation position");
308 // remove not usable hyphens from string
309 nPos
= nIdx
== STRING_NOTFOUND
? 0 : nIdx
+ 1;
310 String
aTmp( sal_Unicode( SW_SOFT_HYPHEN
) ),
312 while (nPos
!= STRING_NOTFOUND
)
313 nPos
= aTxt
.SearchAndReplace( aTmp
, aEmpty
, nPos
+ 1 );
318 // -----------------------------------------------------------------------
320 void SvxHyphenWordDialog::InitControls_Impl()
324 if (xHyphenator
.is())
326 lang::Locale
aLocale( SvxCreateLocale(nActLanguage
) );
327 xPossHyph
= xHyphenator
->createPossibleHyphens( aActWord
, aLocale
,
328 Sequence
< PropertyValue
>() );
331 aTxt
= EraseUnusableHyphens_Impl( xPossHyph
, nMaxHyphenationPos
);
333 SetLabel_Impl( nActLanguage
);
335 aWordEdit
.SetText( aTxt
);
337 nOldPos
= aTxt
.Len();
342 // -----------------------------------------------------------------------
344 void SvxHyphenWordDialog::ContinueHyph_Impl( sal_uInt16 nInsPos
)
346 if ( nInsPos
!= CONTINUE_HYPH
&& xPossHyph
.is())
350 //String aTmp( U2S( xPossHyph->getPossibleHyphens() ) );
351 String
aTmp( aWordEdit
.GetText() );
352 DBG_ASSERT(nInsPos
<= aTmp
.Len() - 2, "wrong hyphen position");
354 sal_uInt16 nIdxPos
= 0;
357 while (i
< aTmp
.Len() && HYPHHERE
!= (c
= aTmp
.GetChar(i
++)) )
359 if (SW_SOFT_HYPHEN
== c
)
363 Sequence
< sal_Int16
> aSeq
= xPossHyph
->getHyphenationPositions();
364 sal_Int32 nLen
= aSeq
.getLength();
365 DBG_ASSERT(nLen
, "empty sequence");
366 DBG_ASSERT(nIdxPos
< nLen
, "index out of range");
367 if (nLen
&& nIdxPos
< nLen
)
369 nInsPos
= aSeq
.getConstArray()[ nIdxPos
];
370 pHyphWrapper
->InsertHyphen( nInsPos
);
375 //! calling with 0 as argument will remove hyphens!
376 pHyphWrapper
->InsertHyphen( nInsPos
);
380 if ( pHyphWrapper
->FindSpellError() )
382 Reference
< XHyphenatedWord
> xHyphWord( pHyphWrapper
->GetLast(), UNO_QUERY
);
384 // adapt actual word and language to new found hyphenation result
387 aActWord
= String( xHyphWord
->getWord() );
388 nActLanguage
= SvxLocaleToLanguage( xHyphWord
->getLocale() );
389 nMaxHyphenationPos
= xHyphWord
->getHyphenationPos();
397 // -----------------------------------------------------------------------
399 sal_uInt16
SvxHyphenWordDialog::GetHyphIndex_Impl()
402 String
aTxt(aWordEdit
.GetText());
404 for ( sal_uInt16 i
=0 ; i
< aTxt
.Len(); ++i
)
406 sal_Unicode nChar
= aTxt
.GetChar( i
);
408 if ( nChar
== HYPHHERE
)
411 if ( nChar
!= SW_SOFT_HYPHEN
)
417 // -----------------------------------------------------------------------
419 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, CutHdl_Impl
, Button
*, EMPTYARG
)
424 ContinueHyph_Impl( nHyphPos
);
429 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, CutHdl_Impl
, Button
*, EMPTYARG
)
431 // -----------------------------------------------------------------------
433 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, DeleteHdl_Impl
, Button
*, EMPTYARG
)
443 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, DeleteHdl_Impl
, Button
*, EMPTYARG
)
445 // -----------------------------------------------------------------------
447 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, ContinueHdl_Impl
, Button
*, EMPTYARG
)
452 ContinueHyph_Impl( CONTINUE_HYPH
);
457 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, ContinueHdl_Impl
, Button
*, EMPTYARG
)
459 // -----------------------------------------------------------------------
461 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, CancelHdl_Impl
, Button
*, EMPTYARG
)
466 pHyphWrapper
->SpellEnd();
467 EndDialog( RET_CANCEL
);
472 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, CancelHdl_Impl
, Button
*, EMPTYARG
)
474 // -----------------------------------------------------------------------
476 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, Left_Impl
, Button
*, EMPTYARG
)
486 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, Left_Impl
, Button
*, EMPTYARG
)
488 // -----------------------------------------------------------------------
490 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, Right_Impl
, Button
*, EMPTYARG
)
500 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, Right_Impl
, Button
*, EMPTYARG
)
502 // -----------------------------------------------------------------------
504 IMPL_LINK_INLINE_START( SvxHyphenWordDialog
, GetFocusHdl_Impl
, Edit
*, EMPTYARG
)
506 aWordEdit
.SetSelection( Selection( nOldPos
, nOldPos
+ 1 ) );
509 IMPL_LINK_INLINE_END( SvxHyphenWordDialog
, GetFocusHdl_Impl
, Edit
*, EMPTYARG
)
511 // -----------------------------------------------------------------------
513 IMPL_LINK( SvxHyphenWordDialog
, LangError_Impl
, void *, nLang
)
516 String
aErr( ::GetLanguageString( (LanguageType
)(sal_IntPtr
)nLang
) );
517 aErr
+= SVX_RESSTR( RID_SVXSTR_HMERR_CHECKINSTALL
);
518 InfoBox( this, aErr
).Execute();