Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/tbxctrls/extrusioncontrols.cxx
Line
Count
Source
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 <sal/config.h>
21
22
#include <comphelper/propertyvalue.hxx>
23
#include <svtools/toolbarmenu.hxx>
24
#include <vcl/toolbox.hxx>
25
26
#include <svx/strings.hrc>
27
#include <svx/svdtrans.hxx>
28
#include <svx/dialmgr.hxx>
29
30
#include <helpids.h>
31
#include "extrusioncontrols.hxx"
32
#include <extrusiondepthdialog.hxx>
33
34
#include <bitmaps.hlst>
35
36
using namespace ::com::sun::star::uno;
37
using namespace ::com::sun::star::beans;
38
using namespace ::com::sun::star::util;
39
using namespace ::com::sun::star::graphic;
40
41
namespace svx
42
{
43
44
const sal_Int32 gSkewList[] = { 135, 90, 45, 180, 0, -360, -135, -90, -45 };
45
constexpr OUString g_sExtrusionDirection = u".uno:ExtrusionDirection"_ustr;
46
constexpr OUString g_sExtrusionProjection = u".uno:ExtrusionProjection"_ustr;
47
constexpr OUString EMPTY = u""_ustr;
48
49
constexpr OUString aLightOffBmps[] =
50
{
51
    RID_SVXBMP_LIGHT_OFF_FROM_TOP_LEFT,
52
    RID_SVXBMP_LIGHT_OFF_FROM_TOP,
53
    RID_SVXBMP_LIGHT_OFF_FROM_TOP_RIGHT,
54
    RID_SVXBMP_LIGHT_OFF_FROM_LEFT,
55
    EMPTY,
56
    RID_SVXBMP_LIGHT_OFF_FROM_RIGHT,
57
    RID_SVXBMP_LIGHT_OFF_FROM_BOTTOM_LEFT,
58
    RID_SVXBMP_LIGHT_OFF_FROM_BOTTOM,
59
    RID_SVXBMP_LIGHT_OFF_FROM_BOTTOM_RIGHT
60
};
61
62
constexpr OUString aLightOnBmps[] =
63
{
64
    RID_SVXBMP_LIGHT_ON_FROM_TOP_LEFT,
65
    RID_SVXBMP_LIGHT_ON_FROM_TOP,
66
    RID_SVXBMP_LIGHT_ON_FROM_TOP_RIGHT,
67
    RID_SVXBMP_LIGHT_ON_FROM_LEFT,
68
    EMPTY,
69
    RID_SVXBMP_LIGHT_ON_FROM_RIGHT,
70
    RID_SVXBMP_LIGHT_ON_FROM_BOTTOM_LEFT,
71
    RID_SVXBMP_LIGHT_ON_FROM_BOTTOM,
72
    RID_SVXBMP_LIGHT_ON_FROM_BOTTOM_RIGHT
73
};
74
75
constexpr OUString aLightPreviewBmps[] =
76
{
77
    RID_SVXBMP_LIGHT_PREVIEW_FROM_TOP_LEFT,
78
    RID_SVXBMP_LIGHT_PREVIEW_FROM_TOP,
79
    RID_SVXBMP_LIGHT_PREVIEW_FROM_TOP_RIGHT,
80
    RID_SVXBMP_LIGHT_PREVIEW_FROM_LEFT,
81
    RID_SVXBMP_LIGHT_PREVIEW_FROM_FRONT,
82
    RID_SVXBMP_LIGHT_PREVIEW_FROM_RIGHT,
83
    RID_SVXBMP_LIGHT_PREVIEW_FROM_BOTTOM_LEFT,
84
    RID_SVXBMP_LIGHT_PREVIEW_FROM_BOTTOM,
85
    RID_SVXBMP_LIGHT_PREVIEW_FROM_BOTTOM_RIGHT
86
};
87
88
constexpr OUString aDirectionBmps[] =
89
{
90
    RID_SVXBMP_DIRECTION_DIRECTION_NW,
91
    RID_SVXBMP_DIRECTION_DIRECTION_N,
92
    RID_SVXBMP_DIRECTION_DIRECTION_NE,
93
    RID_SVXBMP_DIRECTION_DIRECTION_W,
94
    RID_SVXBMP_DIRECTION_DIRECTION_NONE,
95
    RID_SVXBMP_DIRECTION_DIRECTION_E,
96
    RID_SVXBMP_DIRECTION_DIRECTION_SW,
97
    RID_SVXBMP_DIRECTION_DIRECTION_S,
98
    RID_SVXBMP_DIRECTION_DIRECTION_SE
99
};
100
101
constexpr TranslateId aDirectionStrs[] =
102
{
103
    RID_SVXSTR_DIRECTION_NW,
104
    RID_SVXSTR_DIRECTION_N,
105
    RID_SVXSTR_DIRECTION_NE,
106
    RID_SVXSTR_DIRECTION_W,
107
    RID_SVXSTR_DIRECTION_NONE,
108
    RID_SVXSTR_DIRECTION_E,
109
    RID_SVXSTR_DIRECTION_SW,
110
    RID_SVXSTR_DIRECTION_S,
111
    RID_SVXSTR_DIRECTION_SE
112
};
113
114
ExtrusionDirectionWindow::ExtrusionDirectionWindow(
115
    svt::PopupWindowController* pControl,
116
    weld::Widget* pParent)
117
0
    : WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"svx/ui/directionwindow.ui"_ustr, u"DirectionWindow"_ustr)
