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