Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <svx/rubydialog.hxx>
21 : #include <svx/dialmgr.hxx>
22 : #include <svx/dialogs.hrc>
23 : #include <sfx2/app.hxx>
24 : #include <sfx2/dispatch.hxx>
25 : #include <sfx2/viewfrm.hxx>
26 : #include <svl/eitem.hxx>
27 : #include <com/sun/star/frame/XController.hpp>
28 : #include <com/sun/star/style/XStyle.hpp>
29 : #include <com/sun/star/text/XRubySelection.hpp>
30 : #include <com/sun/star/beans/PropertyValues.hpp>
31 : #include <com/sun/star/beans/XPropertySet.hpp>
32 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
33 : #include <com/sun/star/container/XNameContainer.hpp>
34 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
35 : #include <com/sun/star/text/RubyAdjust.hpp>
36 : #include <com/sun/star/view/XSelectionChangeListener.hpp>
37 : #include <com/sun/star/view/XSelectionSupplier.hpp>
38 : #include <cppuhelper/implbase1.hxx>
39 : #include <svtools/colorcfg.hxx>
40 : #include <vcl/layout.hxx>
41 : #include <vcl/settings.hxx>
42 : #include <vcl/builderfactory.hxx>
43 :
44 : using namespace css::uno;
45 : using namespace css::frame;
46 : using namespace css::text;
47 : using namespace css::beans;
48 : using namespace css::style;
49 : using namespace css::view;
50 : using namespace css::lang;
51 : using namespace css::container;
52 :
53 59 : SFX_IMPL_CHILDWINDOW(SvxRubyChildWindow, SID_RUBY_DIALOG);
54 :
55 : namespace
56 : {
57 :
58 : static const sal_Char cRubyBaseText[] = "RubyBaseText";
59 : static const sal_Char cRubyText[] = "RubyText";
60 : static const sal_Char cCharacterStyles[] = "CharacterStyles";
61 : static const sal_Char cRubyAdjust[] = "RubyAdjust";
62 : static const sal_Char cRubyIsAbove[] = "RubyIsAbove";
63 : static const sal_Char cDisplayName[] = "DisplayName";
64 : static const sal_Char cRubyCharStyleName[] = "RubyCharStyleName";
65 : static const sal_Char cRubies[] = "Rubies";
66 :
67 : } // end anonymous namespace
68 :
69 0 : SvxRubyChildWindow::SvxRubyChildWindow(vcl::Window* _pParent, sal_uInt16 nId,SfxBindings* pBindings, SfxChildWinInfo* pInfo)
70 0 : : SfxChildWindow(_pParent, nId)
71 : {
72 0 : VclPtr<SvxRubyDialog> pDlg = VclPtr<SvxRubyDialog>::Create(pBindings, this, _pParent);
73 0 : pWindow = pDlg;
74 :
75 0 : if (pInfo->nFlags & SfxChildWindowFlags::ZOOMIN)
76 0 : pDlg->RollUp();
77 :
78 0 : eChildAlignment = SfxChildAlignment::NOALIGNMENT;
79 :
80 0 : pDlg->Initialize(pInfo);
81 0 : }
82 :
83 0 : SfxChildWinInfo SvxRubyChildWindow::GetInfo() const
84 : {
85 0 : return SfxChildWindow::GetInfo();
86 : }
87 :
88 : class SvxRubyData_Impl : public cppu::WeakImplHelper1<css::view::XSelectionChangeListener>
89 : {
90 : Reference<XModel> xModel;
91 : Reference<XRubySelection> xSelection;
92 : Sequence<PropertyValues> aRubyValues;
93 : Reference<XController> xController;
94 : bool bHasSelectionChanged;
95 :
96 : public:
97 : SvxRubyData_Impl();
98 : virtual ~SvxRubyData_Impl();
99 :
100 : void SetController(Reference<XController> xCtrl);
101 0 : Reference<XModel> GetModel()
102 : {
103 0 : if (!xController.is())
104 0 : xModel = 0;
105 : else
106 0 : xModel = xController->getModel();
107 0 : return xModel;
108 : }
109 0 : bool HasSelectionChanged() const
110 : {
111 0 : return bHasSelectionChanged;
112 : }
113 0 : Reference<XRubySelection> GetRubySelection()
114 : {
115 0 : xSelection = Reference<XRubySelection>(xController, UNO_QUERY);
116 0 : return xSelection;
117 : }
118 0 : void UpdateRubyValues()
119 : {
120 0 : if (!xSelection.is())
121 0 : aRubyValues.realloc(0);
122 : else
123 0 : aRubyValues = xSelection->getRubyList(false);
124 0 : bHasSelectionChanged = false;
125 0 : }
126 0 : Sequence<PropertyValues>& GetRubyValues()
127 : {
128 0 : return aRubyValues;
129 : }
130 : void AssertOneEntry();
131 :
132 : virtual void SAL_CALL selectionChanged(const css::lang::EventObject& aEvent)
133 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
134 : virtual void SAL_CALL disposing( const css::lang::EventObject& Source)
135 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
136 :
137 : };
138 :
139 0 : SvxRubyData_Impl::SvxRubyData_Impl()
140 0 : : bHasSelectionChanged(false)
141 : {
142 0 : }
143 :
144 0 : SvxRubyData_Impl::~SvxRubyData_Impl()
145 : {
146 0 : }
147 :
148 0 : void SvxRubyData_Impl::SetController(Reference<XController> xCtrl)
149 : {
150 0 : if (xCtrl.get() != xController.get())
151 : {
152 : try
153 : {
154 0 : Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
155 0 : if (xSelSupp.is())
156 0 : xSelSupp->removeSelectionChangeListener(this);
157 :
158 0 : bHasSelectionChanged = true;
159 0 : xController = xCtrl;
160 0 : xSelSupp = Reference<XSelectionSupplier>(xController, UNO_QUERY);
161 0 : if (xSelSupp.is())
162 0 : xSelSupp->addSelectionChangeListener(this);
163 : }
164 0 : catch (const Exception&)
165 : {
166 : }
167 : }
168 0 : }
169 :
170 0 : void SvxRubyData_Impl::selectionChanged(const EventObject& ) throw (RuntimeException, std::exception)
171 : {
172 0 : bHasSelectionChanged = true;
173 0 : }
174 :
175 0 : void SvxRubyData_Impl::disposing(const EventObject&) throw (RuntimeException, std::exception)
176 : {
177 : try
178 : {
179 0 : Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
180 0 : if (xSelSupp.is())
181 0 : xSelSupp->removeSelectionChangeListener(this);
182 : }
183 0 : catch (const Exception&)
184 : {
185 : }
186 0 : xController = 0;
187 0 : }
188 :
189 0 : void SvxRubyData_Impl::AssertOneEntry()
190 : {
191 : //create one entry
192 0 : if (!aRubyValues.getLength())
193 : {
194 0 : aRubyValues.realloc(1);
195 0 : Sequence<PropertyValue>& rValues = aRubyValues.getArray()[0];
196 0 : rValues.realloc(5);
197 0 : PropertyValue* pValues = rValues.getArray();
198 0 : pValues[0].Name = cRubyBaseText;
199 0 : pValues[1].Name = cRubyText;
200 0 : pValues[2].Name = cRubyAdjust;
201 0 : pValues[3].Name = cRubyIsAbove;
202 0 : pValues[4].Name = cRubyCharStyleName;
203 : }
204 0 : }
205 :
206 0 : SvxRubyDialog::SvxRubyDialog(SfxBindings* pBind, SfxChildWindow* pCW, vcl::Window* _pParent)
207 : : SfxModelessDialog(pBind, pCW, _pParent, "AsianPhoneticGuideDialog", "svx/ui/asianphoneticguidedialog.ui")
208 : , nLastPos(0)
209 : , nCurrentEdit(0)
210 : , bModified(false)
211 0 : , pBindings(pBind)
212 : {
213 0 : xImpl = pImpl = new SvxRubyData_Impl;
214 0 : get(m_pLeftFT, "basetextft");
215 0 : get(m_pRightFT, "rubytextft");
216 0 : get(m_pAdjustLB, "adjustlb");
217 0 : get(m_pPositionLB, "positionlb");
218 0 : get(m_pCharStyleFT, "styleft");
219 0 : get(m_pCharStyleLB, "stylelb");
220 0 : m_pCharStyleLB->SetStyle(m_pCharStyleLB->GetStyle() | WB_SORT);
221 0 : get(m_pStylistPB, "styles");
222 0 : get(m_pApplyPB, "apply");
223 0 : get(m_pClosePB, "close");
224 0 : get(m_pPreviewWin, "preview");
225 0 : m_pPreviewWin->setRubyDialog(this);
226 0 : get(m_pScrolledWindow, "scrolledwindow");
227 0 : m_pScrolledWindow->setUserManagedScrolling(true);
228 0 : m_pScrollSB = &m_pScrolledWindow->getVertScrollBar();
229 0 : get(m_pLeft1ED, "Left1ED");
230 0 : get(m_pRight1ED, "Right1ED");
231 0 : get(m_pLeft2ED, "Left2ED");
232 0 : get(m_pRight2ED, "Right2ED");
233 0 : get(m_pLeft3ED, "Left3ED");
234 0 : get(m_pRight3ED, "Right3ED");
235 0 : get(m_pLeft4ED, "Left4ED");
236 0 : get(m_pRight4ED, "Right4ED");
237 0 : aEditArr[0] = m_pLeft1ED; aEditArr[1] = m_pRight1ED;
238 0 : aEditArr[2] = m_pLeft2ED; aEditArr[3] = m_pRight2ED;
239 0 : aEditArr[4] = m_pLeft3ED; aEditArr[5] = m_pRight3ED;
240 0 : aEditArr[6] = m_pLeft4ED; aEditArr[7] = m_pRight4ED;
241 :
242 0 : m_pApplyPB->SetClickHdl(LINK(this, SvxRubyDialog, ApplyHdl_Impl));
243 0 : m_pClosePB->SetClickHdl(LINK(this, SvxRubyDialog, CloseHdl_Impl));
244 0 : m_pStylistPB->SetClickHdl(LINK(this, SvxRubyDialog, StylistHdl_Impl));
245 0 : m_pAdjustLB->SetSelectHdl(LINK(this, SvxRubyDialog, AdjustHdl_Impl));
246 0 : m_pPositionLB->SetSelectHdl(LINK(this, SvxRubyDialog, PositionHdl_Impl));
247 0 : m_pCharStyleLB->SetSelectHdl(LINK(this, SvxRubyDialog, CharStyleHdl_Impl));
248 :
249 0 : Link<> aScrLk(LINK(this, SvxRubyDialog, ScrollHdl_Impl));
250 0 : m_pScrollSB->SetScrollHdl(aScrLk);
251 0 : m_pScrollSB->SetEndScrollHdl(aScrLk);
252 :
253 0 : Link<> aEditLk(LINK(this, SvxRubyDialog, EditModifyHdl_Impl));
254 0 : Link<> aScrollLk(LINK(this, SvxRubyDialog, EditScrollHdl_Impl));
255 0 : Link<> aJumpLk(LINK(this, SvxRubyDialog, EditJumpHdl_Impl));
256 0 : for (sal_uInt16 i = 0; i < 8; i++)
257 : {
258 0 : aEditArr[i]->SetModifyHdl(aEditLk);
259 0 : aEditArr[i]->SetJumpHdl(aJumpLk);
260 0 : if (!i || 7 == i)
261 0 : aEditArr[i]->SetScrollHdl(aScrollLk);
262 : }
263 :
264 0 : UpdateColors();
265 :
266 0 : OUString leftLabelName = m_pLeftFT->GetText(), rightLabelName = m_pRightFT->GetText();
267 0 : m_pLeft2ED->SetAccessibleName(leftLabelName);
268 0 : m_pLeft3ED->SetAccessibleName(leftLabelName);
269 0 : m_pLeft4ED->SetAccessibleName(leftLabelName);
270 0 : m_pRight2ED->SetAccessibleName(rightLabelName);
271 0 : m_pRight3ED->SetAccessibleName(rightLabelName);
272 0 : m_pRight4ED->SetAccessibleName(rightLabelName);
273 0 : }
274 :
275 0 : SvxRubyDialog::~SvxRubyDialog()
276 : {
277 0 : disposeOnce();
278 0 : }
279 :
280 0 : void SvxRubyDialog::dispose()
281 : {
282 0 : ClearCharStyleList();
283 0 : EventObject aEvent;
284 0 : xImpl->disposing(aEvent);
285 0 : m_pLeftFT.clear();
286 0 : m_pRightFT.clear();
287 0 : m_pLeft1ED.clear();
288 0 : m_pRight1ED.clear();
289 0 : m_pLeft2ED.clear();
290 0 : m_pRight2ED.clear();
291 0 : m_pLeft3ED.clear();
292 0 : m_pRight3ED.clear();
293 0 : m_pLeft4ED.clear();
294 0 : m_pRight4ED.clear();
295 0 : for (int i = 0; i < 7; i++)
296 0 : aEditArr[i].clear();
297 0 : m_pScrolledWindow.clear();
298 0 : m_pScrollSB.clear();
299 0 : m_pAdjustLB.clear();
300 0 : m_pPositionLB.clear();
301 0 : m_pCharStyleFT.clear();
302 0 : m_pCharStyleLB.clear();
303 0 : m_pStylistPB.clear();
304 0 : m_pPreviewWin.clear();
305 0 : m_pApplyPB.clear();
306 0 : m_pClosePB.clear();
307 0 : SfxModelessDialog::dispose();
308 0 : }
309 :
310 0 : void SvxRubyDialog::ClearCharStyleList()
311 : {
312 0 : for (sal_Int32 i = 0; i < m_pCharStyleLB->GetEntryCount(); i++)
313 : {
314 0 : void* pData = m_pCharStyleLB->GetEntryData(i);
315 0 : delete static_cast<OUString*>(pData);
316 : }
317 0 : m_pCharStyleLB->Clear();
318 0 : }
319 :
320 0 : bool SvxRubyDialog::Close()
321 : {
322 : pBindings->GetDispatcher()->Execute( SID_RUBY_DIALOG,
323 : SfxCallMode::ASYNCHRON |
324 0 : SfxCallMode::RECORD);
325 0 : return true;
326 : }
327 :
328 0 : void SvxRubyDialog::Activate()
329 : {
330 0 : SfxModelessDialog::Activate();
331 0 : SfxPoolItem* pState = 0;
332 0 : SfxItemState eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
333 0 : bool bEnable = (eState < SfxItemState::DEFAULT) || !pState || !static_cast<SfxBoolItem*>(pState)->GetValue();
334 0 : delete pState;
335 0 : m_pStylistPB->Enable(bEnable);
336 : //get selection from current view frame
337 0 : SfxViewFrame* pCurFrm = SfxViewFrame::Current();
338 0 : Reference< XController > xCtrl = pCurFrm->GetFrame().GetController();
339 0 : pImpl->SetController(xCtrl);
340 0 : if (pImpl->HasSelectionChanged())
341 : {
342 :
343 0 : Reference< XRubySelection > xRubySel = pImpl->GetRubySelection();
344 0 : pImpl->UpdateRubyValues();
345 0 : EnableControls(xRubySel.is());
346 0 : if (xRubySel.is())
347 : {
348 0 : Reference< XModel > xModel = pImpl->GetModel();
349 0 : const OUString sCharStyleSelect = m_pCharStyleLB->GetSelectEntry();
350 0 : ClearCharStyleList();
351 0 : Reference<XStyleFamiliesSupplier> xSupplier(xModel, UNO_QUERY);
352 0 : if (xSupplier.is())
353 : {
354 : try
355 : {
356 0 : Reference<XNameAccess> xFam = xSupplier->getStyleFamilies();
357 0 : Any aChar = xFam->getByName(cCharacterStyles);
358 0 : Reference<XNameContainer> xChar;
359 0 : aChar >>= xChar;
360 0 : Reference<XIndexAccess> xCharIdx(xChar, UNO_QUERY);
361 0 : if (xCharIdx.is())
362 : {
363 0 : OUString sUIName(cDisplayName);
364 0 : for (sal_Int32 nStyle = 0; nStyle < xCharIdx->getCount(); nStyle++)
365 : {
366 0 : Any aStyle = xCharIdx->getByIndex(nStyle);
367 0 : Reference<XStyle> xStyle;
368 0 : aStyle >>= xStyle;
369 0 : Reference<XPropertySet> xPrSet(xStyle, UNO_QUERY);
370 0 : OUString sName, sCoreName;
371 0 : if (xPrSet.is())
372 : {
373 0 : Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo();
374 0 : if (xInfo->hasPropertyByName(sUIName))
375 : {
376 0 : Any aName = xPrSet->getPropertyValue(sUIName);
377 0 : aName >>= sName;
378 0 : }
379 : }
380 0 : if (xStyle.is())
381 : {
382 0 : sCoreName = xStyle->getName();
383 0 : if (sName.isEmpty())
384 0 : sName = sCoreName;
385 : }
386 0 : if (!sName.isEmpty())
387 : {
388 0 : sal_uInt16 nPos = m_pCharStyleLB->InsertEntry(sName);
389 0 : m_pCharStyleLB->SetEntryData( nPos, new OUString(sCoreName) );
390 :
391 : }
392 0 : }
393 0 : }
394 : }
395 0 : catch (const Exception&)
396 : {
397 : OSL_FAIL("exception in style access");
398 : }
399 0 : if(!sCharStyleSelect.isEmpty())
400 0 : m_pCharStyleLB->SelectEntry(sCharStyleSelect);
401 : }
402 0 : m_pCharStyleLB->Enable(xSupplier.is());
403 0 : m_pCharStyleFT->Enable(xSupplier.is());
404 : }
405 0 : Update();
406 0 : m_pPreviewWin->Invalidate();
407 0 : }
408 0 : }
409 :
410 0 : void SvxRubyDialog::Deactivate()
411 : {
412 0 : SfxModelessDialog::Deactivate();
413 0 : }
414 :
415 0 : void SvxRubyDialog::SetRubyText(sal_Int32 nPos, Edit& rLeft, Edit& rRight)
416 : {
417 0 : OUString sLeft, sRight;
418 0 : const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
419 0 : bool bEnable = aRubyValues.getLength() > nPos;
420 0 : if (bEnable)
421 : {
422 0 : const Sequence<PropertyValue> aProps = aRubyValues.getConstArray()[nPos];
423 0 : const PropertyValue* pProps = aProps.getConstArray();
424 0 : for (sal_Int32 nProp = 0; nProp < aProps.getLength(); nProp++)
425 : {
426 0 : if (pProps[nProp].Name == cRubyBaseText)
427 0 : pProps[nProp].Value >>= sLeft;
428 0 : else if (pProps[nProp].Name == cRubyText)
429 0 : pProps[nProp].Value >>= sRight;
430 0 : }
431 : }
432 0 : else if (!nPos)
433 : {
434 0 : bEnable = true;
435 : }
436 0 : rLeft.Enable(bEnable);
437 0 : rRight.Enable(bEnable);
438 0 : rLeft.SetText(sLeft);
439 0 : rRight.SetText(sRight);
440 0 : rLeft.SaveValue();
441 0 : rRight.SaveValue();
442 0 : }
443 :
444 0 : void SvxRubyDialog::GetRubyText()
445 : {
446 0 : long nTempLastPos = GetLastPos();
447 0 : for (int i = 0; i < 8; i+=2)
448 : {
449 0 : if (aEditArr[i]->IsEnabled() &&
450 0 : (aEditArr[i]->IsValueChangedFromSaved() || aEditArr[i + 1]->IsValueChangedFromSaved()))
451 : {
452 0 : Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
453 : DBG_ASSERT(aRubyValues.getLength() > (i / 2 + nTempLastPos), "wrong index" );
454 0 : SetModified(true);
455 0 : Sequence<PropertyValue>& rProps = aRubyValues.getArray()[i / 2 + nTempLastPos];
456 0 : PropertyValue* pProps = rProps.getArray();
457 0 : for (sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
458 : {
459 0 : if (pProps[nProp].Name == cRubyBaseText)
460 0 : pProps[nProp].Value <<= OUString(aEditArr[i]->GetText());
461 0 : else if (pProps[nProp].Name == cRubyText)
462 0 : pProps[nProp].Value <<= OUString(aEditArr[i + 1]->GetText());
463 : }
464 : }
465 : }
466 0 : }
467 :
468 0 : void SvxRubyDialog::Update()
469 : {
470 0 : const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
471 0 : sal_Int32 nLen = aRubyValues.getLength();
472 0 : m_pScrollSB->Enable(nLen > 4);
473 0 : m_pScrollSB->SetRange( Range(0, nLen > 4 ? nLen - 4 : 0));
474 0 : m_pScrollSB->SetThumbPos(0);
475 0 : SetLastPos(0);
476 0 : SetModified(false);
477 :
478 0 : sal_Int16 nAdjust = -1;
479 0 : sal_Int16 nPosition = -1;
480 0 : OUString sCharStyleName, sTmp;
481 0 : bool bCharStyleEqual = true;
482 0 : for (sal_Int32 nRuby = 0; nRuby < nLen; nRuby++)
483 : {
484 0 : const Sequence<PropertyValue> &rProps = aRubyValues.getConstArray()[nRuby];
485 0 : const PropertyValue* pProps = rProps.getConstArray();
486 0 : for (sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
487 : {
488 0 : if (nAdjust > -2 && pProps[nProp].Name == cRubyAdjust)
489 : {
490 0 : sal_Int16 nTmp = sal_Int16();
491 0 : pProps[nProp].Value >>= nTmp;
492 0 : if (!nRuby)
493 0 : nAdjust = nTmp;
494 0 : else if(nAdjust != nTmp)
495 0 : nAdjust = -2;
496 : }
497 0 : if (nPosition > -2 && pProps[nProp].Name == cRubyIsAbove)
498 : {
499 0 : bool bTmp = *static_cast<sal_Bool const *>(pProps[nProp].Value.getValue());
500 0 : if (!nRuby)
501 0 : nPosition = bTmp ? 0 : 1;
502 0 : else if ((!nPosition && !bTmp) || (nPosition == 1 && bTmp))
503 0 : nPosition = -2;
504 : }
505 0 : if (bCharStyleEqual && pProps[nProp].Name == cRubyCharStyleName)
506 : {
507 0 : pProps[nProp].Value >>= sTmp;
508 0 : if (!nRuby)
509 0 : sCharStyleName = sTmp;
510 0 : else if (sCharStyleName != sTmp)
511 0 : bCharStyleEqual = false;
512 : }
513 : }
514 : }
515 0 : if (!nLen)
516 : {
517 : //enable selection if the ruby list is empty
518 0 : nAdjust = 0;
519 0 : nPosition = 0;
520 : }
521 0 : if (nAdjust > -1)
522 0 : m_pAdjustLB->SelectEntryPos(nAdjust);
523 : else
524 0 : m_pAdjustLB->SetNoSelection();
525 0 : if (nPosition > -1)
526 0 : m_pPositionLB->SelectEntryPos(nPosition ? 1 : 0);
527 0 : if (!nLen || (bCharStyleEqual && sCharStyleName.isEmpty()))
528 0 : sCharStyleName = cRubies;
529 0 : if (!sCharStyleName.isEmpty())
530 : {
531 0 : for (sal_Int32 i = 0; i < m_pCharStyleLB->GetEntryCount(); i++)
532 : {
533 0 : const OUString* pCoreName = static_cast<const OUString*>(m_pCharStyleLB->GetEntryData(i));
534 0 : if (pCoreName && sCharStyleName == *pCoreName)
535 : {
536 0 : m_pCharStyleLB->SelectEntryPos(i);
537 0 : break;
538 : }
539 : }
540 : }
541 : else
542 0 : m_pCharStyleLB->SetNoSelection();
543 :
544 0 : ScrollHdl_Impl(m_pScrollSB);
545 0 : }
546 :
547 0 : void SvxRubyDialog::GetCurrentText(OUString& rBase, OUString& rRuby)
548 : {
549 0 : rBase = aEditArr[nCurrentEdit * 2]->GetText();
550 0 : rRuby = aEditArr[nCurrentEdit * 2 + 1]->GetText();
551 0 : }
552 :
553 0 : IMPL_LINK(SvxRubyDialog, ScrollHdl_Impl, ScrollBar*, pScroll)
554 : {
555 0 : long nPos = pScroll->GetThumbPos();
556 0 : if (GetLastPos() != nPos)
557 : {
558 0 : GetRubyText();
559 : }
560 0 : SetRubyText(nPos++, *m_pLeft1ED, *m_pRight1ED);
561 0 : SetRubyText(nPos++, *m_pLeft2ED, *m_pRight2ED);
562 0 : SetRubyText(nPos++, *m_pLeft3ED, *m_pRight3ED);
563 0 : SetRubyText(nPos, *m_pLeft4ED, *m_pRight4ED);
564 0 : SetLastPos(nPos - 3);
565 0 : m_pPreviewWin->Invalidate();
566 0 : return 0;
567 : }
568 :
569 0 : IMPL_LINK_NOARG(SvxRubyDialog, ApplyHdl_Impl)
570 : {
571 0 : const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
572 0 : if (!aRubyValues.getLength())
573 : {
574 0 : AssertOneEntry();
575 0 : PositionHdl_Impl(m_pPositionLB);
576 0 : AdjustHdl_Impl(m_pAdjustLB);
577 0 : CharStyleHdl_Impl(m_pCharStyleLB);
578 : }
579 0 : GetRubyText();
580 : //reset all edit fields - SaveValue is called
581 0 : ScrollHdl_Impl(m_pScrollSB);
582 :
583 0 : Reference<XRubySelection> xSelection = pImpl->GetRubySelection();
584 0 : if (IsModified() && xSelection.is())
585 : {
586 : try
587 : {
588 0 : xSelection->setRubyList(aRubyValues, false);
589 : }
590 0 : catch (const Exception&)
591 : {
592 : OSL_FAIL("Exception caught");
593 : }
594 : }
595 0 : return 0;
596 : }
597 :
598 0 : IMPL_LINK_NOARG(SvxRubyDialog, CloseHdl_Impl)
599 : {
600 0 : Close();
601 0 : return 0;
602 : }
603 :
604 0 : IMPL_LINK_NOARG(SvxRubyDialog, StylistHdl_Impl)
605 : {
606 0 : SfxPoolItem* pState = nullptr;
607 0 : SfxItemState eState = pBindings->QueryState(SID_STYLE_DESIGNER, pState);
608 0 : if (eState <= SfxItemState::SET || !pState || !static_cast<SfxBoolItem*>(pState)->GetValue())
609 : {
610 : pBindings->GetDispatcher()->Execute(SID_STYLE_DESIGNER,
611 0 : SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
612 : }
613 0 : delete pState;
614 0 : return 0;
615 : }
616 :
617 0 : IMPL_LINK(SvxRubyDialog, AdjustHdl_Impl, ListBox*, pBox)
618 : {
619 0 : AssertOneEntry();
620 0 : sal_Int16 nAdjust = pBox->GetSelectEntryPos();
621 0 : Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
622 0 : for (sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
623 : {
624 0 : Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
625 0 : PropertyValue* pProps = rProps.getArray();
626 0 : for (sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
627 : {
628 0 : if (pProps[nProp].Name == cRubyAdjust)
629 0 : pProps[nProp].Value <<= nAdjust;
630 : }
631 0 : SetModified(true);
632 : }
633 0 : m_pPreviewWin->Invalidate();
634 0 : return 0;
635 : }
636 :
637 0 : IMPL_LINK(SvxRubyDialog, PositionHdl_Impl, ListBox*, pBox)
638 : {
639 0 : AssertOneEntry();
640 0 : sal_Bool bAbove = !pBox->GetSelectEntryPos();
641 0 : const Type& rType = cppu::UnoType<bool>::get();
642 0 : Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
643 0 : for (sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
644 : {
645 0 : Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
646 0 : PropertyValue* pProps = rProps.getArray();
647 0 : for (sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
648 : {
649 0 : if (pProps[nProp].Name == cRubyIsAbove)
650 0 : pProps[nProp].Value.setValue(&bAbove, rType);
651 : }
652 0 : SetModified(true);
653 : }
654 0 : m_pPreviewWin->Invalidate();
655 0 : return 0;
656 : }
657 :
658 0 : IMPL_LINK_NOARG(SvxRubyDialog, CharStyleHdl_Impl)
659 : {
660 0 : AssertOneEntry();
661 0 : OUString sStyleName;
662 0 : if (LISTBOX_ENTRY_NOTFOUND != m_pCharStyleLB->GetSelectEntryPos())
663 0 : sStyleName = *static_cast<OUString*>(m_pCharStyleLB->GetSelectEntryData());
664 0 : Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
665 0 : for (sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
666 : {
667 0 : Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
668 0 : PropertyValue* pProps = rProps.getArray();
669 0 : for (sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
670 : {
671 0 : if (pProps[nProp].Name == cRubyCharStyleName)
672 : {
673 0 : pProps[nProp].Value <<= sStyleName;
674 : }
675 : }
676 0 : SetModified(true);
677 : }
678 0 : return 0;
679 : }
680 :
681 0 : IMPL_LINK(SvxRubyDialog, EditModifyHdl_Impl, Edit*, pEdit)
682 : {
683 0 : for (sal_uInt16 i = 0; i < 8; i++)
684 : {
685 0 : if (pEdit == aEditArr[i])
686 : {
687 0 : nCurrentEdit = i / 2;
688 0 : break;
689 : }
690 : }
691 0 : m_pPreviewWin->Invalidate();
692 0 : return 0;
693 : }
694 :
695 0 : IMPL_LINK(SvxRubyDialog, EditScrollHdl_Impl, sal_Int32*, pParam)
696 : {
697 0 : long nRet = 0;
698 0 : if (m_pScrollSB->IsEnabled())
699 : {
700 : //scroll forward
701 0 : if (*pParam > 0 && (aEditArr[7]->HasFocus() || aEditArr[6]->HasFocus() ))
702 : {
703 0 : if (m_pScrollSB->GetRangeMax() > m_pScrollSB->GetThumbPos())
704 : {
705 0 : m_pScrollSB->SetThumbPos(m_pScrollSB->GetThumbPos() + 1);
706 0 : aEditArr[6]->GrabFocus();
707 0 : nRet = 1;
708 : }
709 : }
710 : //scroll backward
711 0 : else if (m_pScrollSB->GetThumbPos() && (aEditArr[0]->HasFocus()||aEditArr[1]->HasFocus()) )
712 : {
713 0 : m_pScrollSB->SetThumbPos(m_pScrollSB->GetThumbPos() - 1);
714 0 : aEditArr[1]->GrabFocus();
715 0 : nRet = 1;
716 : }
717 0 : if (nRet)
718 0 : ScrollHdl_Impl(m_pScrollSB);
719 : }
720 0 : return nRet;
721 : }
722 :
723 0 : IMPL_LINK(SvxRubyDialog, EditJumpHdl_Impl, sal_Int32*, pParam)
724 : {
725 0 : sal_uInt16 nIndex = USHRT_MAX;
726 0 : for (sal_uInt16 i = 0; i < 8; i++)
727 : {
728 0 : if(aEditArr[i]->HasFocus())
729 0 : nIndex = i;
730 : }
731 0 : if (nIndex < 8)
732 : {
733 0 : if (*pParam > 0)
734 : {
735 0 : if (nIndex < 6)
736 0 : aEditArr[nIndex + 2]->GrabFocus();
737 0 : else if( EditScrollHdl_Impl(pParam))
738 0 : aEditArr[nIndex]->GrabFocus();
739 : }
740 : else
741 : {
742 0 : if (nIndex > 1)
743 0 : aEditArr[nIndex - 2]->GrabFocus();
744 0 : else if( EditScrollHdl_Impl(pParam))
745 0 : aEditArr[nIndex]->GrabFocus();
746 : }
747 : }
748 0 : return 0;
749 : };
750 :
751 0 : void SvxRubyDialog::AssertOneEntry()
752 : {
753 0 : pImpl->AssertOneEntry();
754 0 : }
755 :
756 0 : void SvxRubyDialog::UpdateColors()
757 : {
758 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
759 0 : svtools::ColorConfig aColorConfig;
760 :
761 0 : vcl::Font aFont(m_pPreviewWin->GetFont());
762 :
763 0 : Color aNewTextColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor);
764 0 : Color aNewFillColor(rStyleSettings.GetWindowColor());
765 :
766 0 : if (aNewFillColor != aFont.GetFillColor() || aNewTextColor != aFont.GetColor())
767 : {
768 0 : aFont.SetFillColor(aNewFillColor);
769 0 : aFont.SetColor(aNewTextColor);
770 0 : m_pPreviewWin->SetFont(aFont);
771 0 : }
772 0 : }
773 :
774 0 : void SvxRubyDialog::DataChanged( const DataChangedEvent& rDCEvt )
775 : {
776 0 : SfxModelessDialog::DataChanged( rDCEvt );
777 :
778 0 : if ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
779 : {
780 0 : UpdateColors();
781 : }
782 0 : }
783 :
784 0 : void SvxRubyDialog::EnableControls(bool bEnable)
785 : {
786 0 : get_content_area()->Enable(bEnable);
787 0 : m_pApplyPB->Enable(bEnable);
788 0 : }
789 :
790 0 : RubyPreview::RubyPreview(vcl::Window *pParent)
791 : : Window(pParent, WB_BORDER)
792 0 : , m_pParentDlg(NULL)
793 : {
794 0 : SetBorderStyle(WindowBorderStyle::MONO);
795 0 : }
796 :
797 0 : RubyPreview::~RubyPreview()
798 : {
799 0 : disposeOnce();
800 0 : }
801 :
802 0 : void RubyPreview::dispose()
803 : {
804 0 : m_pParentDlg.clear();
805 0 : vcl::Window::dispose();
806 0 : }
807 :
808 0 : VCL_BUILDER_FACTORY(RubyPreview)
809 :
810 0 : void RubyPreview::Paint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/)
811 : {
812 0 : rRenderContext.Push(PushFlags::MAPMODE);
813 :
814 0 : rRenderContext.SetMapMode(MAP_TWIP);
815 :
816 0 : Size aWinSize = rRenderContext.GetOutputSize();
817 :
818 0 : vcl::Font aSaveFont = rRenderContext.GetFont();
819 0 : aSaveFont.SetHeight(aWinSize.Height() / 4);
820 0 : rRenderContext.SetFont(aSaveFont);
821 :
822 0 : Rectangle aRect(Point(0, 0), aWinSize);
823 0 : rRenderContext.SetLineColor();
824 0 : rRenderContext.SetFillColor(aSaveFont.GetFillColor());
825 0 : rRenderContext.DrawRect(aRect);
826 :
827 0 : OUString sBaseText, sRubyText;
828 0 : m_pParentDlg->GetCurrentText(sBaseText, sRubyText);
829 :
830 0 : long nTextHeight = rRenderContext.GetTextHeight();
831 0 : long nBaseWidth = rRenderContext.GetTextWidth(sBaseText);
832 :
833 0 : vcl::Font aRubyFont(aSaveFont);
834 0 : aRubyFont.SetHeight(aRubyFont.GetHeight() * 70 / 100);
835 0 : rRenderContext.SetFont(aRubyFont);
836 0 : long nRubyWidth = rRenderContext.GetTextWidth(sRubyText);
837 0 : rRenderContext.SetFont(aSaveFont);
838 :
839 0 : sal_uInt16 nAdjust = m_pParentDlg->m_pAdjustLB->GetSelectEntryPos();
840 : //use center if no adjustment is available
841 0 : if (nAdjust > 4)
842 0 : nAdjust = 1;
843 :
844 : //which part is stretched ?
845 0 : bool bRubyStretch = nBaseWidth >= nRubyWidth;
846 :
847 0 : long nCenter = aWinSize.Width() / 2;
848 0 : long nLeftStart = nCenter - (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
849 0 : long nRightEnd = nCenter + (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
850 :
851 0 : long nYRuby = aWinSize.Height() / 4 - nTextHeight / 2;
852 0 : long nYBase = aWinSize.Height() * 3 / 4 - nTextHeight / 2;
853 :
854 : //use above also if no selection is set
855 0 : bool bAbove = m_pParentDlg->m_pPositionLB->GetSelectEntryPos() != 1;
856 0 : if (!bAbove)
857 : {
858 0 : long nTmp = nYRuby;
859 0 : nYRuby = nYBase;
860 0 : nYBase = nTmp;
861 : }
862 :
863 : long nYOutput;
864 : long nOutTextWidth;
865 0 : OUString sOutputText;
866 :
867 0 : if (bRubyStretch)
868 : {
869 0 : rRenderContext.DrawText(Point(nLeftStart , nYBase), sBaseText);
870 0 : nYOutput = nYRuby;
871 0 : sOutputText = sRubyText;
872 0 : nOutTextWidth = nRubyWidth;
873 0 : rRenderContext.SetFont(aRubyFont);
874 : }
875 : else
876 : {
877 0 : rRenderContext.SetFont(aRubyFont);
878 0 : rRenderContext.DrawText(Point(nLeftStart , nYRuby), sRubyText);
879 0 : nYOutput = nYBase;
880 0 : sOutputText = sBaseText;
881 0 : nOutTextWidth = nBaseWidth;
882 0 : rRenderContext.SetFont(aSaveFont);
883 : }
884 :
885 0 : switch (nAdjust)
886 : {
887 : case RubyAdjust_LEFT:
888 0 : rRenderContext.DrawText(Point(nLeftStart , nYOutput), sOutputText);
889 0 : break;
890 : case RubyAdjust_RIGHT:
891 0 : rRenderContext.DrawText(Point(nRightEnd - nOutTextWidth, nYOutput), sOutputText);
892 0 : break;
893 : case RubyAdjust_INDENT_BLOCK:
894 : {
895 0 : long nCharWidth = GetTextWidth(OUString("X"));
896 0 : if (nOutTextWidth < (nRightEnd - nLeftStart - nCharWidth))
897 : {
898 0 : nCharWidth /= 2;
899 0 : nLeftStart += nCharWidth;
900 0 : nRightEnd -= nCharWidth;
901 : }
902 : }
903 : // no break!
904 : case RubyAdjust_BLOCK:
905 : {
906 0 : if (sOutputText.getLength() > 1)
907 : {
908 0 : sal_Int32 nCount = sOutputText.getLength();
909 0 : long nSpace = ((nRightEnd - nLeftStart) - GetTextWidth(sOutputText)) / (nCount - 1);
910 0 : for (sal_Int32 i = 0; i < nCount; i++)
911 : {
912 0 : OUString sChar(sOutputText[i]);
913 0 : rRenderContext.DrawText(Point(nLeftStart , nYOutput), sChar);
914 0 : long nCharWidth = GetTextWidth(sChar);
915 0 : nLeftStart += nCharWidth + nSpace;
916 0 : }
917 0 : break;
918 : }
919 : }
920 : //no break;
921 : case RubyAdjust_CENTER:
922 0 : rRenderContext.DrawText(Point(nCenter - nOutTextWidth / 2 , nYOutput), sOutputText);
923 0 : break;
924 : }
925 0 : rRenderContext.SetFont(aSaveFont);
926 0 : rRenderContext.Pop();
927 0 : }
928 :
929 0 : Size RubyPreview::GetOptimalSize() const
930 : {
931 0 : return LogicToPixel(Size(215, 50), MapMode(MAP_APPFONT));
932 : }
933 :
934 0 : void RubyEdit::GetFocus()
935 : {
936 0 : GetModifyHdl().Call(this);
937 0 : Edit::GetFocus();
938 0 : }
939 :
940 0 : bool RubyEdit::PreNotify(NotifyEvent& rNEvt)
941 : {
942 0 : bool nHandled = false;
943 0 : if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT)
944 : {
945 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
946 0 : const vcl::KeyCode& rKeyCode = pKEvt->GetKeyCode();
947 0 : sal_uInt16 nMod = rKeyCode.GetModifier();
948 0 : sal_uInt16 nCode = rKeyCode.GetCode();
949 0 : if (nCode == KEY_TAB && (!nMod || KEY_SHIFT == nMod))
950 : {
951 0 : sal_Int32 nParam = KEY_SHIFT == nMod ? -1 : 1;
952 0 : if(aScrollHdl.IsSet() && aScrollHdl.Call(&nParam))
953 0 : nHandled = true;
954 : }
955 0 : else if (KEY_UP == nCode || KEY_DOWN == nCode)
956 : {
957 0 : sal_Int32 nParam = KEY_UP == nCode ? -1 : 1;
958 0 : aJumpHdl.Call(&nParam);
959 : }
960 : }
961 0 : if (!nHandled)
962 0 : nHandled = Edit::PreNotify(rNEvt);
963 0 : return nHandled;
964 : }
965 :
966 390 : VCL_BUILDER_FACTORY(RubyEdit)
967 :
968 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|