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 #include "precompiled_reportdesign.hxx" 24 25 #include "Navigator.hxx" 26 27 #include "uistrings.hrc" 28 #include "ReportController.hxx" 29 #include "UITools.hxx" 30 #include "RptUndo.hxx" 31 #include "reportformula.hxx" 32 #include <com/sun/star/container/XContainerListener.hpp> 33 #include <com/sun/star/report/XReportDefinition.hpp> 34 #include <com/sun/star/report/XFixedText.hpp> 35 #include <com/sun/star/report/XFixedLine.hpp> 36 #include <com/sun/star/report/XFormattedField.hpp> 37 #include <com/sun/star/report/XImageControl.hpp> 38 #include <com/sun/star/report/XShape.hpp> 39 #include <svx/globlmn.hrc> 40 #include <svx/svxids.hrc> 41 #include "helpids.hrc" 42 #include "RptResId.hrc" 43 #include "rptui_slotid.hrc" 44 #include <tools/debug.hxx> 45 #include <comphelper/propmultiplex.hxx> 46 #include <comphelper/containermultiplexer.hxx> 47 #include <comphelper/types.hxx> 48 #include "cppuhelper/basemutex.hxx" 49 #include "comphelper/SelectionMultiplex.hxx" 50 #include <svtools/svtreebx.hxx> 51 #include <svl/solar.hrc> 52 #include "ReportVisitor.hxx" 53 #include "ModuleHelper.hxx" 54 #include <rtl/ref.hxx> 55 56 #include <boost/bind.hpp> 57 #include <memory> 58 #include <algorithm> 59 60 #define RID_SVXIMG_COLLAPSEDNODE (RID_FORMS_START + 2) 61 #define RID_SVXIMG_EXPANDEDNODE (RID_FORMS_START + 3) 62 #define DROP_ACTION_TIMER_INITIAL_TICKS 10 63 #define DROP_ACTION_TIMER_SCROLL_TICKS 3 64 #define DROP_ACTION_TIMER_TICK_BASE 10 65 66 namespace rptui 67 { 68 using namespace ::com::sun::star; 69 using namespace utl; 70 using namespace ::comphelper; 71 72 sal_uInt16 lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement) 73 { 74 sal_uInt16 nId = 0; 75 uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY); 76 if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() ) 77 nId = SID_FM_FIXEDTEXT; 78 else if ( xFixedLine.is() ) 79 nId = xFixedLine->getOrientation() ? SID_INSERT_VFIXEDLINE : SID_INSERT_HFIXEDLINE; 80 else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() ) 81 nId = SID_FM_EDIT; 82 else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() ) 83 nId = SID_FM_IMAGECONTROL; 84 else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() ) 85 nId = SID_DRAWTBX_CS_BASIC; 86 return nId; 87 } 88 // ----------------------------------------------------------------------------- 89 ::rtl::OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement) 90 { 91 OSL_ENSURE(_xElement.is(),"Found report element which is NULL!"); 92 ::rtl::OUString sTempName; 93 _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName; 94 ::rtl::OUStringBuffer sName = sTempName; 95 uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY); 96 uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY); 97 if ( xFixedText.is() ) 98 { 99 sName.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : "))); 100 sName.append(xFixedText->getLabel()); 101 } 102 else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) ) 103 { 104 ReportFormula aFormula( xReportModel->getDataField() ); 105 if ( aFormula.isValid() ) 106 { 107 sName.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : "))); 108 sName.append( aFormula.getUndecoratedContent() ); 109 } 110 } 111 return sName.makeStringAndClear(); 112 } 113 // ----------------------------------------------------------------------------- 114 115 class NavigatorTree : public ::cppu::BaseMutex 116 , public SvTreeListBox 117 , public reportdesign::ITraverseReport 118 , public comphelper::OSelectionChangeListener 119 , public ::comphelper::OPropertyChangeListener 120 { 121 class UserData; 122 friend class UserData; 123 class UserData : public ::cppu::BaseMutex 124 ,public ::comphelper::OPropertyChangeListener 125 ,public ::comphelper::OContainerListener 126 { 127 uno::Reference< uno::XInterface > m_xContent; 128 ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pListener; 129 ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener; 130 NavigatorTree* m_pTree; 131 public: 132 UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent); 133 ~UserData(); 134 135 inline uno::Reference< uno::XInterface > getContent() const { return m_xContent; } 136 inline void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; } 137 protected: 138 // OPropertyChangeListener 139 virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException); 140 141 // OContainerListener 142 virtual void _elementInserted( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException); 143 virtual void _elementRemoved( const container::ContainerEvent& _Event ) throw(uno::RuntimeException); 144 virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException); 145 virtual void _disposing(const lang::EventObject& _rSource) throw( uno::RuntimeException); 146 }; 147 148 enum DROP_ACTION { DA_SCROLLUP, DA_SCROLLDOWN, DA_EXPANDNODE }; 149 AutoTimer m_aDropActionTimer; 150 Timer m_aSynchronizeTimer; 151 ImageList m_aNavigatorImages; 152 ImageList m_aNavigatorImagesHC; 153 Point m_aTimerTriggered; // die Position, an der der DropTimer angeschaltet wurde 154 DROP_ACTION m_aDropActionType; 155 OReportController& m_rController; 156 SvLBoxEntry* m_pMasterReport; 157 SvLBoxEntry* m_pDragedEntry; 158 ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener; 159 ::rtl::Reference< comphelper::OSelectionChangeMultiplexer> m_pSelectionListener; 160 unsigned short m_nTimerCounter; 161 162 SvLBoxEntry* insertEntry(const ::rtl::OUString& _sName,SvLBoxEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition,UserData* _pData); 163 void traverseSection(const uno::Reference< report::XSection>& _xSection,SvLBoxEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition = LIST_APPEND); 164 void traverseFunctions(const uno::Reference< report::XFunctions>& _xFunctions,SvLBoxEntry* _pParent); 165 166 NavigatorTree(const NavigatorTree&); 167 void operator =(const NavigatorTree&); 168 protected: 169 virtual void Command( const CommandEvent& rEvt ); 170 // DragSourceHelper overridables 171 virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ); 172 // DropTargetHelper overridables 173 virtual sal_Int8 AcceptDrop( const AcceptDropEvent& _rEvt ); 174 virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& _rEvt ); 175 176 // OSelectionChangeListener 177 virtual void _disposing(const lang::EventObject& _rSource) throw( uno::RuntimeException); 178 179 // OPropertyChangeListener 180 virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException); 181 182 // OContainerListener Helper 183 void _elementInserted( const container::ContainerEvent& _rEvent ); 184 void _elementRemoved( const container::ContainerEvent& _Event ); 185 void _elementReplaced( const container::ContainerEvent& _rEvent ); 186 187 public: 188 NavigatorTree(Window* pParent,OReportController& _rController ); 189 virtual ~NavigatorTree(); 190 191 DECL_LINK(OnEntrySelDesel, NavigatorTree*); 192 DECL_LINK( OnDropActionTimer, void* ); 193 194 virtual void _selectionChanged( const lang::EventObject& aEvent ) throw (uno::RuntimeException); 195 196 // ITraverseReport 197 virtual void traverseReport(const uno::Reference< report::XReportDefinition>& _xReport); 198 virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& _xFunctions); 199 virtual void traverseReportHeader(const uno::Reference< report::XSection>& _xSection); 200 virtual void traverseReportFooter(const uno::Reference< report::XSection>& _xSection); 201 virtual void traversePageHeader(const uno::Reference< report::XSection>& _xSection); 202 virtual void traversePageFooter(const uno::Reference< report::XSection>& _xSection); 203 204 virtual void traverseGroups(const uno::Reference< report::XGroups>& _xGroups); 205 virtual void traverseGroup(const uno::Reference< report::XGroup>& _xGroup); 206 virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& _xFunctions); 207 virtual void traverseGroupHeader(const uno::Reference< report::XSection>& _xSection); 208 virtual void traverseGroupFooter(const uno::Reference< report::XSection>& _xSection); 209 210 virtual void traverseDetail(const uno::Reference< report::XSection>& _xSection); 211 212 SvLBoxEntry* find(const uno::Reference< uno::XInterface >& _xContent); 213 void removeEntry(SvLBoxEntry* _pEntry,bool _bRemove = true); 214 private: 215 using SvTreeListBox::ExecuteDrop; 216 }; 217 DBG_NAME(rpt_NavigatorTree) 218 // ----------------------------------------------------------------------------- 219 NavigatorTree::NavigatorTree( Window* pParent,OReportController& _rController ) 220 :SvTreeListBox( pParent, WB_TABSTOP| WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HSCROLL|WB_HASBUTTONSATROOT ) 221 ,comphelper::OSelectionChangeListener(m_aMutex) 222 ,OPropertyChangeListener(m_aMutex) 223 ,m_aTimerTriggered(-1,-1) 224 ,m_aDropActionType( DA_SCROLLUP ) 225 ,m_rController(_rController) 226 ,m_pMasterReport(NULL) 227 ,m_pDragedEntry(NULL) 228 ,m_nTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS ) 229 { 230 DBG_CTOR(rpt_NavigatorTree,NULL); 231 m_pReportListener = new OPropertyChangeMultiplexer(this,m_rController.getReportDefinition().get()); 232 m_pReportListener->addProperty(PROPERTY_PAGEHEADERON); 233 m_pReportListener->addProperty(PROPERTY_PAGEFOOTERON); 234 m_pReportListener->addProperty(PROPERTY_REPORTHEADERON); 235 m_pReportListener->addProperty(PROPERTY_REPORTFOOTERON); 236 237 m_pSelectionListener = new OSelectionChangeMultiplexer(this,&m_rController); 238 239 SetHelpId( HID_REPORT_NAVIGATOR_TREE ); 240 241 m_aNavigatorImages = ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL ) ); 242 m_aNavigatorImagesHC = ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL_HC ) ); 243 244 SetNodeBitmaps( 245 m_aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ), 246 m_aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ), 247 BMP_COLOR_NORMAL 248 ); 249 SetNodeBitmaps( 250 m_aNavigatorImagesHC.GetImage( RID_SVXIMG_COLLAPSEDNODE ), 251 m_aNavigatorImagesHC.GetImage( RID_SVXIMG_EXPANDEDNODE ), 252 BMP_COLOR_HIGHCONTRAST 253 ); 254 255 SetDragDropMode(0xFFFF); 256 EnableInplaceEditing( sal_False ); 257 SetSelectionMode(MULTIPLE_SELECTION); 258 Clear(); 259 260 m_aDropActionTimer.SetTimeoutHdl(LINK(this, NavigatorTree, OnDropActionTimer)); 261 SetSelectHdl(LINK(this, NavigatorTree, OnEntrySelDesel)); 262 SetDeselectHdl(LINK(this, NavigatorTree, OnEntrySelDesel)); 263 } 264 // ----------------------------------------------------------------------------- 265 NavigatorTree::~NavigatorTree() 266 { 267 SvLBoxEntry* pCurrent = First(); 268 while ( pCurrent ) 269 { 270 delete static_cast<UserData*>(pCurrent->GetUserData()); 271 pCurrent = Next(pCurrent); 272 } 273 m_pReportListener->dispose(); 274 m_pSelectionListener->dispose(); 275 DBG_DTOR(rpt_NavigatorTree,NULL); 276 } 277 //------------------------------------------------------------------------------ 278 void NavigatorTree::Command( const CommandEvent& rEvt ) 279 { 280 sal_Bool bHandled = sal_False; 281 switch( rEvt.GetCommand() ) 282 { 283 case COMMAND_CONTEXTMENU: 284 { 285 // die Stelle, an der geklickt wurde 286 SvLBoxEntry* ptClickedOn = NULL; 287 ::Point aWhere; 288 if (rEvt.IsMouseEvent()) 289 { 290 aWhere = rEvt.GetMousePosPixel(); 291 ptClickedOn = GetEntry(aWhere); 292 if (ptClickedOn == NULL) 293 break; 294 if ( !IsSelected(ptClickedOn) ) 295 { 296 SelectAll(sal_False); 297 Select(ptClickedOn, sal_True); 298 SetCurEntry(ptClickedOn); 299 } 300 } 301 else 302 { 303 ptClickedOn = GetCurEntry(); 304 if ( !ptClickedOn ) 305 break; 306 aWhere = GetEntryPosition(ptClickedOn); 307 } 308 UserData* pData = static_cast<UserData*>(ptClickedOn->GetUserData()); 309 uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY); 310 uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY); 311 uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY); 312 sal_Bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() || 313 uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is()); 314 PopupMenu aContextMenu( ModuleRes( RID_MENU_NAVIGATOR ) ); 315 316 sal_uInt16 nCount = aContextMenu.GetItemCount(); 317 for (sal_uInt16 i = 0; i < nCount; ++i) 318 { 319 if ( MENUITEM_SEPARATOR != aContextMenu.GetItemType(i)) 320 { 321 sal_uInt16 nId = aContextMenu.GetItemId(i); 322 323 aContextMenu.CheckItem(nId,m_rController.isCommandChecked(nId)); 324 sal_Bool bEnabled = m_rController.isCommandEnabled(nId); 325 if ( nId == SID_RPT_NEW_FUNCTION ) 326 aContextMenu.EnableItem(nId,m_rController.isEditable() && (xSupplier.is() || xFunctions.is()) ); 327 // special condition, check for function and group 328 else if ( nId == SID_DELETE ) 329 aContextMenu.EnableItem(SID_DELETE,bDeleteAllowed); 330 else 331 aContextMenu.EnableItem(nId,bEnabled); 332 } 333 } // for (sal_uInt16 i = 0; i < nCount; ++i) 334 sal_uInt16 nId = aContextMenu.Execute(this, aWhere); 335 if ( nId ) 336 { 337 uno::Sequence< beans::PropertyValue> aArgs; 338 if ( nId == SID_RPT_NEW_FUNCTION ) 339 { 340 aArgs.realloc(1); 341 aArgs[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions()); 342 } 343 else if ( nId == SID_DELETE ) 344 { 345 if ( xGroup.is() ) 346 nId = SID_GROUP_REMOVE; 347 aArgs.realloc(1); 348 aArgs[0].Name = PROPERTY_GROUP; 349 aArgs[0].Value <<= pData->getContent(); 350 } 351 m_rController.executeUnChecked(nId,aArgs); 352 } 353 354 bHandled = sal_True; 355 } break; 356 } 357 358 if (!bHandled) 359 SvTreeListBox::Command( rEvt ); 360 } 361 // ----------------------------------------------------------------------------- 362 sal_Int8 NavigatorTree::AcceptDrop( const AcceptDropEvent& _rEvt ) 363 { 364 sal_Int8 nDropOption = DND_ACTION_NONE; 365 ::Point aDropPos = _rEvt.maPosPixel; 366 if (_rEvt.mbLeaving) 367 { 368 if (m_aDropActionTimer.IsActive()) 369 m_aDropActionTimer.Stop(); 370 } 371 else 372 { 373 bool bNeedTrigger = false; 374 // auf dem ersten Eintrag ? 375 if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight())) 376 { 377 m_aDropActionType = DA_SCROLLUP; 378 bNeedTrigger = true; 379 } 380 else if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight())) 381 { 382 m_aDropActionType = DA_SCROLLDOWN; 383 bNeedTrigger = true; 384 } 385 else 386 { 387 SvLBoxEntry* pDropppedOn = GetEntry(aDropPos); 388 if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn)) 389 { 390 m_aDropActionType = DA_EXPANDNODE; 391 bNeedTrigger = true; 392 } 393 } 394 395 if (bNeedTrigger && (m_aTimerTriggered != aDropPos)) 396 { 397 // neu anfangen zu zaehlen 398 m_nTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS; 399 // die Pos merken, da ich auch AcceptDrops bekomme, wenn sich die Maus gar nicht bewegt hat 400 m_aTimerTriggered = aDropPos; 401 // und den Timer los 402 if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ? 403 { 404 m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE); 405 m_aDropActionTimer.Start(); 406 } 407 } 408 else if (!bNeedTrigger) 409 m_aDropActionTimer.Stop(); 410 } 411 412 return nDropOption; 413 } 414 // ------------------------------------------------------------------------- 415 sal_Int8 NavigatorTree::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ ) 416 { 417 // _rEvt.mnAction; 418 return DND_ACTION_NONE; 419 } 420 // ------------------------------------------------------------------------- 421 void NavigatorTree::StartDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel ) 422 { 423 m_pDragedEntry = GetEntry(_rPosPixel); 424 if ( m_pDragedEntry ) 425 { 426 EndSelection(); 427 } 428 } 429 //------------------------------------------------------------------------ 430 IMPL_LINK( NavigatorTree, OnDropActionTimer, void*, EMPTYARG ) 431 { 432 if (--m_nTimerCounter > 0) 433 return 0L; 434 435 switch ( m_aDropActionType ) 436 { 437 case DA_EXPANDNODE: 438 { 439 SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered); 440 if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand)) 441 // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich 442 // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ... 443 // aber ich denke, die BK sollte es auch so vertragen 444 Expand(pToExpand); 445 446 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun 447 m_aDropActionTimer.Stop(); 448 } 449 break; 450 451 case DA_SCROLLUP : 452 ScrollOutputArea( 1 ); 453 m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS; 454 break; 455 456 case DA_SCROLLDOWN : 457 ScrollOutputArea( -1 ); 458 m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS; 459 break; 460 461 } 462 463 return 0L; 464 } 465 466 // ----------------------------------------------------------------------------- 467 IMPL_LINK(NavigatorTree, OnEntrySelDesel, NavigatorTree*, /*pThis*/) 468 { 469 if ( !m_pSelectionListener->locked() ) 470 { 471 m_pSelectionListener->lock(); 472 SvLBoxEntry* pEntry = GetCurEntry(); 473 uno::Any aSelection; 474 if ( IsSelected(pEntry) ) 475 aSelection <<= static_cast<UserData*>(pEntry->GetUserData())->getContent(); 476 m_rController.select(aSelection); 477 m_pSelectionListener->unlock(); 478 } 479 480 return 0L; 481 } 482 // ----------------------------------------------------------------------------- 483 void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent ) throw (uno::RuntimeException) 484 { 485 m_pSelectionListener->lock(); 486 uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY); 487 uno::Any aSec = xSelectionSupplier->getSelection(); 488 uno::Sequence< uno::Reference< report::XReportComponent > > aSelection; 489 aSec >>= aSelection; 490 if ( !aSelection.getLength() ) 491 { 492 uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY); 493 SvLBoxEntry* pEntry = find(xSelection); 494 if ( pEntry && !IsSelected(pEntry) ) 495 { 496 Select(pEntry, sal_True); 497 SetCurEntry(pEntry); 498 } 499 else if ( !pEntry ) 500 SelectAll(sal_False,sal_False); 501 } 502 else 503 { 504 const uno::Reference< report::XReportComponent >* pIter = aSelection.getConstArray(); 505 const uno::Reference< report::XReportComponent >* pEnd = pIter + aSelection.getLength(); 506 for (; pIter != pEnd; ++pIter) 507 { 508 SvLBoxEntry* pEntry = find(*pIter); 509 if ( pEntry && !IsSelected(pEntry) ) 510 { 511 Select(pEntry, sal_True); 512 SetCurEntry(pEntry); 513 } 514 } 515 } 516 m_pSelectionListener->unlock(); 517 } 518 // ----------------------------------------------------------------------------- 519 SvLBoxEntry* NavigatorTree::insertEntry(const ::rtl::OUString& _sName,SvLBoxEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition,UserData* _pData) 520 { 521 SvLBoxEntry* pEntry = NULL; 522 if ( _nImageId ) 523 { 524 const Image aImage( m_aNavigatorImages.GetImage( _nImageId ) ); 525 pEntry = InsertEntry(_sName,aImage,aImage,_pParent,sal_False,_nPosition,_pData); 526 if ( pEntry ) 527 { 528 const Image aImageHC( m_aNavigatorImagesHC.GetImage( _nImageId ) ); 529 SetExpandedEntryBmp( pEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); 530 SetCollapsedEntryBmp( pEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); 531 } 532 } 533 else 534 pEntry = InsertEntry(_sName,_pParent,sal_False,_nPosition,_pData); 535 return pEntry; 536 } 537 // ----------------------------------------------------------------------------- 538 void NavigatorTree::traverseSection(const uno::Reference< report::XSection>& _xSection,SvLBoxEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition) 539 { 540 SvLBoxEntry* pSection = insertEntry(_xSection->getName(),_pParent,_nImageId,_nPosition,new UserData(this,_xSection)); 541 const sal_Int32 nCount = _xSection->getCount(); 542 for (sal_Int32 i = 0; i < nCount; ++i) 543 { 544 uno::Reference< report::XReportComponent> xElement(_xSection->getByIndex(i),uno::UNO_QUERY_THROW); 545 OSL_ENSURE(xElement.is(),"Found report element which is NULL!"); 546 insertEntry(lcl_getName(xElement.get()),pSection,lcl_getImageId(xElement),LIST_APPEND,new UserData(this,xElement)); 547 uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY); 548 if ( xSubReport.is() ) 549 { 550 m_pMasterReport = find(_xSection->getReportDefinition()); 551 reportdesign::OReportVisitor aSubVisitor(this); 552 aSubVisitor.start(xSubReport); 553 } 554 } 555 } 556 // ----------------------------------------------------------------------------- 557 void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& _xFunctions,SvLBoxEntry* _pParent) 558 { 559 SvLBoxEntry* pFunctions = insertEntry(String(ModuleRes(RID_STR_FUNCTIONS)),_pParent,SID_RPT_NEW_FUNCTION,LIST_APPEND,new UserData(this,_xFunctions)); 560 const sal_Int32 nCount = _xFunctions->getCount(); 561 for (sal_Int32 i = 0; i< nCount; ++i) 562 { 563 uno::Reference< report::XFunction> xElement(_xFunctions->getByIndex(i),uno::UNO_QUERY); 564 insertEntry(xElement->getName(),pFunctions,SID_RPT_NEW_FUNCTION,LIST_APPEND,new UserData(this,xElement)); 565 } 566 } 567 // ----------------------------------------------------------------------------- 568 SvLBoxEntry* NavigatorTree::find(const uno::Reference< uno::XInterface >& _xContent) 569 { 570 SvLBoxEntry* pRet = NULL; 571 if ( _xContent.is() ) 572 { 573 SvLBoxEntry* pCurrent = First(); 574 while ( pCurrent ) 575 { 576 UserData* pData = static_cast<UserData*>(pCurrent->GetUserData()); 577 OSL_ENSURE(pData,"No UserData set an entry!"); 578 if ( pData->getContent() == _xContent ) 579 { 580 pRet = pCurrent; 581 break; 582 } 583 pCurrent = Next(pCurrent); 584 } 585 } 586 return pRet; 587 } 588 // ----------------------------------------------------------------------------- 589 // ITraverseReport 590 // ----------------------------------------------------------------------------- 591 void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>& _xReport) 592 { 593 insertEntry(_xReport->getName(),m_pMasterReport,SID_SELECT_REPORT,LIST_APPEND,new UserData(this,_xReport)); 594 } 595 // ----------------------------------------------------------------------------- 596 void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>& _xFunctions) 597 { 598 SvLBoxEntry* pReport = find(_xFunctions->getParent()); 599 traverseFunctions(_xFunctions,pReport); 600 } 601 // ----------------------------------------------------------------------------- 602 void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& _xSection) 603 { 604 SvLBoxEntry* pReport = find(_xSection->getReportDefinition()); 605 traverseSection(_xSection,pReport,SID_REPORTHEADERFOOTER); 606 } 607 // ----------------------------------------------------------------------------- 608 void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& _xSection) 609 { 610 SvLBoxEntry* pReport = find(_xSection->getReportDefinition()); 611 traverseSection(_xSection,pReport,SID_REPORTHEADERFOOTER); 612 } 613 // ----------------------------------------------------------------------------- 614 void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& _xSection) 615 { 616 SvLBoxEntry* pReport = find(_xSection->getReportDefinition()); 617 traverseSection(_xSection,pReport,SID_PAGEHEADERFOOTER); 618 } 619 // ----------------------------------------------------------------------------- 620 void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& _xSection) 621 { 622 SvLBoxEntry* pReport = find(_xSection->getReportDefinition()); 623 traverseSection(_xSection,pReport,SID_PAGEHEADERFOOTER); 624 } 625 // ----------------------------------------------------------------------------- 626 void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& _xGroups) 627 { 628 SvLBoxEntry* pReport = find(_xGroups->getReportDefinition()); 629 insertEntry(String(ModuleRes(RID_STR_GROUPS)),pReport,SID_SORTINGANDGROUPING,LIST_APPEND,new UserData(this,_xGroups)); 630 } 631 // ----------------------------------------------------------------------------- 632 void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& _xGroup) 633 { 634 uno::Reference< report::XGroups> xGroups(_xGroup->getParent(),uno::UNO_QUERY); 635 SvLBoxEntry* pGroups = find(xGroups); 636 OSL_ENSURE(pGroups,"No Groups inserted so far. Why!"); 637 insertEntry(_xGroup->getExpression(),pGroups,SID_GROUP,rptui::getPositionInIndexAccess(xGroups.get(),_xGroup),new UserData(this,_xGroup)); 638 } 639 // ----------------------------------------------------------------------------- 640 void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>& _xFunctions) 641 { 642 SvLBoxEntry* pGroup = find(_xFunctions->getParent()); 643 traverseFunctions(_xFunctions,pGroup); 644 } 645 // ----------------------------------------------------------------------------- 646 void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& _xSection) 647 { 648 SvLBoxEntry* pGroup = find(_xSection->getGroup()); 649 OSL_ENSURE(pGroup,"No group found"); 650 traverseSection(_xSection,pGroup,SID_GROUPHEADER,1); 651 } 652 // ----------------------------------------------------------------------------- 653 void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& _xSection) 654 { 655 SvLBoxEntry* pGroup = find(_xSection->getGroup()); 656 OSL_ENSURE(pGroup,"No group found"); 657 traverseSection(_xSection,pGroup,SID_GROUPFOOTER); 658 } 659 // ----------------------------------------------------------------------------- 660 void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& _xSection) 661 { 662 uno::Reference< report::XReportDefinition> xReport = _xSection->getReportDefinition(); 663 SvLBoxEntry* pParent = find(xReport); 664 traverseSection(_xSection,pParent,SID_ICON_DETAIL); 665 } 666 // ----------------------------------------------------------------------------- 667 void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException) 668 { 669 uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY); 670 if ( xReport.is() ) 671 { 672 sal_Bool bEnabled = sal_False; 673 _rEvent.NewValue >>= bEnabled; 674 if ( bEnabled ) 675 { 676 SvLBoxEntry* pParent = find(xReport); 677 if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON ) 678 { 679 sal_uLong nPos = xReport->getReportHeaderOn() ? 2 : 1; 680 traverseSection(xReport->getReportHeader(),pParent,SID_REPORTHEADERFOOTER,nPos); 681 } 682 else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON ) 683 { 684 traverseSection(xReport->getPageHeader(),pParent, SID_PAGEHEADERFOOTER,1); 685 } 686 else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON ) 687 traverseSection(xReport->getPageFooter(),pParent, SID_PAGEHEADERFOOTER); 688 else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON ) 689 { 690 sal_uLong nPos = xReport->getPageFooterOn() ? (GetLevelChildCount(pParent) - 1) : LIST_APPEND; 691 traverseSection(xReport->getReportFooter(),pParent,SID_REPORTHEADERFOOTER,nPos); 692 } 693 } 694 } 695 } 696 // ----------------------------------------------------------------------------- 697 void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent ) 698 { 699 SvLBoxEntry* pEntry = find(_rEvent.Source); 700 uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW); 701 ::rtl::OUString sName; 702 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo(); 703 if ( xInfo.is() ) 704 { 705 if ( xInfo->hasPropertyByName(PROPERTY_NAME) ) 706 xProp->getPropertyValue(PROPERTY_NAME) >>= sName; 707 else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) ) 708 xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName; 709 } 710 uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY); 711 if ( xGroup.is() ) 712 { 713 reportdesign::OReportVisitor aSubVisitor(this); 714 aSubVisitor.start(xGroup); 715 } 716 else 717 { 718 uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY); 719 if ( xProp.is() ) 720 sName = lcl_getName(xProp); 721 insertEntry(sName,pEntry,(!xElement.is() ? sal_uInt16(SID_RPT_NEW_FUNCTION) : lcl_getImageId(xElement)),LIST_APPEND,new UserData(this,xProp)); 722 } 723 if ( !IsExpanded(pEntry) ) 724 Expand(pEntry); 725 } 726 // ----------------------------------------------------------------------------- 727 void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent ) 728 { 729 uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY); 730 SvLBoxEntry* pEntry = find(xProp); 731 OSL_ENSURE(pEntry,"NavigatorTree::_elementRemoved: No Entry found!"); 732 733 if ( pEntry ) 734 { 735 SvLBoxEntry* pParent = GetParent(pEntry); 736 removeEntry(pEntry); 737 PaintEntry(pParent); 738 } 739 } 740 // ----------------------------------------------------------------------------- 741 void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent ) 742 { 743 uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY); 744 SvLBoxEntry* pEntry = find(xProp); 745 if ( pEntry ) 746 { 747 UserData* pData = static_cast<UserData*>(pEntry->GetUserData()); 748 xProp.set(_rEvent.Element,uno::UNO_QUERY); 749 pData->setContent(xProp); 750 ::rtl::OUString sName; 751 xProp->getPropertyValue(PROPERTY_NAME) >>= sName; 752 SetEntryText(pEntry,sName); 753 } 754 } 755 // ----------------------------------------------------------------------------- 756 void NavigatorTree::_disposing(const lang::EventObject& _rSource)throw( uno::RuntimeException) 757 { 758 removeEntry(find(_rSource.Source)); 759 } 760 // ----------------------------------------------------------------------------- 761 void NavigatorTree::removeEntry(SvLBoxEntry* _pEntry,bool _bRemove) 762 { 763 if ( _pEntry ) 764 { 765 SvLBoxEntry* pChild = FirstChild(_pEntry); 766 while( pChild ) 767 { 768 removeEntry(pChild,false); 769 pChild = NextSibling(pChild); 770 } 771 delete static_cast<UserData*>(_pEntry->GetUserData()); 772 if ( _bRemove ) 773 GetModel()->Remove(_pEntry); 774 } 775 } 776 DBG_NAME(rpt_NavigatorTree_UserData) 777 // ----------------------------------------------------------------------------- 778 NavigatorTree::UserData::UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent) 779 : OPropertyChangeListener(m_aMutex) 780 , OContainerListener(m_aMutex) 781 , m_xContent(_xContent) 782 , m_pTree(_pTree) 783 { 784 DBG_CTOR(rpt_NavigatorTree_UserData,NULL); 785 uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY); 786 if ( xProp.is() ) 787 { 788 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo(); 789 if ( xInfo.is() ) 790 { 791 m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp); 792 if ( xInfo->hasPropertyByName(PROPERTY_NAME) ) 793 m_pListener->addProperty(PROPERTY_NAME); 794 else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) ) 795 m_pListener->addProperty(PROPERTY_EXPRESSION); 796 if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) ) 797 m_pListener->addProperty(PROPERTY_DATAFIELD); 798 if ( xInfo->hasPropertyByName(PROPERTY_LABEL) ) 799 m_pListener->addProperty(PROPERTY_LABEL); 800 if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) ) 801 m_pListener->addProperty(PROPERTY_HEADERON); 802 if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) ) 803 m_pListener->addProperty(PROPERTY_FOOTERON); 804 } 805 } 806 uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY); 807 if ( xContainer.is() ) 808 { 809 m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer); 810 } 811 } 812 // ----------------------------------------------------------------------------- 813 NavigatorTree::UserData::~UserData() 814 { 815 DBG_DTOR(rpt_NavigatorTree_UserData,NULL); 816 if ( m_pContainerListener.is() ) 817 m_pContainerListener->dispose(); 818 if ( m_pListener.is() ) 819 m_pListener->dispose(); 820 } 821 // ----------------------------------------------------------------------------- 822 // OPropertyChangeListener 823 void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException) 824 { 825 SvLBoxEntry* pEntry = m_pTree->find(_rEvent.Source); 826 OSL_ENSURE(pEntry,"No entry could be found! Why not!"); 827 const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName); 828 try 829 { 830 if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName ) 831 { 832 sal_Int32 nPos = 1; 833 uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY); 834 ::std::mem_fun_t< sal_Bool,OGroupHelper> pIsOn = ::std::mem_fun(&OGroupHelper::getHeaderOn); 835 ::std::mem_fun_t< uno::Reference<report::XSection> ,OGroupHelper> pMemFunSection = ::std::mem_fun(&OGroupHelper::getHeader); 836 if ( bFooterOn ) 837 { 838 pIsOn = ::std::mem_fun(&OGroupHelper::getFooterOn); 839 pMemFunSection = ::std::mem_fun(&OGroupHelper::getFooter); 840 nPos = m_pTree->GetChildCount(pEntry) - 1; 841 } 842 843 OGroupHelper aGroupHelper(xGroup); 844 if ( pIsOn(&aGroupHelper) ) 845 { 846 if ( bFooterOn ) 847 ++nPos; 848 m_pTree->traverseSection(pMemFunSection(&aGroupHelper),pEntry,bFooterOn ? SID_GROUPFOOTER : SID_GROUPHEADER,nPos); 849 } 850 //else 851 // m_pTree->removeEntry(m_pTree->GetEntry(pEntry,nPos)); 852 } 853 else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName) 854 { 855 ::rtl::OUString sNewName; 856 _rEvent.NewValue >>= sNewName; 857 m_pTree->SetEntryText(pEntry,sNewName); 858 } 859 else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName ) 860 { 861 uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY); 862 m_pTree->SetEntryText(pEntry,lcl_getName(xProp)); 863 } 864 } 865 catch(uno::Exception) 866 {} 867 } 868 // ----------------------------------------------------------------------------- 869 void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException) 870 { 871 m_pTree->_elementInserted( _rEvent ); 872 } 873 // ----------------------------------------------------------------------------- 874 void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException) 875 { 876 m_pTree->_elementRemoved( _rEvent ); 877 } 878 // ----------------------------------------------------------------------------- 879 void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException) 880 { 881 m_pTree->_elementReplaced( _rEvent ); 882 } 883 // ----------------------------------------------------------------------------- 884 void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource) throw( uno::RuntimeException) 885 { 886 m_pTree->_disposing( _rSource ); 887 } 888 // ----------------------------------------------------------------------------- 889 // class ONavigatorImpl 890 // ----------------------------------------------------------------------------- 891 class ONavigatorImpl 892 { 893 ONavigatorImpl(const ONavigatorImpl&); 894 void operator =(const ONavigatorImpl&); 895 public: 896 ONavigatorImpl(OReportController& _rController,ONavigator* _pParent); 897 virtual ~ONavigatorImpl(); 898 899 uno::Reference< report::XReportDefinition> m_xReport; 900 ::rptui::OReportController& m_rController; 901 ::std::auto_ptr<NavigatorTree> m_pNavigatorTree; 902 }; 903 904 ONavigatorImpl::ONavigatorImpl(OReportController& _rController,ONavigator* _pParent) 905 :m_xReport(_rController.getReportDefinition()) 906 ,m_rController(_rController) 907 ,m_pNavigatorTree(new NavigatorTree(_pParent,_rController)) 908 { 909 reportdesign::OReportVisitor aVisitor(m_pNavigatorTree.get()); 910 aVisitor.start(m_xReport); 911 m_pNavigatorTree->Expand(m_pNavigatorTree->find(m_xReport)); 912 lang::EventObject aEvent(m_rController); 913 m_pNavigatorTree->_selectionChanged(aEvent); 914 } 915 //------------------------------------------------------------------------ 916 ONavigatorImpl::~ONavigatorImpl() 917 { 918 } 919 // ----------------------------------------------------------------------------- 920 DBG_NAME( rpt_ONavigator ) 921 const long STD_WIN_SIZE_X = 210; 922 const long STD_WIN_SIZE_Y = 280; 923 const long LISTBOX_BORDER = 2; 924 //======================================================================== 925 // class ONavigator 926 //======================================================================== 927 ONavigator::ONavigator( Window* _pParent 928 ,OReportController& _rController) 929 : FloatingWindow( _pParent, ModuleRes(RID_NAVIGATOR) ) 930 { 931 DBG_CTOR( rpt_ONavigator,NULL); 932 933 m_pImpl.reset(new ONavigatorImpl(_rController,this)); 934 935 //Size aSpace = LogicToPixel( Size( 7, 120), MAP_APPFONT ); 936 //Size aOutSize(nMaxTextWidth + m_aHeader.GetSizePixel().Width() + 3*aSpace.Width(),aSpace.Height()); 937 //SetMinOutputSizePixel(aOutSize); 938 //SetOutputSizePixel(aOutSize); 939 FreeResource(); 940 m_pImpl->m_pNavigatorTree->Show(); 941 m_pImpl->m_pNavigatorTree->GrabFocus(); 942 SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y)); 943 Show(); 944 945 } 946 // ----------------------------------------------------------------------------- 947 948 //------------------------------------------------------------------------ 949 ONavigator::~ONavigator() 950 { 951 DBG_DTOR( rpt_ONavigator,NULL); 952 } 953 //------------------------------------------------------------------------------ 954 void ONavigator::Resize() 955 { 956 FloatingWindow::Resize(); 957 958 Point aPos(GetPosPixel()); 959 Size aSize( GetOutputSizePixel() ); 960 961 ////////////////////////////////////////////////////////////////////// 962 963 // Groesse der form::ListBox anpassen 964 Point aLBPos( LISTBOX_BORDER, LISTBOX_BORDER ); 965 Size aLBSize( aSize ); 966 aLBSize.Width() -= (2*LISTBOX_BORDER); 967 aLBSize.Height() -= (2*LISTBOX_BORDER); 968 969 m_pImpl->m_pNavigatorTree->SetPosSizePixel( aLBPos, aLBSize ); 970 } 971 // ----------------------------------------------------------------------------- 972 // ----------------------------------------------------------------------------- 973 void ONavigator::GetFocus() 974 { 975 Window::GetFocus(); 976 if ( m_pImpl->m_pNavigatorTree.get() ) 977 m_pImpl->m_pNavigatorTree->GrabFocus(); 978 } 979 // ============================================================================= 980 } // rptui 981 // ============================================================================= 982 983