xref: /aoo41x/main/svx/source/dialog/rubydialog.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svx/rubydialog.hxx>
31 #include <tools/shl.hxx>
32 #include <svx/dialmgr.hxx>
33 #include <svx/dialogs.hrc>
34 #include <rubydialog.hrc>
35 #include <sfx2/app.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <svl/eitem.hxx>
39 #include <com/sun/star/frame/XController.hpp>
40 #include <com/sun/star/style/XStyle.hpp>
41 #include <com/sun/star/text/XRubySelection.hpp>
42 #include <com/sun/star/beans/PropertyValues.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 #include <com/sun/star/beans/XPropertySetInfo.hpp>
45 #include <com/sun/star/container/XNameContainer.hpp>
46 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
47 #include <com/sun/star/text/RubyAdjust.hpp>
48 #include <com/sun/star/view/XSelectionChangeListener.hpp>
49 #include <com/sun/star/view/XSelectionSupplier.hpp>
50 #ifndef _CPPUHELPER_IMPLBASE3_HXX_
51 #include <cppuhelper/implbase1.hxx>
52 #endif
53 #include <svtools/colorcfg.hxx>
54 
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::frame;
57 using namespace com::sun::star::text;
58 using namespace com::sun::star::beans;
59 using namespace com::sun::star::style;
60 using namespace com::sun::star::text;
61 using namespace com::sun::star::view;
62 using namespace com::sun::star::lang;
63 using namespace com::sun::star::container;
64 using rtl::OUString;
65 
66 #define C2U(cChar) rtl::OUString::createFromAscii(cChar)
67 
68 SFX_IMPL_CHILDWINDOW( SvxRubyChildWindow, SID_RUBY_DIALOG );
69 
70 static const sal_Char cRubyBaseText[] = "RubyBaseText";
71 static const sal_Char cRubyText[] = "RubyText";
72 static const sal_Char cCharacterStyles[] = "CharacterStyles";
73 static const sal_Char cRubyAdjust[] = "RubyAdjust";
74 static const sal_Char cRubyIsAbove[] = "RubyIsAbove";
75 static const sal_Char cDisplayName[] = "DisplayName";
76 static const sal_Char cRubyCharStyleName[] = "RubyCharStyleName";
77 static const sal_Char cRubies[] = "Rubies";
78 /* -----------------------------09.01.01 17:24--------------------------------
79 
80  ---------------------------------------------------------------------------*/
81 SvxRubyChildWindow::SvxRubyChildWindow( Window* _pParent, sal_uInt16 nId,
82 	SfxBindings* pBindings, SfxChildWinInfo* pInfo) :
83 	SfxChildWindow(_pParent, nId)
84 {
85 	pWindow = new SvxRubyDialog( pBindings, this, _pParent, SVX_RES( RID_SVXDLG_RUBY ) );
86 	SvxRubyDialog* pDlg = (SvxRubyDialog*) pWindow;
87 
88 	if ( pInfo->nFlags & SFX_CHILDWIN_ZOOMIN )
89 		pDlg->RollUp();
90 
91 	eChildAlignment = SFX_ALIGN_NOALIGNMENT;
92 
93     pDlg->Initialize( pInfo );
94 }
95 /* -----------------------------10.01.01 13:53--------------------------------
96 
97  ---------------------------------------------------------------------------*/
98 SfxChildWinInfo SvxRubyChildWindow::GetInfo() const
99 {
100 	return SfxChildWindow::GetInfo();
101 }
102 /* -----------------------------09.01.01 17:17--------------------------------
103 
104  ---------------------------------------------------------------------------*/
105 class SvxRubyData_Impl : public cppu::WeakImplHelper1
106                                 <  ::com::sun::star::view::XSelectionChangeListener >
107 {
108     Reference<XModel>               xModel;
109 	Reference<XRubySelection> 		xSelection;
110 	Sequence<PropertyValues>		aRubyValues;
111     Reference<XController>          xController;
112     sal_Bool                        bHasSelectionChanged;
113     public:
114         SvxRubyData_Impl();
115         ~SvxRubyData_Impl();
116 
117     void    SetController(Reference<XController> xCtrl);
118     Reference<XModel>               GetModel()
119                                     {
120                                         if(!xController.is())
121                                             xModel = 0;
122                                         else
123                                             xModel = xController->getModel();
124                                         return xModel;
125                                     }
126     sal_Bool                        HasSelectionChanged() const{return bHasSelectionChanged;}
127     Reference<XRubySelection>       GetRubySelection()
128                                     {
129                                         xSelection = Reference<XRubySelection>(xController, UNO_QUERY);
130                                         return xSelection;
131                                     }
132     void                            UpdateRubyValues(sal_Bool bAutoUpdate)
133                                     {
134                                         if(!xSelection.is())
135                                             aRubyValues.realloc(0);
136                                         else
137                                             aRubyValues = xSelection->getRubyList(bAutoUpdate);
138 										bHasSelectionChanged = sal_False;
139                                     }
140     Sequence<PropertyValues>&       GetRubyValues() {return aRubyValues;}
141     void                            AssertOneEntry();
142 
143     virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent ) throw (RuntimeException);
144     virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (RuntimeException);
145 
146 };
147 //-----------------------------------------------------------------------------
148 SvxRubyData_Impl::SvxRubyData_Impl() :
149     bHasSelectionChanged(sal_False)
150 {
151 }
152 //-----------------------------------------------------------------------------
153 SvxRubyData_Impl::~SvxRubyData_Impl()
154 {
155 }
156 //-----------------------------------------------------------------------------
157 void    SvxRubyData_Impl::SetController(Reference<XController> xCtrl)
158 {
159     if(xCtrl.get() != xController.get())
160     {
161         try
162         {
163             Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
164             if(xSelSupp.is())
165                 xSelSupp->removeSelectionChangeListener(this);
166 
167             bHasSelectionChanged = sal_True;
168             xController = xCtrl;
169             xSelSupp = Reference<XSelectionSupplier>(xController, UNO_QUERY);
170             if(xSelSupp.is())
171                 xSelSupp->addSelectionChangeListener(this);
172         }
173         catch(Exception&)
174         {}
175     }
176 }
177 //-----------------------------------------------------------------------------
178 void SvxRubyData_Impl::selectionChanged( const EventObject& ) throw (RuntimeException)
179 {
180     bHasSelectionChanged = sal_True;
181 }
182 //-----------------------------------------------------------------------------
183 void SvxRubyData_Impl::disposing( const EventObject&) throw (RuntimeException)
184 {
185     try
186     {
187         Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
188         if(xSelSupp.is())
189             xSelSupp->removeSelectionChangeListener(this);
190     }
191     catch(Exception&)
192     {}
193     xController = 0;
194 }
195 //-----------------------------------------------------------------------------
196 void  SvxRubyData_Impl::AssertOneEntry()
197 {
198     //create one entry
199     if(!aRubyValues.getLength())
200     {
201         aRubyValues.realloc(1);
202         Sequence<PropertyValue>& rValues = aRubyValues.getArray()[0];
203         rValues.realloc(5);
204         PropertyValue* pValues = rValues.getArray();
205         pValues[0].Name = C2U(cRubyBaseText);
206         pValues[1].Name = C2U(cRubyText);
207         pValues[2].Name = C2U(cRubyAdjust);
208         pValues[3].Name = C2U(cRubyIsAbove);
209         pValues[4].Name = C2U(cRubyCharStyleName);
210     }
211 }
212 /* ---------------------------------------------------------------------------
213 
214  ---------------------------------------------------------------------------*/
215 SvxRubyDialog::SvxRubyDialog( SfxBindings *pBind, SfxChildWindow *pCW,
216 									Window* _pParent, const ResId& rResId ) :
217 	SfxModelessDialog( pBind, pCW, _pParent, rResId ),
218     aLeftFT(this,               ResId(FT_LEFT,*rResId.GetResMgr() )),
219     aLeft1ED(this,              ResId(ED_LEFT_1,*rResId.GetResMgr()  )),
220     aRightFT(this,              ResId(FT_RIGHT,*rResId.GetResMgr()  )),
221 	aRight1ED(this, 			ResId(ED_RIGHT_1,*rResId.GetResMgr() )),
222 	aLeft2ED(this, 				ResId(ED_LEFT_2,*rResId.GetResMgr()  )),
223 	aRight2ED(this, 			ResId(ED_RIGHT_2,*rResId.GetResMgr() )),
224 	aLeft3ED(this, 				ResId(ED_LEFT_3,*rResId.GetResMgr()  )),
225 	aRight3ED(this, 			ResId(ED_RIGHT_3,*rResId.GetResMgr() )),
226 	aLeft4ED(this, 				ResId(ED_LEFT_4,*rResId.GetResMgr()  )),
227 	aRight4ED(this, 			ResId(ED_RIGHT_4,*rResId.GetResMgr() )),
228 	aScrollSB(this, 			ResId(SB_SCROLL,*rResId.GetResMgr()  )),
229 	aAutoDetectionCB(this, 		ResId(CB_AUTO_DETECT,*rResId.GetResMgr()	)),
230 	aAdjustFT(this, 			ResId(FT_ADJUST,*rResId.GetResMgr()		)),
231 	aAdjustLB(this, 			ResId(LB_ADJUST,*rResId.GetResMgr()		)),
232 	aPositionFT(this,           ResId(FT_POSITION,*rResId.GetResMgr()     )),
233     aPositionLB(this,           ResId(LB_POSITION,*rResId.GetResMgr()     )),
234 	aCharStyleFT(this,          ResId(FT_CHAR_STYLE,*rResId.GetResMgr()     )),
235 	aCharStyleLB(this, 			ResId(LB_CHAR_STYLE,*rResId.GetResMgr()		)),
236 	aStylistPB(this, 			ResId(PB_STYLIST,*rResId.GetResMgr()		)),
237 	aPreviewFT(this, 			ResId(FT_PREVIEW,*rResId.GetResMgr()		)),
238 	aPreviewWin(*this, 			ResId(WIN_PREVIEW,*rResId.GetResMgr()		)),
239 	aApplyPB(this, 				ResId(PB_APPLY,*rResId.GetResMgr()			)),
240 	aClosePB(this, 				ResId(PB_CLOSE,*rResId.GetResMgr()			)),
241 	aHelpPB(this, 				ResId(PB_HELP,*rResId.GetResMgr()			)),
242 	nLastPos(0),
243     nCurrentEdit(0),
244 	bModified(sal_False),
245 	pBindings(pBind)
246 {
247     xImpl = pImpl = new SvxRubyData_Impl;
248     FreeResource();
249     //#85638# automatic detection not yet available
250     aAutoDetectionCB.Hide();
251 	aEditArr[0] = &aLeft1ED; aEditArr[1] = &aRight1ED;
252 	aEditArr[2] = &aLeft2ED; aEditArr[3] = &aRight2ED;
253 	aEditArr[4] = &aLeft3ED; aEditArr[5] = &aRight3ED;
254 	aEditArr[6] = &aLeft4ED; aEditArr[7] = &aRight4ED;
255 
256 	aApplyPB.SetClickHdl(LINK(this, SvxRubyDialog, ApplyHdl_Impl));
257 	aClosePB.SetClickHdl(LINK(this, SvxRubyDialog, CloseHdl_Impl));
258 	aStylistPB.SetClickHdl(LINK(this, SvxRubyDialog, StylistHdl_Impl));
259 	aAutoDetectionCB.SetClickHdl(LINK(this, SvxRubyDialog, AutomaticHdl_Impl));
260 	aAdjustLB.SetSelectHdl(LINK(this, SvxRubyDialog, AdjustHdl_Impl));
261     aPositionLB.SetSelectHdl(LINK(this, SvxRubyDialog, PositionHdl_Impl));
262     aCharStyleLB.SetSelectHdl(LINK(this, SvxRubyDialog, CharStyleHdl_Impl));
263 
264 	Link aScrLk(LINK(this, SvxRubyDialog, ScrollHdl_Impl));
265 	aScrollSB.SetScrollHdl( aScrLk );
266 	aScrollSB.SetEndScrollHdl( aScrLk );
267 
268 	Link aEditLk(LINK(this, SvxRubyDialog, EditModifyHdl_Impl));
269     Link aScrollLk(LINK(this, SvxRubyDialog, EditScrollHdl_Impl));
270     Link aJumpLk(LINK(this, SvxRubyDialog, EditJumpHdl_Impl));
271 	for(sal_uInt16 i = 0; i < 8; i++)
272     {
273 		aEditArr[i]->SetModifyHdl(aEditLk);
274         aEditArr[i]->SetJumpHdl(aJumpLk);
275         if(!i || 7 == i)
276             aEditArr[i]->SetScrollHdl(aScrollLk);
277     }
278 
279 	UpdateColors();
280 
281 	String leftLabelName = aLeftFT.GetText(), rightLabelName = aRightFT.GetText();
282 	aLeft2ED.SetAccessibleName(leftLabelName);
283 	aLeft3ED.SetAccessibleName(leftLabelName);
284 	aLeft4ED.SetAccessibleName(leftLabelName);
285 	aRight2ED.SetAccessibleName(rightLabelName);
286 	aRight3ED.SetAccessibleName(rightLabelName);
287 	aRight4ED.SetAccessibleName(rightLabelName);
288 }
289 /* -----------------------------09.01.01 17:17--------------------------------
290 
291  ---------------------------------------------------------------------------*/
292 SvxRubyDialog::~SvxRubyDialog()
293 {
294 	ClearCharStyleList();
295     EventObject aEvent;
296     xImpl->disposing(aEvent);
297 }
298 /* -----------------------------01.02.01 10:29--------------------------------
299 
300  ---------------------------------------------------------------------------*/
301 void SvxRubyDialog::ClearCharStyleList()
302 {
303     for(sal_uInt16 i = 0; i < aCharStyleLB.GetEntryCount(); i++)
304 	{
305 		void* pData = aCharStyleLB.GetEntryData(i);
306 		delete (OUString*)pData;
307     }
308     aCharStyleLB.Clear();
309 }
310 /* -----------------------------09.01.01 17:17--------------------------------
311 
312  ---------------------------------------------------------------------------*/
313 sal_Bool 	SvxRubyDialog::Close()
314 {
315 	pBindings->GetDispatcher()->Execute( SID_RUBY_DIALOG,
316 		                      SFX_CALLMODE_ASYNCHRON |
317 							  SFX_CALLMODE_RECORD);
318 	return sal_True;
319 }
320 /* -----------------------------29.01.01 15:26--------------------------------
321 
322  ---------------------------------------------------------------------------*/
323 void SvxRubyDialog::Activate()
324 {
325 	SfxModelessDialog::Activate();
326 	SfxPoolItem* pState = 0;
327 	SfxItemState	eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
328     sal_Bool bEnable = (eState < SFX_ITEM_AVAILABLE) || !pState || !((SfxBoolItem*)pState)->GetValue();
329     aStylistPB.Enable(bEnable);
330 	//get selection from current view frame
331 	SfxViewFrame* pCurFrm = SfxViewFrame::Current();
332     Reference< XController > xCtrl = pCurFrm->GetFrame().GetController();
333     pImpl->SetController(xCtrl);
334     if(pImpl->HasSelectionChanged())
335     {
336 
337         Reference< XRubySelection > xRubySel = pImpl->GetRubySelection();
338         pImpl->UpdateRubyValues(aAutoDetectionCB.IsChecked());
339         EnableControls(xRubySel.is());
340         if(xRubySel.is())
341         {
342             Reference< XModel > xModel = pImpl->GetModel();
343             const String sCharStyleSelect = aCharStyleLB.GetSelectEntry();
344             ClearCharStyleList();
345             Reference<XStyleFamiliesSupplier> xSupplier(xModel, UNO_QUERY);
346             if(xSupplier.is())
347             {
348                 try
349                 {
350                     Reference<XNameAccess> xFam = xSupplier->getStyleFamilies();
351                     Any aChar = xFam->getByName(C2U(cCharacterStyles));
352                     Reference<XNameContainer> xChar;
353                     aChar >>= xChar;
354                     Reference<XIndexAccess> xCharIdx(xChar, UNO_QUERY);
355                     if(xCharIdx.is())
356                     {
357                         OUString sUIName(C2U(cDisplayName));
358                         for(sal_Int32 nStyle = 0; nStyle < xCharIdx->getCount(); nStyle++)
359                         {
360                             Any aStyle = xCharIdx->getByIndex(nStyle);
361                             Reference<XStyle> xStyle;
362                             aStyle >>= xStyle;
363                             Reference<XPropertySet> xPrSet(xStyle, UNO_QUERY);
364                             OUString sName, sCoreName;
365                             if(xPrSet.is())
366                             {
367                                 Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo();
368                                 if(xInfo->hasPropertyByName(sUIName))
369                                 {
370                                     Any aName = xPrSet->getPropertyValue(sUIName);
371                                     aName >>= sName;
372                                 }
373                             }
374                             Reference<XNamed> xNamed(xStyle, UNO_QUERY);
375                             if(xNamed.is())
376                             {
377                                 sCoreName = xNamed->getName();
378                                 if(!sName.getLength())
379                                     sName = sCoreName;
380                             }
381                             if(sName.getLength())
382                             {
383                                 sal_uInt16 nPos = aCharStyleLB.InsertEntry(sName);
384                                 aCharStyleLB.SetEntryData( nPos, new OUString(sCoreName) );
385 
386                             }
387                         }
388                     }
389                 }
390                 catch(Exception&)
391                 {
392                     DBG_ERROR("exception in style access");
393                 }
394                 if(sCharStyleSelect.Len())
395                     aCharStyleLB.SelectEntry(sCharStyleSelect);
396             }
397             aCharStyleLB.Enable(xSupplier.is());
398             aCharStyleFT.Enable(xSupplier.is());
399         }
400 		Update();
401 		aPreviewWin.Invalidate();
402 	}
403 }
404 /* -----------------------------29.01.01 15:26--------------------------------
405 
406  ---------------------------------------------------------------------------*/
407 void	SvxRubyDialog::Deactivate()
408 {
409 	SfxModelessDialog::Deactivate();
410 }
411 /* -----------------------------30.01.01 15:35--------------------------------
412 
413  ---------------------------------------------------------------------------*/
414 void SvxRubyDialog::SetText(sal_Int32 nPos, Edit& rLeft, Edit& rRight)
415 {
416 	OUString sLeft, sRight;
417     const Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
418     sal_Bool bEnable = aRubyValues.getLength() > nPos;
419 	if(bEnable)
420 	{
421         const Sequence<PropertyValue> aProps = aRubyValues.getConstArray()[nPos];
422 		const PropertyValue* pProps = aProps.getConstArray();
423 		for(sal_Int32 nProp = 0; nProp < aProps.getLength(); nProp++)
424 		{
425 			if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyBaseText)))
426 				pProps[nProp].Value >>= sLeft;
427 			else if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyText)))
428 				pProps[nProp].Value >>= sRight;
429 		}
430 	}
431 	else if(!nPos)
432         bEnable = sal_True;
433 	rLeft.Enable(bEnable);
434 	rRight.Enable(bEnable);
435 	rLeft.SetText(sLeft);
436 	rRight.SetText(sRight);
437 	rLeft.SaveValue();
438 	rRight.SaveValue();
439 }
440 //-----------------------------------------------------------------------------
441 void SvxRubyDialog::GetText()
442 {
443 	long nTempLastPos = GetLastPos();
444 	for(int i = 0; i < 8; i+=2)
445 	{
446         if(aEditArr[i]->IsEnabled() &&
447 			(aEditArr[i]->GetText() != aEditArr[i]->GetSavedValue() ||
448 			aEditArr[i + 1]->GetText() != aEditArr[i + 1]->GetSavedValue()))
449 		{
450             Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
451             DBG_ASSERT(aRubyValues.getLength() > (i / 2 + nTempLastPos), "wrong index" );
452 			SetModified(sal_True);
453             Sequence<PropertyValue> &rProps = aRubyValues.getArray()[i / 2 + nTempLastPos];
454 			PropertyValue* pProps = rProps.getArray();
455 			for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
456 			{
457 				if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyBaseText)))
458 					pProps[nProp].Value <<= OUString(aEditArr[i]->GetText());
459 				else if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyText)))
460 					pProps[nProp].Value <<= OUString(aEditArr[i + 1]->GetText());
461 			}
462 		}
463 	}
464 }
465 //-----------------------------------------------------------------------------
466 void SvxRubyDialog::Update()
467 {
468     const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
469     sal_Int32 nLen = aRubyValues.getLength();
470 	aScrollSB.Enable(nLen > 4);
471 	aScrollSB.SetRange( Range(0, nLen > 4 ? nLen - 4 : 0));
472 	aScrollSB.SetThumbPos(0);
473 	SetLastPos(0);
474 	SetModified(sal_False);
475 
476 	sal_Int16 nAdjust = -1;
477     sal_Int16 nPosition = -1;
478 	OUString sCharStyleName, sTmp;
479 	sal_Bool bCharStyleEqual = sal_True;
480 	for(sal_Int32 nRuby = 0; nRuby < nLen; nRuby++)
481 	{
482         const Sequence<PropertyValue> &rProps = aRubyValues.getConstArray()[nRuby];
483         const PropertyValue* pProps = rProps.getConstArray();
484 		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
485 		{
486 			if(nAdjust > -2 &&
487 				pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyAdjust)))
488 			{
489                 sal_Int16 nTmp = sal_Int16();
490 				pProps[nProp].Value >>= nTmp;
491 				if(!nRuby)
492 					nAdjust = nTmp;
493 				else if(nAdjust != nTmp)
494 					nAdjust = -2;
495 			}
496             if(nPosition > -2 &&
497                 pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyIsAbove)))
498             {
499                 sal_Bool bTmp = *(sal_Bool*)pProps[nProp].Value.getValue();
500                 if(!nRuby)
501                     nPosition = bTmp ? 0 : 1;
502                 else if( (!nPosition && !bTmp) || (nPosition == 1 && bTmp)  )
503                     nPosition = -2;
504             }
505 			if(bCharStyleEqual &&
506 				pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyCharStyleName)))
507 			{
508 				pProps[nProp].Value >>= sTmp;
509 				if(!nRuby)
510 					sCharStyleName = sTmp;
511 				else if(sCharStyleName != sTmp)
512 					bCharStyleEqual = sal_False;
513 			}
514 		}
515 	}
516     if(!nLen)
517     {
518         //enable selection if the ruby list is empty
519         nAdjust = 0;
520         nPosition = 0;
521     }
522     if(nAdjust > -1)
523 		aAdjustLB.SelectEntryPos(nAdjust);
524 	else
525 		aAdjustLB.SetNoSelection();
526     if(nPosition > -1)
527         aPositionLB.SelectEntryPos(nPosition ? 1 : 0);
528     if(!nLen || (bCharStyleEqual && !sCharStyleName.getLength()))
529         sCharStyleName = C2U(cRubies);
530     if(sCharStyleName.getLength())
531     {
532         for(sal_uInt16 i = 0; i < aCharStyleLB.GetEntryCount(); i++)
533         {
534             const OUString* pCoreName = (const OUString*)aCharStyleLB.GetEntryData(i);
535             if(pCoreName && sCharStyleName == *pCoreName)
536             {
537                 aCharStyleLB.SelectEntryPos(i);
538                 break;
539             }
540         }
541     }
542     else
543 		aCharStyleLB.SetNoSelection();
544 
545 	ScrollHdl_Impl(&aScrollSB);
546 }
547 /* -----------------------------16.02.01 14:01--------------------------------
548 
549  ---------------------------------------------------------------------------*/
550 void	SvxRubyDialog::GetCurrentText(String& rBase, String& rRuby)
551 {
552 	rBase = aEditArr[nCurrentEdit * 2]->GetText();
553 	rRuby = aEditArr[nCurrentEdit * 2 + 1]->GetText();
554 }
555 /* -----------------------------31.01.01 14:09--------------------------------
556 
557  ---------------------------------------------------------------------------*/
558 IMPL_LINK(SvxRubyDialog, ScrollHdl_Impl, ScrollBar*, pScroll)
559 {
560 	long nPos = pScroll->GetThumbPos();
561 	if(GetLastPos() != nPos)
562 	{
563 		GetText();
564 	}
565 	SetText(nPos++, aLeft1ED, aRight1ED);
566 	SetText(nPos++, aLeft2ED, aRight2ED);
567 	SetText(nPos++, aLeft3ED, aRight3ED);
568 	SetText(nPos, aLeft4ED, aRight4ED);
569 	SetLastPos(nPos - 3);
570 	aPreviewWin.Invalidate();
571 	return 0;
572 }
573 /* -----------------------------30.01.01 14:48--------------------------------
574 
575  ---------------------------------------------------------------------------*/
576 IMPL_LINK(SvxRubyDialog, ApplyHdl_Impl, PushButton*, EMPTYARG)
577 {
578     const Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
579     if(!aRubyValues.getLength())
580     {
581         AssertOneEntry();
582         PositionHdl_Impl(&aPositionLB);
583         AdjustHdl_Impl(&aAdjustLB);
584         CharStyleHdl_Impl(&aCharStyleLB);
585     }
586     GetText();
587 	//reset all edit fields - SaveValue is called
588 	ScrollHdl_Impl(&aScrollSB);
589 
590     Reference<XRubySelection>  xSelection = pImpl->GetRubySelection();
591     if(IsModified() && xSelection.is())
592     {
593         try
594         {
595             xSelection->setRubyList(aRubyValues, aAutoDetectionCB.IsChecked());
596         }
597         catch(Exception& )
598         {
599             DBG_ERROR("Exception caught");
600         }
601     }
602 	return 0;
603 }
604 /* -----------------------------29.01.01 09:38--------------------------------
605 
606  ---------------------------------------------------------------------------*/
607 IMPL_LINK(SvxRubyDialog, CloseHdl_Impl, PushButton*, EMPTYARG)
608 {
609 	Close();
610 	return 0;
611 }
612 /* -----------------------------29.01.01 15:10--------------------------------
613 
614  ---------------------------------------------------------------------------*/
615 IMPL_LINK(SvxRubyDialog, StylistHdl_Impl, PushButton*, EMPTYARG)
616 {
617 	SfxPoolItem* pState = 0;
618 	SfxItemState	eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
619 	if(eState <= SFX_ITEM_SET || !pState || !((SfxBoolItem*)pState)->GetValue())
620 	{
621 		pBindings->GetDispatcher()->Execute( SID_STYLE_DESIGNER,
622 		                      SFX_CALLMODE_ASYNCHRON |
623 							  SFX_CALLMODE_RECORD);
624 	}
625 	return 0;
626 }
627 /* -----------------------------30.01.01 15:32--------------------------------
628 
629  ---------------------------------------------------------------------------*/
630 IMPL_LINK(SvxRubyDialog, AutomaticHdl_Impl, CheckBox*, pBox)
631 {
632     pImpl->UpdateRubyValues(pBox->IsChecked());
633     Update();
634 	return 0;
635 }
636 /* -----------------------------31.01.01 16:37--------------------------------
637 
638  ---------------------------------------------------------------------------*/
639 IMPL_LINK(SvxRubyDialog, AdjustHdl_Impl, ListBox*, pBox)
640 {
641     AssertOneEntry();
642     sal_Int16 nAdjust = pBox->GetSelectEntryPos();
643     Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
644     for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
645 	{
646         Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
647 		PropertyValue* pProps = rProps.getArray();
648 		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
649 		{
650 			if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyAdjust)))
651 				pProps[nProp].Value <<= nAdjust;
652 		}
653 		SetModified(sal_True);
654 	}
655 	aPreviewWin.Invalidate();
656 	return 0;
657 }
658 /* -----------------------------01.06.01 10:24--------------------------------
659 
660  ---------------------------------------------------------------------------*/
661 IMPL_LINK(SvxRubyDialog, PositionHdl_Impl, ListBox*, pBox)
662 {
663     AssertOneEntry();
664     sal_Bool bAbove = !pBox->GetSelectEntryPos();
665     const Type& rType = ::getBooleanCppuType();
666     Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
667     for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
668 	{
669         Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
670 		PropertyValue* pProps = rProps.getArray();
671 		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
672 		{
673             if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyIsAbove)))
674                 pProps[nProp].Value.setValue(&bAbove, rType);
675 		}
676 		SetModified(sal_True);
677 	}
678 	aPreviewWin.Invalidate();
679 	return 0;
680 }
681 /* -----------------------------01.02.01 10:06--------------------------------
682 
683  ---------------------------------------------------------------------------*/
684 IMPL_LINK(SvxRubyDialog, CharStyleHdl_Impl, ListBox*, EMPTYARG )
685 {
686     AssertOneEntry();
687     OUString sStyleName;
688 	if(LISTBOX_ENTRY_NOTFOUND != aCharStyleLB.GetSelectEntryPos())
689 		sStyleName = *(OUString*) aCharStyleLB.GetEntryData(aCharStyleLB.GetSelectEntryPos());
690     Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
691     for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
692 	{
693         Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
694 		PropertyValue* pProps = rProps.getArray();
695 		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
696 		{
697 			if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyCharStyleName)))
698 			{
699 				pProps[nProp].Value <<= sStyleName;
700 			}
701 		}
702 		SetModified(sal_True);
703 	}
704 	return 0;
705 }
706 /* -----------------------------16.02.01 08:35--------------------------------
707 
708  ---------------------------------------------------------------------------*/
709 IMPL_LINK(SvxRubyDialog, EditModifyHdl_Impl, Edit*, pEdit)
710 {
711 	for(sal_uInt16 i = 0; i < 8; i++)
712 	{
713 		if(pEdit == aEditArr[i])
714 		{
715 			nCurrentEdit = i / 2;
716 			break;
717 		}
718 	}
719 	aPreviewWin.Invalidate();
720 	return 0;
721 }
722 /* -----------------------------17.07.01 09:11--------------------------------
723 
724  ---------------------------------------------------------------------------*/
725 IMPL_LINK(SvxRubyDialog, EditScrollHdl_Impl, sal_Int32*, pParam)
726 {
727     long nRet = 0;
728     if(aScrollSB.IsEnabled())
729     {
730         //scroll forward
731         if(*pParam > 0 && (aEditArr[7]->HasFocus() || aEditArr[6]->HasFocus() ))
732         {
733             if(aScrollSB.GetRangeMax() > aScrollSB.GetThumbPos())
734             {
735                 aScrollSB.SetThumbPos(aScrollSB.GetThumbPos() + 1);
736                 aEditArr[6]->GrabFocus();
737                 nRet = 1;
738             }
739         }
740         //scroll backward
741         else if(aScrollSB.GetThumbPos() && (aEditArr[0]->HasFocus()||aEditArr[1]->HasFocus()) )
742         {
743             aScrollSB.SetThumbPos(aScrollSB.GetThumbPos() - 1);
744             aEditArr[1]->GrabFocus();
745             nRet = 1;
746         }
747         if(nRet)
748             ScrollHdl_Impl(&aScrollSB);
749     }
750     return nRet;
751 }
752 /* -----------------------------20.07.2001 15:18------------------------------
753 
754  ---------------------------------------------------------------------------*/
755 IMPL_LINK(SvxRubyDialog, EditJumpHdl_Impl, sal_Int32*, pParam)
756 {
757     sal_uInt16 nIndex = USHRT_MAX;
758     for(sal_uInt16 i = 0; i < 8; i++)
759     {
760         if(aEditArr[i]->HasFocus())
761             nIndex = i;
762     }
763     if(nIndex < 8)
764     {
765         if(*pParam > 0)
766         {
767             if(nIndex < 6)
768                 aEditArr[nIndex + 2]->GrabFocus();
769             else if( EditScrollHdl_Impl(pParam))
770                 aEditArr[nIndex]->GrabFocus();
771         }
772         else
773         {
774             if(nIndex > 1)
775                 aEditArr[nIndex - 2]->GrabFocus();
776             else if( EditScrollHdl_Impl(pParam))
777                 aEditArr[nIndex]->GrabFocus();
778         }
779     }
780     return 0;
781 };
782 /* -----------------------------19.06.01 11:33--------------------------------
783 
784  ---------------------------------------------------------------------------*/
785 void SvxRubyDialog::AssertOneEntry()
786 {
787     pImpl->AssertOneEntry();
788 }
789 
790 // ----------------------------------------------------------------------------
791 
792 void SvxRubyDialog::UpdateColors( void )
793 {
794 	const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
795 	svtools::ColorConfig		aColorConfig;
796 
797 	Font					aFnt( aPreviewWin.GetFont() );
798 
799 	Color					aNewTextCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
800 	Color					aNewFillCol( rStyleSettings.GetWindowColor() );
801 
802 	if( aNewFillCol != aFnt.GetFillColor() || aNewTextCol != aFnt.GetColor() )
803 	{
804 		aFnt.SetFillColor( aNewFillCol );
805 		aFnt.SetColor( aNewTextCol );
806 		aPreviewWin.SetFont( aFnt );
807 
808 		aPreviewWin.Invalidate();
809 	}
810 }
811 
812 // ----------------------------------------------------------------------------
813 
814 void SvxRubyDialog::DataChanged( const DataChangedEvent& rDCEvt )
815 {
816 	SfxModelessDialog::DataChanged( rDCEvt );
817 
818 	if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
819 		UpdateColors();
820 }
821 
822 /* -----------------------------29.01.01 15:44--------------------------------
823 
824  ---------------------------------------------------------------------------*/
825 void lcl_MoveBox(long nOffset, Edit& rLeft, Edit& rRight)
826 {
827 	Size aLeftSz(rLeft.GetSizePixel());
828 	Point aRightPos(rRight.GetPosPixel());
829 	Size aRightSz(rRight.GetSizePixel());
830 	aLeftSz.Width() += nOffset;
831 	aRightSz.Width() -= nOffset;
832 	aRightPos.X() += nOffset;
833 	rLeft.SetSizePixel(aLeftSz);
834 	rRight.SetPosSizePixel(aRightPos, aRightSz);
835 
836 }
837 /* -----------------------------16.02.01 08:09--------------------------------
838 
839  ---------------------------------------------------------------------------*/
840 RubyPreview::RubyPreview(SvxRubyDialog& rParent, const ResId& rResId) :
841 		Window(&rParent, rResId),
842 		rParentDlg(rParent)
843 {
844 	SetMapMode(MAP_TWIP);
845 	Size aWinSize = GetOutputSize();
846 
847 	Font aFont = GetFont();
848 	aFont.SetHeight(aWinSize.Height() / 4);
849 	SetFont(aFont);
850 
851 	SetBorderStyle( WINDOW_BORDER_MONO );
852 }
853 /* -----------------------------29.01.01 14:05--------------------------------
854 
855  ---------------------------------------------------------------------------*/
856 void RubyPreview::Paint( const Rectangle& /* rRect */ )
857 {
858     Font aRubyFont = GetFont();
859     Font aSaveFont(aRubyFont);
860     aRubyFont.SetHeight(aRubyFont.GetHeight() * 70 / 100);
861 
862     Size aWinSize = GetOutputSize();
863 	Rectangle aRect(Point(0, 0), aWinSize);
864 	SetLineColor();
865 	SetFillColor( aSaveFont.GetFillColor() );
866 	DrawRect(aRect);
867 
868 	String sBaseText, sRubyText;
869 	rParentDlg.GetCurrentText(sBaseText, sRubyText);
870 
871 	long nTextHeight = GetTextHeight();
872 	long nBaseWidth = GetTextWidth(sBaseText);
873     SetFont(aRubyFont);
874     long nRubyWidth = GetTextWidth(sRubyText);
875     SetFont(aSaveFont);
876 
877 	sal_uInt16 nAdjust = rParentDlg.aAdjustLB.GetSelectEntryPos();
878 	//use center if no adjustment is available
879 	if(nAdjust > 4)
880 		nAdjust = 1;
881 
882     //which part is stretched ?
883 	sal_Bool bRubyStretch = nBaseWidth >= nRubyWidth;
884 
885 	long nCenter = aWinSize.Width() / 2;
886 	long nLeftStart = nCenter - (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
887 	long nRightEnd = nCenter + (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
888 
889 	long nYRuby = aWinSize.Height() / 4 - nTextHeight / 2;
890 	long nYBase = aWinSize.Height() * 3 / 4 - nTextHeight / 2;
891 
892     //use above also if no selection is set
893     sal_Bool bAbove = rParentDlg.aPositionLB.GetSelectEntryPos() != 1;
894     if(!bAbove)
895     {
896         long nTmp = nYRuby;
897         nYRuby = nYBase;
898         nYBase = nTmp;
899     }
900 	long nYOutput, nOutTextWidth;
901 	String sOutputText;
902 
903 
904     if(bRubyStretch)
905 	{
906 		DrawText( Point( nLeftStart , nYBase),  sBaseText );
907 		nYOutput = nYRuby;
908 		sOutputText = sRubyText;
909 		nOutTextWidth = nRubyWidth;
910         SetFont(aRubyFont);
911 	}
912 	else
913 	{
914         SetFont(aRubyFont);
915         DrawText( Point( nLeftStart , nYRuby),  sRubyText );
916 		nYOutput = nYBase;
917 		sOutputText = sBaseText;
918 		nOutTextWidth = nBaseWidth;
919         SetFont(aSaveFont);
920     }
921 
922 	switch(nAdjust)
923 	{
924 		case RubyAdjust_LEFT:
925 			DrawText( Point( nLeftStart , nYOutput),  sOutputText );
926 		break;
927 		case RubyAdjust_RIGHT:
928 			DrawText( Point( nRightEnd - nOutTextWidth, nYOutput),  sOutputText );
929 		break;
930 		case RubyAdjust_INDENT_BLOCK:
931 		{
932 			long nCharWidth = GetTextWidth(String::CreateFromAscii("X"));
933 			if(nOutTextWidth < (nRightEnd - nLeftStart - nCharWidth))
934 			{
935 				nCharWidth /= 2;
936 				nLeftStart += nCharWidth;
937 				nRightEnd -= nCharWidth;
938 			}
939 		}
940 		// no break!
941 		case RubyAdjust_BLOCK:
942 		if(sOutputText.Len() > 1)
943 		{
944 			xub_StrLen nCount = sOutputText.Len();
945 			long nSpace = ((nRightEnd - nLeftStart) - GetTextWidth(sOutputText)) / (nCount - 1);
946 			for(xub_StrLen i = 0; i < nCount; i++)
947 			{
948 				sal_Unicode cChar = sOutputText.GetChar(i);
949 				DrawText( Point( nLeftStart , nYOutput),  cChar);
950 				long nCharWidth = GetTextWidth(cChar);
951 				nLeftStart += nCharWidth + nSpace;
952 			}
953 			break;
954 		}
955 		//no break;
956 		case RubyAdjust_CENTER:
957 			DrawText( Point( nCenter - nOutTextWidth / 2 , nYOutput),  sOutputText );
958 		break;
959 	}
960     SetFont(aSaveFont);
961 }
962 /* -----------------------------16.02.01 15:12--------------------------------
963 
964  ---------------------------------------------------------------------------*/
965 void RubyEdit::GetFocus()
966 {
967 	GetModifyHdl().Call(this);
968 	Edit::GetFocus();
969 }
970 /* -----------------------------17.07.01 09:00--------------------------------
971 
972  ---------------------------------------------------------------------------*/
973 long  RubyEdit::PreNotify( NotifyEvent& rNEvt )
974 {
975     long nHandled = 0;
976 	if ( rNEvt.GetType() == EVENT_KEYINPUT )
977 	{
978         const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
979         const KeyCode&  rKeyCode = pKEvt->GetKeyCode();
980         sal_uInt16 nMod = rKeyCode.GetModifier();
981         sal_uInt16 nCode = rKeyCode.GetCode();
982         if( nCode == KEY_TAB && (!nMod || KEY_SHIFT == nMod))
983         {
984             sal_Int32 nParam = KEY_SHIFT == nMod ? -1 : 1;
985             if(aScrollHdl.IsSet() && aScrollHdl.Call(&nParam))
986                 nHandled = 1;
987         }
988         else if(KEY_UP == nCode || KEY_DOWN == nCode)
989         {
990             sal_Int32 nParam = KEY_UP == nCode ? -1 : 1;
991             aJumpHdl.Call(&nParam);
992         }
993 	}
994 	if(!nHandled)
995         nHandled = Edit::PreNotify(rNEvt);
996 	return nHandled;
997 }
998 
999