1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 #include "optiongrouplayouter.hxx"
27 #include <tools/debug.hxx>
28 #include <tools/string.hxx>
29 #include <com/sun/star/awt/Size.hpp>
30 #include <com/sun/star/awt/Point.hpp>
31 #include <com/sun/star/container/XIndexAccess.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/drawing/XShapes.hpp>
34 #include <com/sun/star/drawing/XShapeGrouper.hpp>
35 #include <com/sun/star/text/TextContentAnchorType.hpp>
36 #include <com/sun/star/view/XSelectionSupplier.hpp>
37 #include "controlwizard.hxx"
38 #include "groupboxwiz.hxx"
39 #include "dbptools.hxx"
40 
41 //.........................................................................
42 namespace dbp
43 {
44 //.........................................................................
45 
46 #define BUTTON_HEIGHT		300
47 #define TOP_HEIGHT			300
48 #define HEIGHT				450
49 #define OFFSET				300
50 #define MIN_WIDTH			600
51 
52 	using namespace ::com::sun::star::uno;
53 	using namespace ::com::sun::star::drawing;
54 	using namespace ::com::sun::star::beans;
55 	using namespace ::com::sun::star::awt;
56 	using namespace ::com::sun::star::container;
57 	using namespace ::com::sun::star::lang;
58 	using namespace ::com::sun::star::text;
59 	using namespace ::com::sun::star::view;
60 
61 	//=====================================================================
62 	//= OOptionGroupLayouter
63 	//=====================================================================
64 	//---------------------------------------------------------------------
OOptionGroupLayouter(const Reference<XMultiServiceFactory> & _rxORB)65 	OOptionGroupLayouter::OOptionGroupLayouter(const Reference< XMultiServiceFactory >& _rxORB)
66 		:m_xORB(_rxORB)
67 	{
68 	}
69 
70 	//---------------------------------------------------------------------
doLayout(const OControlWizardContext & _rContext,const OOptionGroupSettings & _rSettings)71 	void OOptionGroupLayouter::doLayout(const OControlWizardContext& _rContext, const OOptionGroupSettings& _rSettings)
72 	{
73 		Reference< XShapes > xPageShapes(_rContext.xDrawPage, UNO_QUERY);
74 		if (!xPageShapes.is())
75 		{
76 			DBG_ERROR("OOptionGroupLayouter::OOptionGroupLayouter: missing the XShapes interface for the page!");
77 			return;
78 		}
79 
80 		Reference< XMultiServiceFactory > xDocFactory(_rContext.xDocumentModel, UNO_QUERY);
81 		if (!xDocFactory.is())
82 		{
83 			DBG_ERROR("OOptionGroupLayouter::OOptionGroupLayouter: no document service factory!");
84 			return;
85 		}
86 
87 		// no. of buttons to create
88 		sal_Int32 nRadioButtons = _rSettings.aLabels.size();
89 
90 		sal_Int32 nTopSpace = 0;
91 
92 		// the shape of the groupbox
93 		::com::sun::star::awt::Size aControlShapeSize = _rContext.xObjectShape->getSize();
94 		// maybe need to adjust the size if the control shapes
95 		sal_Int32 nMinShapeHeight = BUTTON_HEIGHT*(nRadioButtons+1) + BUTTON_HEIGHT + BUTTON_HEIGHT/4;
96 		if (aControlShapeSize.Height < nMinShapeHeight)
97 			aControlShapeSize.Height = nMinShapeHeight;
98 		if (aControlShapeSize.Width < MIN_WIDTH)
99 			aControlShapeSize.Width = MIN_WIDTH;
100 		_rContext.xObjectShape->setSize(aControlShapeSize);
101 
102 		// if we're working on a writer document, we need to anchor the shape
103 		implAnchorShape(Reference< XPropertySet >(_rContext.xObjectShape, UNO_QUERY));
104 
105 		// shape collection (for grouping the shapes)
106 		Reference< XShapes > xButtonCollection(m_xORB->createInstance(
107 				::rtl::OUString::createFromAscii("com.sun.star.drawing.ShapeCollection")),
108 			UNO_QUERY);
109 		// first member : the shape of the control
110 		xButtonCollection->add(_rContext.xObjectShape.get());
111 
112 		sal_Int32 nTempHeight = (aControlShapeSize.Height - BUTTON_HEIGHT/4) / (nRadioButtons + 1);
113 
114 		::com::sun::star::awt::Point aShapePosition = _rContext.xObjectShape->getPosition();
115 
116 		::com::sun::star::awt::Size aButtonSize(aControlShapeSize);
117 		aButtonSize.Width = aControlShapeSize.Width - OFFSET;
118 		aButtonSize.Height = HEIGHT;
119 		::com::sun::star::awt::Point aButtonPosition;
120 		aButtonPosition.X = aShapePosition.X + OFFSET;
121 
122 		::rtl::OUString sElementsName = ::rtl::OUString::createFromAscii("RadioGroup");
123 		disambiguateName(Reference< XNameAccess >(_rContext.xForm, UNO_QUERY), sElementsName);
124 
125 		StringArray::const_iterator aLabelIter = _rSettings.aLabels.begin();
126 		StringArray::const_iterator aValueIter = _rSettings.aValues.begin();
127 		for (sal_Int32 i=0; i<nRadioButtons; ++i, ++aLabelIter, ++aValueIter)
128 		{
129 			aButtonPosition.Y = aShapePosition.Y + (i+1) * nTempHeight + nTopSpace;
130 
131 			Reference< XPropertySet > xRadioModel(
132 					xDocFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.RadioButton")),
133 				UNO_QUERY);
134 
135 			// the label
136 			xRadioModel->setPropertyValue(::rtl::OUString::createFromAscii("Label"), makeAny(rtl::OUString(*aLabelIter)));
137 			// the value
138 			xRadioModel->setPropertyValue(::rtl::OUString::createFromAscii("RefValue"), makeAny(rtl::OUString(*aValueIter)));
139 
140 			// default selection
141 			if (_rSettings.sDefaultField == *aLabelIter)
142 				xRadioModel->setPropertyValue(::rtl::OUString::createFromAscii("DefaultState"), makeAny(sal_Int16(1)));
143 
144 			// the connection to the database field
145 			if (0 != _rSettings.sDBField.Len())
146 				xRadioModel->setPropertyValue(::rtl::OUString::createFromAscii("DataField"), makeAny(::rtl::OUString(_rSettings.sDBField)));
147 
148 			// the name for the model
149 			xRadioModel->setPropertyValue(::rtl::OUString::createFromAscii("Name"), makeAny(sElementsName));
150 
151 			// create a shape for the radio button
152 			Reference< XControlShape > xRadioShape(
153 					xDocFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.drawing.ControlShape")),
154 				UNO_QUERY);
155 			Reference< XPropertySet > xShapeProperties(xRadioShape, UNO_QUERY);
156 
157 			// if we're working on a writer document, we need to anchor the shape
158 			implAnchorShape(xShapeProperties);
159 
160 			// position it
161 			xRadioShape->setSize(aButtonSize);
162 			xRadioShape->setPosition(aButtonPosition);
163 			// knitting with the model
164 			xRadioShape->setControl(Reference< XControlModel >(xRadioModel, UNO_QUERY));
165 
166 			// the name of the shape
167 			if (xShapeProperties.is())
168 				xShapeProperties->setPropertyValue(::rtl::OUString::createFromAscii("Name"), makeAny(sElementsName));
169 
170 			// add to the page
171 			xPageShapes->add(xRadioShape.get());
172 			// add to the collection (for the later grouping)
173 			xButtonCollection->add(xRadioShape.get());
174 
175 			// set the GroupBox as "LabelControl" for the RadioButton
176 			// (_after_ having inserted the model into the page!)
177 			xRadioModel->setPropertyValue(::rtl::OUString::createFromAscii("LabelControl"), makeAny(_rContext.xObjectModel));
178 		}
179 
180 		// group the shapes
181 		try
182 		{
183 			Reference< XShapeGrouper > xGrouper(_rContext.xDrawPage, UNO_QUERY);
184 			if (xGrouper.is())
185 			{
186 				Reference< XShapeGroup > xGroupedOptions = xGrouper->group(xButtonCollection);
187 				Reference< XSelectionSupplier > xSelector(_rContext.xDocumentModel->getCurrentController(), UNO_QUERY);
188 				if (xSelector.is())
189 					xSelector->select(makeAny(xGroupedOptions));
190 			}
191 		}
192 		catch(Exception&)
193 		{
194 			DBG_ERROR("OOptionGroupLayouter::doLayout: caught an exception while grouping the shapes!");
195 		}
196 	}
197 
198 	//---------------------------------------------------------------------
implAnchorShape(const Reference<XPropertySet> & _rxShapeProps)199 	void OOptionGroupLayouter::implAnchorShape(const Reference< XPropertySet >& _rxShapeProps)
200 	{
201 		static const ::rtl::OUString s_sAnchorPropertyName = ::rtl::OUString::createFromAscii("AnchorType");
202 		Reference< XPropertySetInfo > xPropertyInfo;
203 		if (_rxShapeProps.is())
204 			xPropertyInfo = _rxShapeProps->getPropertySetInfo();
205 		if (xPropertyInfo.is() && xPropertyInfo->hasPropertyByName(s_sAnchorPropertyName))
206 			_rxShapeProps->setPropertyValue(s_sAnchorPropertyName, makeAny(TextContentAnchorType_AT_PAGE));
207 	}
208 
209 //.........................................................................
210 }	// namespace dbp
211 //.........................................................................
212 
213