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
10*2ee96f1cSAndrew Rist *
11*2ee96f1cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*2ee96f1cSAndrew Rist *
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.
19*2ee96f1cSAndrew Rist *
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
HyphenEdit_Impl(Window * pParent,const ResId & rResId)65cdf0e10cSrcweir HyphenEdit_Impl::HyphenEdit_Impl( Window* pParent, const ResId& rResId ) :
66cdf0e10cSrcweir Edit( pParent, rResId )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir }
69cdf0e10cSrcweir
70cdf0e10cSrcweir
KeyInput(const KeyEvent & rKEvt)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
SvxHyphenWordDialog_Impl(SvxHyphenWordDialog * pDialog,const String & rWord,LanguageType nLang,uno::Reference<linguistic2::XHyphenator> & xHyphen,SvxSpellWrapper * pWrapper)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
~SvxHyphenWordDialog_Impl()219cdf0e10cSrcweir SvxHyphenWordDialog_Impl::~SvxHyphenWordDialog_Impl()
220cdf0e10cSrcweir {
221cdf0e10cSrcweir }
222cdf0e10cSrcweir
223cdf0e10cSrcweir
EnableLRBtn_Impl()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
EraseUnusableHyphens_Impl(uno::Reference<linguistic2::XPossibleHyphens> & rxPossHyph,sal_uInt16 _nMaxHyphenationPos)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
InitControls_Impl()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
ContinueHyph_Impl(sal_uInt16 nInsPos)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
GetHyphIndex_Impl()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
SelLeft_Impl()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
SelRight_Impl()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
IMPL_LINK(SvxHyphenWordDialog_Impl,CutHdl_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,HyphenateAllHdl_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,DeleteHdl_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,ContinueHdl_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,CancelHdl_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,Left_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,Right_Impl,Button *,EMPTYARG)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
IMPL_LINK(SvxHyphenWordDialog_Impl,GetFocusHdl_Impl,Edit *,EMPTYARG)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
SvxHyphenWordDialog(const String & rWord,LanguageType nLang,Window * pParent,uno::Reference<linguistic2::XHyphenator> & xHyphen,SvxSpellWrapper * pWrapper)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
~SvxHyphenWordDialog()626cdf0e10cSrcweir SvxHyphenWordDialog::~SvxHyphenWordDialog()
627cdf0e10cSrcweir {
628cdf0e10cSrcweir }
629cdf0e10cSrcweir
630cdf0e10cSrcweir
SetWindowTitle(LanguageType nLang)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
SelLeft()642cdf0e10cSrcweir void SvxHyphenWordDialog::SelLeft()
643cdf0e10cSrcweir {
644cdf0e10cSrcweir m_pImpl->SelRight_Impl();
645cdf0e10cSrcweir }
646cdf0e10cSrcweir
647cdf0e10cSrcweir
SelRight()648cdf0e10cSrcweir void SvxHyphenWordDialog::SelRight()
649cdf0e10cSrcweir {
650cdf0e10cSrcweir m_pImpl->SelLeft_Impl();
651cdf0e10cSrcweir }
652cdf0e10cSrcweir
653cdf0e10cSrcweir
654