1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "optiongrouplayouter.hxx"
21 #include <com/sun/star/awt/Size.hpp>
22 #include <com/sun/star/awt/Point.hpp>
23 #include <com/sun/star/container/XNameAccess.hpp>
24 #include <com/sun/star/drawing/ShapeCollection.hpp>
25 #include <com/sun/star/drawing/XShapes.hpp>
26 #include <com/sun/star/drawing/XShapeGrouper.hpp>
27 #include <com/sun/star/text/TextContentAnchorType.hpp>
28 #include <com/sun/star/view/XSelectionSupplier.hpp>
29 #include "groupboxwiz.hxx"
30 #include "dbptools.hxx"
31 #include <comphelper/diagnose_ex.hxx>
38 #define BUTTON_HEIGHT 300
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::drawing
;
45 using namespace ::com::sun::star::beans
;
46 using namespace ::com::sun::star::awt
;
47 using namespace ::com::sun::star::container
;
48 using namespace ::com::sun::star::lang
;
49 using namespace ::com::sun::star::text
;
50 using namespace ::com::sun::star::view
;
52 OOptionGroupLayouter::OOptionGroupLayouter(const Reference
< XComponentContext
>& _rxContext
)
53 :mxContext(_rxContext
)
58 void OOptionGroupLayouter::doLayout(const OControlWizardContext
& _rContext
, const OOptionGroupSettings
& _rSettings
)
60 Reference
< XShapes
> xPageShapes
= _rContext
.xDrawPage
;
61 if (!xPageShapes
.is())
63 OSL_FAIL("OOptionGroupLayouter::OOptionGroupLayouter: missing the XShapes interface for the page!");
67 Reference
< XMultiServiceFactory
> xDocFactory(_rContext
.xDocumentModel
, UNO_QUERY
);
68 if (!xDocFactory
.is())
70 OSL_FAIL("OOptionGroupLayouter::OOptionGroupLayouter: no document service factory!");
74 // no. of buttons to create
75 sal_Int32 nRadioButtons
= _rSettings
.aLabels
.size();
77 // the shape of the groupbox
78 css::awt::Size aControlShapeSize
= _rContext
.xObjectShape
->getSize();
79 // maybe need to adjust the size if the control shapes
80 sal_Int32 nMinShapeHeight
= BUTTON_HEIGHT
*(nRadioButtons
+1) + BUTTON_HEIGHT
+ BUTTON_HEIGHT
/4;
81 if (aControlShapeSize
.Height
< nMinShapeHeight
)
82 aControlShapeSize
.Height
= nMinShapeHeight
;
83 if (aControlShapeSize
.Width
< MIN_WIDTH
)
84 aControlShapeSize
.Width
= MIN_WIDTH
;
85 _rContext
.xObjectShape
->setSize(aControlShapeSize
);
87 // if we're working on a writer document, we need to anchor the shape
88 implAnchorShape(Reference
< XPropertySet
>(_rContext
.xObjectShape
, UNO_QUERY
));
90 // shape collection (for grouping the shapes)
91 Reference
< XShapes
> xButtonCollection( ShapeCollection::create(mxContext
) );
92 // first member : the shape of the control
93 xButtonCollection
->add(_rContext
.xObjectShape
);
95 sal_Int32 nTempHeight
= (aControlShapeSize
.Height
- BUTTON_HEIGHT
/4) / (nRadioButtons
+ 1);
97 css::awt::Point aShapePosition
= _rContext
.xObjectShape
->getPosition();
99 css::awt::Size
aButtonSize(aControlShapeSize
);
100 aButtonSize
.Width
= aControlShapeSize
.Width
- OFFSET
;
101 aButtonSize
.Height
= HEIGHT
;
102 css::awt::Point aButtonPosition
;
103 aButtonPosition
.X
= aShapePosition
.X
+ OFFSET
;
105 OUString
sElementsName(u
"RadioGroup"_ustr
);
106 disambiguateName(Reference
< XNameAccess
>(_rContext
.xForm
, UNO_QUERY
), sElementsName
);
108 auto aLabelIter
= _rSettings
.aLabels
.cbegin();
109 auto aValueIter
= _rSettings
.aValues
.cbegin();
110 for (sal_Int32 i
=0; i
<nRadioButtons
; ++i
, ++aLabelIter
, ++aValueIter
)
112 aButtonPosition
.Y
= aShapePosition
.Y
+ (i
+1) * nTempHeight
;
114 Reference
< XPropertySet
> xRadioModel(
115 xDocFactory
->createInstance(u
"com.sun.star.form.component.RadioButton"_ustr
),
119 xRadioModel
->setPropertyValue(u
"Label"_ustr
, Any(*aLabelIter
));
121 xRadioModel
->setPropertyValue(u
"RefValue"_ustr
, Any(*aValueIter
));
124 if (_rSettings
.sDefaultField
== *aLabelIter
)
125 xRadioModel
->setPropertyValue(u
"DefaultState"_ustr
, Any(sal_Int16(1)));
127 // the connection to the database field
128 if (!_rSettings
.sDBField
.isEmpty())
129 xRadioModel
->setPropertyValue(u
"DataField"_ustr
, Any(_rSettings
.sDBField
));
131 // the name for the model
132 xRadioModel
->setPropertyValue(u
"Name"_ustr
, Any(sElementsName
));
134 // create a shape for the radio button
135 Reference
< XControlShape
> xRadioShape(
136 xDocFactory
->createInstance(u
"com.sun.star.drawing.ControlShape"_ustr
),
138 Reference
< XPropertySet
> xShapeProperties(xRadioShape
, UNO_QUERY
);
140 // if we're working on a writer document, we need to anchor the shape
141 implAnchorShape(xShapeProperties
);
144 xRadioShape
->setSize(aButtonSize
);
145 xRadioShape
->setPosition(aButtonPosition
);
146 // knitting with the model
147 xRadioShape
->setControl(Reference
< XControlModel
>(xRadioModel
, UNO_QUERY
));
149 // the name of the shape
150 // tdf#117282 com.sun.star.drawing.ControlShape *has* no property
151 // of type 'Name'. In older versions it was an error that this did
152 // not throw an UnknownPropertyException. Still, it was never set
153 // at the Shape/SdrObject and was lost.
154 // Thus - just do no tset it. It is/stays part of the FormControl
155 // data, so it will be shown in the FormControl dialogs. It is not
156 // shown/used in SdrObject::Name dialog (e.g. context menu/Name...)
157 // if (xShapeProperties.is())
158 // xShapeProperties->setPropertyValue("Name", makeAny(sElementsName));
161 xPageShapes
->add(xRadioShape
);
162 // add to the collection (for the later grouping)
163 xButtonCollection
->add(xRadioShape
);
165 // set the GroupBox as "LabelControl" for the RadioButton
166 // (_after_ having inserted the model into the page!)
167 xRadioModel
->setPropertyValue(u
"LabelControl"_ustr
, Any(_rContext
.xObjectModel
));
173 Reference
< XShapeGrouper
> xGrouper(_rContext
.xDrawPage
, UNO_QUERY
);
176 Reference
< XShapeGroup
> xGroupedOptions
= xGrouper
->group(xButtonCollection
);
177 Reference
< XSelectionSupplier
> xSelector(_rContext
.xDocumentModel
->getCurrentController(), UNO_QUERY
);
179 xSelector
->select(Any(xGroupedOptions
));
184 TOOLS_WARN_EXCEPTION("extensions.dbpilots",
185 "caught an exception while grouping the shapes!");
190 void OOptionGroupLayouter::implAnchorShape(const Reference
< XPropertySet
>& _rxShapeProps
)
192 static constexpr OUString s_sAnchorPropertyName
= u
"AnchorType"_ustr
;
193 Reference
< XPropertySetInfo
> xPropertyInfo
;
194 if (_rxShapeProps
.is())
195 xPropertyInfo
= _rxShapeProps
->getPropertySetInfo();
196 if (xPropertyInfo
.is() && xPropertyInfo
->hasPropertyByName(s_sAnchorPropertyName
))
197 _rxShapeProps
->setPropertyValue(s_sAnchorPropertyName
, Any(TextContentAnchorType_AT_PAGE
));
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */