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