Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/table/TableDesignPane.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 <string_view>
23
24
#include <com/sun/star/beans/XPropertySet.hpp>
25
#include <com/sun/star/drawing/XDrawView.hpp>
26
#include <com/sun/star/frame/XController.hpp>
27
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
28
#include <com/sun/star/util/XModifiable.hpp>
29
#include <com/sun/star/view/XSelectionSupplier.hpp>
30
#include <com/sun/star/style/XStyle.hpp>
31
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
32
33
#include <comphelper/sequence.hxx>
34
#include <sfx2/viewfrm.hxx>
35
#include <vcl/commandevent.hxx>
36
#include <vcl/image.hxx>
37
#include <vcl/settings.hxx>
38
#include <vcl/svapp.hxx>
39
#include <vcl/virdev.hxx>
40
#include <vcl/weld/Menu.hxx>
41
#include <vcl/weld/MessageDialog.hxx>
42
43
#include <tools/debug.hxx>
44
#include <comphelper/diagnose_ex.hxx>
45
#include <svl/style.hxx>
46
#include <svl/stritem.hxx>
47
#include <sfx2/bindings.hxx>
48
#include <sfx2/app.hxx>
49
#include <sfx2/request.hxx>
50
#include <sfx2/dispatch.hxx>
51
#include <svx/svxids.hrc>
52
#include <svx/svdetc.hxx>
53
#include <svx/svxdlg.hxx>
54
#include <editeng/boxitem.hxx>
55
#include <editeng/borderline.hxx>
56
#include <editeng/colritem.hxx>
57
#include <editeng/eeitem.hxx>
58
#include <svx/sdr/table/tabledesign.hxx>
59
#include <svx/sdr/table/tablecontroller.hxx>
60
#include <o3tl/enumrange.hxx>
61
62
#include <TableDesignPane.hxx>
63
64
#include <stlsheet.hxx>
65
#include <strings.hrc>
66
#include <sdresid.hxx>
67
#include <bitmaps.hlst>
68
#include <ViewShell.hxx>
69
#include <ViewShellBase.hxx>
70
#include <EventMultiplexer.hxx>
71
#include <DrawController.hxx>
72
73
using namespace ::com::sun::star;
74
using namespace ::com::sun::star::uno;
75
using namespace ::com::sun::star::drawing;
76
using namespace ::com::sun::star::container;
77
using namespace ::com::sun::star::beans;
78
using namespace ::com::sun::star::view;
79
using namespace ::com::sun::star::style;
80
using namespace ::com::sun::star::frame;
81
using namespace ::com::sun::star::lang;
82
83
namespace sd {
84
85
const sal_Int32 nPreviewColumns = 5;
86
const sal_Int32 nPreviewRows = 5;
87
const sal_Int32 nCellWidth = 12; // one pixel is shared with the next cell!
88
const sal_Int32 nCellHeight = 7; // one pixel is shared with the next cell!
89
const sal_Int32 nBitmapWidth = (nCellWidth * nPreviewColumns) - (nPreviewColumns - 1);
90
const sal_Int32 nBitmapHeight = (nCellHeight * nPreviewRows) - (nPreviewRows - 1);
91
92
const std::u16string_view gPropNames[CB_COUNT] =
93
{
94
    u"UseFirstRowStyle",
95
    u"UseLastRowStyle",
96
    u"UseBandingRowStyle",
97
    u"UseFirstColumnStyle",
98
    u"UseLastColumnStyle",
99
    u"UseBandingColumnStyle"
100
};
101
102
constexpr std::u16string_view aTableStyleBaseName = u"table";
103
104
TableDesignWidget::TableDesignWidget(weld::Builder& rBuilder, ViewShellBase& rBase)
105
0
    : mrBase(rBase)
106
0
    , m_xMenu(rBuilder.weld_menu(u"menu"_ustr))
107
0
    , m_xValueSet(new TableValueSet(rBuilder.weld_scrolled_window(u"previewswin"_ustr, true)))
108
0
    , m_xValueSetWin(new weld::CustomWeld(rBuilder, u"previews"_ustr, *m_xValueSet))
109
0
{
110
0
    m_xValueSet->SetStyle(m_xValueSet->GetStyle() | WB_NO_DIRECTSELECT | WB_FLATVALUESET | WB_ITEMBORDER);
111
0
    m_xValueSet->SetExtraSpacing(8);
112
0
    m_xValueSet->setModal(false);
113
0
    m_xValueSet->SetColor();
114
0
    m_xValueSet->SetSelectHdl(LINK(this, TableDesignWidget, implValueSetHdl));
115
0
    m_xValueSet->SetContextMenuHandler(LINK(this, TableDesignWidget, implContextMenuHandler));
116
117
0
    for (sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i)
118
0
    {
119
0
        m_aCheckBoxes[i] = rBuilder.weld_check_button(OUString(gPropNames[i]));
120
0
        m_aCheckBoxes[i]->connect_toggled(LINK(this, TableDesignWidget, implCheckBoxHdl));
121
0
    }
122
123
    // get current controller and initialize listeners
124
0
    try
125
0
    {
126
0
        mxView = mrBase.GetDrawController();
127
0
        addListener();
128
129
0
        DrawController* pController = mrBase.GetDrawController();
130
0
        if (pController)
131
0
        {
132
0
            Reference< XStyleFamiliesSupplier > xFamiliesSupp( pController->getModel(), UNO_QUERY_THROW );
133
0
            Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
134
0
            mxTableFamily.set( xFamilies->getByName( u"table"_ustr ), UNO_QUERY_THROW );
135
0
            mxCellFamily.set( xFamilies->getByName( u"cell"_ustr ), UNO_QUERY_THROW );
136
0
        }
137
0
    }
138
0
    catch (const Exception&)
139
0
    {
140
0
        TOOLS_WARN_EXCEPTION( "sd", "sd::CustomAnimationPane::CustomAnimationPane()" );
141
0
    }
142
143
0
    onSelectionChanged();
144
0
    updateControls();
145
0
}
146
147
TableDesignWidget::~TableDesignWidget()
148
0
{
149
0
    removeListener();
150
0
}
151
152
void TableDesignWidget::setDocumentModified()
153
0
{
154
0
    try
155
0
    {
156
0
        Reference<XController> xController(mrBase.GetController(), UNO_SET_THROW);
157
0
        Reference<util::XModifiable> xModifiable(xController->getModel(), UNO_QUERY_THROW);
158
0
        xModifiable->setModified(true);
159
0
    }
160
0
    catch (Exception&)
161
0
    {
162
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::setDocumentModified()");
163
0
    }
164
0
}
165
166
IMPL_LINK(TableDesignWidget, implContextMenuHandler, const Point*, pPoint, void)
167
0
{
168
0
    auto nClickedItemId = pPoint ? m_xValueSet->GetItemId(*pPoint) : m_xValueSet->GetSelectedItemId();
169
170
0
    try
171
0
    {
172
0
        if (nClickedItemId > mxTableFamily->getCount())
173
0
            return;
174
175
0
        if (nClickedItemId)
176
0
        {
177
0
            Reference<XStyle> xStyle(mxTableFamily->getByIndex(nClickedItemId - 1), UNO_QUERY_THROW);
178
179
0
            m_xMenu->set_visible(u"clone"_ustr, true);
180
0
            m_xMenu->set_visible(u"format"_ustr, true);
181
0
            m_xMenu->set_visible(u"delete"_ustr, xStyle->isUserDefined());
182
0
            m_xMenu->set_visible(u"reset"_ustr, !xStyle->isUserDefined());
183
0
            m_xMenu->set_sensitive(u"reset"_ustr, Reference<util::XModifiable>(xStyle, UNO_QUERY_THROW)->isModified());
184
0
        }
185
0
        else
186
0
        {
187
0
            m_xMenu->set_visible(u"clone"_ustr, false);
188
0
            m_xMenu->set_visible(u"format"_ustr, false);
189
0
            m_xMenu->set_visible(u"delete"_ustr, false);
190
0
            m_xMenu->set_visible(u"reset"_ustr, false);
191
0
        }
192
0
    }
193
0
    catch (Exception&)
194
0
    {
195
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::implContextMenuHandler()");
196
0
    }
197
198
0
    m_xValueSet->SelectItem(nClickedItemId);
199
200
0
    Point aPosition = pPoint ? *pPoint : m_xValueSet->GetItemRect(nClickedItemId).Center();
201
0
    OUString aCommand = m_xMenu->popup_at_rect(m_xValueSet->GetDrawingArea(), ::tools::Rectangle(aPosition, Size(1,1)));
202
203
0
    if (aCommand == "new")
204
0
        InsertStyle();
205
0
    else if (aCommand == "clone")
206
0
        CloneStyle();
207
0
    else if (aCommand == "delete")
208
0
        DeleteStyle();
209
0
    else if (aCommand == "reset")
210
0
        ResetStyle();
211
0
    else if (!aCommand.isEmpty())
212
0
        EditStyle(aCommand);
213
0
}
214
215
namespace
216
{
217
    OUString getNewStyleName(const Reference<XNameContainer>& rFamily, std::u16string_view rBaseName)
218
0
    {
219
0
        OUString aName(rBaseName);
220
0
        sal_Int32 nIndex = 1;
221
0
        while(rFamily->hasByName(aName))
222
0
        {
223
0
            aName = rBaseName + OUString::number(nIndex++);
224
0
        }
225
226
0
        return aName;
227
0
    }
228
}
229
230
void TableDesignWidget::InsertStyle()
231
0
{
232
0
    try
233
0
    {
234
0
        Reference<XSingleServiceFactory> xFactory(mxTableFamily, UNO_QUERY_THROW);
235
0
        Reference<XNameContainer> xTableFamily(mxTableFamily, UNO_QUERY_THROW);
236
0
        Reference<XNameReplace> xTableStyle(xFactory->createInstance(), UNO_QUERY_THROW);
237
0
        const OUString aName(getNewStyleName(xTableFamily, aTableStyleBaseName));
238
0
        xTableFamily->insertByName(aName, Any(xTableStyle));
239
240
0
        Reference<XStyle> xCellStyle(mxCellFamily->getByName(u"default"_ustr), UNO_QUERY_THROW);
241
242
0
        xTableStyle->replaceByName(u"body"_ustr, Any(xCellStyle));
243
0
        xTableStyle->replaceByName(u"odd-rows"_ustr , Any(xCellStyle));
244
0
        xTableStyle->replaceByName(u"odd-columns"_ustr , Any(xCellStyle));
245
0
        xTableStyle->replaceByName(u"first-row"_ustr , Any(xCellStyle));
246
0
        xTableStyle->replaceByName(u"first-column"_ustr , Any(xCellStyle));
247
0
        xTableStyle->replaceByName(u"last-row"_ustr , Any(xCellStyle));
248
0
        xTableStyle->replaceByName(u"last-column"_ustr , Any(xCellStyle));
249
250
0
        updateControls();
251
0
        selectStyle(aName);
252
0
        setDocumentModified();
253
0
    }
254
0
    catch (Exception&)
255
0
    {
256
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::InsertStyle()");
257
0
    }
258
0
}
259
260
void TableDesignWidget::CloneStyle()
261
0
{
262
0
    try
263
0
    {
264
0
        Reference<XNameAccess> xSrcTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW);
265
266
0
        Reference<XSingleServiceFactory> xFactory(mxTableFamily, UNO_QUERY_THROW);
267
0
        Reference<XNameContainer> xTableFamily(mxTableFamily, UNO_QUERY_THROW);
268
0
        Reference<XNameReplace> xDestTableStyle(xFactory->createInstance(), UNO_QUERY_THROW);
269
0
        const OUString aName(getNewStyleName(xTableFamily, aTableStyleBaseName));
270
0
        xTableFamily->insertByName(aName, Any(xDestTableStyle));
271
272
0
        auto aNames(xSrcTableStyle->getElementNames());
273
0
        for (const auto& name : aNames)
274
0
        {
275
0
            Reference<XStyle> xSrcCellStyle(xSrcTableStyle->getByName(name), UNO_QUERY);
276
0
            if (xSrcCellStyle && xSrcCellStyle->isUserDefined())
277
0
            {
278
0
                Reference<XSingleServiceFactory> xCellFactory(mxCellFamily, UNO_QUERY_THROW);
279
0
                Reference<XStyle> xDestCellStyle(xCellFactory->createInstance(), UNO_QUERY_THROW);
280
0
                xDestCellStyle->setParentStyle(xSrcCellStyle->getParentStyle());
281
0
                const OUString aStyleName(getNewStyleName(mxCellFamily, Concat2View(aName + "-" + name)));
282
0
                mxCellFamily->insertByName(aStyleName, Any(xDestCellStyle));
283
284
0
                rtl::Reference xSrcStyleSheet = static_cast<SdStyleSheet*>(xSrcCellStyle.get());
285
0
                rtl::Reference xDestStyleSheet = static_cast<SdStyleSheet*>(xDestCellStyle.get());
286
287
0
                xDestStyleSheet->GetItemSet().Put(xSrcStyleSheet->GetItemSet());
288
289
0
                xDestTableStyle->replaceByName(name, Any(xDestCellStyle));
290
0
            }
291
0
            else
292
0
                xDestTableStyle->replaceByName(name, Any(xSrcCellStyle));
293
0
        }
294
295
0
        updateControls();
296
0
        selectStyle(aName);
297
0
        setDocumentModified();
298
0
    }
299
0
    catch (Exception&)
300
0
    {
301
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::CloneStyle()");
302
0
    }
303
0
}
304
305
void TableDesignWidget::ResetStyle()
306
0
{
307
0
    try
308
0
    {
309
0
        Reference<XIndexReplace> xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW);
310
311
0
        for (sal_Int32 i = 0; i < xTableStyle->getCount(); ++i)
312
0
        {
313
0
            Reference<XStyle> xCellStyle(xTableStyle->getByIndex(i), UNO_QUERY);
314
0
            while (xCellStyle && xCellStyle->isUserDefined() && !xCellStyle->getParentStyle().isEmpty())
315
0
                xCellStyle.set(mxCellFamily->getByName(xCellStyle->getParentStyle()), UNO_QUERY);
316
317
0
            xTableStyle->replaceByIndex(i, Any(xCellStyle));
318
0
        }
319
320
0
        endTextEditForStyle(xTableStyle);
321
0
        Reference<util::XModifiable>(xTableStyle, UNO_QUERY_THROW)->setModified(false);
322
323
0
        updateControls();
324
0
        setDocumentModified();
325
0
    }