118
0
    , mxControl(pControl)
119
0
    , mxDirectionSet(new ValueSet(nullptr))
120
0
    , mxDirectionSetWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *mxDirectionSet))
121
0
    , mxPerspective(m_xBuilder->weld_radio_button(u"perspective"_ustr))
122
0
    , mxParallel(m_xBuilder->weld_radio_button(u"parallel"_ustr))
123
0
{
124
0
    mxDirectionSet->SetStyle(WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT);
125
126
0
    for (sal_uInt16 i = DIRECTION_NW; i <= DIRECTION_SE; ++i)
127
0
    {
128
0
        maImgDirection[i] = Image(StockImage::Yes, aDirectionBmps[i]);
129
0
    }
130
131
0
    mxDirectionSet->SetSelectHdl( LINK( this, ExtrusionDirectionWindow, SelectValueSetHdl ) );
132
0
    mxDirectionSet->SetColCount( 3 );
133
0
    mxDirectionSet->EnableFullItemMode( false );
134
135
0
    for (sal_uInt16 i = DIRECTION_NW; i <= DIRECTION_SE; ++i)
136
0
    {
137
0
        mxDirectionSet->InsertItem(i + 1, maImgDirection[i], SvxResId(aDirectionStrs[i]));
138
0
    }
139
140
0
    Size aSize(72, 72);
141
0
    mxDirectionSet->GetDrawingArea()->set_size_request(aSize.Width(), aSize.Height());
142
0
    mxDirectionSet->SetOutputSizePixel(aSize);
143
144
0
    mxPerspective->connect_toggled(LINK(this, ExtrusionDirectionWindow, SelectToolbarMenuHdl));
145
146
0
    AddStatusListener( g_sExtrusionDirection );
147
0
    AddStatusListener( g_sExtrusionProjection );
148
0
}
149
150
void ExtrusionDirectionWindow::GrabFocus()
151
0
{
152
0
    mxDirectionSet->GrabFocus();
153
0
}
154
155
ExtrusionDirectionWindow::~ExtrusionDirectionWindow()
156
0
{
157
0
}
158
159
void ExtrusionDirectionWindow::implSetDirection( sal_Int32 nSkew, bool bEnabled )
160
0
{
161
0
    sal_uInt16 nItemId;
162
0
    for( nItemId = DIRECTION_NW; nItemId <= DIRECTION_SE; nItemId++ )
163
0
    {
164
0
        if( gSkewList[nItemId] == nSkew )
165
0
            break;
166
0
    }
167
168
0
    if( nItemId <= DIRECTION_SE )
169
0
    {
170
0
        mxDirectionSet->SelectItem( nItemId+1 );
171
0
    }
172
0
    else
173
0
    {
174
0
        mxDirectionSet->SetNoSelection();
175
0
    }
176
177
0
    if (bEnabled)
178
0
        mxDirectionSet->Enable();
179
0
    else
180
0
        mxDirectionSet->Disable();
181
0
}
182
183
void ExtrusionDirectionWindow::implSetProjection( sal_Int32 nProjection, bool bEnabled )
184
0
{
185
0
    mxPerspective->set_active(nProjection == 0 && bEnabled);
186
0
    mxParallel->set_active(nProjection == 1 && bEnabled);
187
0
    mxPerspective->set_sensitive(bEnabled);
188
0
    mxParallel->set_sensitive(bEnabled);
189
0
}
190
191
void ExtrusionDirectionWindow::statusChanged(
192
    const css::frame::FeatureStateEvent& Event
193
)
194
0
{
195
0
    if( Event.FeatureURL.Main == g_sExtrusionDirection )
196
0
    {
197
0
        if( !Event.IsEnabled )
198
0
        {
199
0
            implSetDirection( -1, false );
200
0
        }
201
0
        else
202
0
        {
203
0
            sal_Int32 nValue = 0;
204
0
            if( Event.State >>= nValue )
205
0
                implSetDirection( nValue, true );
206
0
        }
207
0
    }
208
0
    else if( Event.FeatureURL.Main == g_sExtrusionProjection )
209
0
    {
210
0
        if( !Event.IsEnabled )
211
0
        {
212
0
            implSetProjection( -1, false );
213
0
        }
214
0
        else
215
0
        {
216
0
            sal_Int32 nValue = 0;
217
0
            if( Event.State >>= nValue )
218
0
                implSetProjection( nValue, true );
219
0
        }
220
0
    }
221
0
}
222
223
IMPL_LINK_NOARG(ExtrusionDirectionWindow, SelectValueSetHdl, ValueSet*, void)
224
0
{
225
0
    Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
226
0
        g_sExtrusionDirection.copy(5),
227
0
        gSkewList[mxDirectionSet->GetSelectedItemId()-1]) };
228
229
0
    mxControl->dispatchCommand( g_sExtrusionDirection, aArgs );
230
231
0
    mxControl->EndPopupMode();
232
0
}
233
234
IMPL_LINK_NOARG(ExtrusionDirectionWindow, SelectToolbarMenuHdl, weld::Toggleable&, void)
235
0
{
236
0
    int nProjection = mxPerspective->get_active() ? 0 : 1;
237
238
0
    Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
239
0
        g_sExtrusionProjection.copy(5), static_cast<sal_Int32>(nProjection)) };
240
241
0
    mxControl->dispatchCommand( g_sExtrusionProjection, aArgs );
242
0
    implSetProjection( nProjection, true );
243
244
0
    mxControl->EndPopupMode();
245
0
}
246
247
ExtrusionDirectionControl::ExtrusionDirectionControl(
248
    const Reference< XComponentContext >& rxContext
249
0
)   : svt::PopupWindowController(
250
0
        rxContext,
251
0
        Reference< css::frame::XFrame >(),
252
0
        u".uno:ExtrusionDirectionFloater"_ustr
253
0
    )
254
0
{
255
0
}
256
257
std::unique_ptr<WeldToolbarPopup> ExtrusionDirectionControl::weldPopupWindow()
258
0
{
259
0
    return std::make_unique<ExtrusionDirectionWindow>(this, m_pToolbar);
260
0
}
261
262
VclPtr<vcl::Window> ExtrusionDirectionControl::createVclPopupWindow( vcl::Window* pParent )
263
0
{
264
0
    mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
265
0
        std::make_unique<ExtrusionDirectionWindow>(this, pParent->GetFrameWeld()));
266
267
0
    mxInterimPopover->Show();
268
269
0
    return mxInterimPopover;
270
0
}
271
272
// XInitialization
273
void SAL_CALL ExtrusionDirectionControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
274
0
{
275
0
    svt::PopupWindowController::initialize( aArguments );
276
277
0
    ToolBox* pToolBox = nullptr;
278
0
    ToolBoxItemId nId;
279
0
    if ( getToolboxId( nId, &pToolBox ) )
280
0
        pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
281
0
}
282
283
// XServiceInfo
284
285
286
OUString ExtrusionDirectionControl::getImplementationName()
287
0
{
288
0
    return u"com.sun.star.comp.svx.ExtrusionDirectionController"_ustr;
289
0
}
290
291
292
Sequence< OUString > ExtrusionDirectionControl::getSupportedServiceNames()
293
0
{
294
0
    return { u"com.sun.star.frame.ToolbarController"_ustr };
295
0
}
296
297
298
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
299
com_sun_star_comp_svx_ExtrusionDirectionControl_get_implementation(
300
    css::uno::XComponentContext* xContext,
301
    css::uno::Sequence<css::uno::Any> const &)
302
0
{
303
0
    return cppu::acquire(new ExtrusionDirectionControl(xContext));
304
0
}
305
306
307
ExtrusionDepthDialog::ExtrusionDepthDialog(weld::Window* pParent, double fDepth, FieldUnit eDefaultUnit)
308
0
    : GenericDialogController(pParent, u"svx/ui/extrustiondepthdialog.ui"_ustr, u"ExtrustionDepthDialog"_ustr)
309
0
    , m_xMtrDepth(m_xBuilder->weld_metric_spin_button(u"depth"_ustr, eDefaultUnit))
310
0
{
311
0
    m_xMtrDepth->set_value(static_cast<int>(fDepth) * 100, FieldUnit::MM_100TH);
312
0
}
313
314
ExtrusionDepthDialog::~ExtrusionDepthDialog()
315
0
{
316
0
}
317
318
double ExtrusionDepthDialog::getDepth() const
319
0
{
320
0
    return static_cast<double>(m_xMtrDepth->get_value(FieldUnit::MM_100TH)) / 100.0;
321
0
}
322
323
double const aDepthListInch[] = { 0, 1270,2540,5080,10160 };
324
double const aDepthListMM[] = { 0, 1000, 2500, 5000, 10000 };
325
326
constexpr OUString gsExtrusionDepth( u".uno:ExtrusionDepth"_ustr );
327
constexpr OUString gsMetricUnit(     u".uno:MetricUnit"_ustr     );
328
329
ExtrusionDepthWindow::ExtrusionDepthWindow(svt::PopupWindowController* pControl, weld::Widget* pParent)
330
0
    : WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"svx/ui/depthwindow.ui"_ustr, u"DepthWindow"_ustr)
331
0
    , mxControl(pControl)
332
0
    , mxDepth0(m_xBuilder->weld_radio_button(u"depth0"_ustr))
333
0
    , mxDepth1(m_xBuilder->weld_radio_button(u"depth1"_ustr))
334
0
    , mxDepth2(m_xBuilder->weld_radio_button(u"depth2"_ustr))
335
0
    , mxDepth3(m_xBuilder->weld_radio_button(u"depth3"_ustr))
336
0
    , mxDepth4(m_xBuilder->weld_radio_button(u"depth4"_ustr))
337
0
    , mxInfinity(m_xBuilder->weld_radio_button(u"infinity"_ustr))
338
0
    , mxCustom(m_xBuilder->weld_radio_button(u"custom"_ustr))
339
0
    , meUnit(FieldUnit::NONE)
340
0
    , mfDepth( -1.0 )
341
0
    , mbSettingValue(false)
342
0
    , mbCommandDispatched(false)
343
0
{
344
0
    mxDepth0->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
345
0
    mxDepth1->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
346
0
    mxDepth2->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
347
0
    mxDepth3->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
348
0
    mxDepth4->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
349
0
    mxInfinity->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
350
0
    mxCustom->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
351
0
    mxCustom->connect_mouse_release(LINK(this, ExtrusionDepthWindow, MouseReleaseHdl));
352
353
0
    AddStatusListener( gsExtrusionDepth );
354
0
    AddStatusListener( gsMetricUnit );
355
0
}
356
357
void ExtrusionDepthWindow::GrabFocus()
358
0
{
359
0
    mxDepth0->grab_focus();
360
0
}
361
362
void ExtrusionDepthWindow::implSetDepth( double fDepth )
363
0
{
364
0
    mfDepth = fDepth;
365
366
0
    bool bSettingValue = mbSettingValue;
367
0
    mbSettingValue = true;
368
369
0
    mxCustom->set_active(true);
370
0
    bool bIsMetric = IsMetric(meUnit);
371
0
    mxDepth0->set_active(fDepth == (bIsMetric ? aDepthListMM[0] : aDepthListInch[0]));
372
0
    mxDepth1->set_active(fDepth == (bIsMetric ? aDepthListMM[1] : aDepthListInch[1]));
373
0
    mxDepth2->set_active(fDepth == (bIsMetric ? aDepthListMM[2] : aDepthListInch[2]));
374
0
    mxDepth3->set_active(fDepth == (bIsMetric ? aDepthListMM[3] : aDepthListInch[3]));
375
0
    mxDepth4->set_active(fDepth == (bIsMetric ? aDepthListMM[4] : aDepthListInch[4]));
376
0
    mxInfinity->set_active(fDepth >= 338666);
377
378
0
    mbSettingValue = bSettingValue;
379
0
}
380
381
void ExtrusionDepthWindow::implFillStrings( FieldUnit eUnit )
382
0
{
383
0
    meUnit = eUnit;
384
385
0
    const TranslateId aDepths[] =
386
0
    {
387
0
        RID_SVXSTR_DEPTH_0,
388
0
        RID_SVXSTR_DEPTH_1,
389
0
        RID_SVXSTR_DEPTH_2,
390
0
        RID_SVXSTR_DEPTH_3,
391
0
        RID_SVXSTR_DEPTH_4
392
0
    };
393
394
0
    const TranslateId aDepthsInch[] =
395
0
    {
396
0
        RID_SVXSTR_DEPTH_0_INCH,
397
0
        RID_SVXSTR_DEPTH_1_INCH,
398
0
        RID_SVXSTR_DEPTH_2_INCH,
399
0
        RID_SVXSTR_DEPTH_3_INCH,
400
0
        RID_SVXSTR_DEPTH_4_INCH
401
0
    };
402
403
0
    static_assert(SAL_N_ELEMENTS(aDepths) == SAL_N_ELEMENTS(aDepthsInch));
404
405
0
    const TranslateId* pResource = IsMetric(eUnit) ? aDepths : aDepthsInch;
406
407
0
    mxDepth0->set_label(SvxResId(pResource[0]));
408
0
    mxDepth1->set_label(SvxResId(pResource[1]));
409
0
    mxDepth2->set_label(SvxResId(pResource[2]));
410
0
    mxDepth3->set_label(SvxResId(pResource[3]));
411
0
    mxDepth4->set_label(SvxResId(pResource[4]));
412
0
}
413
414
void ExtrusionDepthWindow::statusChanged(
415
    const css::frame::FeatureStateEvent& Event
416
)
417
0
{
418
0
    if( Event.FeatureURL.Main == gsExtrusionDepth )
419
0
    {
420
0
        if( !Event.IsEnabled )
421
0
        {
422
0
            implSetDepth( 0 );
423
0
        }
424
0
        else
425
0
        {
426
0
            double fValue = 0.0;
427
0
            if( Event.State >>= fValue )
428
0
                implSetDepth( fValue );
429
0
        }
430
0
    }
431
0
    else if( Event.FeatureURL.Main == gsMetricUnit )
432
0
    {
433
0
        if( Event.IsEnabled )
434
0
        {
435
0
            sal_Int32 nValue = 0;
436
0
            if( Event.State >>= nValue )
437
0
            {
438
0
                implFillStrings( static_cast<FieldUnit>(nValue) );
439
0
                if( mfDepth >= 0.0 )
440
0
                    implSetDepth( mfDepth );
441
0
            }
442
0
        }
443
0
    }
444
0
}
445
446
void ExtrusionDepthWindow::DispatchDepthDialog()
447
0
{
448
0
    Sequence< PropertyValue > aArgs{
449
0
        comphelper::makePropertyValue(u"Depth"_ustr, mfDepth),
450
0
        comphelper::makePropertyValue(u"Metric"_ustr, static_cast<sal_Int32>( meUnit ))
451
0
    };
452
453
0
    rtl::Reference<svt::PopupWindowController> xControl(mxControl);
454
0
    xControl->EndPopupMode();
455
0
    xControl->dispatchCommand(u".uno:ExtrusionDepthDialog"_ustr, aArgs);
456
0
    mbCommandDispatched = true;
457
0
}
458
459
IMPL_LINK(ExtrusionDepthWindow, SelectHdl, weld::Toggleable&, rButton, void)
460
0
{
461
0
    if (mbSettingValue || !rButton.get_active())
462
0
        return;
463
464
    // see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
465
    // this toggle will happen before that mouse release though it does in
466
    // practice for vcl and gtk
467
0
    if (mbCommandDispatched)
468
0
        return;
469
470
0
    if (mxCustom->get_active())
471
0
        DispatchDepthDialog();
472
0
    else
473
0
    {
474
0
        double fDepth;
475
476
0
        if (mxInfinity->get_active())
477
0
        {
478
0
            fDepth = 338666.6;
479
0
        }
480
0
        else
481
0
        {
482
0
            int nSelected;
483
0
            if (mxDepth0->get_active())
484
0
                nSelected = 0;
485
0
            else if (mxDepth1->get_active())
486
0
                nSelected = 1;
487
0
            else if (mxDepth2->get_active())
488
0
                nSelected = 2;
489
0
            else if (mxDepth3->get_active())
490
0
                nSelected = 3;
491
0
            else
492
0
                nSelected = 4;
493
494
0
            fDepth = IsMetric( meUnit ) ? aDepthListMM[nSelected] : aDepthListInch[nSelected];
495
0
        }
496
497
0
        Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
498
0
            gsExtrusionDepth.copy(5), fDepth) };
499
500
0
        mxControl->dispatchCommand( gsExtrusionDepth,  aArgs );
501
0
        mbCommandDispatched = true;
502
0
        implSetDepth( fDepth );
503
504
0
        mxControl->EndPopupMode();
505
0
    }
506
0
}
507
508
IMPL_LINK_NOARG(ExtrusionDepthWindow, MouseReleaseHdl, const MouseEvent&, bool)
509
0
{
510
    /*
511
     tdf#145296 if the "custom" radiobutton was presented preselected as
512
     toggled on and the user clicked on it then there's no toggled signal sent
513
     because the item was already toggled on and didn't change state.
514
515
     So if that happens launch the custom spacing dialog explicitly here on
516
     mouse release.
517
    */
518
0
    if (mxCustom->get_active() && !mbCommandDispatched)
519
0
    {
520
0
        DispatchDepthDialog();
521
0
        return true;
522
0
    }
523
0
    return false;
524
0
}
525
526
// ExtrusionDirectionControl
527
ExtrusionDepthController::ExtrusionDepthController(
528
    const Reference< XComponentContext >& rxContext
529
0
)   : svt::PopupWindowController(
530
0
        rxContext,
531
0
        Reference< css::frame::XFrame >(),
532
0
        u".uno:ExtrusionDepthFloater"_ustr
533
0
    )
534
0
{
535
0
}
536
537
std::unique_ptr<WeldToolbarPopup> ExtrusionDepthController::weldPopupWindow()
538
0
{
539
0
    return std::make_unique<ExtrusionDepthWindow>(this, m_pToolbar);
540
0
}
541
542
VclPtr<vcl::Window> ExtrusionDepthController::createVclPopupWindow( vcl::Window* pParent )
543
0
{
544
0
    mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
545
0
        std::make_unique<ExtrusionDepthWindow>(this, pParent->GetFrameWeld()));
546
547
0
    mxInterimPopover->Show();
548
549
0
    return mxInterimPopover;
550
0
}
551
552
// XInitialization
553
void SAL_CALL ExtrusionDepthController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
554
0
{
555
0
    svt::PopupWindowController::initialize( aArguments );
556
557
0
    ToolBox* pToolBox = nullptr;
558
0
    ToolBoxItemId nId;
559
0
    if ( getToolboxId( nId, &pToolBox ) )
560
0
        pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
561
0
}
562
563
// XServiceInfo
564
565
566
OUString ExtrusionDepthController::getImplementationName()
567
0
{
568
0
    return u"com.sun.star.comp.svx.ExtrusionDepthController"_ustr;
569
0
}
570
571
572
Sequence< OUString > ExtrusionDepthController::getSupportedServiceNames()
573
0
{
574
0
    return { u"com.sun.star.frame.ToolbarController"_ustr };
575
0
}
576
577
578
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
579
com_sun_star_comp_svx_ExtrusionDepthController_get_implementation(
580
    css::uno::XComponentContext* xContext,
581
    css::uno::Sequence<css::uno::Any> const &)
582
0
{
583
0
    return cppu::acquire(new ExtrusionDepthController(xContext));
584
0
}
585
586
587
constexpr OUString g_sExtrusionLightingDirection = u".uno:ExtrusionLightingDirection"_ustr;
588
constexpr OUString g_sExtrusionLightingIntensity = u".uno:ExtrusionLightingIntensity"_ustr;
589
590
ExtrusionLightingWindow::ExtrusionLightingWindow(svt::PopupWindowController* pControl,
591
                                                 weld::Widget* pParent)
592
0
    : WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"svx/ui/lightingwindow.ui"_ustr, u"LightingWindow"_ustr)
593
0
    , mxControl(pControl)
594
0
    , mxLightingSet(new ValueSet(nullptr))
595
0
    , mxLightingSetWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *mxLightingSet))
596
0
    , mxBright(m_xBuilder->weld_radio_button(u"bright"_ustr))
597
0
    , mxNormal(m_xBuilder->weld_radio_button(u"normal"_ustr))
598
0
    , mxDim(m_xBuilder->weld_radio_button(u"dim"_ustr))
599
0
{
600
0
    mxLightingSet->SetStyle(WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT);
601
602
0
    for (sal_uInt16 i = FROM_TOP_LEFT; i <= FROM_BOTTOM_RIGHT; ++i)
603
0
    {
604
0
        if( i != FROM_FRONT )
605
0
        {
606
0
            maImgLightingOff[i] = Image(StockImage::Yes, aLightOffBmps[i]);
607
0
            maImgLightingOn[i] = Image(StockImage::Yes, aLightOnBmps[i]);
608
0
        }
609
0
        maImgLightingPreview[i] = Image(StockImage::Yes, aLightPreviewBmps[i]);
610
0
    }
611
612
0
    mxLightingSet->SetHelpId( HID_VALUESET_EXTRUSION_LIGHTING );
613
614
0
    mxLightingSet->SetSelectHdl( LINK( this, ExtrusionLightingWindow, SelectValueSetHdl ) );
615
0
    mxLightingSet->SetColCount( 3 );
616
0
    mxLightingSet->EnableFullItemMode( false );
617
618
0
    for (sal_uInt16 i = FROM_TOP_LEFT; i <= FROM_BOTTOM_RIGHT; ++i)
619
0
    {
620
0
        if( i != FROM_FRONT )
621
0
        {
622
0
            mxLightingSet->InsertItem( i+1, maImgLightingOff[i] );
623
0
        }
624
0
        else
625
0
        {
626
0
            mxLightingSet->InsertItem( 5, maImgLightingPreview[FROM_FRONT] );
627
0
        }
628
0
    }
629
0
    Size aSize(72, 72);
630
0
    mxLightingSet->GetDrawingArea()->set_size_request(aSize.Width(), aSize.Height());
631
0
    mxLightingSet->SetOutputSizePixel(aSize);
632
633
0
    mxBright->connect_toggled(LINK(this, ExtrusionLightingWindow, SelectToolbarMenuHdl));
634
0
    mxNormal->connect_toggled(LINK(this, ExtrusionLightingWindow, SelectToolbarMenuHdl));
635
0
    mxDim->connect_toggled(LINK(this, ExtrusionLightingWindow, SelectToolbarMenuHdl));
636
637
0
    AddStatusListener( g_sExtrusionLightingDirection );
638
0
    AddStatusListener( g_sExtrusionLightingIntensity );
639
0
}
640
641
void ExtrusionLightingWindow::GrabFocus()
642
0
{
643
0
    mxLightingSet->GrabFocus();
644
0
}
645
646
ExtrusionLightingWindow::~ExtrusionLightingWindow()
647
0
{
648
0
}
649
650
void ExtrusionLightingWindow::implSetIntensity( int nLevel, bool bEnabled )
651
0
{
652
0
    mxBright->set_sensitive(bEnabled);
653
0
    mxBright->set_active(nLevel == 0 && bEnabled);
654
0
    mxNormal->set_sensitive(bEnabled);
655
0
    mxNormal->set_active(nLevel == 1 && bEnabled);
656
0
    mxDim->set_sensitive(bEnabled);
657
0
    mxDim->set_active(nLevel == 2 && bEnabled);
658
0
}
659
660
void ExtrusionLightingWindow::implSetDirection( int nDirection, bool bEnabled )
661
0
{
662
0
    if( !bEnabled )
663
0
        nDirection = FROM_FRONT;
664
665
0
    sal_uInt16 nItemId;
666
0
    for( nItemId = FROM_TOP_LEFT; nItemId <= FROM_BOTTOM_RIGHT; nItemId++ )
667
0
    {
668
0
        if( nItemId == FROM_FRONT )
669
0
        {
670
0
            mxLightingSet->SetItemImage( nItemId + 1, maImgLightingPreview[ nDirection ] );
671
0
        }
672
0
        else
673
0
        {
674
0
            mxLightingSet->SetItemImage(
675
0
                nItemId + 1,
676
0
                static_cast<sal_uInt16>(nDirection) == nItemId ? maImgLightingOn[nItemId] : maImgLightingOff[nItemId]
677
0
            );
678
0
        }
679
0
    }
680
681
0
    if (bEnabled)
682
0
        mxLightingSet->Enable();
683
0
    else
684
0
        mxLightingSet->Disable();
685
0
}
686
687
void ExtrusionLightingWindow::statusChanged(
688
    const css::frame::FeatureStateEvent& Event
689
)
690
0
{
691
0
    if( Event.FeatureURL.Main == g_sExtrusionLightingIntensity )
692
0
    {
693
0
        if( !Event.IsEnabled )
694
0
        {
695
0
            implSetIntensity( 0, false );
696
0
        }
697
0
        else
698
0
        {
699
0
            sal_Int32 nValue = 0;
700
0
            if( Event.State >>= nValue )
701
0
                implSetIntensity( nValue, true );
702
0
        }
703
0
    }
704
0
    else if( Event.FeatureURL.Main == g_sExtrusionLightingDirection )
705
0
    {
706
0
        if( !Event.IsEnabled )
707
0
        {
708
0
            implSetDirection( 0, false );
709
0
        }
710
0
        else
711
0
        {
712
0
            sal_Int32 nValue = 0;
713
0
            if( Event.State >>= nValue )
714
0
                implSetDirection( nValue, true );
715
0
        }
716
0
    }
717
0
}
718
719
IMPL_LINK_NOARG(ExtrusionLightingWindow, SelectValueSetHdl, ValueSet*, void)
720
0
{
721
0
    sal_Int32 nDirection = mxLightingSet->GetSelectedItemId();
722
723
0
    if( (nDirection > 0) && (nDirection < 10) )
724
0
    {
725
0
        nDirection--;
726
727
0
        Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
728
0
            g_sExtrusionLightingDirection.copy(5), nDirection) };
729
730
0
        mxControl->dispatchCommand( g_sExtrusionLightingDirection, aArgs );
731
732
0
        implSetDirection( nDirection, true );
733
0
    }
734
735
0
    mxControl->EndPopupMode();
736
0
}
737
738
IMPL_LINK(ExtrusionLightingWindow, SelectToolbarMenuHdl, weld::Toggleable&, rButton, void)
739
0
{
740
0
    if (!rButton.get_active())
741
0
        return;
742
743
0
    int nLevel;
744
0
    if (mxBright->get_active())
745
0
        nLevel = 0;
746
0
    else if (mxNormal->get_active())
747
0
        nLevel = 1;
748
0
    else
749
0
        nLevel = 2;
750
751
0
    Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
752
0
        g_sExtrusionLightingIntensity.copy(5), static_cast<sal_Int32>(nLevel)) };
753
754
0
    mxControl->dispatchCommand( g_sExtrusionLightingIntensity, aArgs );
755
756
0
    implSetIntensity( nLevel, true );
757
758
0
    mxControl->EndPopupMode();
759
0
}
760
761
ExtrusionLightingControl::ExtrusionLightingControl(
762
    const Reference< XComponentContext >& rxContext
763
0
)   : svt::PopupWindowController( rxContext,
764
0
                Reference< css::frame::XFrame >(),
765
0
                u".uno:ExtrusionDirectionFloater"_ustr
766
0
    )
767
0
{
768
0
}
769
770
std::unique_ptr<WeldToolbarPopup> ExtrusionLightingControl::weldPopupWindow()
771
0
{
772
0
    return std::make_unique<ExtrusionLightingWindow>(this, m_pToolbar);
773
0
}
774
775
VclPtr<vcl::Window> ExtrusionLightingControl::createVclPopupWindow( vcl::Window* pParent )
776
0
{
777
0
    mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
778
0
        std::make_unique<ExtrusionLightingWindow>(this, pParent->GetFrameWeld()));
779
780
0
    mxInterimPopover->Show();
781
782
0
    return mxInterimPopover;
783
0
}
784
785
// XInitialization
786
void SAL_CALL ExtrusionLightingControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
787
0
{
788
0
    svt::PopupWindowController::initialize( aArguments );
789
790
0
    ToolBox* pToolBox = nullptr;
791
0
    ToolBoxItemId nId;
792
0
    if ( getToolboxId( nId, &pToolBox ) )
793
0
        pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
794
0
}
795
796
// XServiceInfo
797
798
799
OUString ExtrusionLightingControl::getImplementationName()
800
0
{
801
0
    return u"com.sun.star.comp.svx.ExtrusionLightingController"_ustr;
802
0
}
803
804
805
Sequence< OUString > ExtrusionLightingControl::getSupportedServiceNames()
806
0
{
807
0
    return { u"com.sun.star.frame.ToolbarController"_ustr };
808
0
}
809
810
811
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
812
com_sun_star_comp_svx_ExtrusionLightingControl_get_implementation(
813
    css::uno::XComponentContext* xContext,
814
    css::uno::Sequence<css::uno::Any> const &)
815
0
{
816
0
    return cppu::acquire(new ExtrusionLightingControl(xContext));
817
0
}
818
819
820
constexpr OUString g_sExtrusionSurface = u".uno:ExtrusionSurface"_ustr;
821
822
ExtrusionSurfaceWindow::ExtrusionSurfaceWindow(svt::PopupWindowController* pControl, weld::Widget* pParent)
823
0
    : WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"svx/ui/surfacewindow.ui"_ustr, u"SurfaceWindow"_ustr)
824
0
    , mxControl(pControl)
825
0
    , mxWireFrame(m_xBuilder->weld_radio_button(u"wireframe"_ustr))
826
0
    , mxMatt(m_xBuilder->weld_radio_button(u"matt"_ustr))
827
0
    , mxPlastic(m_xBuilder->weld_radio_button(u"plastic"_ustr))
828
0
    , mxMetal(m_xBuilder->weld_radio_button(u"metal"_ustr))
829
0
    , mxMetalMSO(m_xBuilder->weld_radio_button(u"metalMSO"_ustr))
830
0
{
831
0
    mxWireFrame->connect_toggled(LINK(this, ExtrusionSurfaceWindow, SelectHdl));
832
0
    mxMatt->connect_toggled(LINK(this, ExtrusionSurfaceWindow, SelectHdl));
833
0
    mxPlastic->connect_toggled(LINK(this, ExtrusionSurfaceWindow, SelectHdl));
834
0
    mxMetal->connect_toggled(LINK(this, ExtrusionSurfaceWindow, SelectHdl));
835
0
    mxMetalMSO->connect_toggled(LINK(this, ExtrusionSurfaceWindow, SelectHdl));
836
837
0
    AddStatusListener( g_sExtrusionSurface );
838
0
}
839
840
void ExtrusionSurfaceWindow::GrabFocus()
841
0
{
842
0
    mxWireFrame->grab_focus();
843
0
}
844
845
void ExtrusionSurfaceWindow::implSetSurface( int nSurface, bool bEnabled )
846
0
{
847
0
    mxWireFrame->set_active(nSurface == 0 && bEnabled);
848
0
    mxWireFrame->set_sensitive(bEnabled);
849
0
    mxMatt->set_active(nSurface == 1 && bEnabled);
850
0
    mxMatt->set_sensitive(bEnabled);
851
0
    mxPlastic->set_active(nSurface == 2 && bEnabled);
852
0
    mxPlastic->set_sensitive(bEnabled);
853
0
    mxMetal->set_active(nSurface == 3 && bEnabled);
854
0
    mxMetal->set_sensitive(bEnabled);
855
0
    mxMetalMSO->set_active(nSurface == 4 && bEnabled);
856
0
    mxMetalMSO->set_sensitive(bEnabled);
857
0
}
858
859
void ExtrusionSurfaceWindow::statusChanged(
860
    const css::frame::FeatureStateEvent& Event
861
)
862
0
{
863
0
    if( Event.FeatureURL.Main != g_sExtrusionSurface )
864
0
        return;
865
866
0
    if( !Event.IsEnabled )
867
0
    {
868
0
        implSetSurface( 0, false );
869
0
    }
870
0
    else
871
0
    {
872
0
        sal_Int32 nValue = 0;
873
0
        if( Event.State >>= nValue )
874
0
            implSetSurface( nValue, true );
875
0
    }
876
0
}
877
878
IMPL_LINK(ExtrusionSurfaceWindow, SelectHdl, weld::Toggleable&, rButton, void)
879
0
{
880
0
    if (!rButton.get_active())
881
0
        return;
882
883
0
    sal_Int32 nSurface;
884
0
    if (mxWireFrame->get_active())
885
0
        nSurface = 0;
886
0
    else if (mxMatt->get_active())
887
0
        nSurface = 1;
888
0
    else if (mxPlastic->get_active())
889
0
        nSurface = 2;
890
0
    else if (mxMetal->get_active())
891
0
        nSurface = 3;
892
0
    else
893
0
        nSurface = 4;
894
895
0
    Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
896
0
        g_sExtrusionSurface.copy(5), nSurface) };
897
898
0
    mxControl->dispatchCommand( g_sExtrusionSurface, aArgs );
899
900
0
    implSetSurface( nSurface, true );
901
902
0
    mxControl->EndPopupMode();
903
0
}
904
905
ExtrusionSurfaceControl::ExtrusionSurfaceControl(
906
    const Reference< XComponentContext >& rxContext
907
)
908
0
:   svt::PopupWindowController(
909
0
        rxContext,
910
0
        Reference< css::frame::XFrame >(),
911
0
        u".uno:ExtrusionSurfaceFloater"_ustr
912
0
    )
913
0
{
914
0
}
915
916
std::unique_ptr<WeldToolbarPopup> ExtrusionSurfaceControl::weldPopupWindow()
917
0
{
918
0
    return std::make_unique<ExtrusionSurfaceWindow>(this, m_pToolbar);
919
0
}
920
921
VclPtr<vcl::Window> ExtrusionSurfaceControl::createVclPopupWindow( vcl::Window* pParent )
922
0
{
923
0
    mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
924
0
        std::make_unique<ExtrusionSurfaceWindow>(this, pParent->GetFrameWeld()));
925
926
0
    mxInterimPopover->Show();
927
928
0
    return mxInterimPopover;
929
0
}
930
931
// XInitialization
932
void SAL_CALL ExtrusionSurfaceControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
933
0
{
934
0
    svt::PopupWindowController::initialize( aArguments );
935
936
0
    ToolBox* pToolBox = nullptr;
937
0
    ToolBoxItemId nId;
938
0
    if ( getToolboxId( nId, &pToolBox ) )
939
0
        pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
940
0
}
941
942
// XServiceInfo
943
944
945
OUString ExtrusionSurfaceControl::getImplementationName()
946
0
{
947
0
    return u"com.sun.star.comp.svx.ExtrusionSurfaceController"_ustr;
948
0
}
949
950
951
Sequence< OUString > ExtrusionSurfaceControl::getSupportedServiceNames()
952
0
{
953
0
    return { u"com.sun.star.frame.ToolbarController"_ustr };
954
0
}
955
956
957
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
958
com_sun_star_comp_svx_ExtrusionSurfaceControl_get_implementation(
959
    css::uno::XComponentContext* xContext,
960
    css::uno::Sequence<css::uno::Any> const &)
961
0
{
962
0
    return cppu::acquire(new ExtrusionSurfaceControl(xContext));
963
0
}
964
965
}
966
967
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */