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 "gridwizard.hxx" 27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 28 #include <com/sun/star/sdbc/DataType.hpp> 29 #include <comphelper/stl_types.hxx> 30 #include <tools/string.hxx> 31 #include <com/sun/star/form/XGridColumnFactory.hpp> 32 #include <com/sun/star/awt/MouseWheelBehavior.hpp> 33 #include <com/sun/star/container/XNameContainer.hpp> 34 #include <tools/debug.hxx> 35 #include "dbptools.hxx" 36 #include "dbpilots.hrc" 37 38 #define GW_STATE_DATASOURCE_SELECTION 0 39 #define GW_STATE_FIELDSELECTION 1 40 41 //......................................................................... 42 namespace dbp 43 { 44 //......................................................................... 45 46 using namespace ::com::sun::star::uno; 47 using namespace ::com::sun::star::lang; 48 using namespace ::com::sun::star::beans; 49 using namespace ::com::sun::star::sdbc; 50 using namespace ::com::sun::star::container; 51 using namespace ::com::sun::star::form; 52 using namespace ::com::sun::star::awt; 53 using namespace ::svt; 54 55 //===================================================================== 56 //= OGridWizard 57 //===================================================================== 58 //--------------------------------------------------------------------- OGridWizard(Window * _pParent,const Reference<XPropertySet> & _rxObjectModel,const Reference<XMultiServiceFactory> & _rxORB)59 OGridWizard::OGridWizard( Window* _pParent, 60 const Reference< XPropertySet >& _rxObjectModel, const Reference< XMultiServiceFactory >& _rxORB ) 61 :OControlWizard(_pParent, ModuleRes(RID_DLG_GRIDWIZARD), _rxObjectModel, _rxORB) 62 ,m_bHadDataSelection(sal_True) 63 { 64 initControlSettings(&m_aSettings); 65 66 m_pPrevPage->SetHelpId(HID_GRIDWIZARD_PREVIOUS); 67 m_pNextPage->SetHelpId(HID_GRIDWIZARD_NEXT); 68 m_pCancel->SetHelpId(HID_GRIDWIZARD_CANCEL); 69 m_pFinish->SetHelpId(HID_GRIDWIZARD_FINISH); 70 71 // if we do not need the data source selection page ... 72 if (!needDatasourceSelection()) 73 { // ... skip it! 74 skip(1); 75 m_bHadDataSelection = sal_False; 76 } 77 } 78 79 //--------------------------------------------------------------------- approveControl(sal_Int16 _nClassId)80 sal_Bool OGridWizard::approveControl(sal_Int16 _nClassId) 81 { 82 if (FormComponentType::GRIDCONTROL != _nClassId) 83 return sal_False; 84 85 Reference< XGridColumnFactory > xColumnFactory(getContext().xObjectModel, UNO_QUERY); 86 if (!xColumnFactory.is()) 87 return sal_False; 88 89 return sal_True; 90 } 91 92 //--------------------------------------------------------------------- implApplySettings()93 void OGridWizard::implApplySettings() 94 { 95 const OControlWizardContext& rContext = getContext(); 96 97 // the factory for the columns 98 Reference< XGridColumnFactory > xColumnFactory(rContext.xObjectModel, UNO_QUERY); 99 DBG_ASSERT(xColumnFactory.is(), "OGridWizard::implApplySettings: should never have made it 'til here!"); 100 // (if we're here, what the hell happened in approveControl??) 101 102 // the container for the columns 103 Reference< XNameContainer > xColumnContainer(rContext.xObjectModel, UNO_QUERY); 104 DBG_ASSERT(xColumnContainer.is(), "OGridWizard::implApplySettings: no container!"); 105 106 if (!xColumnFactory.is() || !xColumnContainer.is()) 107 return; 108 109 static const ::rtl::OUString s_sDataFieldProperty = ::rtl::OUString::createFromAscii("DataField"); 110 static const ::rtl::OUString s_sLabelProperty = ::rtl::OUString::createFromAscii("Label"); 111 static const ::rtl::OUString s_sWidthProperty = ::rtl::OUString::createFromAscii("Width"); 112 static const ::rtl::OUString s_sMouseWheelBehavior = ::rtl::OUString::createFromAscii("MouseWheelBehavior"); 113 static const ::rtl::OUString s_sEmptyString; 114 115 // collect "descriptors" for the to-be-created (grid)columns 116 DECLARE_STL_VECTOR( ::rtl::OUString, StringArray ); 117 StringArray aColumnServiceNames; // service names to be used with the XGridColumnFactory 118 StringArray aColumnLabelPostfixes; // postfixes to append to the column labels 119 StringArray aFormFieldNames; // data field names 120 121 aColumnServiceNames.reserve(getSettings().aSelectedFields.getLength()); 122 aColumnLabelPostfixes.reserve(getSettings().aSelectedFields.getLength()); 123 aFormFieldNames.reserve(getSettings().aSelectedFields.getLength()); 124 125 // loop through the selected field names 126 const ::rtl::OUString* pSelectedFields = getSettings().aSelectedFields.getConstArray(); 127 const ::rtl::OUString* pEnd = pSelectedFields + getSettings().aSelectedFields.getLength(); 128 for (;pSelectedFields < pEnd; ++pSelectedFields) 129 { 130 // get the information for the selected column 131 sal_Int32 nFieldType = DataType::OTHER; 132 OControlWizardContext::TNameTypeMap::const_iterator aFind = rContext.aTypes.find(*pSelectedFields); 133 if ( aFind != rContext.aTypes.end() ) 134 nFieldType = aFind->second; 135 136 aFormFieldNames.push_back(*pSelectedFields); 137 switch (nFieldType) 138 { 139 case DataType::BIT: 140 case DataType::BOOLEAN: 141 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("CheckBox")); 142 aColumnLabelPostfixes.push_back(s_sEmptyString); 143 break; 144 145 case DataType::TINYINT: 146 case DataType::SMALLINT: 147 case DataType::INTEGER: 148 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("NumericField")); 149 aColumnLabelPostfixes.push_back(s_sEmptyString); 150 break; 151 152 case DataType::FLOAT: 153 case DataType::REAL: 154 case DataType::DOUBLE: 155 case DataType::NUMERIC: 156 case DataType::DECIMAL: 157 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("FormattedField")); 158 aColumnLabelPostfixes.push_back(s_sEmptyString); 159 break; 160 161 case DataType::DATE: 162 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("DateField")); 163 aColumnLabelPostfixes.push_back(s_sEmptyString); 164 break; 165 166 case DataType::TIME: 167 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("TimeField")); 168 aColumnLabelPostfixes.push_back(s_sEmptyString); 169 break; 170 171 case DataType::TIMESTAMP: 172 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("DateField")); 173 aColumnLabelPostfixes.push_back(String(ModuleRes(RID_STR_DATEPOSTFIX))); 174 175 aFormFieldNames.push_back(*pSelectedFields); 176 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("TimeField")); 177 aColumnLabelPostfixes.push_back(String(ModuleRes(RID_STR_TIMEPOSTFIX))); 178 break; 179 180 default: 181 aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("TextField")); 182 aColumnLabelPostfixes.push_back(s_sEmptyString); 183 } 184 } 185 186 DBG_ASSERT( aFormFieldNames.size() == aColumnServiceNames.size() 187 && aColumnServiceNames.size() == aColumnLabelPostfixes.size(), 188 "OGridWizard::implApplySettings: inconsistent descriptor sequences!"); 189 190 // now loop through the descriptions and create the (grid)columns out of th descriptors 191 { 192 Reference< XNameAccess > xExistenceChecker(xColumnContainer.get()); 193 194 ConstStringArrayIterator pColumnServiceName = aColumnServiceNames.begin(); 195 ConstStringArrayIterator pColumnLabelPostfix = aColumnLabelPostfixes.begin(); 196 ConstStringArrayIterator pFormFieldName = aFormFieldNames.begin(); 197 ConstStringArrayIterator pColumnServiceNameEnd = aColumnServiceNames.end(); 198 199 for (;pColumnServiceName < pColumnServiceNameEnd; ++pColumnServiceName, ++pColumnLabelPostfix, ++pFormFieldName) 200 { 201 // create a (grid)column for the (resultset)column 202 try 203 { 204 Reference< XPropertySet > xColumn( xColumnFactory->createColumn(*pColumnServiceName), UNO_SET_THROW ); 205 Reference< XPropertySetInfo > xColumnPSI( xColumn->getPropertySetInfo(), UNO_SET_THROW ); 206 207 ::rtl::OUString sColumnName(*pColumnServiceName); 208 disambiguateName(xExistenceChecker, sColumnName); 209 210 // the data field the column should be bound to 211 xColumn->setPropertyValue(s_sDataFieldProperty, makeAny(*pFormFieldName)); 212 // the label 213 xColumn->setPropertyValue(s_sLabelProperty, makeAny(::rtl::OUString(*pFormFieldName) += *pColumnLabelPostfix)); 214 // the width (<void/> => column will be auto-sized) 215 xColumn->setPropertyValue(s_sWidthProperty, Any()); 216 217 if ( xColumnPSI->hasPropertyByName( s_sMouseWheelBehavior ) ) 218 xColumn->setPropertyValue( s_sMouseWheelBehavior, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ); 219 220 // insert the column 221 xColumnContainer->insertByName(sColumnName, makeAny(xColumn)); 222 } 223 catch(Exception&) 224 { 225 DBG_ERROR( ::rtl::OString("OGridWizard::implApplySettings: unexpected exception while creating the grid column for field ") 226 += ::rtl::OString(pFormFieldName->getStr(), pFormFieldName->getLength(), gsl_getSystemTextEncoding()) 227 += ::rtl::OString("!")); 228 } 229 } 230 } 231 } 232 233 //--------------------------------------------------------------------- createPage(WizardState _nState)234 OWizardPage* OGridWizard::createPage(WizardState _nState) 235 { 236 switch (_nState) 237 { 238 case GW_STATE_DATASOURCE_SELECTION: 239 return new OTableSelectionPage(this); 240 case GW_STATE_FIELDSELECTION: 241 return new OGridFieldsSelection(this); 242 } 243 244 return NULL; 245 } 246 247 //--------------------------------------------------------------------- determineNextState(WizardState _nCurrentState) const248 WizardTypes::WizardState OGridWizard::determineNextState( WizardState _nCurrentState ) const 249 { 250 switch (_nCurrentState) 251 { 252 case GW_STATE_DATASOURCE_SELECTION: 253 return GW_STATE_FIELDSELECTION; 254 case GW_STATE_FIELDSELECTION: 255 return WZS_INVALID_STATE; 256 } 257 258 return WZS_INVALID_STATE; 259 } 260 261 //--------------------------------------------------------------------- enterState(WizardState _nState)262 void OGridWizard::enterState(WizardState _nState) 263 { 264 OControlWizard::enterState(_nState); 265 266 enableButtons(WZB_PREVIOUS, m_bHadDataSelection ? (GW_STATE_DATASOURCE_SELECTION < _nState) : GW_STATE_FIELDSELECTION < _nState); 267 enableButtons(WZB_NEXT, GW_STATE_FIELDSELECTION != _nState); 268 if (_nState < GW_STATE_FIELDSELECTION) 269 enableButtons(WZB_FINISH, sal_False); 270 271 if (GW_STATE_FIELDSELECTION == _nState) 272 defaultButton(WZB_FINISH); 273 } 274 275 //--------------------------------------------------------------------- leaveState(WizardState _nState)276 sal_Bool OGridWizard::leaveState(WizardState _nState) 277 { 278 if (!OControlWizard::leaveState(_nState)) 279 return sal_False; 280 281 if (GW_STATE_FIELDSELECTION == _nState) 282 defaultButton(WZB_NEXT); 283 284 return sal_True; 285 } 286 287 //--------------------------------------------------------------------- onFinish()288 sal_Bool OGridWizard::onFinish() 289 { 290 if ( !OControlWizard::onFinish() ) 291 return sal_False; 292 293 implApplySettings(); 294 295 return sal_True; 296 } 297 298 //===================================================================== 299 //= OGridFieldsSelection 300 //===================================================================== 301 //--------------------------------------------------------------------- OGridFieldsSelection(OGridWizard * _pParent)302 OGridFieldsSelection::OGridFieldsSelection( OGridWizard* _pParent ) 303 :OGridPage(_pParent, ModuleRes(RID_PAGE_GW_FIELDSELECTION)) 304 ,m_aFrame (this, ModuleRes(FL_FRAME)) 305 ,m_aExistFieldsLabel (this, ModuleRes(FT_EXISTING_FIELDS)) 306 ,m_aExistFields (this, ModuleRes(LB_EXISTING_FIELDS)) 307 ,m_aSelectOne (this, ModuleRes(PB_FIELDRIGHT)) 308 ,m_aSelectAll (this, ModuleRes(PB_ALLFIELDSRIGHT)) 309 ,m_aDeselectOne (this, ModuleRes(PB_FIELDLEFT)) 310 ,m_aDeselectAll (this, ModuleRes(PB_ALLFIELDSLEFT)) 311 ,m_aSelFieldsLabel (this, ModuleRes(FT_SELECTED_FIELDS)) 312 ,m_aSelFields (this, ModuleRes(LB_SELECTED_FIELDS)) 313 { 314 FreeResource(); 315 316 enableFormDatasourceDisplay(); 317 318 m_aSelectOne.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry)); 319 m_aSelectAll.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries)); 320 m_aDeselectOne.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry)); 321 m_aDeselectAll.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries)); 322 323 m_aExistFields.SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected)); 324 m_aSelFields.SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected)); 325 m_aExistFields.SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked)); 326 m_aSelFields.SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked)); 327 } 328 329 //--------------------------------------------------------------------- ActivatePage()330 void OGridFieldsSelection::ActivatePage() 331 { 332 OGridPage::ActivatePage(); 333 m_aExistFields.GrabFocus(); 334 } 335 336 //--------------------------------------------------------------------- canAdvance() const337 bool OGridFieldsSelection::canAdvance() const 338 { 339 return false; 340 // we're the last page in our wizard 341 } 342 343 //--------------------------------------------------------------------- initializePage()344 void OGridFieldsSelection::initializePage() 345 { 346 OGridPage::initializePage(); 347 348 const OControlWizardContext& rContext = getContext(); 349 fillListBox(m_aExistFields, rContext.aFieldNames); 350 351 m_aSelFields.Clear(); 352 const OGridSettings& rSettings = getSettings(); 353 const ::rtl::OUString* pSelected = rSettings.aSelectedFields.getConstArray(); 354 const ::rtl::OUString* pEnd = pSelected + rSettings.aSelectedFields.getLength(); 355 for (; pSelected < pEnd; ++pSelected) 356 { 357 m_aSelFields.InsertEntry(*pSelected); 358 m_aExistFields.RemoveEntry(*pSelected); 359 } 360 361 implCheckButtons(); 362 } 363 364 //--------------------------------------------------------------------- commitPage(::svt::WizardTypes::CommitPageReason _eReason)365 sal_Bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason ) 366 { 367 if (!OGridPage::commitPage(_eReason)) 368 return sal_False; 369 370 OGridSettings& rSettings = getSettings(); 371 sal_uInt16 nSelected = m_aSelFields.GetEntryCount(); 372 373 rSettings.aSelectedFields.realloc(nSelected); 374 ::rtl::OUString* pSelected = rSettings.aSelectedFields.getArray(); 375 376 for (sal_uInt16 i=0; i<nSelected; ++i, ++pSelected) 377 *pSelected = m_aSelFields.GetEntry(i); 378 379 return sal_True; 380 } 381 382 //--------------------------------------------------------------------- implCheckButtons()383 void OGridFieldsSelection::implCheckButtons() 384 { 385 m_aSelectOne.Enable(m_aExistFields.GetSelectEntryCount() != 0); 386 m_aSelectAll.Enable(m_aExistFields.GetEntryCount() != 0); 387 388 m_aDeselectOne.Enable(m_aSelFields.GetSelectEntryCount() != 0); 389 m_aDeselectAll.Enable(m_aSelFields.GetEntryCount() != 0); 390 391 getDialog()->enableButtons(WZB_FINISH, 0 != m_aSelFields.GetEntryCount()); 392 } 393 394 //--------------------------------------------------------------------- IMPL_LINK(OGridFieldsSelection,OnEntryDoubleClicked,ListBox *,_pList)395 IMPL_LINK(OGridFieldsSelection, OnEntryDoubleClicked, ListBox*, _pList) 396 { 397 PushButton* pSimulateButton = &m_aExistFields == _pList ? &m_aSelectOne : &m_aDeselectOne; 398 if (pSimulateButton->IsEnabled()) 399 return OnMoveOneEntry( pSimulateButton ); 400 else 401 return 1L; 402 } 403 404 //--------------------------------------------------------------------- 405 IMPL_LINK(OGridFieldsSelection, OnEntrySelected, ListBox*, /*NOTINTERESTEDIN*/) 406 { 407 implCheckButtons(); 408 return 0L; 409 } 410 411 //--------------------------------------------------------------------- IMPL_LINK(OGridFieldsSelection,OnMoveOneEntry,PushButton *,_pButton)412 IMPL_LINK(OGridFieldsSelection, OnMoveOneEntry, PushButton*, _pButton) 413 { 414 sal_Bool bMoveRight = (&m_aSelectOne == _pButton); 415 ListBox& rMoveTo = bMoveRight ? m_aSelFields : m_aExistFields; 416 417 // the index of the selected entry 418 sal_uInt16 nSelected = bMoveRight ? m_aExistFields.GetSelectEntryPos() : m_aSelFields.GetSelectEntryPos(); 419 // the (original) relative position of the entry 420 sal_IntPtr nRelativeIndex = reinterpret_cast<sal_IntPtr>(bMoveRight ? m_aExistFields.GetEntryData(nSelected) : m_aSelFields.GetEntryData(nSelected)); 421 422 sal_uInt16 nInsertPos = LISTBOX_APPEND; 423 if (!bMoveRight) 424 { // need to determine an insert pos which reflects the original 425 nInsertPos = 0; 426 while (nInsertPos < rMoveTo.GetEntryCount()) 427 { 428 if (reinterpret_cast<sal_IntPtr>(rMoveTo.GetEntryData(nInsertPos)) > nRelativeIndex) 429 break; 430 ++nInsertPos; 431 } 432 } 433 434 // the text of the entry to move 435 String sMovingEntry = bMoveRight ? m_aExistFields.GetEntry(nSelected) : m_aSelFields.GetEntry(nSelected); 436 437 // insert the entry 438 nInsertPos = rMoveTo.InsertEntry(sMovingEntry, nInsertPos); 439 // preserve it's "relative position" entry data 440 rMoveTo.SetEntryData(nInsertPos, reinterpret_cast<void*>(nRelativeIndex)); 441 442 // remove the entry from it's old list 443 if (bMoveRight) 444 { 445 sal_uInt16 nSelectPos = m_aExistFields.GetSelectEntryPos(); 446 m_aExistFields.RemoveEntry(nSelected); 447 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_aExistFields.GetEntryCount())) 448 m_aExistFields.SelectEntryPos(nSelectPos); 449 450 m_aExistFields.GrabFocus(); 451 } 452 else 453 { 454 sal_uInt16 nSelectPos = m_aSelFields.GetSelectEntryPos(); 455 m_aSelFields.RemoveEntry(nSelected); 456 if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_aSelFields.GetEntryCount())) 457 m_aSelFields.SelectEntryPos(nSelectPos); 458 459 m_aSelFields.GrabFocus(); 460 } 461 462 implCheckButtons(); 463 return 0; 464 } 465 466 //--------------------------------------------------------------------- IMPL_LINK(OGridFieldsSelection,OnMoveAllEntries,PushButton *,_pButton)467 IMPL_LINK(OGridFieldsSelection, OnMoveAllEntries, PushButton*, _pButton) 468 { 469 sal_Bool bMoveRight = (&m_aSelectAll == _pButton); 470 m_aExistFields.Clear(); 471 m_aSelFields.Clear(); 472 fillListBox(bMoveRight ? m_aSelFields : m_aExistFields, getContext().aFieldNames); 473 474 implCheckButtons(); 475 return 0; 476 } 477 478 //......................................................................... 479 } // namespace dbp 480 //......................................................................... 481 482