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 "selectlabeldialog.hxx"
21 #include "formresid.hrc"
22 #include "formbrowsertools.hxx"
23 #include "formstrings.hxx"
24 #include <com/sun/star/form/FormComponentType.hpp>
25 #include <com/sun/star/container/XChild.hpp>
26 #include <com/sun/star/container/XIndexAccess.hpp>
27 #include <com/sun/star/sdbc/XResultSet.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <comphelper/property.hxx>
31 #include <comphelper/types.hxx>
32 #include "svtools/treelistentry.hxx"
34 //............................................................................
37 //............................................................................
39 using namespace ::com::sun::star::uno
;
40 using namespace ::com::sun::star::container
;
41 using namespace ::com::sun::star::beans
;
42 using namespace ::com::sun::star::form
;
43 using namespace ::com::sun::star::sdbc
;
44 using namespace ::com::sun::star::lang
;
46 //========================================================================
48 //========================================================================
49 DBG_NAME(OSelectLabelDialog
)
50 //------------------------------------------------------------------------
51 OSelectLabelDialog::OSelectLabelDialog( Window
* pParent
, Reference
< XPropertySet
> _xControlModel
)
52 :ModalDialog(pParent
, PcrRes(RID_DLG_SELECTLABELCONTROL
))
53 ,m_aMainDesc(this, PcrRes(1))
54 ,m_aControlTree(this, PcrRes(1))
55 ,m_aNoAssignment(this, PcrRes(1))
56 ,m_aSeparator(this, PcrRes(1))
57 ,m_aOk(this, PcrRes(1))
58 ,m_aCancel(this, PcrRes(1))
59 ,m_aModelImages(PcrRes(RID_IL_FORMEXPLORER
))
60 ,m_xControlModel(_xControlModel
)
61 ,m_pInitialSelection(NULL
)
62 ,m_pLastSelected(NULL
)
63 ,m_bHaveAssignableControl(sal_False
)
65 DBG_CTOR(OSelectLabelDialog
,NULL
);
67 // initialize the TreeListBox
68 m_aControlTree
.SetSelectionMode( SINGLE_SELECTION
);
69 m_aControlTree
.SetDragDropMode( 0 );
70 m_aControlTree
.EnableInplaceEditing( sal_False
);
71 m_aControlTree
.SetStyle(m_aControlTree
.GetStyle() | WB_BORDER
| WB_HASLINES
| WB_HASLINESATROOT
| WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HSCROLL
);
73 m_aControlTree
.SetNodeBitmaps( m_aModelImages
.GetImage( RID_SVXIMG_COLLAPSEDNODE
), m_aModelImages
.GetImage( RID_SVXIMG_EXPANDEDNODE
) );
74 m_aControlTree
.SetSelectHdl(LINK(this, OSelectLabelDialog
, OnEntrySelected
));
75 m_aControlTree
.SetDeselectHdl(LINK(this, OSelectLabelDialog
, OnEntrySelected
));
77 // fill the description
78 OUString sDescription
= m_aMainDesc
.GetText();
79 sal_Int16 nClassID
= FormComponentType::CONTROL
;
80 if (::comphelper::hasProperty(PROPERTY_CLASSID
, m_xControlModel
))
81 nClassID
= ::comphelper::getINT16(m_xControlModel
->getPropertyValue(PROPERTY_CLASSID
));
83 sDescription
= sDescription
.replaceAll(OUString("$control_class$"),
84 GetUIHeadlineName(nClassID
, makeAny(m_xControlModel
)));
85 OUString sName
= ::comphelper::getString(m_xControlModel
->getPropertyValue(PROPERTY_NAME
));
86 sDescription
= sDescription
.replaceAll(OUString("$control_name$"), sName
);
87 m_aMainDesc
.SetText(sDescription
);
89 // search for the root of the form hierarchy
90 Reference
< XChild
> xCont(m_xControlModel
, UNO_QUERY
);
91 Reference
< XInterface
> xSearch( xCont
.is() ? xCont
->getParent() : Reference
< XInterface
> ());
92 Reference
< XResultSet
> xParentAsResultSet(xSearch
, UNO_QUERY
);
93 while (xParentAsResultSet
.is())
95 xCont
= Reference
< XChild
> (xSearch
, UNO_QUERY
);
96 xSearch
= xCont
.is() ? xCont
->getParent() : Reference
< XInterface
> ();
97 xParentAsResultSet
= Reference
< XResultSet
> (xSearch
, UNO_QUERY
);
100 // and insert all entries below this root into the listbox
103 // check which service the allowed components must suppport
104 sal_Int16 nClassId
= 0;
105 try { nClassId
= ::comphelper::getINT16(m_xControlModel
->getPropertyValue(PROPERTY_CLASSID
)); } catch(...) { }
106 m_sRequiredService
= (FormComponentType::RADIOBUTTON
== nClassId
) ? OUString(SERVICE_COMPONENT_GROUPBOX
) : OUString(SERVICE_COMPONENT_FIXEDTEXT
);
107 m_aRequiredControlImage
= m_aModelImages
.GetImage((FormComponentType::RADIOBUTTON
== nClassId
) ? RID_SVXIMG_GROUPBOX
: RID_SVXIMG_FIXEDTEXT
);
109 // calc the currently set label control (so InsertEntries can calc m_pInitialSelection)
110 Any
aCurrentLabelControl( m_xControlModel
->getPropertyValue(PROPERTY_CONTROLLABEL
) );
111 DBG_ASSERT((aCurrentLabelControl
.getValueTypeClass() == TypeClass_INTERFACE
) || !aCurrentLabelControl
.hasValue(),
113 "OSelectLabelDialog::OSelectLabelDialog : invalid ControlLabel property !");
114 if (aCurrentLabelControl
.hasValue())
115 aCurrentLabelControl
>>= m_xInitialLabelControl
;
118 Image aRootImage
= m_aModelImages
.GetImage(RID_SVXIMG_FORMS
);
119 SvTreeListEntry
* pRoot
= m_aControlTree
.InsertEntry(PcrRes(RID_STR_FORMS
), aRootImage
, aRootImage
);
122 m_pInitialSelection
= NULL
;
123 m_bHaveAssignableControl
= sal_False
;
124 InsertEntries(xSearch
, pRoot
);
125 m_aControlTree
.Expand(pRoot
);
128 if (m_pInitialSelection
)
130 m_aControlTree
.MakeVisible(m_pInitialSelection
, sal_True
);
131 m_aControlTree
.Select(m_pInitialSelection
, sal_True
);
135 m_aControlTree
.MakeVisible(m_aControlTree
.First(), sal_True
);
136 if (m_aControlTree
.FirstSelected())
137 m_aControlTree
.Select(m_aControlTree
.FirstSelected(), sal_False
);
138 m_aNoAssignment
.Check(sal_True
);
141 if (!m_bHaveAssignableControl
)
142 { // no controls which can be assigned
143 m_aNoAssignment
.Check(sal_True
);
144 m_aNoAssignment
.Enable(sal_False
);
147 m_aNoAssignment
.SetClickHdl(LINK(this, OSelectLabelDialog
, OnNoAssignmentClicked
));
148 m_aNoAssignment
.GetClickHdl().Call(&m_aNoAssignment
);
153 //------------------------------------------------------------------------
154 OSelectLabelDialog::~OSelectLabelDialog()
156 // delete the entry datas of the listbox entries
157 SvTreeListEntry
* pLoop
= m_aControlTree
.First();
160 void* pData
= pLoop
->GetUserData();
162 delete (Reference
< XPropertySet
> *)pData
;
163 pLoop
= m_aControlTree
.Next(pLoop
);
166 DBG_DTOR(OSelectLabelDialog
,NULL
);
169 //------------------------------------------------------------------------
170 sal_Int32
OSelectLabelDialog::InsertEntries(const Reference
< XInterface
> & _xContainer
, SvTreeListEntry
* pContainerEntry
)
172 Reference
< XIndexAccess
> xContainer(_xContainer
, UNO_QUERY
);
173 if (!xContainer
.is())
176 sal_Int32 nChildren
= 0;
178 Reference
< XPropertySet
> xAsSet
;
179 for (sal_Int32 i
=0; i
<xContainer
->getCount(); ++i
)
181 xContainer
->getByIndex(i
) >>= xAsSet
;
184 DBG_WARNING("OSelectLabelDialog::InsertEntries : strange : a form component which isn't a property set !");
188 if (!::comphelper::hasProperty(PROPERTY_NAME
, xAsSet
))
189 // we need at least a name for displaying ...
191 sName
= ::comphelper::getString(xAsSet
->getPropertyValue(PROPERTY_NAME
)).getStr();
193 // we need to check if the control model supports the required service
194 Reference
< XServiceInfo
> xInfo(xAsSet
, UNO_QUERY
);
198 if (!xInfo
->supportsService(m_sRequiredService
))
199 { // perhaps it is a container
200 Reference
< XIndexAccess
> xCont(xAsSet
, UNO_QUERY
);
201 if (xCont
.is() && xCont
->getCount())
202 { // yes -> step down
203 Image aFormImage
= m_aModelImages
.GetImage( RID_SVXIMG_FORM
);
204 SvTreeListEntry
* pCont
= m_aControlTree
.InsertEntry(sName
, aFormImage
, aFormImage
, pContainerEntry
);
205 sal_Int32 nContChildren
= InsertEntries(xCont
, pCont
);
208 m_aControlTree
.Expand(pCont
);
212 { // oops, no valid children -> remove the entry
213 m_aControlTree
.ModelIsRemoving(pCont
);
214 m_aControlTree
.GetModel()->Remove(pCont
);
215 m_aControlTree
.ModelHasRemoved(pCont
);
222 if (!::comphelper::hasProperty(PROPERTY_LABEL
, xAsSet
))
225 OUString sDisplayName
= OUStringBuffer(
226 ::comphelper::getString(xAsSet
->getPropertyValue(PROPERTY_LABEL
))).
227 appendAscii(RTL_CONSTASCII_STRINGPARAM(" (")).append(sName
).append(')').
228 makeStringAndClear();
230 // all requirements met -> insert
231 SvTreeListEntry
* pCurrent
= m_aControlTree
.InsertEntry(sDisplayName
, m_aRequiredControlImage
, m_aRequiredControlImage
, pContainerEntry
);
232 pCurrent
->SetUserData(new Reference
< XPropertySet
> (xAsSet
));
235 if (m_xInitialLabelControl
== xAsSet
)
236 m_pInitialSelection
= pCurrent
;
238 m_bHaveAssignableControl
= sal_True
;
244 //------------------------------------------------------------------------
245 IMPL_LINK(OSelectLabelDialog
, OnEntrySelected
, SvTreeListBox
*, pLB
)
247 DBG_ASSERT(pLB
== &m_aControlTree
, "OSelectLabelDialog::OnEntrySelected : where did this come from ?");
249 SvTreeListEntry
* pSelected
= m_aControlTree
.FirstSelected();
250 void* pData
= pSelected
? pSelected
->GetUserData() : NULL
;
253 m_xSelectedControl
= Reference
< XPropertySet
> (*(Reference
< XPropertySet
> *)pData
);
255 m_aNoAssignment
.SetClickHdl(Link());
256 m_aNoAssignment
.Check(pData
== NULL
);
257 m_aNoAssignment
.SetClickHdl(LINK(this, OSelectLabelDialog
, OnNoAssignmentClicked
));
262 //------------------------------------------------------------------------
263 IMPL_LINK(OSelectLabelDialog
, OnNoAssignmentClicked
, Button
*, pButton
)
265 DBG_ASSERT(pButton
== &m_aNoAssignment
, "OSelectLabelDialog::OnNoAssignmentClicked : where did this come from ?");
268 if (m_aNoAssignment
.IsChecked())
269 m_pLastSelected
= m_aControlTree
.FirstSelected();
272 DBG_ASSERT(m_bHaveAssignableControl
, "OSelectLabelDialog::OnNoAssignmentClicked");
273 // search the first assignable entry
274 SvTreeListEntry
* pSearch
= m_aControlTree
.First();
277 if (pSearch
->GetUserData())
279 pSearch
= m_aControlTree
.Next(pSearch
);
284 m_aControlTree
.Select(pSearch
);
285 m_pLastSelected
= pSearch
;
291 m_aControlTree
.SetSelectHdl(Link());
292 m_aControlTree
.SetDeselectHdl(Link());
293 m_aControlTree
.Select(m_pLastSelected
, !m_aNoAssignment
.IsChecked());
294 m_aControlTree
.SetSelectHdl(LINK(this, OSelectLabelDialog
, OnEntrySelected
));
295 m_aControlTree
.SetDeselectHdl(LINK(this, OSelectLabelDialog
, OnEntrySelected
));
301 //............................................................................
303 //............................................................................
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */