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 "selectlabeldialog.hxx" 27 #ifndef _EXTENSIONS_PROPCTRLR_FORMRESID_HRC_ 28 #include "formresid.hrc" 29 #endif 30 #include "formbrowsertools.hxx" 31 #include "formstrings.hxx" 32 #include <com/sun/star/form/FormComponentType.hpp> 33 #include <com/sun/star/container/XChild.hpp> 34 #include <com/sun/star/container/XIndexAccess.hpp> 35 #include <com/sun/star/sdbc/XResultSet.hpp> 36 #include <com/sun/star/beans/XPropertySet.hpp> 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 #include <comphelper/property.hxx> 39 #include <comphelper/types.hxx> 40 41 //............................................................................ 42 namespace pcr 43 { 44 //............................................................................ 45 46 using namespace ::com::sun::star::uno; 47 using namespace ::com::sun::star::container; 48 using namespace ::com::sun::star::beans; 49 using namespace ::com::sun::star::form; 50 using namespace ::com::sun::star::sdbc; 51 using namespace ::com::sun::star::lang; 52 53 //======================================================================== 54 // OSelectLabelDialog 55 //======================================================================== DBG_NAME(OSelectLabelDialog)56 DBG_NAME(OSelectLabelDialog) 57 //------------------------------------------------------------------------ 58 OSelectLabelDialog::OSelectLabelDialog( Window* pParent, Reference< XPropertySet > _xControlModel ) 59 :ModalDialog(pParent, PcrRes(RID_DLG_SELECTLABELCONTROL)) 60 ,m_aMainDesc(this, PcrRes(1)) 61 ,m_aControlTree(this, PcrRes(1)) 62 ,m_aNoAssignment(this, PcrRes(1)) 63 ,m_aSeparator(this, PcrRes(1)) 64 ,m_aOk(this, PcrRes(1)) 65 ,m_aCancel(this, PcrRes(1)) 66 ,m_aModelImages(PcrRes(RID_IL_FORMEXPLORER)) 67 ,m_xControlModel(_xControlModel) 68 ,m_pInitialSelection(NULL) 69 ,m_pLastSelected(NULL) 70 ,m_bHaveAssignableControl(sal_False) 71 { 72 DBG_CTOR(OSelectLabelDialog,NULL); 73 74 // initialize the TreeListBox 75 m_aControlTree.SetSelectionMode( SINGLE_SELECTION ); 76 m_aControlTree.SetDragDropMode( 0 ); 77 m_aControlTree.EnableInplaceEditing( sal_False ); 78 m_aControlTree.SetStyle(m_aControlTree.GetStyle() | WB_BORDER | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL); 79 80 m_aControlTree.SetNodeBitmaps( m_aModelImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ), m_aModelImages.GetImage( RID_SVXIMG_EXPANDEDNODE ) ); 81 m_aControlTree.SetSelectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected)); 82 m_aControlTree.SetDeselectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected)); 83 84 // fill the description 85 UniString sDescription = m_aMainDesc.GetText(); 86 sal_Int16 nClassID = FormComponentType::CONTROL; 87 if (::comphelper::hasProperty(PROPERTY_CLASSID, m_xControlModel)) 88 nClassID = ::comphelper::getINT16(m_xControlModel->getPropertyValue(PROPERTY_CLASSID)); 89 90 sDescription.SearchAndReplace(String::CreateFromAscii("$control_class$"), GetUIHeadlineName(nClassID, makeAny(m_xControlModel))); 91 UniString sName = ::comphelper::getString(m_xControlModel->getPropertyValue(PROPERTY_NAME)).getStr(); 92 sDescription.SearchAndReplace(String::CreateFromAscii("$control_name$"), sName); 93 m_aMainDesc.SetText(sDescription); 94 95 // search for the root of the form hierarchy 96 Reference< XChild > xCont(m_xControlModel, UNO_QUERY); 97 Reference< XInterface > xSearch( xCont.is() ? xCont->getParent() : Reference< XInterface > ()); 98 Reference< XResultSet > xParentAsResultSet(xSearch, UNO_QUERY); 99 while (xParentAsResultSet.is()) 100 { 101 xCont = Reference< XChild > (xSearch, UNO_QUERY); 102 xSearch = xCont.is() ? xCont->getParent() : Reference< XInterface > (); 103 xParentAsResultSet = Reference< XResultSet > (xSearch, UNO_QUERY); 104 } 105 106 // and insert all entries below this root into the listbox 107 if (xSearch.is()) 108 { 109 // check wich service the allowed components must suppport 110 sal_Int16 nClassId = 0; 111 try { nClassId = ::comphelper::getINT16(m_xControlModel->getPropertyValue(PROPERTY_CLASSID)); } catch(...) { } 112 m_sRequiredService = (FormComponentType::RADIOBUTTON == nClassId) ? SERVICE_COMPONENT_GROUPBOX : SERVICE_COMPONENT_FIXEDTEXT; 113 m_aRequiredControlImage = m_aModelImages.GetImage((FormComponentType::RADIOBUTTON == nClassId) ? RID_SVXIMG_GROUPBOX : RID_SVXIMG_FIXEDTEXT); 114 115 // calc the currently set label control (so InsertEntries can calc m_pInitialSelection) 116 Any aCurrentLabelControl( m_xControlModel->getPropertyValue(PROPERTY_CONTROLLABEL) ); 117 DBG_ASSERT((aCurrentLabelControl.getValueTypeClass() == TypeClass_INTERFACE) || !aCurrentLabelControl.hasValue(), 118 119 "OSelectLabelDialog::OSelectLabelDialog : invalid ControlLabel property !"); 120 if (aCurrentLabelControl.hasValue()) 121 aCurrentLabelControl >>= m_xInitialLabelControl; 122 123 // insert the root 124 Image aRootImage = m_aModelImages.GetImage(RID_SVXIMG_FORMS); 125 SvLBoxEntry* pRoot = m_aControlTree.InsertEntry(PcrRes(RID_STR_FORMS), aRootImage, aRootImage); 126 127 // build the tree 128 m_pInitialSelection = NULL; 129 m_bHaveAssignableControl = sal_False; 130 InsertEntries(xSearch, pRoot); 131 m_aControlTree.Expand(pRoot); 132 } 133 134 if (m_pInitialSelection) 135 { 136 m_aControlTree.MakeVisible(m_pInitialSelection, sal_True); 137 m_aControlTree.Select(m_pInitialSelection, sal_True); 138 } 139 else 140 { 141 m_aControlTree.MakeVisible(m_aControlTree.First(), sal_True); 142 if (m_aControlTree.FirstSelected()) 143 m_aControlTree.Select(m_aControlTree.FirstSelected(), sal_False); 144 m_aNoAssignment.Check(sal_True); 145 } 146 147 if (!m_bHaveAssignableControl) 148 { // no controls which can be assigned 149 m_aNoAssignment.Check(sal_True); 150 m_aNoAssignment.Enable(sal_False); 151 } 152 153 m_aNoAssignment.SetClickHdl(LINK(this, OSelectLabelDialog, OnNoAssignmentClicked)); 154 m_aNoAssignment.GetClickHdl().Call(&m_aNoAssignment); 155 156 FreeResource(); 157 } 158 159 //------------------------------------------------------------------------ ~OSelectLabelDialog()160 OSelectLabelDialog::~OSelectLabelDialog() 161 { 162 // delete the entry datas of the listbox entries 163 SvLBoxEntry* pLoop = m_aControlTree.First(); 164 while (pLoop) 165 { 166 void* pData = pLoop->GetUserData(); 167 if (pData) 168 delete (Reference< XPropertySet > *)pData; 169 pLoop = m_aControlTree.Next(pLoop); 170 } 171 172 DBG_DTOR(OSelectLabelDialog,NULL); 173 } 174 175 //------------------------------------------------------------------------ InsertEntries(const Reference<XInterface> & _xContainer,SvLBoxEntry * pContainerEntry)176 sal_Int32 OSelectLabelDialog::InsertEntries(const Reference< XInterface > & _xContainer, SvLBoxEntry* pContainerEntry) 177 { 178 Reference< XIndexAccess > xContainer(_xContainer, UNO_QUERY); 179 if (!xContainer.is()) 180 return 0; 181 182 sal_Int32 nChildren = 0; 183 UniString sName,sDisplayName; 184 Reference< XPropertySet > xAsSet; 185 for (sal_Int32 i=0; i<xContainer->getCount(); ++i) 186 { 187 xContainer->getByIndex(i) >>= xAsSet; 188 if (!xAsSet.is()) 189 { 190 DBG_WARNING("OSelectLabelDialog::InsertEntries : strange : a form component which isn't a property set !"); 191 continue; 192 } 193 194 if (!::comphelper::hasProperty(PROPERTY_NAME, xAsSet)) 195 // we need at least a name for displaying ... 196 continue; 197 sName = ::comphelper::getString(xAsSet->getPropertyValue(PROPERTY_NAME)).getStr(); 198 199 // we need to check if the control model supports the required service 200 Reference< XServiceInfo > xInfo(xAsSet, UNO_QUERY); 201 if (!xInfo.is()) 202 continue; 203 204 if (!xInfo->supportsService(m_sRequiredService)) 205 { // perhaps it is a container 206 Reference< XIndexAccess > xCont(xAsSet, UNO_QUERY); 207 if (xCont.is() && xCont->getCount()) 208 { // yes -> step down 209 Image aFormImage = m_aModelImages.GetImage( RID_SVXIMG_FORM ); 210 SvLBoxEntry* pCont = m_aControlTree.InsertEntry(sName, aFormImage, aFormImage, pContainerEntry); 211 sal_Int32 nContChildren = InsertEntries(xCont, pCont); 212 if (nContChildren) 213 { 214 m_aControlTree.Expand(pCont); 215 ++nChildren; 216 } 217 else 218 { // oops, no valid childs -> remove the entry 219 m_aControlTree.ModelIsRemoving(pCont); 220 m_aControlTree.GetModel()->Remove(pCont); 221 m_aControlTree.ModelHasRemoved(pCont); 222 } 223 } 224 continue; 225 } 226 227 // get the label 228 if (!::comphelper::hasProperty(PROPERTY_LABEL, xAsSet)) 229 continue; 230 sDisplayName = ::comphelper::getString(xAsSet->getPropertyValue(PROPERTY_LABEL)).getStr(); 231 sDisplayName += String::CreateFromAscii(" ("); 232 sDisplayName += sName; 233 sDisplayName += ')'; 234 235 // all requirements met -> insert 236 SvLBoxEntry* pCurrent = m_aControlTree.InsertEntry(sDisplayName, m_aRequiredControlImage, m_aRequiredControlImage, pContainerEntry); 237 pCurrent->SetUserData(new Reference< XPropertySet > (xAsSet)); 238 ++nChildren; 239 240 if (m_xInitialLabelControl == xAsSet) 241 m_pInitialSelection = pCurrent; 242 243 m_bHaveAssignableControl = sal_True; 244 } 245 246 return nChildren; 247 } 248 249 //------------------------------------------------------------------------ IMPL_LINK(OSelectLabelDialog,OnEntrySelected,SvTreeListBox *,pLB)250 IMPL_LINK(OSelectLabelDialog, OnEntrySelected, SvTreeListBox*, pLB) 251 { 252 DBG_ASSERT(pLB == &m_aControlTree, "OSelectLabelDialog::OnEntrySelected : where did this come from ?"); 253 (void)pLB; 254 SvLBoxEntry* pSelected = m_aControlTree.FirstSelected(); 255 void* pData = pSelected ? pSelected->GetUserData() : NULL; 256 257 if (pData) 258 m_xSelectedControl = Reference< XPropertySet > (*(Reference< XPropertySet > *)pData); 259 260 m_aNoAssignment.SetClickHdl(Link()); 261 m_aNoAssignment.Check(pData == NULL); 262 m_aNoAssignment.SetClickHdl(LINK(this, OSelectLabelDialog, OnNoAssignmentClicked)); 263 264 return 0L; 265 } 266 267 //------------------------------------------------------------------------ IMPL_LINK(OSelectLabelDialog,OnNoAssignmentClicked,Button *,pButton)268 IMPL_LINK(OSelectLabelDialog, OnNoAssignmentClicked, Button*, pButton) 269 { 270 DBG_ASSERT(pButton == &m_aNoAssignment, "OSelectLabelDialog::OnNoAssignmentClicked : where did this come from ?"); 271 (void)pButton; 272 273 if (m_aNoAssignment.IsChecked()) 274 m_pLastSelected = m_aControlTree.FirstSelected(); 275 else 276 { 277 DBG_ASSERT(m_bHaveAssignableControl, "OSelectLabelDialog::OnNoAssignmentClicked"); 278 // search the first assignable entry 279 SvLBoxEntry* pSearch = m_aControlTree.First(); 280 while (pSearch) 281 { 282 if (pSearch->GetUserData()) 283 break; 284 pSearch = m_aControlTree.Next(pSearch); 285 } 286 // and select it 287 if (pSearch) 288 { 289 m_aControlTree.Select(pSearch); 290 m_pLastSelected = pSearch; 291 } 292 } 293 294 if (m_pLastSelected) 295 { 296 m_aControlTree.SetSelectHdl(Link()); 297 m_aControlTree.SetDeselectHdl(Link()); 298 m_aControlTree.Select(m_pLastSelected, !m_aNoAssignment.IsChecked()); 299 m_aControlTree.SetSelectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected)); 300 m_aControlTree.SetDeselectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected)); 301 } 302 303 return 0L; 304 } 305 306 //............................................................................ 307 } // namespace pcr 308 //............................................................................ 309 310