xref: /trunk/main/svx/source/dialog/rubydialog.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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