326
0
    catch (Exception&)
327
0
    {
328
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::ResetStyle()");
329
0
    }
330
0
}
331
332
void TableDesignWidget::DeleteStyle()
333
0
{
334
0
    try
335
0
    {
336
0
        Reference<XStyle> xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW);
337
338
0
        if (xTableStyle->isInUse())
339
0
        {
340
0
            std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
341
0
                m_xValueSet->GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, SdResId(STR_REMOVE_TABLESTYLE)));
342
343
0
            if (xBox->run() != RET_YES)
344
0
                return;
345
346
0
            endTextEditForStyle(xTableStyle);
347
0
        }
348
349
0
        Reference<XNameContainer>(mxTableFamily, UNO_QUERY_THROW)->removeByName(xTableStyle->getName());
350
351
0
        updateControls();
352
0
        setDocumentModified();
353
0
    }
354
0
    catch (Exception&)
355
0
    {
356
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::DeleteStyle()");
357
0
    }
358
0
}
359
360
void TableDesignWidget::EditStyle(const OUString& rCommand)
361
0
{
362
0
    try
363
0
    {
364
0
        Reference<XNameReplace> xTableStyle(mxTableFamily->getByIndex(m_xValueSet->GetSelectedItemId() - 1), UNO_QUERY_THROW);
365
0
        Reference<XStyle> xCellStyle(xTableStyle->getByName(rCommand), UNO_QUERY_THROW);
366
0
        rtl::Reference xStyleSheet = static_cast<SdStyleSheet*>(xCellStyle.get());
367
368
0
        bool bUserDefined = xStyleSheet->IsEditable();
369
0
        if (!bUserDefined)
370
0
        {
371
0
            Reference<XSingleServiceFactory> xFactory(mxCellFamily, UNO_QUERY_THROW);
372
0
            xCellStyle.set(xFactory->createInstance(), UNO_QUERY_THROW);
373
0
            xCellStyle->setParentStyle(xStyleSheet->getName());
374
0
            xStyleSheet = static_cast<SdStyleSheet*>(xCellStyle.get());
375
0
        }
376
377
0
        SfxItemSet aNewAttr(xStyleSheet->GetItemSet());
378
379
        // merge drawing layer text distance items into SvxBoxItem used by the dialog
380
0
        SvxBoxItem aBoxItem(sdr::table::SvxTableController::TextDistancesToSvxBoxItem(aNewAttr));
381
0
        aNewAttr.Put(aBoxItem);
382
383
        // inner borders do not apply to a cell style
384
0
        SvxBoxInfoItem aBoxInfoItem(aNewAttr.Get(SDRATTR_TABLE_BORDER_INNER));
385
0
        aBoxInfoItem.SetTable(false);
386
0
        aNewAttr.Put(aBoxInfoItem);
387
388
0
        SdrView* pDrawView = mrBase.GetDrawView();
389
0
        if (!pDrawView)
390
0
            return;
391
392
0
        SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
393
0
        ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact ? pFact->CreateSvxFormatCellsDialog(
394
0
            mrBase.GetFrameWeld(), aNewAttr, pDrawView->GetModel(), true) : nullptr);
395
0
        if (pDlg && pDlg->Execute() == RET_OK)
396
0
        {
397
0
            endTextEditForStyle(xTableStyle);
398
399
0
            if (!bUserDefined)
400
0
            {
401
0
                Reference<XNamed> xNamed(xTableStyle, UNO_QUERY_THROW);
402
0
                const OUString aStyleName(getNewStyleName(mxCellFamily, Concat2View(xNamed->getName() + "-" + rCommand)));
403
0
                mxCellFamily->insertByName(aStyleName, Any(xCellStyle));
404
0
                xTableStyle->replaceByName(rCommand, Any(xCellStyle));
405
0
            }
406
407
0
            SfxItemSet aNewSet(*pDlg->GetOutputItemSet());
408
0
            sdr::table::SvxTableController::SvxBoxItemToTextDistances(aBoxItem, aNewSet);
409
0
            sdr::properties::CleanupFillProperties(aNewSet);
410
0
            xStyleSheet->GetItemSet().Put(aNewSet);
411
0
            xStyleSheet->Broadcast(SfxHint(SfxHintId::DataChanged));
412
413
0
            updateControls();
414
0
            setDocumentModified();
415
0
        }
416
0
    }
