Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / dialog / rubydialog.cxx
blobec2daf383fd47da368474684709fd88162cda909
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/rubydialog.hxx>
21 #include <tools/shl.hxx>
22 #include <svx/dialmgr.hxx>
23 #include <svx/dialogs.hrc>
24 #include <sfx2/app.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <svl/eitem.hxx>
28 #include <com/sun/star/frame/XController.hpp>
29 #include <com/sun/star/style/XStyle.hpp>
30 #include <com/sun/star/text/XRubySelection.hpp>
31 #include <com/sun/star/beans/PropertyValues.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/beans/XPropertySetInfo.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
36 #include <com/sun/star/text/RubyAdjust.hpp>
37 #include <com/sun/star/view/XSelectionChangeListener.hpp>
38 #include <com/sun/star/view/XSelectionSupplier.hpp>
39 #include <cppuhelper/implbase1.hxx>
40 #include <svtools/colorcfg.hxx>
41 #include <vcl/layout.hxx>
42 #include <vcl/settings.hxx>
44 using namespace com::sun::star::uno;
45 using namespace com::sun::star::frame;
46 using namespace com::sun::star::text;
47 using namespace com::sun::star::beans;
48 using namespace com::sun::star::style;
49 using namespace com::sun::star::view;
50 using namespace com::sun::star::lang;
51 using namespace com::sun::star::container;
53 SFX_IMPL_CHILDWINDOW( SvxRubyChildWindow, SID_RUBY_DIALOG );
55 static const sal_Char cRubyBaseText[] = "RubyBaseText";
56 static const sal_Char cRubyText[] = "RubyText";
57 static const sal_Char cCharacterStyles[] = "CharacterStyles";
58 static const sal_Char cRubyAdjust[] = "RubyAdjust";
59 static const sal_Char cRubyIsAbove[] = "RubyIsAbove";
60 static const sal_Char cDisplayName[] = "DisplayName";
61 static const sal_Char cRubyCharStyleName[] = "RubyCharStyleName";
62 static const sal_Char cRubies[] = "Rubies";
64 SvxRubyChildWindow::SvxRubyChildWindow( Window* _pParent, sal_uInt16 nId,
65 SfxBindings* pBindings, SfxChildWinInfo* pInfo) :
66 SfxChildWindow(_pParent, nId)
68 SvxRubyDialog* pDlg = new SvxRubyDialog(pBindings, this, _pParent);
69 pWindow = pDlg;
71 if ( pInfo->nFlags & SFX_CHILDWIN_ZOOMIN )
72 pDlg->RollUp();
74 eChildAlignment = SFX_ALIGN_NOALIGNMENT;
76 pDlg->Initialize( pInfo );
79 SfxChildWinInfo SvxRubyChildWindow::GetInfo() const
81 return SfxChildWindow::GetInfo();
84 class SvxRubyData_Impl : public cppu::WeakImplHelper1
85 < ::com::sun::star::view::XSelectionChangeListener >
87 Reference<XModel> xModel;
88 Reference<XRubySelection> xSelection;
89 Sequence<PropertyValues> aRubyValues;
90 Reference<XController> xController;
91 bool bHasSelectionChanged;
92 public:
93 SvxRubyData_Impl();
94 virtual ~SvxRubyData_Impl();
96 void SetController(Reference<XController> xCtrl);
97 Reference<XModel> GetModel()
99 if(!xController.is())
100 xModel = 0;
101 else
102 xModel = xController->getModel();
103 return xModel;
105 bool HasSelectionChanged() const{return bHasSelectionChanged;}
106 Reference<XRubySelection> GetRubySelection()
108 xSelection = Reference<XRubySelection>(xController, UNO_QUERY);
109 return xSelection;
111 void UpdateRubyValues()
113 if(!xSelection.is())
114 aRubyValues.realloc(0);
115 else
116 aRubyValues = xSelection->getRubyList(false);
117 bHasSelectionChanged = false;
119 Sequence<PropertyValues>& GetRubyValues() {return aRubyValues;}
120 void AssertOneEntry();
122 virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
123 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
127 SvxRubyData_Impl::SvxRubyData_Impl() :
128 bHasSelectionChanged(false)
132 SvxRubyData_Impl::~SvxRubyData_Impl()
136 void SvxRubyData_Impl::SetController(Reference<XController> xCtrl)
138 if(xCtrl.get() != xController.get())
142 Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
143 if(xSelSupp.is())
144 xSelSupp->removeSelectionChangeListener(this);
146 bHasSelectionChanged = true;
147 xController = xCtrl;
148 xSelSupp = Reference<XSelectionSupplier>(xController, UNO_QUERY);
149 if(xSelSupp.is())
150 xSelSupp->addSelectionChangeListener(this);
152 catch (const Exception&)
158 void SvxRubyData_Impl::selectionChanged( const EventObject& ) throw (RuntimeException, std::exception)
160 bHasSelectionChanged = true;
163 void SvxRubyData_Impl::disposing( const EventObject&) throw (RuntimeException, std::exception)
167 Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
168 if(xSelSupp.is())
169 xSelSupp->removeSelectionChangeListener(this);
171 catch (const Exception&)
174 xController = 0;
177 void SvxRubyData_Impl::AssertOneEntry()
179 //create one entry
180 if(!aRubyValues.getLength())
182 aRubyValues.realloc(1);
183 Sequence<PropertyValue>& rValues = aRubyValues.getArray()[0];
184 rValues.realloc(5);
185 PropertyValue* pValues = rValues.getArray();
186 pValues[0].Name = cRubyBaseText;
187 pValues[1].Name = cRubyText;
188 pValues[2].Name = cRubyAdjust;
189 pValues[3].Name = cRubyIsAbove;
190 pValues[4].Name = cRubyCharStyleName;
194 SvxRubyDialog::SvxRubyDialog(SfxBindings *pBind, SfxChildWindow *pCW,
195 Window* _pParent)
196 : SfxModelessDialog(pBind, pCW, _pParent, "AsianPhoneticGuideDialog",
197 "svx/ui/asianphoneticguidedialog.ui")
198 , nLastPos(0)
199 , nCurrentEdit(0)
200 , bModified(false)
201 , pBindings(pBind)
203 xImpl = pImpl = new SvxRubyData_Impl;
204 get(m_pLeftFT, "basetextft");
205 get(m_pRightFT, "rubytextft");
206 get(m_pAdjustLB, "adjustlb");
207 get(m_pPositionLB, "positionlb");
208 get(m_pCharStyleFT, "styleft");
209 get(m_pCharStyleLB, "stylelb");
210 m_pCharStyleLB->SetStyle(m_pCharStyleLB->GetStyle() | WB_SORT);
211 get(m_pStylistPB, "styles");
212 get(m_pApplyPB, "apply");
213 get(m_pClosePB, "close");
214 get(m_pPreviewWin, "preview");
215 m_pPreviewWin->setRubyDialog(this);
216 get(m_pScrolledWindow, "scrolledwindow");
217 m_pScrolledWindow->setUserManagedScrolling(true);
218 m_pScrollSB = &m_pScrolledWindow->getVertScrollBar();
219 get(m_pLeft1ED, "Left1ED");
220 get(m_pRight1ED, "Right1ED");
221 get(m_pLeft2ED, "Left2ED");
222 get(m_pRight2ED, "Right2ED");
223 get(m_pLeft3ED, "Left3ED");
224 get(m_pRight3ED, "Right3ED");
225 get(m_pLeft4ED, "Left4ED");
226 get(m_pRight4ED, "Right4ED");
227 aEditArr[0] = m_pLeft1ED; aEditArr[1] = m_pRight1ED;
228 aEditArr[2] = m_pLeft2ED; aEditArr[3] = m_pRight2ED;
229 aEditArr[4] = m_pLeft3ED; aEditArr[5] = m_pRight3ED;
230 aEditArr[6] = m_pLeft4ED; aEditArr[7] = m_pRight4ED;
232 m_pApplyPB->SetClickHdl(LINK(this, SvxRubyDialog, ApplyHdl_Impl));
233 m_pClosePB->SetClickHdl(LINK(this, SvxRubyDialog, CloseHdl_Impl));
234 m_pStylistPB->SetClickHdl(LINK(this, SvxRubyDialog, StylistHdl_Impl));
235 m_pAdjustLB->SetSelectHdl(LINK(this, SvxRubyDialog, AdjustHdl_Impl));
236 m_pPositionLB->SetSelectHdl(LINK(this, SvxRubyDialog, PositionHdl_Impl));
237 m_pCharStyleLB->SetSelectHdl(LINK(this, SvxRubyDialog, CharStyleHdl_Impl));
239 Link aScrLk(LINK(this, SvxRubyDialog, ScrollHdl_Impl));
240 m_pScrollSB->SetScrollHdl( aScrLk );
241 m_pScrollSB->SetEndScrollHdl( aScrLk );
243 Link aEditLk(LINK(this, SvxRubyDialog, EditModifyHdl_Impl));
244 Link aScrollLk(LINK(this, SvxRubyDialog, EditScrollHdl_Impl));
245 Link aJumpLk(LINK(this, SvxRubyDialog, EditJumpHdl_Impl));
246 for(sal_uInt16 i = 0; i < 8; i++)
248 aEditArr[i]->SetModifyHdl(aEditLk);
249 aEditArr[i]->SetJumpHdl(aJumpLk);
250 if(!i || 7 == i)
251 aEditArr[i]->SetScrollHdl(aScrollLk);
254 UpdateColors();
256 OUString leftLabelName = m_pLeftFT->GetText(), rightLabelName = m_pRightFT->GetText();
257 m_pLeft2ED->SetAccessibleName(leftLabelName);
258 m_pLeft3ED->SetAccessibleName(leftLabelName);
259 m_pLeft4ED->SetAccessibleName(leftLabelName);
260 m_pRight2ED->SetAccessibleName(rightLabelName);
261 m_pRight3ED->SetAccessibleName(rightLabelName);
262 m_pRight4ED->SetAccessibleName(rightLabelName);
265 SvxRubyDialog::~SvxRubyDialog()
267 ClearCharStyleList();
268 EventObject aEvent;
269 xImpl->disposing(aEvent);
272 void SvxRubyDialog::ClearCharStyleList()
274 for(sal_uInt16 i = 0; i < m_pCharStyleLB->GetEntryCount(); i++)
276 void* pData = m_pCharStyleLB->GetEntryData(i);
277 delete (OUString*)pData;
279 m_pCharStyleLB->Clear();
282 bool SvxRubyDialog::Close()
284 pBindings->GetDispatcher()->Execute( SID_RUBY_DIALOG,
285 SFX_CALLMODE_ASYNCHRON |
286 SFX_CALLMODE_RECORD);
287 return true;
290 void SvxRubyDialog::Activate()
292 SfxModelessDialog::Activate();
293 SfxPoolItem* pState = 0;
294 SfxItemState eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
295 bool bEnable = (eState < SFX_ITEM_AVAILABLE) || !pState || !((SfxBoolItem*)pState)->GetValue();
296 delete pState;
297 m_pStylistPB->Enable(bEnable);
298 //get selection from current view frame
299 SfxViewFrame* pCurFrm = SfxViewFrame::Current();
300 Reference< XController > xCtrl = pCurFrm->GetFrame().GetController();
301 pImpl->SetController(xCtrl);
302 if(pImpl->HasSelectionChanged())
305 Reference< XRubySelection > xRubySel = pImpl->GetRubySelection();
306 pImpl->UpdateRubyValues();
307 EnableControls(xRubySel.is());
308 if(xRubySel.is())
310 Reference< XModel > xModel = pImpl->GetModel();
311 const OUString sCharStyleSelect = m_pCharStyleLB->GetSelectEntry();
312 ClearCharStyleList();
313 Reference<XStyleFamiliesSupplier> xSupplier(xModel, UNO_QUERY);
314 if(xSupplier.is())
318 Reference<XNameAccess> xFam = xSupplier->getStyleFamilies();
319 Any aChar = xFam->getByName(cCharacterStyles);
320 Reference<XNameContainer> xChar;
321 aChar >>= xChar;
322 Reference<XIndexAccess> xCharIdx(xChar, UNO_QUERY);
323 if(xCharIdx.is())
325 OUString sUIName(cDisplayName);
326 for(sal_Int32 nStyle = 0; nStyle < xCharIdx->getCount(); nStyle++)
328 Any aStyle = xCharIdx->getByIndex(nStyle);
329 Reference<XStyle> xStyle;
330 aStyle >>= xStyle;
331 Reference<XPropertySet> xPrSet(xStyle, UNO_QUERY);
332 OUString sName, sCoreName;
333 if(xPrSet.is())
335 Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo();
336 if(xInfo->hasPropertyByName(sUIName))
338 Any aName = xPrSet->getPropertyValue(sUIName);
339 aName >>= sName;
342 if(xStyle.is())
344 sCoreName = xStyle->getName();
345 if(sName.isEmpty())
346 sName = sCoreName;
348 if(!sName.isEmpty())
350 sal_uInt16 nPos = m_pCharStyleLB->InsertEntry(sName);
351 m_pCharStyleLB->SetEntryData( nPos, new OUString(sCoreName) );
357 catch (const Exception&)
359 OSL_FAIL("exception in style access");
361 if(!sCharStyleSelect.isEmpty())
362 m_pCharStyleLB->SelectEntry(sCharStyleSelect);
364 m_pCharStyleLB->Enable(xSupplier.is());
365 m_pCharStyleFT->Enable(xSupplier.is());
367 Update();
368 m_pPreviewWin->Invalidate();
372 void SvxRubyDialog::Deactivate()
374 SfxModelessDialog::Deactivate();
377 void SvxRubyDialog::SetRubyText(sal_Int32 nPos, Edit& rLeft, Edit& rRight)
379 OUString sLeft, sRight;
380 const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
381 bool bEnable = aRubyValues.getLength() > nPos;
382 if(bEnable)
384 const Sequence<PropertyValue> aProps = aRubyValues.getConstArray()[nPos];
385 const PropertyValue* pProps = aProps.getConstArray();
386 for(sal_Int32 nProp = 0; nProp < aProps.getLength(); nProp++)
388 if ( pProps[nProp].Name == cRubyBaseText )
389 pProps[nProp].Value >>= sLeft;
390 else if ( pProps[nProp].Name == cRubyText )
391 pProps[nProp].Value >>= sRight;
394 else if(!nPos)
395 bEnable = true;
396 rLeft.Enable(bEnable);
397 rRight.Enable(bEnable);
398 rLeft.SetText(sLeft);
399 rRight.SetText(sRight);
400 rLeft.SaveValue();
401 rRight.SaveValue();
404 void SvxRubyDialog::GetRubyText()
406 long nTempLastPos = GetLastPos();
407 for(int i = 0; i < 8; i+=2)
409 if(aEditArr[i]->IsEnabled() &&
410 (aEditArr[i]->IsValueChangedFromSaved() ||
411 aEditArr[i + 1]->IsValueChangedFromSaved()))
413 Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
414 DBG_ASSERT(aRubyValues.getLength() > (i / 2 + nTempLastPos), "wrong index" );
415 SetModified(true);
416 Sequence<PropertyValue> &rProps = aRubyValues.getArray()[i / 2 + nTempLastPos];
417 PropertyValue* pProps = rProps.getArray();
418 for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
420 if ( pProps[nProp].Name == cRubyBaseText )
421 pProps[nProp].Value <<= OUString(aEditArr[i]->GetText());
422 else if ( pProps[nProp].Name == cRubyText )
423 pProps[nProp].Value <<= OUString(aEditArr[i + 1]->GetText());
429 void SvxRubyDialog::Update()
431 const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
432 sal_Int32 nLen = aRubyValues.getLength();
433 m_pScrollSB->Enable(nLen > 4);
434 m_pScrollSB->SetRange( Range(0, nLen > 4 ? nLen - 4 : 0));
435 m_pScrollSB->SetThumbPos(0);
436 SetLastPos(0);
437 SetModified(false);
439 sal_Int16 nAdjust = -1;
440 sal_Int16 nPosition = -1;
441 OUString sCharStyleName, sTmp;
442 bool bCharStyleEqual = true;
443 for(sal_Int32 nRuby = 0; nRuby < nLen; nRuby++)
445 const Sequence<PropertyValue> &rProps = aRubyValues.getConstArray()[nRuby];
446 const PropertyValue* pProps = rProps.getConstArray();
447 for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
449 if(nAdjust > -2 && pProps[nProp].Name == cRubyAdjust )
451 sal_Int16 nTmp = sal_Int16();
452 pProps[nProp].Value >>= nTmp;
453 if(!nRuby)
454 nAdjust = nTmp;
455 else if(nAdjust != nTmp)
456 nAdjust = -2;
458 if(nPosition > -2 && pProps[nProp].Name == cRubyIsAbove )
460 bool bTmp = *(sal_Bool*)pProps[nProp].Value.getValue();
461 if(!nRuby)
462 nPosition = bTmp ? 0 : 1;
463 else if( (!nPosition && !bTmp) || (nPosition == 1 && bTmp) )
464 nPosition = -2;
466 if(bCharStyleEqual && pProps[nProp].Name == cRubyCharStyleName )
468 pProps[nProp].Value >>= sTmp;
469 if(!nRuby)
470 sCharStyleName = sTmp;
471 else if(sCharStyleName != sTmp)
472 bCharStyleEqual = false;
476 if(!nLen)
478 //enable selection if the ruby list is empty
479 nAdjust = 0;
480 nPosition = 0;
482 if(nAdjust > -1)
483 m_pAdjustLB->SelectEntryPos(nAdjust);
484 else
485 m_pAdjustLB->SetNoSelection();
486 if(nPosition > -1)
487 m_pPositionLB->SelectEntryPos(nPosition ? 1 : 0);
488 if(!nLen || (bCharStyleEqual && sCharStyleName.isEmpty()))
489 sCharStyleName = cRubies;
490 if(!sCharStyleName.isEmpty())
492 for(sal_uInt16 i = 0; i < m_pCharStyleLB->GetEntryCount(); i++)
494 const OUString* pCoreName = (const OUString*)m_pCharStyleLB->GetEntryData(i);
495 if(pCoreName && sCharStyleName == *pCoreName)
497 m_pCharStyleLB->SelectEntryPos(i);
498 break;
502 else
503 m_pCharStyleLB->SetNoSelection();
505 ScrollHdl_Impl(m_pScrollSB);
508 void SvxRubyDialog::GetCurrentText(OUString& rBase, OUString& rRuby)
510 rBase = aEditArr[nCurrentEdit * 2]->GetText();
511 rRuby = aEditArr[nCurrentEdit * 2 + 1]->GetText();
514 IMPL_LINK(SvxRubyDialog, ScrollHdl_Impl, ScrollBar*, pScroll)
516 long nPos = pScroll->GetThumbPos();
517 if(GetLastPos() != nPos)
519 GetRubyText();
521 SetRubyText(nPos++, *m_pLeft1ED, *m_pRight1ED);
522 SetRubyText(nPos++, *m_pLeft2ED, *m_pRight2ED);
523 SetRubyText(nPos++, *m_pLeft3ED, *m_pRight3ED);
524 SetRubyText(nPos, *m_pLeft4ED, *m_pRight4ED);
525 SetLastPos(nPos - 3);
526 m_pPreviewWin->Invalidate();
527 return 0;
530 IMPL_LINK_NOARG(SvxRubyDialog, ApplyHdl_Impl)
532 const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
533 if(!aRubyValues.getLength())
535 AssertOneEntry();
536 PositionHdl_Impl(m_pPositionLB);
537 AdjustHdl_Impl(m_pAdjustLB);
538 CharStyleHdl_Impl(m_pCharStyleLB);
540 GetRubyText();
541 //reset all edit fields - SaveValue is called
542 ScrollHdl_Impl(m_pScrollSB);
544 Reference<XRubySelection> xSelection = pImpl->GetRubySelection();
545 if(IsModified() && xSelection.is())
549 xSelection->setRubyList(aRubyValues, false);
551 catch (const Exception&)
553 OSL_FAIL("Exception caught");
556 return 0;
559 IMPL_LINK_NOARG(SvxRubyDialog, CloseHdl_Impl)
561 Close();
562 return 0;
565 IMPL_LINK_NOARG(SvxRubyDialog, StylistHdl_Impl)
567 SfxPoolItem* pState = 0;
568 SfxItemState eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
569 if(eState <= SFX_ITEM_SET || !pState || !((SfxBoolItem*)pState)->GetValue())
571 pBindings->GetDispatcher()->Execute( SID_STYLE_DESIGNER,
572 SFX_CALLMODE_ASYNCHRON |
573 SFX_CALLMODE_RECORD);
575 delete pState;
576 return 0;
579 IMPL_LINK(SvxRubyDialog, AdjustHdl_Impl, ListBox*, pBox)
581 AssertOneEntry();
582 sal_Int16 nAdjust = pBox->GetSelectEntryPos();
583 Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
584 for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
586 Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
587 PropertyValue* pProps = rProps.getArray();
588 for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
590 if ( pProps[nProp].Name == cRubyAdjust )
591 pProps[nProp].Value <<= nAdjust;
593 SetModified(true);
595 m_pPreviewWin->Invalidate();
596 return 0;
599 IMPL_LINK(SvxRubyDialog, PositionHdl_Impl, ListBox*, pBox)
601 AssertOneEntry();
602 sal_Bool bAbove = !pBox->GetSelectEntryPos();
603 const Type& rType = ::getBooleanCppuType();
604 Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
605 for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
607 Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
608 PropertyValue* pProps = rProps.getArray();
609 for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
611 if ( pProps[nProp].Name == cRubyIsAbove )
612 pProps[nProp].Value.setValue(&bAbove, rType);
614 SetModified(true);
616 m_pPreviewWin->Invalidate();
617 return 0;
620 IMPL_LINK_NOARG(SvxRubyDialog, CharStyleHdl_Impl)
622 AssertOneEntry();
623 OUString sStyleName;
624 if(LISTBOX_ENTRY_NOTFOUND != m_pCharStyleLB->GetSelectEntryPos())
625 sStyleName = *(OUString*) m_pCharStyleLB->GetEntryData(m_pCharStyleLB->GetSelectEntryPos());
626 Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
627 for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
629 Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
630 PropertyValue* pProps = rProps.getArray();
631 for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
633 if ( pProps[nProp].Name == cRubyCharStyleName )
635 pProps[nProp].Value <<= sStyleName;
638 SetModified(true);
640 return 0;
643 IMPL_LINK(SvxRubyDialog, EditModifyHdl_Impl, Edit*, pEdit)
645 for(sal_uInt16 i = 0; i < 8; i++)
647 if(pEdit == aEditArr[i])
649 nCurrentEdit = i / 2;
650 break;
653 m_pPreviewWin->Invalidate();
654 return 0;
657 IMPL_LINK(SvxRubyDialog, EditScrollHdl_Impl, sal_Int32*, pParam)
659 long nRet = 0;
660 if(m_pScrollSB->IsEnabled())
662 //scroll forward
663 if(*pParam > 0 && (aEditArr[7]->HasFocus() || aEditArr[6]->HasFocus() ))
665 if(m_pScrollSB->GetRangeMax() > m_pScrollSB->GetThumbPos())
667 m_pScrollSB->SetThumbPos(m_pScrollSB->GetThumbPos() + 1);
668 aEditArr[6]->GrabFocus();
669 nRet = 1;
672 //scroll backward
673 else if(m_pScrollSB->GetThumbPos() && (aEditArr[0]->HasFocus()||aEditArr[1]->HasFocus()) )
675 m_pScrollSB->SetThumbPos(m_pScrollSB->GetThumbPos() - 1);
676 aEditArr[1]->GrabFocus();
677 nRet = 1;
679 if(nRet)
680 ScrollHdl_Impl(m_pScrollSB);
682 return nRet;
685 IMPL_LINK(SvxRubyDialog, EditJumpHdl_Impl, sal_Int32*, pParam)
687 sal_uInt16 nIndex = USHRT_MAX;
688 for(sal_uInt16 i = 0; i < 8; i++)
690 if(aEditArr[i]->HasFocus())
691 nIndex = i;
693 if(nIndex < 8)
695 if(*pParam > 0)
697 if(nIndex < 6)
698 aEditArr[nIndex + 2]->GrabFocus();
699 else if( EditScrollHdl_Impl(pParam))
700 aEditArr[nIndex]->GrabFocus();
702 else
704 if(nIndex > 1)
705 aEditArr[nIndex - 2]->GrabFocus();
706 else if( EditScrollHdl_Impl(pParam))
707 aEditArr[nIndex]->GrabFocus();
710 return 0;
713 void SvxRubyDialog::AssertOneEntry()
715 pImpl->AssertOneEntry();
720 void SvxRubyDialog::UpdateColors( void )
722 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
723 svtools::ColorConfig aColorConfig;
725 Font aFnt( m_pPreviewWin->GetFont() );
727 Color aNewTextCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
728 Color aNewFillCol( rStyleSettings.GetWindowColor() );
730 if( aNewFillCol != aFnt.GetFillColor() || aNewTextCol != aFnt.GetColor() )
732 aFnt.SetFillColor( aNewFillCol );
733 aFnt.SetColor( aNewTextCol );
734 m_pPreviewWin->SetFont( aFnt );
736 m_pPreviewWin->Invalidate();
742 void SvxRubyDialog::DataChanged( const DataChangedEvent& rDCEvt )
744 SfxModelessDialog::DataChanged( rDCEvt );
746 if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
747 UpdateColors();
750 void SvxRubyDialog::EnableControls(bool bEnable)
752 get_content_area()->Enable(bEnable);
753 m_pApplyPB->Enable(bEnable);
756 RubyPreview::RubyPreview(Window *pParent)
757 : Window(pParent, WB_BORDER)
758 , m_pParentDlg(NULL)
760 SetMapMode(MAP_TWIP);
761 SetBorderStyle( WINDOW_BORDER_MONO );
764 extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeRubyPreview(Window *pParent, VclBuilder::stringmap &)
766 return new RubyPreview(pParent);
769 void RubyPreview::Paint( const Rectangle& /* rRect */ )
771 Size aWinSize = GetOutputSize();
773 Font aSaveFont = GetFont();
774 aSaveFont.SetHeight(aWinSize.Height() / 4);
775 SetFont(aSaveFont);
777 Rectangle aRect(Point(0, 0), aWinSize);
778 SetLineColor();
779 SetFillColor( aSaveFont.GetFillColor() );
780 DrawRect(aRect);
782 OUString sBaseText, sRubyText;
783 m_pParentDlg->GetCurrentText(sBaseText, sRubyText);
785 long nTextHeight = GetTextHeight();
786 long nBaseWidth = GetTextWidth(sBaseText);
788 Font aRubyFont(aSaveFont);
789 aRubyFont.SetHeight(aRubyFont.GetHeight() * 70 / 100);
790 SetFont(aRubyFont);
791 long nRubyWidth = GetTextWidth(sRubyText);
792 SetFont(aSaveFont);
794 sal_uInt16 nAdjust = m_pParentDlg->m_pAdjustLB->GetSelectEntryPos();
795 //use center if no adjustment is available
796 if(nAdjust > 4)
797 nAdjust = 1;
799 //which part is stretched ?
800 bool bRubyStretch = nBaseWidth >= nRubyWidth;
802 long nCenter = aWinSize.Width() / 2;
803 long nLeftStart = nCenter - (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
804 long nRightEnd = nCenter + (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
806 long nYRuby = aWinSize.Height() / 4 - nTextHeight / 2;
807 long nYBase = aWinSize.Height() * 3 / 4 - nTextHeight / 2;
809 //use above also if no selection is set
810 bool bAbove = m_pParentDlg->m_pPositionLB->GetSelectEntryPos() != 1;
811 if(!bAbove)
813 long nTmp = nYRuby;
814 nYRuby = nYBase;
815 nYBase = nTmp;
817 long nYOutput, nOutTextWidth;
818 OUString sOutputText;
821 if(bRubyStretch)
823 DrawText( Point( nLeftStart , nYBase), sBaseText );
824 nYOutput = nYRuby;
825 sOutputText = sRubyText;
826 nOutTextWidth = nRubyWidth;
827 SetFont(aRubyFont);
829 else
831 SetFont(aRubyFont);
832 DrawText( Point( nLeftStart , nYRuby), sRubyText );
833 nYOutput = nYBase;
834 sOutputText = sBaseText;
835 nOutTextWidth = nBaseWidth;
836 SetFont(aSaveFont);
839 switch(nAdjust)
841 case RubyAdjust_LEFT:
842 DrawText( Point( nLeftStart , nYOutput), sOutputText );
843 break;
844 case RubyAdjust_RIGHT:
845 DrawText( Point( nRightEnd - nOutTextWidth, nYOutput), sOutputText );
846 break;
847 case RubyAdjust_INDENT_BLOCK:
849 long nCharWidth = GetTextWidth(OUString("X"));
850 if(nOutTextWidth < (nRightEnd - nLeftStart - nCharWidth))
852 nCharWidth /= 2;
853 nLeftStart += nCharWidth;
854 nRightEnd -= nCharWidth;
857 // no break!
858 case RubyAdjust_BLOCK:
859 if(sOutputText.getLength() > 1)
861 sal_Int32 nCount = sOutputText.getLength();
862 long nSpace = ((nRightEnd - nLeftStart) - GetTextWidth(sOutputText)) / (nCount - 1);
863 for(sal_Int32 i = 0; i < nCount; i++)
865 OUString sChar(sOutputText[i]);
866 DrawText( Point( nLeftStart , nYOutput), sChar);
867 long nCharWidth = GetTextWidth(sChar);
868 nLeftStart += nCharWidth + nSpace;
870 break;
872 //no break;
873 case RubyAdjust_CENTER:
874 DrawText( Point( nCenter - nOutTextWidth / 2 , nYOutput), sOutputText );
875 break;
877 SetFont(aSaveFont);
880 Size RubyPreview::GetOptimalSize() const
882 return LogicToPixel(Size(215, 50), MapMode(MAP_APPFONT));
885 void RubyEdit::GetFocus()
887 GetModifyHdl().Call(this);
888 Edit::GetFocus();
891 bool RubyEdit::PreNotify( NotifyEvent& rNEvt )
893 bool nHandled = false;
894 if ( rNEvt.GetType() == EVENT_KEYINPUT )
896 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
897 const KeyCode& rKeyCode = pKEvt->GetKeyCode();
898 sal_uInt16 nMod = rKeyCode.GetModifier();
899 sal_uInt16 nCode = rKeyCode.GetCode();
900 if( nCode == KEY_TAB && (!nMod || KEY_SHIFT == nMod))
902 sal_Int32 nParam = KEY_SHIFT == nMod ? -1 : 1;
903 if(aScrollHdl.IsSet() && aScrollHdl.Call(&nParam))
904 nHandled = true;
906 else if(KEY_UP == nCode || KEY_DOWN == nCode)
908 sal_Int32 nParam = KEY_UP == nCode ? -1 : 1;
909 aJumpHdl.Call(&nParam);
912 if(!nHandled)
913 nHandled = Edit::PreNotify(rNEvt);
914 return nHandled;
917 extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeRubyEdit(Window *pParent, VclBuilder::stringmap &)
919 return new RubyEdit(pParent);
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */