1 diff --git svx/inc/svx/msocximex.hxx svx/inc/svx/msocximex.hxx
2 index 2d0827f..733304d 100644
3 --- svx/inc/svx/msocximex.hxx
4 +++ svx/inc/svx/msocximex.hxx
5 @@ -289,6 +289,7 @@ public:
9 + UniString msParentName;
10 OCX_FontData aFontData;
11 SfxObjectShell *pDocSh;
13 @@ -506,54 +507,8 @@ typedef std::vector<OCX_Control*>::iterator CtrlIterator;
14 typedef std::vector<OCX_Control*>::const_iterator CtrlIteratorConst;
15 typedef std::vector<OCX_Control*> CtrlList;
22 - RBGroup():mRBGroupPos(0){}
23 - RBGroup(sal_uInt16& groupPos ):mRBGroupPos(groupPos){}
24 - sal_Int16 tabPos() const { return mRBGroupPos; }
25 - std::vector<OCX_Control*>::size_type numControls()
26 - { return mpControls.size(); }
27 - std::vector<OCX_Control*>& controls() { return mpControls; }
29 - void add(OCX_Control* pRB);
31 - sal_uInt16 mRBGroupPos;
32 - std::vector<OCX_Control*> mpControls;
35 -typedef ::std::hash_map < ::rtl::OUString, RBGroup*, ::rtl::OUStringHash,
36 - ::std::equal_to< ::rtl::OUString > > RBGroupHash;
37 -typedef std::vector<RBGroup*>::iterator GroupIterator;
39 class OCX_OptionButton;
44 - RBGroupManager( String& defaultName );
47 - CtrlList insertGroupsIntoControlList( const CtrlList& sourceList );
48 - void addRadioButton( OCX_OptionButton* pRButton );
51 - void addSeperator( std::vector< OCX_Control* >& dest );
52 - void copyList( std::vector< OCX_Control* >& src,
53 - std::vector< OCX_Control* >& dest,
54 - bool addGroupSeperator );
56 - RBGroupHash rbGroups;
57 - String mSDefaultName;
58 - std::vector< RBGroup* > groupList;
59 - sal_uInt16 numRadioButtons;
65 class OCX_ContainerControl : public OCX_Control
68 @@ -593,7 +548,6 @@ protected:
69 OCX_Control* pParent = NULL );
70 rtl::OUString createSubStreamName( const sal_uInt32& subStorageID );
72 - RBGroupManager rbGroupMgr;
73 com::sun::star::uno::Reference<
74 com::sun::star::container::XNameContainer > mxParent;
75 std::vector<OCX_Control*> mpControls;
76 diff --git svx/source/msfilter/msocximex.cxx svx/source/msfilter/msocximex.cxx
77 index 2aba883..617caf8 100644
78 --- svx/source/msfilter/msocximex.cxx
79 +++ svx/source/msfilter/msocximex.cxx
80 @@ -825,176 +825,6 @@ class ContainerRecordReaderFac
82 // ============================================================================
84 -void RBGroup::add(OCX_Control* pRB)
86 - // The tab index for the group is calculated as
87 - // the lowest tab index found in the list of RadioButtons
88 - if ( pRB->mnTabPos < mRBGroupPos )
90 - mRBGroupPos = pRB->mnTabPos;
91 - CtrlIterator aEnd = mpControls.end();
92 - for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
94 - (*aIter)->mnTabPos = mRBGroupPos;
97 - mpControls.push_back( pRB );
100 -struct SortGroupByTabPos
102 - bool operator()( const RBGroup* a, const RBGroup* b )
104 - return a->tabPos() < b->tabPos();
108 -RBGroupManager::RBGroupManager( String& defaultName ):mSDefaultName( defaultName ),
111 - groupList.reserve( 8 ); // reserve far more than we expect
114 -RBGroupManager::~RBGroupManager()
116 - for ( GroupIterator gIter=groupList.begin(); gIter!=groupList.end(); ++gIter )
122 -// Loose description of the method below ( I sure there is a better way to do
124 -// In order to "fake" MS grouping behavior for OptionButtons the OptionButtons
125 -// in the same group need to have consecutive tab indices ( regardless of the
126 -// imported tab indices of the RadioButtons ). Additionally if two
127 -// groups of OptionButtons end up having all consecutive indices they
128 -// will be treated as a single group by OpenOffice. In this case
129 -// a dummy seperator control needs to be inserted between the groups.
131 -// This method returns a new list "destinationList" containing the controls
132 -// passed in "sourceList" and the OptionButtons contained in the various
133 -// Groups maintained by this class.
134 -// Controls are ordered in the destination list by tab index.
135 -// Each RadioButtonGroup has a tab index associated with it.
136 -// ( Tab index of a RadioGroup is determined as the tab index of the
137 -// OptionButton control with the lowest tab index in the group )
140 -void RBGroupManager::addRadioButton( OCX_OptionButton* pRButton )
144 - OUString groupName = mSDefaultName;
145 - if ( pRButton->nGroupNameLen )
148 - lclCreateOUString(pRButton->pGroupName,
149 - pRButton->nGroupNameLen);
152 - RBGroupHash::iterator iter = rbGroups.find( groupName );
153 - if ( iter != rbGroups.end() )
155 - iter->second->controls().push_back( pRButton );
159 - RBGroup* newGroup = new RBGroup(pRButton->mnTabPos);
160 - newGroup->controls().push_back( pRButton );
161 - rbGroups[ groupName ] = newGroup;
162 - groupList.push_back( newGroup );
168 -CtrlList RBGroupManager::insertGroupsIntoControlList( const CtrlList& sourceList )
170 - ::std::sort( groupList.begin(), groupList.end(), SortGroupByTabPos() );
171 - std::vector<OCX_Control*> destinationList;
172 - if ( groupList.size() )
174 - destinationList.reserve( sourceList.size() + numRadioButtons );
176 - GroupIterator groupEnd = groupList.end();
177 - CtrlIteratorConst sourceEnd = sourceList.end();
179 - size_t prevGroupListSize = 0;
181 - CtrlIteratorConst containees = sourceList.begin();
182 - GroupIterator groupIter=groupList.begin();
183 - while ( containees != sourceEnd ||
184 - groupIter != groupEnd )
186 - bool addGroupSeperator = false;
187 - if ( containees != sourceEnd )
189 - if ( groupIter != groupEnd )
191 - sal_Int16 groupTabPos = (*groupIter)->tabPos();
192 - if ( (*containees)->mnTabPos >= groupTabPos )
194 - if ( !(destinationList.size() >= prevGroupListSize ))
196 - addGroupSeperator = true;
198 - copyList( (*groupIter)->controls(), destinationList, addGroupSeperator );
201 - prevGroupListSize = destinationList.size();
204 - destinationList.push_back(*containees);
209 - if ( groupIter != groupEnd )
211 - if ( !(destinationList.size() > prevGroupListSize ))
213 - addGroupSeperator = true;
215 - copyList( (*groupIter)->controls(), destinationList, addGroupSeperator );
217 - prevGroupListSize = destinationList.size();
224 - destinationList = sourceList;
226 - return destinationList;
231 -void RBGroupManager::addSeperator( std::vector< OCX_Control* >& dest )
233 - OCX_Control* seperator = new OCX_CommandButton;
234 - seperator->SetInDialog(true);
235 - seperator->sName = C2S("GroupSeperator");
236 - dest.push_back( seperator );
239 -void RBGroupManager::copyList( std::vector< OCX_Control* >& src,
240 - std::vector< OCX_Control* >& dest,
241 - bool addGroupSeperator )
243 - if ( addGroupSeperator )
245 - addSeperator( dest );
248 - for ( CtrlIterator rbIter = src.begin(); rbIter != src.end(); ++rbIter )
250 - dest.push_back( *rbIter );
254 class OCX_UserFormLabel : public OCX_Label
257 @@ -1698,6 +1528,36 @@ sal_Bool OCX_OptionButton::Import(com::s
259 rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
261 + // If this is a dialog control then we need to set a groupname *always*
262 + rtl::OUString sGroupName = lclCreateOUString( pGroupName, nGroupNameLen );
263 + if ( GetInDialog() ) // Userform/Dialog
265 + // By default groupnames are not set in Excel, it's not unusual to have
266 + // a number of groups of radiobuttons located inside frame ( or other container
267 + // controls ) where there is *no* specific groupname set for the radiobuttons.
268 + // But... there is implicit grouping for radio buttons in seperate containers
269 + // e.g. radio buttons in a frame are by default in the same group.
270 + // Unfortunately in openoffice there are no containers below the dialog itself :-(
271 + // To ensure correct grouping for imported radiobuttons either with no groupname
272 + // or identical groupnames that are in separate containers we *must* ensure
273 + // that a suitable groupname is applied.
274 + // Because controlNames are unique even across different containers we can use the
275 + // controls container (e.g. parent) name as a prefix for a group name
276 + rtl::OUString sParentName = msParentName;
277 + sGroupName = sParentName.concat( C2U( ":" ) ).concat( sGroupName );
279 + if ( sGroupName.getLength() > 0 )
281 + OSL_TRACE("RadioButton %s has groupname %s",
282 + rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( sGroupName, RTL_TEXTENCODING_UTF8 ).getStr() );
285 + rPropSet->setPropertyValue( WW8_ASCII2STR("GroupName"), aTmp);
287 + catch( uno::Exception& )
294 @@ -3416,7 +3276,7 @@ OCX_ContainerControl::OCX_ContainerContr
295 const ::rtl::OUString& sN,
296 const uno::Reference< container::XNameContainer > &rParent,
297 OCX_Control* pParent ) :
298 - OCX_Control(sN, pParent), rbGroupMgr( sName ), mxParent(rParent), nNoRecords(0), nTotalLen(0), containerType( STDCONTAINER )
299 + OCX_Control(sN, pParent), mxParent(rParent), nNoRecords(0), nTotalLen(0), containerType( STDCONTAINER )
302 mContainerStorage = parent->OpenSotStorage(storageName,
303 @@ -3627,6 +3487,7 @@ void OCX_ContainerControl::ProcessContro
304 // applied to all containees
305 pControl->mnStep = mnStep;
307 + pControl->msParentName = sName;
309 // #117490# DR: container records provide size of substream, use it here...
311 @@ -3637,17 +3498,7 @@ void OCX_ContainerControl::ProcessContro
312 // set stream to position behind substream of this control
313 oStream->Seek( nStrmPos + rec.nSubStreamLen );
315 - //need to fake grouping behaviour for radio ( option ) buttons
316 - if ( rec.nTypeIdent == OPTIONBUTTON )
318 - OCX_OptionButton* pRButton =
319 - static_cast< OCX_OptionButton*>(pControl);
320 - rbGroupMgr.addRadioButton( pRButton );
324 - mpControls.push_back( pControl );
326 + mpControls.push_back( pControl );
330 @@ -3670,7 +3521,6 @@ sal_Bool OCX_ContainerControl::Read(SvSt
331 // this ensures that the default tab index created by Star/Open office
332 // reflects the "flattened" ms tab order.
333 ::std::sort( mpControls.begin(), mpControls.end(), SortOrderByTabPos() );
334 - mpControls = rbGroupMgr.insertGroupsIntoControlList( mpControls );
338 diff --git xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx
339 index f864d51..4f87c16 100644
340 --- xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx
341 +++ xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx
342 @@ -458,6 +458,8 @@ void ElementDescriptor::readRadioButtonModel( StyleBag * all_styles, Reference<
343 OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":image-position") ) );
344 readBoolAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("MultiLine") ),
345 OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":multiline") ) );
346 + readStringAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("GroupName") ),
347 + OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":group-name") ) );
349 sal_Int16 nState = 0;
350 if (readProp( OUString( RTL_CONSTASCII_USTRINGPARAM("State") ) ) >>= nState)
351 diff --git xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
352 index 9db354d..92c1a09 100644
353 --- xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
354 +++ xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
355 @@ -1634,6 +1634,9 @@ void TitledBoxElement::endElement()
356 ctx.importBooleanProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("MultiLine") ),
357 OUString( RTL_CONSTASCII_USTRINGPARAM("multiline") ),
359 + ctx.importStringProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("GroupName") ),
360 + OUString( RTL_CONSTASCII_USTRINGPARAM("group-name") ),
364 sal_Bool bChecked = sal_False;
365 @@ -1775,6 +1778,9 @@ void RadioGroupElement::endElement()
366 ctx.importBooleanProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("MultiLine") ),
367 OUString( RTL_CONSTASCII_USTRINGPARAM("multiline") ),
369 + ctx.importStringProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("GroupName") ),
370 + OUString( RTL_CONSTASCII_USTRINGPARAM("group-name") ),
373 sal_Bool bChecked = sal_False;
374 if (getBoolAttr( &bChecked,