417
0
    catch (Exception&)
418
0
    {
419
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::EditStyle()");
420
0
    }
421
0
}
422
423
static SfxBindings* getBindings( ViewShellBase const & rBase )
424
0
{
425
0
    auto pViewShell = rBase.GetMainViewShell().get();
426
0
    if( !pViewShell )
427
0
        return nullptr;
428
0
    auto pViewFrame = pViewShell->GetViewFrame();
429
0
    if( !pViewFrame )
430
0
        return nullptr;
431
0
    return &pViewFrame->GetBindings();
432
0
}
433
434
static SfxDispatcher* getDispatcher( ViewShellBase const & rBase )
435
0
{
436
0
    auto pViewShell = rBase.GetMainViewShell().get();
437
0
    if( !pViewShell )
438
0
        return nullptr;
439
0
    auto pViewFrame = pViewShell->GetViewFrame();
440
0
    if( !pViewFrame )
441
0
        return nullptr;
442
0
    return pViewFrame->GetDispatcher();
443
0
}
444
445
IMPL_LINK_NOARG(TableDesignWidget, implValueSetHdl, ValueSet*, void)
446
0
{
447
0
    ApplyStyle();
448
0
}
449
450
void TableDesignWidget::ApplyStyle()
451
0
{
452
0
    try
453
0
    {
454
0
        OUString sStyleName;
455
0
        sal_Int32 nIndex = static_cast< sal_Int32 >( m_xValueSet->GetSelectedItemId() ) - 1;
456
457
0
        if( (nIndex >= 0) && (nIndex < mxTableFamily->getCount()) )
458
0
        {
459
0
            Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY_THROW );
460
0
            sStyleName = xNames->getElementNames()[nIndex];
461
0
        }
462
0
        else if (nIndex == mxTableFamily->getCount())
463
0
        {
464
0
            InsertStyle();
465
0
            return;
466
0
        }
467
468
0
        if( sStyleName.isEmpty() )
469
0
            return;
470
471
0
        if( mxSelectedTable.is() )
472
0
        {
473
0
            if (SdrView* pView = mrBase.GetDrawView())
474
0
            {
475
0
                if (pView->IsTextEdit())
476
0
                    pView->SdrEndTextEdit();
477
478
0
                SfxRequest aReq( SID_TABLE_STYLE, SfxCallMode::SYNCHRON, SfxGetpApp()->GetPool() );
479
0
                aReq.AppendItem( SfxStringItem( SID_TABLE_STYLE, sStyleName ) );
480
481
0
                const rtl::Reference< sdr::SelectionController >& xController( pView->getSelectionController() );
482
0
                if( xController.is() )
483
0
                    xController->Execute( aReq );
484
485
0
                SfxBindings* pBindings = getBindings( mrBase );
486
0
                if( pBindings )
487
0
                {
488
0
                    pBindings->Invalidate( SID_UNDO );
489
0
                    pBindings->Invalidate( SID_REDO );
490
0
                }
491
0
            }
492
0
            setDocumentModified();
493
0
        }
494
0
        else
495
0
        {
496
0
            SfxDispatcher* pDispatcher = getDispatcher( mrBase );
497
0
            SfxStringItem aArg( SID_TABLE_STYLE, sStyleName );
498
0
            pDispatcher->ExecuteList(SID_INSERT_TABLE, SfxCallMode::ASYNCHRON,
499
0
                    { &aArg });
500
0
        }
501
0
    }
502
0
    catch( Exception& )
503
0
    {
504
0
        TOOLS_WARN_EXCEPTION( "sd", "TableDesignWidget::implValueSetHdl()");
505
0
    }
506
0
}
507
508
IMPL_LINK_NOARG(TableDesignWidget, implCheckBoxHdl, weld::Toggleable&, void)
509
0
{
510
0
    ApplyOptions();
511
0
    FillDesignPreviewControl();
512
0
}
513
514
void TableDesignWidget::ApplyOptions()
515
0
{
516
0
    static const sal_uInt16 gParamIds[CB_COUNT] =
517
0
    {
518
0
        ID_VAL_USEFIRSTROWSTYLE, ID_VAL_USELASTROWSTYLE, ID_VAL_USEBANDINGROWSTYLE,
519
0
        ID_VAL_USEFIRSTCOLUMNSTYLE, ID_VAL_USELASTCOLUMNSTYLE, ID_VAL_USEBANDINGCOLUMNSTYLE
520
0
    };
521
522
0
    if( !mxSelectedTable.is() )
523
0
        return;
524
525
0
    SfxRequest aReq( SID_TABLE_STYLE_SETTINGS, SfxCallMode::SYNCHRON, SfxGetpApp()->GetPool() );
526
527
0
    for( sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i )
528
0
    {
529
0
        aReq.AppendItem( SfxBoolItem( gParamIds[i], m_aCheckBoxes[i]->get_active() ) );
530
0
    }
531
532
0
    SdrView* pView = mrBase.GetDrawView();
533
0
    if( !pView )
534
0
        return;
535
536
0
    const rtl::Reference< sdr::SelectionController >& xController( pView->getSelectionController() );
537
0
    if( xController.is() )
538
0
    {
539
0
        xController->Execute( aReq );
540
541
0
        SfxBindings* pBindings = getBindings( mrBase );
542
0
        if( pBindings )
543
0
        {
544
0
            pBindings->Invalidate( SID_UNDO );
545
0
            pBindings->Invalidate( SID_REDO );
546
0
        }
547
0
    }
548
0
    setDocumentModified();
549
0
}
550
551
void TableDesignWidget::onSelectionChanged()
552
0
{
553
0
    Reference< XPropertySet > xNewSelection;
554
555
0
    if( mxView.is() ) try
556
0
    {
557
0
        Any aSel( mxView->getSelection() );
558
0
        Sequence< XShape > xShapeSeq;
559
0
        if( aSel >>= xShapeSeq )
560
0
        {
561
0
            if( xShapeSeq.getLength() == 1 )
562
0
                aSel <<= xShapeSeq[0];
563
0
        }
564
0
        else
565
0
        {
566
0
            Reference< XShapes > xShapes( aSel, UNO_QUERY );
567
0
            if( xShapes.is() && (xShapes->getCount() == 1) )
568
0
                aSel = xShapes->getByIndex(0);
569
0
        }
570
571
0
        Reference< XShapeDescriptor > xDesc( aSel, UNO_QUERY );
572
0
        if( xDesc.is() && ( xDesc->getShapeType() == "com.sun.star.drawing.TableShape" || xDesc->getShapeType() == "com.sun.star.presentation.TableShape" ) )
573
0
        {
574
0
            xNewSelection.set( xDesc, UNO_QUERY );
575
0
        }
576
0
    }
577
0
    catch( Exception& )
578
0
    {
579
0
        TOOLS_WARN_EXCEPTION( "sd", "sd::TableDesignWidget::onSelectionChanged()" );
580
0
    }
581
582
0
    if( mxSelectedTable != xNewSelection )
583
0
    {
584
0
        mxSelectedTable = std::move(xNewSelection);
585
0
        updateControls();
586
0
    }
587
0
}
588
589
bool TableValueSet::Command(const CommandEvent& rEvent)
590
0
{
591
0
    if (rEvent.GetCommand() != CommandEventId::ContextMenu)
592
0
        return ValueSet::Command(rEvent);
593
594
0
    maContextMenuHandler.Call(rEvent.IsMouseEvent() ? &rEvent.GetMousePosPixel() : nullptr);
595
0
    return true;
596
0
}
597
598
void TableValueSet::Resize()
599
0
{
600
0
    ValueSet::Resize();
601
    // Calculate the number of rows and columns.
602
0
    if( GetItemCount() <= 0 )
603
0
        return;
604
605
0
    Size aValueSetSize = GetOutputSizePixel();
606
607
0
    Image aImage = GetItemImage(GetItemId(0));
608
0
    Size aItemSize = aImage.GetSizePixel();
609
610
0
    aItemSize.AdjustHeight(10 );
611
0
    int nColumnCount = (aValueSetSize.Width() - GetScrollWidth()) / aItemSize.Width();
612
0
    if (nColumnCount < 1)
613
0
        nColumnCount = 1;
614
615
0
    int nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount;
616
0
    if (nRowCount < 1)
617
0
        nRowCount = 1;
618
619
0
    int nVisibleRowCount = std::min(nRowCount, getMaxRowCount());
620
621
0
    SetColCount (static_cast<sal_uInt16>(nColumnCount));
622
0
    SetLineCount (static_cast<sal_uInt16>(nVisibleRowCount));
623
624
0
    if( !m_bModal )
625
0
    {
626
0
        WinBits nStyle = GetStyle() & ~WB_VSCROLL;
627
0
        if( nRowCount > nVisibleRowCount )
628
0
        {
629
0
            nStyle |= WB_VSCROLL;
630
0
        }
631
0
        SetStyle( nStyle );
632
0
    }
633
0
}
634
635
TableValueSet::TableValueSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow)
636
0
    : ValueSet(std::move(pScrolledWindow))
637
0
    , m_bModal(false)
638
0
{
639
0
}
640
641
void TableValueSet::StyleUpdated()
642
0
{
643
0
    updateSettings();
644
0
}
645
646
void TableValueSet::updateSettings()
647
0
{
648
0
    if( !m_bModal )
649
0
    {
650
0
        Color aColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
651
0
        SetColor(aColor);
652
0
        SetExtraSpacing(8);
653
0
    }
654
0
}
655
656
void TableDesignWidget::updateControls()
657
0
{
658
0
    static const bool gDefaults[CB_COUNT] = { true, false, true, false, false, false };
659
660
0
    const bool bHasTable = mxSelectedTable.is();
661
662
0
    for (sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i)
663
0
    {
664
0
        bool bUse = gDefaults[i];
665
0
        if( bHasTable ) try
666
0
        {
667
0
            mxSelectedTable->getPropertyValue( OUString(gPropNames[i]) ) >>= bUse;
668
0
        }
669
0
        catch( Exception& )
670
0
        {
671
0
            TOOLS_WARN_EXCEPTION( "sd", "sd::TableDesignWidget::updateControls()");
672
0
        }
673
0
        m_aCheckBoxes[i]->set_active(bUse);
674
0
        m_aCheckBoxes[i]->set_sensitive(bHasTable);
675
0
    }
676
677
0
    FillDesignPreviewControl();
678
0
    m_xValueSet->updateSettings();
679
0
    m_xValueSet->Resize();
680
681
0
    if( mxSelectedTable.is() )
682
0
    {
683
0
        Reference< XNamed > xNamed( mxSelectedTable->getPropertyValue( u"TableTemplate"_ustr ), UNO_QUERY );
684
0
        if( xNamed.is() )
685
0
            selectStyle(xNamed->getName());
686
0
    }
687
0
}
688
689
void TableDesignWidget::selectStyle(std::u16string_view rStyle)
690
0
{
691
0
    Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY );
692
0
    if( xNames.is() )
693
0
    {
694
0
        Sequence< OUString > aNames( xNames->getElementNames() );
695
0
        sal_Int32 nIndex = comphelper::findValue(aNames, rStyle);
696
0
        if (nIndex != -1)
697
0
            m_xValueSet->SelectItem(static_cast<sal_uInt16>(nIndex) + 1);
698
0
    }
699
0
}
700
701
void TableDesignWidget::endTextEditForStyle(const Reference<XInterface>& rStyle)
702
0
{
703
0
    if (!mxSelectedTable)
704
0
        return;
705
706
0
    Reference<XInterface> xTableStyle(mxSelectedTable->getPropertyValue(u"TableTemplate"_ustr), UNO_QUERY);
707
0
    if (xTableStyle != rStyle)
708
0
        return;
709
710
0
    SdrView* pDrawView = mrBase.GetDrawView();
711
0
    if (pDrawView && pDrawView->IsTextEdit())
712
0
        pDrawView->SdrEndTextEdit();
713
0
}
714
715
void TableDesignWidget::addListener()
716
0
{
717
0
    Link<sdtools::EventMultiplexerEvent&,void> aLink( LINK(this,TableDesignWidget,EventMultiplexerListener) );
718
0
    mrBase.GetEventMultiplexer()->AddEventListener( aLink );
719
0
}
720
721
void TableDesignWidget::removeListener()
722
0
{
723
0
    Link<sdtools::EventMultiplexerEvent&,void> aLink( LINK(this,TableDesignWidget,EventMultiplexerListener) );
724
0
    mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
725
0
}
726
727
IMPL_LINK(TableDesignWidget,EventMultiplexerListener,
728
    sdtools::EventMultiplexerEvent&, rEvent, void)
729
0
{
730
0
    switch (rEvent.meEventId)
731
0
    {
732
0
        case EventMultiplexerEventId::CurrentPageChanged:
733
0
        case EventMultiplexerEventId::EditViewSelection:
734
0
            onSelectionChanged();
735
0
            break;
736
737
0
        case EventMultiplexerEventId::MainViewRemoved:
738
0
            mxView.clear();
739
0
            onSelectionChanged();
740
0
            break;
741
742
0
        case EventMultiplexerEventId::MainViewAdded:
743
0
            mxView = mrBase.GetDrawController();
744
0
            onSelectionChanged();
745
0
            break;
746
747
0
        default: break;
748
0
    }
749
0
}
750
751
namespace {
752
753
struct CellInfo
754
{
755
    Color maCellColor;
756
    Color maTextColor;
757
    std::shared_ptr<SvxBoxItem> maBorder;
758
759
    explicit CellInfo( const Reference< XStyle >& xStyle );
760
};
761
762
}
763
764
CellInfo::CellInfo( const Reference< XStyle >& xStyle )
765
0
: maBorder(std::make_shared<SvxBoxItem>(SDRATTR_TABLE_BORDER))
766
0
{
767
0
    SfxStyleSheet* pStyleSheet = SfxUnoStyleSheet::getUnoStyleSheet( xStyle );
768
0
    if( !pStyleSheet )
769
0
        return;
770
771
0
    SfxItemSet& rSet = pStyleSheet->GetItemSet();
772
773
    // get style fill color
774
0
    maCellColor = GetDraftFillColor(rSet).value_or(COL_TRANSPARENT);
775
776
    // get style text color
777
0
    const SvxColorItem* pTextColor = rSet.GetItem(EE_CHAR_COLOR);
778
0
    if( pTextColor )
779
0
        maTextColor = pTextColor->GetValue();
780
0
    else
781
0
        maTextColor = COL_TRANSPARENT;
782
783
    // get border
784
0
    const SvxBoxItem* pBoxItem = rSet.GetItem( SDRATTR_TABLE_BORDER );
785
0
    if( pBoxItem )
786
0
        maBorder.reset(pBoxItem->Clone());
787
0
}
788
789
typedef std::vector< std::shared_ptr< CellInfo > > CellInfoVector;
790
typedef std::shared_ptr< CellInfo > CellInfoMatrix[nPreviewColumns * nPreviewRows];
791
792
namespace {
793
794
struct TableStyleSettings
795
{
796
    bool mbUseFirstRow;
797
    bool mbUseLastRow;
798
    bool mbUseFirstColumn;
799
    bool mbUseLastColumn;
800
    bool mbUseRowBanding;
801
    bool mbUseColumnBanding;
802
803
    TableStyleSettings()
804
0
        : mbUseFirstRow(true)
805
0
        , mbUseLastRow(false)
806
0
        , mbUseFirstColumn(false)
807
0
        , mbUseLastColumn(false)
808
0
        , mbUseRowBanding(true)
809
0
        , mbUseColumnBanding(false) {}
810
};
811
812
}
813
814
static void FillCellInfoVector( const Reference< XIndexAccess >& xTableStyle, CellInfoVector& rVector )
815
0
{
816
0
    DBG_ASSERT( xTableStyle.is() && (xTableStyle->getCount() == sdr::table::style_count ), "sd::FillCellInfoVector(), invalid table style!" );
817
0
    if( !xTableStyle.is() )
818
0
        return;
819
820
0
    try
821
0
    {
822
0
        rVector.resize( sdr::table::style_count );
823
824
0
        for( sal_Int32 nStyle = 0; nStyle < sdr::table::style_count; ++nStyle )
825
0
        {
826
0
            Reference< XStyle > xStyle( xTableStyle->getByIndex( nStyle ), UNO_QUERY );
827
0
            if( xStyle.is() )
828
0
                rVector[nStyle] = std::make_shared<CellInfo>( xStyle );
829
0
        }
830
0
    }
831
0
    catch(Exception&)
832
0
    {
833
0
        TOOLS_WARN_EXCEPTION( "sd", "sd::FillCellInfoVector()");
834
0
    }
835
0
}
836
837
static void FillCellInfoMatrix( const CellInfoVector& rStyle, const TableStyleSettings& rSettings, CellInfoMatrix& rMatrix )
838
0
{
839
0
    for( sal_Int32 nRow = 0; nRow < nPreviewColumns; ++nRow )
840
0
    {
841
0
        const bool bFirstRow = rSettings.mbUseFirstRow && (nRow == 0);
842
0
        const bool bLastRow = rSettings.mbUseLastRow && (nRow == nPreviewColumns - 1);
843
844
0
        for( sal_Int32 nCol = 0; nCol < nPreviewColumns; ++nCol )
845
0
        {
846
0
            std::shared_ptr< CellInfo > xCellInfo;
847
848
            // first and last row win first, if used and available
849
0
            if( bFirstRow )
850
0
            {
851
0
                xCellInfo = rStyle[sdr::table::first_row_style];
852
0
            }
853
0
            else if( bLastRow )
854
0
            {
855
0
                xCellInfo = rStyle[sdr::table::last_row_style];
856
0
            }
857
858
0
            if( !xCellInfo )
859
0
            {
860
                // next come first and last column, if used and available
861
0
                if( rSettings.mbUseFirstColumn && (nCol == 0)  )
862
0
                {
863
0
                    xCellInfo = rStyle[sdr::table::first_column_style];
864
0
                }
865
0
                else if( rSettings.mbUseLastColumn && (nCol == nPreviewColumns-1) )
866
0
                {
867
0
                    xCellInfo = rStyle[sdr::table::last_column_style];
868
0
                }
869
0
            }
870
871
0
            if( !xCellInfo )
872
0
            {
873
0
                if( rSettings.mbUseRowBanding )
874
0
                {
875
0
                    if( (nRow & 1) == 0 )
876
0
                    {
877
0
                        xCellInfo = rStyle[sdr::table::even_rows_style];
878
0
                    }
879
0
                    else
880
0
                    {
881
0
                        xCellInfo = rStyle[sdr::table::odd_rows_style];
882
0
                    }
883
0
                }
884
0
            }
885
886
0
            if( !xCellInfo )
887
0
            {
888
0
                if( rSettings.mbUseColumnBanding )
889
0
                {
890
0
                    if( (nCol & 1) == 0 )
891
0
                    {
892
0
                        xCellInfo = rStyle[sdr::table::even_columns_style];
893
0
                    }
894
0
                    else
895
0
                    {
896
0
                        xCellInfo = rStyle[sdr::table::odd_columns_style];
897
0
                    }
898
0
                }
899
0
            }
900
901
0
            if( !xCellInfo )
902
0
            {
903
                // use default cell style if non found yet
904
0
                xCellInfo = rStyle[sdr::table::body_style];
905
0
            }
906
907
0
            rMatrix[(nCol * nPreviewColumns) + nRow] = std::move(xCellInfo);
908
0
        }
909
0
    }
910
0
}
911
912
static Bitmap CreateDesignPreview( const Reference< XIndexAccess >& xTableStyle, const TableStyleSettings& rSettings, bool bIsPageDark )
913
0
{
914
0
    CellInfoVector aCellInfoVector(sdr::table::style_count);
915
0
    FillCellInfoVector( xTableStyle, aCellInfoVector );
916
917
0
    CellInfoMatrix aMatrix;
918
0
    FillCellInfoMatrix( aCellInfoVector, rSettings, aMatrix );
919
920
    // bbbbbbbbbbbb w = 12 pixel
921
    // bccccccccccb h = 7 pixel
922
    // bccccccccccb b = border color
923
    // bcttttttttcb c = cell color
924
    // bccccccccccb t = text color
925
    // bccccccccccb
926
    // bbbbbbbbbbbb
927
928
0
    ScopedVclPtr<VirtualDevice> pVirDev(VclPtr<VirtualDevice>::Create());
929
0
    Size aBmpSize(nBitmapWidth, nBitmapHeight);
930
0
    pVirDev->SetOutputSizePixel(aBmpSize);
931
932
0
    pVirDev->SetBackground( bIsPageDark ? COL_BLACK : COL_WHITE );
933
0
    pVirDev->Erase();
934
935
    // first draw cell background and text line previews
936
0
    sal_Int32 nY = 0;
937
0
    sal_Int32 nRow;
938
0
    for( nRow = 0; nRow < nPreviewRows; ++nRow, nY += nCellHeight-1 )
939
0
    {
940
0
        sal_Int32 nX = 0;
941
0
        for( sal_Int32 nCol = 0; nCol < nPreviewColumns; ++nCol, nX += nCellWidth-1 )
942
0
        {
943
0
            std::shared_ptr< CellInfo > xCellInfo(aMatrix[(nCol * nPreviewColumns) + nRow]);
944
945
0
            Color aTextColor( COL_AUTO );
946
0
            if( xCellInfo )
947
0
            {
948
                // fill cell background
949
0
                const ::tools::Rectangle aRect( nX, nY, nX + nCellWidth - 1, nY + nCellHeight - 1 );
950
951
0
                if( xCellInfo->maCellColor != COL_TRANSPARENT )
952
0
                {
953
0
                    pVirDev->SetFillColor( xCellInfo->maCellColor );
954
0
                    pVirDev->DrawRect( aRect );
955
0
                }
956
957
0
                aTextColor = xCellInfo->maTextColor;
958
0
            }
959
960
            // draw text preview line
961
0
            if( aTextColor == COL_AUTO )
962
0
                aTextColor = bIsPageDark ? COL_WHITE : COL_BLACK;
963
0
            pVirDev->SetLineColor( aTextColor );
964
0
            const Point aPnt1( nX + 2, nY + ((nCellHeight - 1 ) >> 1) );
965
0
            const Point aPnt2( nX + nCellWidth - 3, aPnt1.Y() );
966
0
            pVirDev->DrawLine( aPnt1, aPnt2 );
967
0
        }
968
0
    }
969
970
    // second draw border lines
971
0
    nY = 0;
972
0
    for( nRow = 0; nRow < nPreviewRows; ++nRow, nY += nCellHeight-1 )
973
0
    {
974
0
        sal_Int32 nX = 0;
975
0
        for( sal_Int32 nCol = 0; nCol < nPreviewColumns; ++nCol, nX += nCellWidth-1 )
976
0
        {
977
0
            std::shared_ptr< CellInfo > xCellInfo(aMatrix[(nCol * nPreviewColumns) + nRow]);
978
979
0
            if( xCellInfo )
980
0
            {
981
0
                const Point aPntTL( nX, nY );
982
0
                const Point aPntTR( nX + nCellWidth - 1, nY );
983
0
                const Point aPntBL( nX, nY + nCellHeight - 1 );
984
0
                const Point aPntBR( nX + nCellWidth - 1, nY + nCellHeight - 1 );
985
986
0
                sal_Int32 border_diffs[8] = { 0,-1, 0,1, -1,0, 1,0 };
987
0
                sal_Int32* pDiff = &border_diffs[0];
988
989
                // draw top border
990
0
                for( SvxBoxItemLine nLine : o3tl::enumrange<SvxBoxItemLine>() )
991
0
                {
992
0
                    const ::editeng::SvxBorderLine* pBorderLine = xCellInfo->maBorder->GetLine(nLine);
993
0
                    if( !pBorderLine || ((pBorderLine->GetOutWidth() == 0) && (pBorderLine->GetInWidth()==0)) )
994
0
                        continue;
995
996
0
                    sal_Int32 nBorderCol = nCol + *pDiff++;
997
0
                    sal_Int32 nBorderRow = nRow + *pDiff++;
998
0
                    if( (nBorderCol >= 0) && (nBorderCol < nPreviewColumns) && (nBorderRow >= 0) && (nBorderRow < nPreviewRows) )
999
0
                    {
1000
                        // check border
1001
0
                        std::shared_ptr< CellInfo > xBorderInfo(aMatrix[(nBorderCol * nPreviewColumns) + nBorderRow]);
1002
0
                        if( xBorderInfo )
1003
0
                        {
1004
0
                            const ::editeng::SvxBorderLine* pBorderLine2 = xBorderInfo->maBorder->GetLine(static_cast<SvxBoxItemLine>(static_cast<int>(nLine)^1));
1005
0
                            if( pBorderLine2 && pBorderLine2->HasPriority(*pBorderLine) )
1006
0
                                continue; // other border line wins
1007
0
                        }
1008
0
                    }
1009
1010
0
                    pVirDev->SetLineColor( pBorderLine->GetColor() );
1011
0
                    switch( nLine )
1012
0
                    {
1013
0
                    case SvxBoxItemLine::TOP: pVirDev->DrawLine( aPntTL, aPntTR ); break;
1014
0
                    case SvxBoxItemLine::BOTTOM: pVirDev->DrawLine( aPntBL, aPntBR ); break;
1015
0
                    case SvxBoxItemLine::LEFT: pVirDev->DrawLine( aPntTL, aPntBL ); break;
1016
0
                    case SvxBoxItemLine::RIGHT: pVirDev->DrawLine( aPntTR, aPntBR ); break;
1017
0
                    }
1018
0
                }
1019
0
            }
1020
0
        }
1021
0
    }
1022
1023
0
    return pVirDev->GetBitmap(Point(0,0), aBmpSize);
1024
0
}
1025
1026
void TableDesignWidget::FillDesignPreviewControl()
1027
0
{
1028
0
    sal_uInt16 nSelectedItem = m_xValueSet->GetSelectedItemId();
1029
0
    m_xValueSet->Clear();
1030
0
    try
1031
0
    {
1032
0
        TableStyleSettings aSettings;
1033
0
        if( mxSelectedTable.is() )
1034
0
        {
1035
0
            aSettings.mbUseFirstRow = m_aCheckBoxes[CB_HEADER_ROW]->get_active();
1036
0
            aSettings.mbUseLastRow = m_aCheckBoxes[CB_TOTAL_ROW]->get_active();
1037
0
            aSettings.mbUseRowBanding = m_aCheckBoxes[CB_BANDED_ROWS]->get_active();
1038
0
            aSettings.mbUseFirstColumn = m_aCheckBoxes[CB_FIRST_COLUMN]->get_active();
1039
0
            aSettings.mbUseLastColumn = m_aCheckBoxes[CB_LAST_COLUMN]->get_active();
1040
0
            aSettings.mbUseColumnBanding = m_aCheckBoxes[CB_BANDED_COLUMNS]->get_active();
1041
0
        }
1042
1043
0
        bool bIsPageDark = false;
1044
0
        if( mxView.is() )
1045
0
        {
1046
0
            Reference< XPropertySet > xPageSet( mxView->getCurrentPage(), UNO_QUERY );
1047
0
            if( xPageSet.is() )
1048
0
            {
1049
0
                xPageSet->getPropertyValue(u"IsBackgroundDark"_ustr) >>= bIsPageDark;
1050
0
            }
1051
0
        }
1052
1053
0
        sal_Int32 nCount = mxTableFamily->getCount();
1054
0
        for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) try
1055
0
        {
1056
0
            Reference< XIndexAccess > xTableStyle( mxTableFamily->getByIndex( nIndex ), UNO_QUERY );
1057
0
            if( xTableStyle.is() )
1058
0
                m_xValueSet->InsertItem( sal::static_int_cast<sal_uInt16>( nIndex + 1 ), Image( CreateDesignPreview( xTableStyle, aSettings, bIsPageDark ) ) );
1059
0
        }
1060
0
        catch( Exception& )
1061
0
        {
1062
0
            TOOLS_WARN_EXCEPTION( "sd", "sd::TableDesignWidget::FillDesignPreviewControl()");
1063
0
        }
1064
0
        m_xValueSet->InsertItem(++nCount, Image(StockImage::Yes, BMP_INSERT_TABLESTYLE), SdResId(STR_INSERT_TABLESTYLE));
1065
1066
0
        sal_Int32 nCols = 3;
1067
0
        sal_Int32 nRows = std::min<sal_Int32>((nCount+2)/3, TableValueSet::getMaxRowCount());
1068
0
        m_xValueSet->SetColCount(nCols);
1069
0
        m_xValueSet->SetLineCount(nRows);
1070
0
        WinBits nStyle = m_xValueSet->GetStyle() & ~WB_VSCROLL;
1071
0
        m_xValueSet->SetStyle(nStyle);
1072
1073
0
        m_xValueSet->SetOptimalSize();
1074
0
        weld::DrawingArea* pDrawingArea = m_xValueSet->GetDrawingArea();
1075
0
        Size aSize = pDrawingArea->get_preferred_size();
1076
0
        aSize.AdjustWidth(10 * nCols);
1077
0
        aSize.AdjustHeight(10 * nRows);
1078
0
        pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
1079
1080
0
        m_xValueSet->Resize();
1081
0
    }
1082
0
    catch( Exception& )
1083
0
    {
1084
0
        TOOLS_WARN_EXCEPTION( "sd", "sd::TableDesignWidget::FillDesignPreviewControl()");
1085
0
    }
1086
0
    m_xValueSet->SelectItem(nSelectedItem);
1087
0
}
1088
1089
}
1090
1091
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */