1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_cui.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "hyphen.hxx" 32*cdf0e10cSrcweir #include "hyphen.hrc" 33*cdf0e10cSrcweir #include "cuires.hrc" 34*cdf0e10cSrcweir #include "dialmgr.hxx" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include <editeng/splwrap.hxx> 37*cdf0e10cSrcweir #include <editeng/svxenum.hxx> 38*cdf0e10cSrcweir #include <editeng/unolingu.hxx> 39*cdf0e10cSrcweir #include <svtools/langtab.hxx> 40*cdf0e10cSrcweir #include <svx/dialmgr.hxx> 41*cdf0e10cSrcweir #include <svx/dlgutil.hxx> 42*cdf0e10cSrcweir #include <tools/list.hxx> 43*cdf0e10cSrcweir #include <tools/shl.hxx> 44*cdf0e10cSrcweir #include <vcl/msgbox.hxx> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir #include <com/sun/star/linguistic2/XPossibleHyphens.hpp> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir using namespace ::com::sun::star; 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #define HYPH_POS_CHAR '=' 52*cdf0e10cSrcweir #define CONTINUE_HYPH USHRT_MAX 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #define CUR_HYPH_POS_CHAR '-' 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir // class HyphenEdit_Impl ------------------------------------------------------- 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir class HyphenEdit_Impl : public Edit 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir public: 62*cdf0e10cSrcweir HyphenEdit_Impl( Window* pParent, const ResId& rResId ); 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir protected: 65*cdf0e10cSrcweir virtual void KeyInput( const KeyEvent &rKEvt ); 66*cdf0e10cSrcweir }; 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir HyphenEdit_Impl::HyphenEdit_Impl( Window* pParent, const ResId& rResId ) : 70*cdf0e10cSrcweir Edit( pParent, rResId ) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir } 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir void HyphenEdit_Impl::KeyInput( const KeyEvent& rKEvt ) 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir // sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier(); 78*cdf0e10cSrcweir sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir switch ( nCode ) 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir case KEY_LEFT: 83*cdf0e10cSrcweir ( (SvxHyphenWordDialog*)GetParent() )->SelLeft(); 84*cdf0e10cSrcweir break; 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir case KEY_RIGHT: 87*cdf0e10cSrcweir ( (SvxHyphenWordDialog*)GetParent() )->SelRight(); 88*cdf0e10cSrcweir break; 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir case KEY_TAB: 91*cdf0e10cSrcweir case KEY_ESCAPE: 92*cdf0e10cSrcweir case KEY_RETURN: 93*cdf0e10cSrcweir Edit::KeyInput(rKEvt); 94*cdf0e10cSrcweir break; 95*cdf0e10cSrcweir default: 96*cdf0e10cSrcweir Control::KeyInput( rKEvt ); // An den Dialog weiterleiten 97*cdf0e10cSrcweir break; 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir // struct SvxHyphenWordDialog_Impl --------------------------------------------- 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir struct SvxHyphenWordDialog_Impl 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir SvxHyphenWordDialog * m_pDialog; 107*cdf0e10cSrcweir // Window * m_pParent; 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir FixedText aWordFT; 110*cdf0e10cSrcweir HyphenEdit_Impl aWordEdit; 111*cdf0e10cSrcweir ImageButton aLeftBtn; 112*cdf0e10cSrcweir ImageButton aRightBtn; 113*cdf0e10cSrcweir OKButton aOkBtn; 114*cdf0e10cSrcweir PushButton aContBtn; 115*cdf0e10cSrcweir PushButton aDelBtn; 116*cdf0e10cSrcweir FixedLine aFLBottom; 117*cdf0e10cSrcweir HelpButton aHelpBtn; 118*cdf0e10cSrcweir PushButton aHyphAll; 119*cdf0e10cSrcweir CancelButton aCancelBtn; 120*cdf0e10cSrcweir String aLabel; 121*cdf0e10cSrcweir SvxSpellWrapper* pHyphWrapper; 122*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenator > xHyphenator; 123*cdf0e10cSrcweir uno::Reference< linguistic2::XPossibleHyphens > xPossHyph; 124*cdf0e10cSrcweir String aEditWord; // aEditWord and aWordEdit.GetText() differ only by the character for the current selected hyphenation position 125*cdf0e10cSrcweir String aActWord; // actual word to be hyphenated 126*cdf0e10cSrcweir LanguageType nActLanguage; // and its language 127*cdf0e10cSrcweir sal_uInt16 nMaxHyphenationPos; // right most valid hyphenation pos 128*cdf0e10cSrcweir sal_uInt16 nHyphPos; 129*cdf0e10cSrcweir sal_uInt16 nOldPos; 130*cdf0e10cSrcweir sal_Int32 nHyphenationPositionsOffset; 131*cdf0e10cSrcweir sal_Bool bBusy; 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir void EnableLRBtn_Impl(); 135*cdf0e10cSrcweir String EraseUnusableHyphens_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XPossibleHyphens > &rxPossHyph, sal_uInt16 nMaxHyphenationPos ); 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir void InitControls_Impl(); 138*cdf0e10cSrcweir void ContinueHyph_Impl( sal_uInt16 nInsPos = 0 ); 139*cdf0e10cSrcweir sal_uInt16 GetHyphIndex_Impl(); 140*cdf0e10cSrcweir void SelLeft_Impl(); 141*cdf0e10cSrcweir void SelRight_Impl(); 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir DECL_LINK( Left_Impl, Button* ); 144*cdf0e10cSrcweir DECL_LINK( Right_Impl, Button* ); 145*cdf0e10cSrcweir DECL_LINK( CutHdl_Impl, Button* ); 146*cdf0e10cSrcweir DECL_LINK( ContinueHdl_Impl, Button* ); 147*cdf0e10cSrcweir DECL_LINK( DeleteHdl_Impl, Button* ); 148*cdf0e10cSrcweir DECL_LINK( HyphenateAllHdl_Impl, Button* ); 149*cdf0e10cSrcweir DECL_LINK( CancelHdl_Impl, Button* ); 150*cdf0e10cSrcweir DECL_LINK( GetFocusHdl_Impl, Edit* ); 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir SvxHyphenWordDialog_Impl( 154*cdf0e10cSrcweir SvxHyphenWordDialog * pDialog, 155*cdf0e10cSrcweir const String &rWord, 156*cdf0e10cSrcweir LanguageType nLang, 157*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenator > &xHyphen, 158*cdf0e10cSrcweir SvxSpellWrapper* pWrapper ); 159*cdf0e10cSrcweir ~SvxHyphenWordDialog_Impl(); 160*cdf0e10cSrcweir }; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir SvxHyphenWordDialog_Impl::SvxHyphenWordDialog_Impl( 164*cdf0e10cSrcweir SvxHyphenWordDialog * pDialog, 165*cdf0e10cSrcweir const String &rWord, 166*cdf0e10cSrcweir LanguageType nLang, 167*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenator > &xHyphen, 168*cdf0e10cSrcweir SvxSpellWrapper* pWrapper ) : 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir m_pDialog ( pDialog ), 171*cdf0e10cSrcweir aWordFT ( pDialog, CUI_RES( FT_WORD ) ), 172*cdf0e10cSrcweir aWordEdit ( pDialog, CUI_RES( ED_WORD ) ), 173*cdf0e10cSrcweir aLeftBtn ( pDialog, CUI_RES( BTN_LEFT ) ), 174*cdf0e10cSrcweir aRightBtn ( pDialog, CUI_RES( BTN_RIGHT ) ), 175*cdf0e10cSrcweir aOkBtn ( pDialog, CUI_RES( BTN_HYPH_CUT ) ), 176*cdf0e10cSrcweir aContBtn ( pDialog, CUI_RES( BTN_HYPH_CONTINUE ) ), 177*cdf0e10cSrcweir aDelBtn ( pDialog, CUI_RES( BTN_HYPH_DELETE ) ), 178*cdf0e10cSrcweir aFLBottom ( pDialog, CUI_RES( FL_BOTTOM ) ), 179*cdf0e10cSrcweir aHelpBtn ( pDialog, CUI_RES( BTN_HYPH_HELP ) ), 180*cdf0e10cSrcweir aHyphAll ( pDialog, CUI_RES( BTN_HYPH_ALL ) ), 181*cdf0e10cSrcweir aCancelBtn ( pDialog, CUI_RES( BTN_HYPH_CANCEL ) ), 182*cdf0e10cSrcweir aLabel ( pDialog->GetText() ), 183*cdf0e10cSrcweir pHyphWrapper ( NULL ), 184*cdf0e10cSrcweir xHyphenator ( NULL ), 185*cdf0e10cSrcweir xPossHyph ( NULL ), 186*cdf0e10cSrcweir aActWord ( ), 187*cdf0e10cSrcweir nActLanguage ( LANGUAGE_NONE ), 188*cdf0e10cSrcweir nMaxHyphenationPos ( 0 ), 189*cdf0e10cSrcweir nHyphPos ( 0 ), 190*cdf0e10cSrcweir nOldPos ( 0 ), 191*cdf0e10cSrcweir nHyphenationPositionsOffset( 0 ), 192*cdf0e10cSrcweir bBusy ( sal_False ) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir aActWord = rWord; 195*cdf0e10cSrcweir nActLanguage = nLang; 196*cdf0e10cSrcweir xHyphenator = xHyphen; 197*cdf0e10cSrcweir pHyphWrapper = pWrapper; 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenatedWord > xHyphWord( pHyphWrapper ? 200*cdf0e10cSrcweir pHyphWrapper->GetLast() : NULL, uno::UNO_QUERY ); 201*cdf0e10cSrcweir DBG_ASSERT( xHyphWord.is(), "hyphenation result missing" ); 202*cdf0e10cSrcweir if (xHyphWord.is()) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir DBG_ASSERT( aActWord == String( xHyphWord->getWord() ), "word mismatch" ); 205*cdf0e10cSrcweir DBG_ASSERT( nActLanguage == SvxLocaleToLanguage( xHyphWord->getLocale() ), "language mismatch" ); 206*cdf0e10cSrcweir nMaxHyphenationPos = xHyphWord->getHyphenationPos(); 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir InitControls_Impl(); 210*cdf0e10cSrcweir aWordEdit.GrabFocus(); 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir aLeftBtn.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, Left_Impl ) ); 213*cdf0e10cSrcweir aRightBtn.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, Right_Impl ) ); 214*cdf0e10cSrcweir aOkBtn.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, CutHdl_Impl ) ); 215*cdf0e10cSrcweir aContBtn.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, ContinueHdl_Impl ) ); 216*cdf0e10cSrcweir aDelBtn.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, DeleteHdl_Impl ) ); 217*cdf0e10cSrcweir aHyphAll.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, HyphenateAllHdl_Impl ) ); 218*cdf0e10cSrcweir aCancelBtn.SetClickHdl( LINK( this, SvxHyphenWordDialog_Impl, CancelHdl_Impl ) ); 219*cdf0e10cSrcweir aWordEdit.SetGetFocusHdl( LINK( this, SvxHyphenWordDialog_Impl, GetFocusHdl_Impl ) ); 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir SvxHyphenWordDialog_Impl::~SvxHyphenWordDialog_Impl() 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir void SvxHyphenWordDialog_Impl::EnableLRBtn_Impl() 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir String aTxt( aEditWord ); 231*cdf0e10cSrcweir xub_StrLen nLen = aTxt.Len(); 232*cdf0e10cSrcweir xub_StrLen i; 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir aRightBtn.Disable(); 235*cdf0e10cSrcweir for ( i = nOldPos + 2; i < nLen; ++i ) 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir if ( aTxt.GetChar( i ) == sal_Unicode( HYPH_POS_CHAR ) ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir aRightBtn.Enable(); 240*cdf0e10cSrcweir break; 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir DBG_ASSERT(nOldPos < aTxt.Len(), "nOldPos out of range"); 245*cdf0e10cSrcweir if (nOldPos >= aTxt.Len()) 246*cdf0e10cSrcweir nOldPos = aTxt.Len() - 1; 247*cdf0e10cSrcweir aLeftBtn.Disable(); 248*cdf0e10cSrcweir for ( i = nOldPos; i-- > 0; ) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir if ( aTxt.GetChar( i ) == sal_Unicode( HYPH_POS_CHAR ) ) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir aLeftBtn.Enable(); 253*cdf0e10cSrcweir break; 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir String SvxHyphenWordDialog_Impl::EraseUnusableHyphens_Impl( 260*cdf0e10cSrcweir uno::Reference< linguistic2::XPossibleHyphens > &rxPossHyph, 261*cdf0e10cSrcweir sal_uInt16 _nMaxHyphenationPos ) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir // returns a String showing only those hyphen positions which will result 264*cdf0e10cSrcweir // in a line break if hyphenation is done there 265*cdf0e10cSrcweir // 1) we will need to discard all hyphenation positions at th end that 266*cdf0e10cSrcweir // will not result in a line break where the text to the left still fits 267*cdf0e10cSrcweir // on the line. 268*cdf0e10cSrcweir // 2) since as from OOo 3.2 '-' are part of a word an thus text like 269*cdf0e10cSrcweir // 'multi-line-editor' is regarded as single word we also need to discard those 270*cdf0e10cSrcweir // hyphenation positions to the left of the rightmost '-' that is still left of 271*cdf0e10cSrcweir // the rightmost valid hyphenation position according to 1) 272*cdf0e10cSrcweir // 273*cdf0e10cSrcweir // Example: 274*cdf0e10cSrcweir // If the possible hyphenation position in 'multi-line-editor' are to eb marked 275*cdf0e10cSrcweir // by '=' then the text will look like this 'mul=ti-line-ed=it=or'. 276*cdf0e10cSrcweir // If now the first line is only large enough for 'multi-line-edi' we need to discard 277*cdf0e10cSrcweir // the last possible hyphnation point because of 1). The the right most valid 278*cdf0e10cSrcweir // hyphenation position is "ed=itor". The first '-' left of this position is 279*cdf0e10cSrcweir // "line-ed", thus because of 2) we now need to discard all possible hyphneation 280*cdf0e10cSrcweir // positions to the left of that as well. Thus in the end leaving us with just 281*cdf0e10cSrcweir // 'multi-line-ed=itor' as return value for this function. (Just one valid hyphenation 282*cdf0e10cSrcweir // position for the user too choose from. However ALL the '-' characters in the word 283*cdf0e10cSrcweir // will ALWAYS be valid implicit hyphenation positions for the core to choose from! 284*cdf0e10cSrcweir // And thus even if this word is skipped in the hyphenation dialog it will still be broken 285*cdf0e10cSrcweir // right after 'multi-line-' (actually it might already be broken up that way before 286*cdf0e10cSrcweir // the hyphenation dialog is called!). 287*cdf0e10cSrcweir // Thus rule 2) just eliminates those positions which will not be used by the core at all 288*cdf0e10cSrcweir // even if the user were to select one of them. 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir String aTxt; 291*cdf0e10cSrcweir DBG_ASSERT(rxPossHyph.is(), "missing possible hyphens"); 292*cdf0e10cSrcweir if (rxPossHyph.is()) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir DBG_ASSERT( aActWord == String( rxPossHyph->getWord() ), "word mismatch" ); 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir aTxt = String( rxPossHyph->getPossibleHyphens() ); 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir nHyphenationPositionsOffset = 0; 299*cdf0e10cSrcweir uno::Sequence< sal_Int16 > aHyphenationPositions( 300*cdf0e10cSrcweir rxPossHyph->getHyphenationPositions() ); 301*cdf0e10cSrcweir sal_Int32 nLen = aHyphenationPositions.getLength(); 302*cdf0e10cSrcweir const sal_Int16 *pHyphenationPos = aHyphenationPositions.getConstArray(); 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir // find position nIdx after which all hyphen positions are unusable 305*cdf0e10cSrcweir xub_StrLen nIdx = STRING_NOTFOUND; 306*cdf0e10cSrcweir xub_StrLen nPos = 0, nPos1 = 0, nPos2 = 0; 307*cdf0e10cSrcweir if (nLen) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir xub_StrLen nStart = 0; 310*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir if (pHyphenationPos[i] > _nMaxHyphenationPos) 313*cdf0e10cSrcweir break; 314*cdf0e10cSrcweir else 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir // find corresponding hyphen pos in string 317*cdf0e10cSrcweir nPos = aTxt.Search( sal_Unicode( HYPH_POS_CHAR ), nStart ); 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir if (nStart == STRING_NOTFOUND) 320*cdf0e10cSrcweir break; 321*cdf0e10cSrcweir else 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir nIdx = nPos; 324*cdf0e10cSrcweir nStart = nPos + 1; 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir DBG_ASSERT(nIdx != STRING_NOTFOUND, "no usable hyphenation position"); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir // 1) remove all not usable hyphenation positions from the end of the string 332*cdf0e10cSrcweir nPos = nIdx == STRING_NOTFOUND ? 0 : nIdx + 1; 333*cdf0e10cSrcweir nPos1 = nPos; //save for later use in 2) below 334*cdf0e10cSrcweir const String aTmp( sal_Unicode( HYPH_POS_CHAR ) ); 335*cdf0e10cSrcweir const String aEmpty; 336*cdf0e10cSrcweir while (nPos != STRING_NOTFOUND) 337*cdf0e10cSrcweir nPos = aTxt.SearchAndReplace( aTmp, aEmpty, nPos + 1 ); 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir // 2) remove all hyphenation positions from the start that are not considered by the core 340*cdf0e10cSrcweir const String aSearchRange( aTxt.Copy( 0, nPos1 ) ); 341*cdf0e10cSrcweir nPos2 = aSearchRange.SearchBackward( '-' ); // the '-' position the core will use by default 342*cdf0e10cSrcweir if (nPos2 != STRING_NOTFOUND) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir String aLeft( aSearchRange.Copy( 0, nPos2 ) ); 345*cdf0e10cSrcweir nPos = 0; 346*cdf0e10cSrcweir while (nPos != STRING_NOTFOUND) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir nPos = aLeft.SearchAndReplace( aTmp, aEmpty, nPos + 1 ); 349*cdf0e10cSrcweir if (nPos != STRING_NOTFOUND) 350*cdf0e10cSrcweir ++nHyphenationPositionsOffset; 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir aTxt.Replace( 0, nPos2, aLeft ); 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir return aTxt; 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir void SvxHyphenWordDialog_Impl::InitControls_Impl() 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir xPossHyph = NULL; 362*cdf0e10cSrcweir if (xHyphenator.is()) 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir lang::Locale aLocale( SvxCreateLocale(nActLanguage) ); 365*cdf0e10cSrcweir xPossHyph = xHyphenator->createPossibleHyphens( aActWord, aLocale, 366*cdf0e10cSrcweir uno::Sequence< beans::PropertyValue >() ); 367*cdf0e10cSrcweir if (xPossHyph.is()) 368*cdf0e10cSrcweir aEditWord = EraseUnusableHyphens_Impl( xPossHyph, nMaxHyphenationPos ); 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir aWordEdit.SetText( aEditWord ); 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir nOldPos = aEditWord.Len(); 373*cdf0e10cSrcweir SelLeft_Impl(); 374*cdf0e10cSrcweir EnableLRBtn_Impl(); 375*cdf0e10cSrcweir } 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir void SvxHyphenWordDialog_Impl::ContinueHyph_Impl( sal_uInt16 nInsPos ) 379*cdf0e10cSrcweir { 380*cdf0e10cSrcweir if ( nInsPos != CONTINUE_HYPH && xPossHyph.is()) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir if (nInsPos) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir String aTmp( aEditWord ); 385*cdf0e10cSrcweir DBG_ASSERT(nInsPos <= aTmp.Len() - 2, "wrong hyphen position"); 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir sal_Int16 nIdxPos = -1; 388*cdf0e10cSrcweir for (sal_uInt16 i = 0; i <= nInsPos; ++i) 389*cdf0e10cSrcweir { 390*cdf0e10cSrcweir if (HYPH_POS_CHAR == aTmp.GetChar( i )) 391*cdf0e10cSrcweir nIdxPos++; 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir // take the possible hyphenation positions that got removed from the 394*cdf0e10cSrcweir // start of the wor dinot account: 395*cdf0e10cSrcweir nIdxPos += nHyphenationPositionsOffset; 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir uno::Sequence< sal_Int16 > aSeq = xPossHyph->getHyphenationPositions(); 398*cdf0e10cSrcweir sal_Int32 nLen = aSeq.getLength(); 399*cdf0e10cSrcweir DBG_ASSERT(nLen, "empty sequence"); 400*cdf0e10cSrcweir DBG_ASSERT(0 <= nIdxPos && nIdxPos < nLen, "index out of range"); 401*cdf0e10cSrcweir if (nLen && 0 <= nIdxPos && nIdxPos < nLen) 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir nInsPos = aSeq.getConstArray()[ nIdxPos ]; 404*cdf0e10cSrcweir pHyphWrapper->InsertHyphen( nInsPos ); 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir else 408*cdf0e10cSrcweir { 409*cdf0e10cSrcweir //! calling with 0 as argument will remove hyphens! 410*cdf0e10cSrcweir pHyphWrapper->InsertHyphen( nInsPos ); 411*cdf0e10cSrcweir } 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir if ( pHyphWrapper->FindSpellError() ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenatedWord > xHyphWord( pHyphWrapper->GetLast(), uno::UNO_QUERY ); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir // adapt actual word and language to new found hyphenation result 419*cdf0e10cSrcweir if(xHyphWord.is()) 420*cdf0e10cSrcweir { 421*cdf0e10cSrcweir aActWord = String( xHyphWord->getWord() ); 422*cdf0e10cSrcweir nActLanguage = SvxLocaleToLanguage( xHyphWord->getLocale() ); 423*cdf0e10cSrcweir nMaxHyphenationPos = xHyphWord->getHyphenationPos(); 424*cdf0e10cSrcweir InitControls_Impl(); 425*cdf0e10cSrcweir m_pDialog->SetWindowTitle( nActLanguage ); 426*cdf0e10cSrcweir } 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir else 429*cdf0e10cSrcweir m_pDialog->EndDialog( RET_OK ); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir sal_uInt16 SvxHyphenWordDialog_Impl::GetHyphIndex_Impl() 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir sal_uInt16 nPos = 0; 436*cdf0e10cSrcweir String aTxt( aWordEdit.GetText() ); 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir for ( sal_uInt16 i=0 ; i < aTxt.Len(); ++i ) 439*cdf0e10cSrcweir { 440*cdf0e10cSrcweir sal_Unicode cChar = aTxt.GetChar( i ); 441*cdf0e10cSrcweir if ( cChar == CUR_HYPH_POS_CHAR ) 442*cdf0e10cSrcweir break; 443*cdf0e10cSrcweir if ( cChar != HYPH_POS_CHAR ) 444*cdf0e10cSrcweir nPos++; 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir return nPos; 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir void SvxHyphenWordDialog_Impl::SelLeft_Impl() 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir DBG_ASSERT( nOldPos > 0, "invalid hyphenation position" ); 453*cdf0e10cSrcweir if (nOldPos > 0) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir String aTxt( aEditWord ); 456*cdf0e10cSrcweir for ( xub_StrLen i = nOldPos - 1; i > 0; --i) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir DBG_ASSERT(i <= aTxt.Len(), "index out of range"); 459*cdf0e10cSrcweir if (aTxt.GetChar( i ) == sal_Unicode( HYPH_POS_CHAR )) 460*cdf0e10cSrcweir { 461*cdf0e10cSrcweir aTxt.SetChar( i, sal_Unicode( CUR_HYPH_POS_CHAR ) ); 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir nOldPos = i; 464*cdf0e10cSrcweir aWordEdit.SetText( aTxt ); 465*cdf0e10cSrcweir aWordEdit.GrabFocus(); 466*cdf0e10cSrcweir aWordEdit.SetSelection( Selection( i, i + 1 ) ); 467*cdf0e10cSrcweir break; 468*cdf0e10cSrcweir } 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir nHyphPos = GetHyphIndex_Impl(); 471*cdf0e10cSrcweir EnableLRBtn_Impl(); 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir void SvxHyphenWordDialog_Impl::SelRight_Impl() 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir String aTxt( aEditWord ); 479*cdf0e10cSrcweir for ( xub_StrLen i = nOldPos + 1; i < aTxt.Len(); ++i ) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir if (aTxt.GetChar( i ) == sal_Unicode( HYPH_POS_CHAR )) 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir aTxt.SetChar( i, sal_Unicode( CUR_HYPH_POS_CHAR ) ); 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir nOldPos = i; 486*cdf0e10cSrcweir aWordEdit.SetText( aTxt ); 487*cdf0e10cSrcweir aWordEdit.GrabFocus(); 488*cdf0e10cSrcweir aWordEdit.SetSelection( Selection( i, i + 1 ) ); 489*cdf0e10cSrcweir break; 490*cdf0e10cSrcweir } 491*cdf0e10cSrcweir } 492*cdf0e10cSrcweir nHyphPos = GetHyphIndex_Impl(); 493*cdf0e10cSrcweir EnableLRBtn_Impl(); 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, CutHdl_Impl, Button *, EMPTYARG ) 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir if( !bBusy ) 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir bBusy = sal_True; 502*cdf0e10cSrcweir ContinueHyph_Impl( /*nHyphPos*/nOldPos ); 503*cdf0e10cSrcweir bBusy = sal_False; 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir return 0; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, HyphenateAllHdl_Impl, Button *, EMPTYARG /*pButton*/ ) 510*cdf0e10cSrcweir { 511*cdf0e10cSrcweir if( !bBusy ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir try 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xProp( SvxGetLinguPropertySet() ); 516*cdf0e10cSrcweir const rtl::OUString aName( rtl::OUString::createFromAscii( "IsHyphAuto" ) ); 517*cdf0e10cSrcweir uno::Any aAny; 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir aAny <<= sal_True; 520*cdf0e10cSrcweir xProp->setPropertyValue( aName, aAny ); 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir bBusy = sal_True; 523*cdf0e10cSrcweir ContinueHyph_Impl( /*nHyphPos*/nOldPos ); 524*cdf0e10cSrcweir bBusy = sal_False; 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir aAny <<= sal_False; 527*cdf0e10cSrcweir xProp->setPropertyValue( aName, aAny ); 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir catch (uno::Exception &e) 530*cdf0e10cSrcweir { 531*cdf0e10cSrcweir (void) e; 532*cdf0e10cSrcweir DBG_ASSERT( 0, "Hyphenate All failed" ); 533*cdf0e10cSrcweir } 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir return 0; 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, DeleteHdl_Impl, Button *, EMPTYARG ) 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir if( !bBusy ) 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir bBusy = sal_True; 544*cdf0e10cSrcweir ContinueHyph_Impl(); 545*cdf0e10cSrcweir bBusy = sal_False; 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir return 0; 548*cdf0e10cSrcweir } 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir 551*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, ContinueHdl_Impl, Button *, EMPTYARG ) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir if( !bBusy ) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir bBusy = sal_True; 556*cdf0e10cSrcweir ContinueHyph_Impl( CONTINUE_HYPH ); 557*cdf0e10cSrcweir bBusy = sal_False; 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir return 0; 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, CancelHdl_Impl, Button *, EMPTYARG ) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir if( !bBusy ) 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir bBusy = sal_True; 568*cdf0e10cSrcweir pHyphWrapper->SpellEnd(); 569*cdf0e10cSrcweir m_pDialog->EndDialog( RET_CANCEL ); 570*cdf0e10cSrcweir bBusy = sal_False; 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir return 0; 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, Left_Impl, Button *, EMPTYARG ) 577*cdf0e10cSrcweir { 578*cdf0e10cSrcweir if( !bBusy ) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir bBusy = sal_True; 581*cdf0e10cSrcweir SelLeft_Impl(); 582*cdf0e10cSrcweir bBusy = sal_False; 583*cdf0e10cSrcweir } 584*cdf0e10cSrcweir return 0; 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, Right_Impl, Button *, EMPTYARG ) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir if( !bBusy ) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir bBusy = sal_True; 593*cdf0e10cSrcweir SelRight_Impl(); 594*cdf0e10cSrcweir bBusy = sal_False; 595*cdf0e10cSrcweir } 596*cdf0e10cSrcweir return 0; 597*cdf0e10cSrcweir } 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir IMPL_LINK( SvxHyphenWordDialog_Impl, GetFocusHdl_Impl, Edit *, EMPTYARG ) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir aWordEdit.SetSelection( Selection( nOldPos, nOldPos + 1 ) ); 603*cdf0e10cSrcweir return 0; 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir // class SvxHyphenWordDialog --------------------------------------------- 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir SvxHyphenWordDialog::SvxHyphenWordDialog( 610*cdf0e10cSrcweir const String &rWord, LanguageType nLang, 611*cdf0e10cSrcweir Window* pParent, 612*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenator > &xHyphen, 613*cdf0e10cSrcweir SvxSpellWrapper* pWrapper ) : 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir SfxModalDialog( pParent, CUI_RES( RID_SVXDLG_HYPHENATE ) ) 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir m_pImpl = std::auto_ptr< SvxHyphenWordDialog_Impl >( 618*cdf0e10cSrcweir new SvxHyphenWordDialog_Impl( this, rWord, nLang, xHyphen, pWrapper ) ); 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir FreeResource(); 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir SetWindowTitle( nLang ); 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir // disable controls if service is not available 625*cdf0e10cSrcweir if (!m_pImpl->xHyphenator.is()) 626*cdf0e10cSrcweir Enable( sal_False ); 627*cdf0e10cSrcweir } 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir 630*cdf0e10cSrcweir SvxHyphenWordDialog::~SvxHyphenWordDialog() 631*cdf0e10cSrcweir { 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir void SvxHyphenWordDialog::SetWindowTitle( LanguageType nLang ) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir String aLangStr( SvtLanguageTable::GetLanguageString( nLang ) ); 638*cdf0e10cSrcweir String aTmp( m_pImpl->aLabel ); 639*cdf0e10cSrcweir aTmp.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) ); 640*cdf0e10cSrcweir aTmp.Append( aLangStr ); 641*cdf0e10cSrcweir aTmp.Append( sal_Unicode( ')' ) ); 642*cdf0e10cSrcweir SetText( aTmp ); 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir void SvxHyphenWordDialog::SelLeft() 647*cdf0e10cSrcweir { 648*cdf0e10cSrcweir m_pImpl->SelRight_Impl(); 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir void SvxHyphenWordDialog::SelRight() 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir m_pImpl->SelLeft_Impl(); 655*cdf0e10cSrcweir } 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir 658