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