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 <textanim.hxx>
21 #include <textattr.hxx>
22 #include <svx/dlgutil.hxx>
23 #include <svx/svdmark.hxx>
24 #include <svx/svdview.hxx>
25 #include <svx/sdtaaitm.hxx>
26 #include <svx/sdtacitm.hxx>
27 #include <svx/sdtaiitm.hxx>
28 #include <svx/sdtayitm.hxx>
29 #include <svtools/unitconv.hxx>
30 
31 const sal_uInt16 SvxTextAnimationPage::pRanges[] =
32 {
33     SDRATTR_TEXT_ANIKIND,
34     SDRATTR_TEXT_ANIAMOUNT,
35     0
36 };
37 
38 /*************************************************************************
39 |*
40 |* constructor of the tab dialog: adds pages to the dialog
41 |*
42 \************************************************************************/
43 
SvxTextTabDialog(weld::Window * pParent,const SfxItemSet * pAttr,const SdrView * pSdrView)44 SvxTextTabDialog::SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrView* pSdrView)
45     : SfxTabDialogController(pParent, "cui/ui/textdialog.ui", "TextDialog", pAttr)
46     , pView(pSdrView)
47 {
48     AddTabPage("RID_SVXPAGE_TEXTATTR", SvxTextAttrPage::Create, nullptr);
49     AddTabPage("RID_SVXPAGE_TEXTANIMATION", SvxTextAnimationPage::Create, nullptr);
50 }
51 
52 /*************************************************************************
53 |*
54 |* PageCreated()
55 |*
56 \************************************************************************/
57 
PageCreated(const OString & rId,SfxTabPage & rPage)58 void SvxTextTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
59 {
60     if (rId == "RID_SVXPAGE_TEXTATTR")
61     {
62         SdrObjKind eKind = OBJ_NONE;
63         if (pView)
64         {
65             const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
66             bool bHasMarked = rMarkList.GetMarkCount() > 0;
67             if (bHasMarked)
68             {
69                 if (rMarkList.GetMarkCount() == 1)
70                 {
71                     const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
72                     eKind = static_cast<SdrObjKind>(pObj->GetObjIdentifier());
73                 }
74             }
75         }
76         static_cast<SvxTextAttrPage&>(rPage).SetObjKind(eKind);
77         static_cast<SvxTextAttrPage&>(rPage).Construct();
78     }
79 }
80 
81 /*************************************************************************
82 |*
83 |* Page
84 |*
85 \************************************************************************/
SvxTextAnimationPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rInAttrs)86 SvxTextAnimationPage::SvxTextAnimationPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
87     : SfxTabPage(pPage, pController, "cui/ui/textanimtabpage.ui", "TextAnimation", &rInAttrs)
88     , rOutAttrs(rInAttrs)
89     , eAniKind(SdrTextAniKind::NONE)
90     , m_aUpState(TRISTATE_INDET)
91     , m_aLeftState(TRISTATE_INDET)
92     , m_aRightState(TRISTATE_INDET)
93     , m_aDownState(TRISTATE_INDET)
94     , m_xLbEffect(m_xBuilder->weld_combo_box("LB_EFFECT"))
95     , m_xBoxDirection(m_xBuilder->weld_widget("boxDIRECTION"))
96     , m_xBtnUp(m_xBuilder->weld_toggle_button("BTN_UP"))
97     , m_xBtnLeft(m_xBuilder->weld_toggle_button("BTN_LEFT"))
98     , m_xBtnRight(m_xBuilder->weld_toggle_button("BTN_RIGHT"))
99     , m_xBtnDown(m_xBuilder->weld_toggle_button("BTN_DOWN"))
100     , m_xFlProperties(m_xBuilder->weld_frame("FL_PROPERTIES"))
101     , m_xTsbStartInside(m_xBuilder->weld_check_button("TSB_START_INSIDE"))
102     , m_xTsbStopInside(m_xBuilder->weld_check_button("TSB_STOP_INSIDE"))
103     , m_xBoxCount(m_xBuilder->weld_widget("boxCOUNT"))
104     , m_xTsbEndless(m_xBuilder->weld_check_button("TSB_ENDLESS"))
105     , m_xNumFldCount(m_xBuilder->weld_spin_button("NUM_FLD_COUNT"))
106     , m_xTsbPixel(m_xBuilder->weld_check_button("TSB_PIXEL"))
107     , m_xMtrFldAmount(m_xBuilder->weld_metric_spin_button("MTR_FLD_AMOUNT", FieldUnit::PIXEL))
108     , m_xTsbAuto(m_xBuilder->weld_check_button("TSB_AUTO"))
109     , m_xMtrFldDelay(m_xBuilder->weld_metric_spin_button("MTR_FLD_DELAY", FieldUnit::MILLISECOND))
110 {
111     eFUnit = GetModuleFieldUnit( rInAttrs );
112     SfxItemPool* pPool = rOutAttrs.GetPool();
113     DBG_ASSERT( pPool, "Where is the pool?" );
114     eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
115 
116     m_xLbEffect->connect_changed( LINK( this, SvxTextAnimationPage, SelectEffectHdl_Impl ) );
117     m_xTsbEndless->connect_clicked( LINK( this, SvxTextAnimationPage, ClickEndlessHdl_Impl ) );
118     m_xTsbAuto->connect_clicked( LINK( this, SvxTextAnimationPage, ClickAutoHdl_Impl ) );
119     m_xTsbPixel->connect_clicked( LINK( this, SvxTextAnimationPage, ClickPixelHdl_Impl ) );
120 
121     Link<weld::Button&,void> aLink( LINK( this, SvxTextAnimationPage, ClickDirectionHdl_Impl ) );
122     m_xBtnUp->connect_clicked( aLink );
123     m_xBtnLeft->connect_clicked( aLink );
124     m_xBtnRight->connect_clicked( aLink );
125     m_xBtnDown->connect_clicked( aLink );
126 }
127 
~SvxTextAnimationPage()128 SvxTextAnimationPage::~SvxTextAnimationPage()
129 {
130 }
131 
132 /*************************************************************************
133 |*
134 |* reads the passed item set
135 |*
136 \************************************************************************/
137 
Reset(const SfxItemSet * rAttrs)138 void SvxTextAnimationPage::Reset( const SfxItemSet* rAttrs )
139 {
140     const SfxItemPool* pPool = rAttrs->GetPool();
141 
142     // animation type
143     const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIKIND );
144 
145     if( !pItem )
146         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIKIND );
147 
148     eAniKind = static_cast<const SdrTextAniKindItem*>(pItem)->GetValue();
149     m_xLbEffect->set_active(sal::static_int_cast<sal_Int32>(eAniKind));
150     m_xLbEffect->save_value();
151 
152     // animation direction
153     pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDIRECTION );
154     if( !pItem )
155         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDIRECTION );
156 
157     SelectDirection(static_cast<const SdrTextAniDirectionItem*>(pItem)->GetValue());
158     m_aUpState = m_xBtnUp->get_state();
159     m_aLeftState = m_xBtnLeft->get_state();
160     m_aRightState = m_xBtnRight->get_state();
161     m_aDownState = m_xBtnDown->get_state();
162 
163     // Start inside
164     pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTARTINSIDE );
165     if( !pItem )
166         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTARTINSIDE );
167 
168     if (static_cast<const SdrTextAniStartInsideItem*>(pItem)->GetValue())
169         m_xTsbStartInside->set_state(TRISTATE_TRUE);
170     else
171         m_xTsbStartInside->set_state(TRISTATE_FALSE);
172     m_xTsbStartInside->save_state();
173 
174     // Stop inside
175     pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTOPINSIDE );
176     if( !pItem )
177         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTOPINSIDE );
178 
179     if (static_cast<const SdrTextAniStopInsideItem*>(pItem)->GetValue())
180         m_xTsbStopInside->set_state(TRISTATE_TRUE);
181     else
182         m_xTsbStopInside->set_state(TRISTATE_FALSE);
183     m_xTsbStopInside->save_state();
184 
185     // quantity
186     pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANICOUNT );
187     if( !pItem )
188         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANICOUNT );
189 
190     long nValue = static_cast<long>(static_cast<const SdrTextAniCountItem*>(pItem)->GetValue());
191     m_xNumFldCount->set_value(nValue);
192     if (nValue == 0)
193     {
194         if (eAniKind == SdrTextAniKind::Slide)
195         {
196             m_xTsbEndless->set_state(TRISTATE_FALSE);
197             m_xTsbEndless->set_sensitive(false);
198         }
199         else
200         {
201             m_xTsbEndless->set_state(TRISTATE_TRUE);
202             m_xNumFldCount->set_text("");
203         }
204     }
205     else
206         m_xTsbEndless->set_state(TRISTATE_FALSE);
207     m_xTsbEndless->save_state();
208     m_xNumFldCount->save_value();
209 
210     // delay
211     pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDELAY );
212     if( !pItem )
213         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDELAY );
214 
215     nValue = static_cast<long>(static_cast<const SdrTextAniDelayItem*>(pItem)->GetValue());
216     m_xMtrFldDelay->set_value(nValue, FieldUnit::NONE);
217     if (nValue == 0)
218     {
219         m_xTsbAuto->set_state(TRISTATE_TRUE);
220         m_xMtrFldDelay->set_text("");
221     }
222     else
223         m_xTsbAuto->set_state(TRISTATE_FALSE);
224     m_xTsbAuto->save_state();
225     m_xMtrFldDelay->save_value();
226 
227     // step size
228     pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIAMOUNT );
229     if( !pItem )
230         pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIAMOUNT );
231 
232     nValue = static_cast<long>(static_cast<const SdrTextAniAmountItem*>(pItem)->GetValue());
233     if (nValue <= 0)
234     {
235         m_xTsbPixel->set_state(TRISTATE_TRUE);
236         nValue = -nValue;
237         if (nValue == 0)
238             nValue++;
239         m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
240         m_xMtrFldAmount->set_digits(0);
241 
242         m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
243         m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
244         m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
245     }
246     else
247     {
248         m_xTsbPixel->set_state(TRISTATE_FALSE);
249         m_xMtrFldAmount->set_unit(eFUnit);
250         m_xMtrFldAmount->set_digits(2);
251 
252         m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
253         m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
254 
255         SetMetricValue(*m_xMtrFldAmount, nValue, eUnit);
256     }
257     m_xTsbPixel->save_state();
258     m_xMtrFldAmount->save_value();
259 
260     SelectEffectHdl_Impl(*m_xLbEffect);
261     ClickEndlessHdl_Impl(*m_xTsbEndless);
262     ClickAutoHdl_Impl(*m_xTsbAuto);
263 }
264 
265 /*************************************************************************
266 |*
267 |* fills the passed item set with dialog box attributes
268 |*
269 \************************************************************************/
270 
FillItemSet(SfxItemSet * rAttrs)271 bool SvxTextAnimationPage::FillItemSet( SfxItemSet* rAttrs)
272 {
273     bool bModified = false;
274     TriState eState;
275 
276     // animation type
277     int nPos = m_xLbEffect->get_active();
278     if( nPos != -1 &&
279         m_xLbEffect->get_value_changed_from_saved() )
280     {
281         rAttrs->Put( SdrTextAniKindItem( static_cast<SdrTextAniKind>(nPos) ) );
282         bModified = true;
283     }
284 
285     // animation direction
286     if (m_aUpState != m_xBtnUp->get_state() ||
287         m_aLeftState != m_xBtnLeft->get_state() ||
288         m_aRightState != m_xBtnRight->get_state() ||
289         m_aDownState != m_xBtnDown->get_state())
290     {
291         SdrTextAniDirection eValue = static_cast<SdrTextAniDirection>(GetSelectedDirection());
292         rAttrs->Put( SdrTextAniDirectionItem( eValue ) );
293         bModified = true;
294     }
295 
296     // Start inside
297     eState = m_xTsbStartInside->get_state();
298     if (m_xTsbStartInside->get_state_changed_from_saved())
299     {
300         rAttrs->Put( SdrTextAniStartInsideItem( TRISTATE_TRUE == eState ) );
301         bModified = true;
302     }
303 
304     // Stop inside
305     eState = m_xTsbStopInside->get_state();
306     if (m_xTsbStopInside->get_state_changed_from_saved())
307     {
308         rAttrs->Put( SdrTextAniStopInsideItem( TRISTATE_TRUE == eState ) );
309         bModified = true;
310     }
311 
312     // quantity
313     eState = m_xTsbEndless->get_state();
314     if (m_xTsbEndless->get_state_changed_from_saved() ||
315         m_xNumFldCount->get_value_changed_from_saved())
316     {
317         sal_Int64 nValue = 0;
318         if( eState == TRISTATE_TRUE /*#89844#*/ && m_xTsbEndless->get_sensitive())
319             bModified = true;
320         else
321         {
322             if( m_xNumFldCount->get_value_changed_from_saved() )
323             {
324                 nValue = m_xNumFldCount->get_value();
325                 bModified = true;
326             }
327         }
328         if( bModified )
329             rAttrs->Put( SdrTextAniCountItem( static_cast<sal_uInt16>(nValue) ) );
330     }
331 
332     // delay
333     eState = m_xTsbAuto->get_state();
334     if (m_xTsbAuto->get_state_changed_from_saved() ||
335         m_xMtrFldDelay->get_value_changed_from_saved())
336     {
337         sal_Int64 nValue = 0;
338         if( eState == TRISTATE_TRUE )
339             bModified = true;
340         else
341         {
342             if( m_xMtrFldDelay->get_value_changed_from_saved() )
343             {
344                 nValue = m_xMtrFldDelay->get_value(FieldUnit::NONE);
345                 bModified = true;
346             }
347         }
348         if( bModified )
349             rAttrs->Put( SdrTextAniDelayItem( static_cast<sal_uInt16>(nValue) ) );
350     }
351 
352     // step size
353     eState = m_xTsbPixel->get_state();
354     if (m_xTsbPixel->get_state_changed_from_saved() ||
355         m_xMtrFldAmount->get_value_changed_from_saved())
356     {
357         sal_Int64 nValue = 0;
358         if( eState == TRISTATE_TRUE )
359         {
360             nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE);
361             nValue = -nValue;
362         }
363         else
364         {
365             nValue = GetCoreValue( *m_xMtrFldAmount, eUnit );
366         }
367         rAttrs->Put( SdrTextAniAmountItem( static_cast<sal_Int16>(nValue) ) );
368 
369         bModified = true;
370     }
371 
372     return bModified;
373 }
374 
375 /*************************************************************************
376 |*
377 |* creates the page
378 |*
379 \************************************************************************/
380 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrs)381 std::unique_ptr<SfxTabPage> SvxTextAnimationPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
382 {
383     return std::make_unique<SvxTextAnimationPage>(pPage, pController, *rAttrs);
384 }
385 
IMPL_LINK_NOARG(SvxTextAnimationPage,SelectEffectHdl_Impl,weld::ComboBox &,void)386 IMPL_LINK_NOARG(SvxTextAnimationPage, SelectEffectHdl_Impl, weld::ComboBox&, void)
387 {
388     int nPos = m_xLbEffect->get_active();
389     if (nPos != -1)
390     {
391         eAniKind = static_cast<SdrTextAniKind>(nPos);
392         switch( eAniKind )
393         {
394             case SdrTextAniKind::NONE:
395             {
396                 m_xBoxDirection->set_sensitive(false);
397                 m_xFlProperties->set_sensitive(false);
398             }
399             break;
400 
401             case SdrTextAniKind::Blink:
402             case SdrTextAniKind::Scroll:
403             case SdrTextAniKind::Alternate:
404             case SdrTextAniKind::Slide:
405             {
406                 m_xFlProperties->set_sensitive(true);
407                 if( eAniKind == SdrTextAniKind::Slide )
408                 {
409                     m_xTsbStartInside->set_sensitive(false);
410                     m_xTsbStopInside->set_sensitive(false);
411                     m_xTsbEndless->set_sensitive(false);
412                     m_xNumFldCount->set_sensitive(true);
413                     m_xNumFldCount->set_value(m_xNumFldCount->get_value());
414                 }
415                 else
416                 {
417                     m_xTsbStartInside->set_sensitive(true);
418                     m_xTsbStopInside->set_sensitive(true);
419                     m_xTsbEndless->set_sensitive(true);
420                     ClickEndlessHdl_Impl(*m_xTsbEndless);
421                 }
422 
423                 m_xTsbAuto->set_sensitive(true);
424                 ClickAutoHdl_Impl(*m_xTsbAuto);
425 
426                 if( eAniKind == SdrTextAniKind::Blink )
427                 {
428                     m_xBoxDirection->set_sensitive(false);
429                     m_xBoxCount->set_sensitive(false);
430                 }
431                 else
432                 {
433                     m_xBoxDirection->set_sensitive(true);
434                     m_xBoxCount->set_sensitive(true);
435                 }
436             }
437             break;
438         }
439 
440     }
441 }
442 
IMPL_LINK_NOARG(SvxTextAnimationPage,ClickEndlessHdl_Impl,weld::Button &,void)443 IMPL_LINK_NOARG(SvxTextAnimationPage, ClickEndlessHdl_Impl, weld::Button&, void)
444 {
445     if( eAniKind != SdrTextAniKind::Slide )
446     {
447         TriState eState = m_xTsbEndless->get_state();
448         if( eState != TRISTATE_FALSE )
449         {
450             m_xNumFldCount->set_sensitive(false);
451             m_xNumFldCount->set_text("");
452         }
453         else
454         {
455             m_xNumFldCount->set_sensitive(true);
456             m_xNumFldCount->set_value(m_xNumFldCount->get_value());
457         }
458     }
459 }
460 
IMPL_LINK_NOARG(SvxTextAnimationPage,ClickAutoHdl_Impl,weld::Button &,void)461 IMPL_LINK_NOARG(SvxTextAnimationPage, ClickAutoHdl_Impl, weld::Button&, void)
462 {
463     TriState eState = m_xTsbAuto->get_state();
464     if( eState != TRISTATE_FALSE )
465     {
466         m_xMtrFldDelay->set_sensitive(false);
467         m_xMtrFldDelay->set_text("");
468     }
469     else
470     {
471         m_xMtrFldDelay->set_sensitive(true);
472         m_xMtrFldDelay->set_value(m_xMtrFldDelay->get_value(FieldUnit::NONE), FieldUnit::NONE); //to-do
473     }
474 }
475 
IMPL_LINK_NOARG(SvxTextAnimationPage,ClickPixelHdl_Impl,weld::Button &,void)476 IMPL_LINK_NOARG(SvxTextAnimationPage, ClickPixelHdl_Impl, weld::Button&, void)
477 {
478     TriState eState = m_xTsbPixel->get_state();
479     if (eState == TRISTATE_TRUE)
480     {
481         int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) / 10;
482         m_xMtrFldAmount->set_sensitive(true);
483         m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
484         m_xMtrFldAmount->set_digits(0);
485 
486         m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
487         m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
488 
489         m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
490     }
491     else if( eState == TRISTATE_FALSE )
492     {
493         int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) * 10;
494         m_xMtrFldAmount->set_sensitive(true);
495         m_xMtrFldAmount->set_unit(eFUnit);
496         m_xMtrFldAmount->set_digits(2);
497 
498         m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
499         m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
500 
501         m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
502     }
503 }
504 
IMPL_LINK(SvxTextAnimationPage,ClickDirectionHdl_Impl,weld::Button &,rBtn,void)505 IMPL_LINK(SvxTextAnimationPage, ClickDirectionHdl_Impl, weld::Button&, rBtn, void)
506 {
507     m_xBtnUp->set_active(&rBtn == m_xBtnUp.get());
508     m_xBtnLeft->set_active(&rBtn == m_xBtnLeft.get());
509     m_xBtnRight->set_active(&rBtn == m_xBtnRight.get());
510     m_xBtnDown->set_active(&rBtn == m_xBtnDown.get());
511 }
512 
SelectDirection(SdrTextAniDirection nValue)513 void SvxTextAnimationPage::SelectDirection( SdrTextAniDirection nValue )
514 {
515     m_xBtnUp->set_active( nValue == SdrTextAniDirection::Up );
516     m_xBtnLeft->set_active( nValue == SdrTextAniDirection::Left );
517     m_xBtnRight->set_active( nValue == SdrTextAniDirection::Right );
518     m_xBtnDown->set_active( nValue == SdrTextAniDirection::Down );
519 }
520 
GetSelectedDirection() const521 sal_uInt16 SvxTextAnimationPage::GetSelectedDirection() const
522 {
523     SdrTextAniDirection nValue = SdrTextAniDirection::Left;
524 
525     if( m_xBtnUp->get_active() )
526         nValue = SdrTextAniDirection::Up;
527     else if( m_xBtnLeft->get_active() )
528         nValue = SdrTextAniDirection::Left;
529     else if( m_xBtnRight->get_active() )
530         nValue = SdrTextAniDirection::Right;
531     else if( m_xBtnDown->get_active() )
532         nValue = SdrTextAniDirection::Down;
533 
534     return static_cast<sal_uInt16>(nValue);
535 }
536 
537 
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
539