1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #include "precompiled_reportdesign.hxx" 28 #include "SectionWindow.hxx" 29 #include "ReportWindow.hxx" 30 #include "ReportRuler.hxx" 31 #include "rptui_slotid.hrc" 32 #include "ReportController.hxx" 33 #include "SectionView.hxx" 34 #include "RptDef.hxx" 35 #include "ReportSection.hxx" 36 #include "DesignView.hxx" 37 #include "uistrings.hrc" 38 #include "helpids.hrc" 39 #include "RptResId.hrc" 40 #include "StartMarker.hxx" 41 #include "EndMarker.hxx" 42 #include "ViewsWindow.hxx" 43 44 #include <svtools/colorcfg.hxx> 45 #include <boost/bind.hpp> 46 #include <functional> 47 #include <algorithm> 48 #include <vcl/svapp.hxx> 49 #include <connectivity/dbtools.hxx> 50 51 namespace rptui 52 { 53 #define SECTION_OFFSET 3 54 55 using namespace ::com::sun::star; 56 using namespace ::comphelper; 57 58 DBG_NAME( rpt_OSectionWindow ) 59 OSectionWindow::OSectionWindow( OViewsWindow* _pParent,const uno::Reference< report::XSection >& _xSection,const ::rtl::OUString& _sColorEntry) 60 : Window( _pParent,WB_DIALOGCONTROL) 61 ,OPropertyChangeListener(m_aMutex) 62 ,m_pParent(_pParent) 63 ,m_aStartMarker( this,_sColorEntry) 64 ,m_aReportSection( this,_xSection) 65 ,m_aSplitter(this) 66 ,m_aEndMarker( this,_sColorEntry) 67 { 68 DBG_CTOR( rpt_OSectionWindow,NULL); 69 SetUniqueId(UID_RPT_SECTIONSWINDOW); 70 const MapMode& rMapMode = _pParent->GetMapMode(); 71 SetMapMode( rMapMode ); 72 ImplInitSettings(); 73 // TRY 74 m_aSplitter.SetMapMode( MapMode( MAP_100TH_MM ) ); 75 m_aSplitter.SetStartSplitHdl(LINK(this, OSectionWindow,StartSplitHdl)); 76 m_aSplitter.SetSplitHdl(LINK(this, OSectionWindow,SplitHdl)); 77 m_aSplitter.SetEndSplitHdl(LINK(this, OSectionWindow,EndSplitHdl)); 78 m_aSplitter.SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() )); 79 m_aSplitter.SetSplitPosPixel(m_aSplitter.LogicToPixel(Size(0,_xSection->getHeight())).Height()); 80 81 82 m_aStartMarker.setCollapsedHdl(LINK(this,OSectionWindow,Collapsed)); 83 84 m_aStartMarker.zoom(rMapMode.GetScaleX()); 85 setZoomFactor(rMapMode.GetScaleX(),m_aReportSection); 86 setZoomFactor(rMapMode.GetScaleX(),m_aSplitter); 87 setZoomFactor(rMapMode.GetScaleX(),m_aEndMarker); 88 89 m_aSplitter.Show(); 90 m_aStartMarker.Show(); 91 m_aReportSection.Show(); 92 m_aEndMarker.Show(); 93 Show(); 94 95 m_pSectionMulti = new OPropertyChangeMultiplexer(this,_xSection.get()); 96 m_pSectionMulti->addProperty(PROPERTY_NAME); 97 m_pSectionMulti->addProperty(PROPERTY_HEIGHT); 98 99 beans::PropertyChangeEvent aEvent; 100 aEvent.Source = _xSection; 101 aEvent.PropertyName = PROPERTY_NAME; 102 uno::Reference< report::XGroup > xGroup(_xSection->getGroup()); 103 if ( xGroup.is() ) 104 { 105 m_pGroupMulti = new OPropertyChangeMultiplexer(this,xGroup.get()); 106 m_pGroupMulti->addProperty(PROPERTY_EXPRESSION); 107 aEvent.Source = xGroup; 108 aEvent.PropertyName = PROPERTY_EXPRESSION; 109 } 110 111 _propertyChanged(aEvent); 112 } 113 // ----------------------------------------------------------------------------- 114 OSectionWindow::~OSectionWindow() 115 { 116 DBG_DTOR( rpt_OSectionWindow,NULL); 117 try 118 { 119 if ( m_pSectionMulti.is() ) 120 m_pSectionMulti->dispose(); 121 if ( m_pGroupMulti.is() ) 122 m_pGroupMulti->dispose(); 123 } 124 catch (uno::Exception&) 125 { 126 } 127 } 128 // ----------------------------------------------------------------------------- 129 void OSectionWindow::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException) 130 { 131 const uno::Reference< report::XSection > xSection(_rEvent.Source,uno::UNO_QUERY); 132 if ( xSection.is() ) 133 { 134 const uno::Reference< report::XSection> xCurrentSection = m_aReportSection.getSection(); 135 if ( _rEvent.PropertyName.equals(PROPERTY_HEIGHT) ) 136 { 137 static bool t4 = true; 138 if ( t4 ) 139 m_pParent->getView()->SetUpdateMode(sal_False); 140 //Resize(); 141 m_pParent->getView()->notifySizeChanged(); 142 m_pParent->resize(*this); 143 if ( t4 ) 144 m_pParent->getView()->SetUpdateMode(sal_True); 145 // getViewsWindow()->getView()->getReportView()->getController().resetZoomType(); 146 } 147 else if ( _rEvent.PropertyName.equals(PROPERTY_NAME) && !xSection->getGroup().is() ) 148 { 149 uno::Reference< report::XReportDefinition > xReport = xSection->getReportDefinition(); 150 if ( setReportSectionTitle(xReport,RID_STR_REPORT_HEADER,::std::mem_fun(&OReportHelper::getReportHeader),::std::mem_fun(&OReportHelper::getReportHeaderOn)) 151 || setReportSectionTitle(xReport,RID_STR_REPORT_FOOTER,::std::mem_fun(&OReportHelper::getReportFooter),::std::mem_fun(&OReportHelper::getReportFooterOn)) 152 || setReportSectionTitle(xReport,RID_STR_PAGE_HEADER,::std::mem_fun(&OReportHelper::getPageHeader),::std::mem_fun(&OReportHelper::getPageHeaderOn)) 153 || setReportSectionTitle(xReport,RID_STR_PAGE_FOOTER,::std::mem_fun(&OReportHelper::getPageFooter),::std::mem_fun(&OReportHelper::getPageFooterOn)) ) 154 { 155 m_aStartMarker.Invalidate(INVALIDATE_NOERASE); 156 } 157 else 158 { 159 String sTitle = String(ModuleRes(RID_STR_DETAIL)); 160 m_aStartMarker.setTitle(sTitle); 161 m_aStartMarker.Invalidate(INVALIDATE_CHILDREN); 162 } 163 } 164 } // if ( xSection.is() ) 165 else if ( _rEvent.PropertyName.equals(PROPERTY_EXPRESSION) ) 166 { 167 uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY); 168 if ( xGroup.is() && !setGroupSectionTitle(xGroup,RID_STR_HEADER,::std::mem_fun(&OGroupHelper::getHeader),::std::mem_fun(&OGroupHelper::getHeaderOn))) 169 { 170 setGroupSectionTitle(xGroup,RID_STR_FOOTER,::std::mem_fun(&OGroupHelper::getFooter),::std::mem_fun(&OGroupHelper::getFooterOn)); 171 } 172 } 173 } 174 // ----------------------------------------------------------------------------- 175 bool OSectionWindow::setReportSectionTitle(const uno::Reference< report::XReportDefinition>& _xReport,sal_uInt16 _nResId,::std::mem_fun_t<uno::Reference<report::XSection> , OReportHelper> _pGetSection,::std::mem_fun_t<sal_Bool,OReportHelper> _pIsSectionOn) 176 { 177 OReportHelper aReportHelper(_xReport); 178 const bool bRet = _pIsSectionOn(&aReportHelper) && _pGetSection(&aReportHelper) == m_aReportSection.getSection(); 179 if ( bRet ) 180 { 181 String sTitle = String(ModuleRes(_nResId)); 182 m_aStartMarker.setTitle(sTitle); 183 m_aStartMarker.Invalidate(INVALIDATE_CHILDREN); 184 } // if ( bRet ) 185 return bRet; 186 } 187 // ----------------------------------------------------------------------------- 188 bool OSectionWindow::setGroupSectionTitle(const uno::Reference< report::XGroup>& _xGroup,sal_uInt16 _nResId,::std::mem_fun_t<uno::Reference<report::XSection> , OGroupHelper> _pGetSection,::std::mem_fun_t<sal_Bool,OGroupHelper> _pIsSectionOn) 189 { 190 OGroupHelper aGroupHelper(_xGroup); 191 const bool bRet = _pIsSectionOn(&aGroupHelper) && _pGetSection(&aGroupHelper) == m_aReportSection.getSection() ; 192 if ( bRet ) 193 { 194 ::rtl::OUString sExpression = _xGroup->getExpression(); 195 ::rtl::OUString sLabel = getViewsWindow()->getView()->getReportView()->getController().getColumnLabel_throw(sExpression); 196 if ( sLabel.getLength() ) 197 { 198 sExpression = sLabel; 199 } 200 201 String sTitle = String(ModuleRes(_nResId)); 202 sTitle.SearchAndReplace('#',sExpression); 203 m_aStartMarker.setTitle(sTitle); 204 m_aStartMarker.Invalidate(INVALIDATE_CHILDREN); 205 } // if ( _pIsSectionOn(&aGroupHelper) ) 206 return bRet; 207 } 208 //------------------------------------------------------------------------------ 209 void OSectionWindow::ImplInitSettings() 210 { 211 static bool t = false; 212 if ( t ) 213 { 214 EnableChildTransparentMode( sal_True ); 215 SetParentClipMode( PARENTCLIPMODE_NOCLIP ); 216 SetPaintTransparent( sal_True ); 217 } 218 SetBackground( ); 219 } 220 //----------------------------------------------------------------------------- 221 void OSectionWindow::DataChanged( const DataChangedEvent& rDCEvt ) 222 { 223 Window::DataChanged( rDCEvt ); 224 225 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 226 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 227 { 228 ImplInitSettings(); 229 Invalidate(); 230 } 231 } 232 //------------------------------------------------------------------------------ 233 void OSectionWindow::Resize() 234 { 235 Window::Resize(); 236 237 Size aOutputSize = GetOutputSizePixel(); 238 Fraction aEndWidth(long(REPORT_ENDMARKER_WIDTH)); 239 aEndWidth *= GetMapMode().GetScaleX(); 240 241 const Point aThumbPos = m_pParent->getView()->getThumbPos(); 242 aOutputSize.Width() -= aThumbPos.X(); 243 aOutputSize.Height() -= m_aSplitter.GetSizePixel().Height(); 244 245 if ( m_aStartMarker.isCollapsed() ) 246 { 247 Point aPos(0,0); 248 m_aStartMarker.SetPosSizePixel(aPos,aOutputSize); 249 } 250 else 251 { 252 const bool bShowEndMarker = m_pParent->getView()->GetTotalWidth() <= (aThumbPos.X() + aOutputSize.Width() ); 253 254 Fraction aStartWidth(long(REPORT_STARTMARKER_WIDTH)); 255 aStartWidth *= GetMapMode().GetScaleX(); 256 257 // set start marker 258 m_aStartMarker.SetPosSizePixel(Point(0,0),Size(aStartWidth,aOutputSize.Height())); 259 260 // set report section 261 const uno::Reference< report::XSection> xSection = m_aReportSection.getSection(); 262 Size aSectionSize = LogicToPixel( Size( 0,xSection->getHeight() ) ); 263 Point aReportPos(aStartWidth,0); 264 aSectionSize.Width() = aOutputSize.Width() - (long)aStartWidth; 265 if ( bShowEndMarker ) 266 aSectionSize.Width() -= (long)aEndWidth; 267 268 m_aReportSection.SetPosSizePixel(aReportPos,aSectionSize); 269 270 // set splitter 271 aReportPos.Y() += aSectionSize.Height(); 272 m_aSplitter.SetPosSizePixel(aReportPos,Size(aSectionSize.Width(),m_aSplitter.GetSizePixel().Height())); 273 aSectionSize.Height() = (long)(1000 * (double)GetMapMode().GetScaleY()); 274 m_aSplitter.SetDragRectPixel( Rectangle(Point(aStartWidth,0),aSectionSize)); 275 276 // set end marker 277 aReportPos.X() += aSectionSize.Width(); 278 aReportPos.Y() = 0; 279 m_aEndMarker.Show(bShowEndMarker); 280 m_aEndMarker.SetPosSizePixel(aReportPos,Size(aEndWidth,aOutputSize.Height())); 281 } 282 } 283 // ----------------------------------------------------------------------------- 284 void OSectionWindow::setCollapsed(sal_Bool _bCollapsed) 285 { 286 if ( m_aStartMarker.isCollapsed() != _bCollapsed ) 287 { 288 m_aStartMarker.setCollapsed(_bCollapsed); 289 } 290 } 291 //----------------------------------------------------------------------------- 292 void OSectionWindow::showProperties() 293 { 294 m_pParent->getView()->showProperties( m_aReportSection.getSection().get() ); 295 } 296 //----------------------------------------------------------------------------- 297 void OSectionWindow::setMarked(sal_Bool _bMark) 298 { 299 m_aStartMarker.setMarked(_bMark); 300 m_aEndMarker.setMarked(_bMark); 301 } 302 // ----------------------------------------------------------------------------- 303 IMPL_LINK( OSectionWindow, Collapsed, OColorListener *, _pMarker ) 304 { 305 if ( _pMarker ) 306 { 307 sal_Bool bShow = !_pMarker->isCollapsed(); 308 m_aReportSection.Show(bShow); 309 m_aEndMarker.Show(bShow); 310 m_aSplitter.Show(bShow); 311 312 m_pParent->resize(*this); 313 } 314 return 0L; 315 } 316 // ----------------------------------------------------------------------------- 317 void OSectionWindow::zoom(const Fraction& _aZoom) 318 { 319 setZoomFactor(_aZoom,*this); 320 m_aStartMarker.zoom(_aZoom); 321 322 setZoomFactor(_aZoom,m_aReportSection); 323 setZoomFactor(_aZoom,m_aSplitter); 324 setZoomFactor(_aZoom,m_aEndMarker); 325 //Resize(); 326 Invalidate(/*INVALIDATE_UPDATE |*/ /* | INVALIDATE_TRANSPARENT *//*INVALIDATE_NOCHILDREN*/); 327 } 328 //----------------------------------------------------------------------------- 329 IMPL_LINK( OSectionWindow, StartSplitHdl, Splitter*, ) 330 { 331 const String sUndoAction( ModuleRes( RID_STR_UNDO_CHANGE_SIZE ) ); 332 getViewsWindow()->getView()->getReportView()->getController().getUndoManager().EnterListAction( sUndoAction, String() ); 333 return 0L; 334 } 335 //------------------------------------------------------------------------------ 336 IMPL_LINK( OSectionWindow, EndSplitHdl, Splitter*, ) 337 { 338 getViewsWindow()->getView()->getReportView()->getController().getUndoManager().LeaveListAction(); 339 return 0L; 340 } 341 //----------------------------------------------------------------------------- 342 IMPL_LINK( OSectionWindow, SplitHdl, Splitter*, _pSplitter ) 343 { 344 if ( !getViewsWindow()->getView()->getReportView()->getController().isEditable() ) 345 { 346 return 0L; 347 } 348 349 sal_Int32 nSplitPos = _pSplitter->GetSplitPosPixel(); 350 const Point aPos = _pSplitter->GetPosPixel(); 351 352 353 const uno::Reference< report::XSection> xSection = m_aReportSection.getSection(); 354 nSplitPos = m_aSplitter.PixelToLogic(Size(0,nSplitPos)).Height(); 355 // nSplitPos = xSection->getHeight() + m_aSplitter.PixelToLogic(Size(0,nSplitPos - aPos.Y() )).Height(); 356 357 const sal_Int32 nCount = xSection->getCount(); 358 for (sal_Int32 i = 0; i < nCount; ++i) 359 { 360 uno::Reference<report::XReportComponent> xReportComponent(xSection->getByIndex(i),uno::UNO_QUERY); 361 if ( xReportComponent.is() /*&& nSplitPos < (xReportComponent->getPositionY() + xReportComponent->getHeight())*/ ) 362 { 363 nSplitPos = ::std::max(nSplitPos,xReportComponent->getPositionY() + xReportComponent->getHeight()); 364 } 365 } // for (sal_Int32 i = 0; i < nCount; ++i) 366 367 if ( nSplitPos < 0 ) 368 nSplitPos = 0; 369 370 xSection->setHeight(nSplitPos); 371 m_aSplitter.SetSplitPosPixel(m_aSplitter.LogicToPixel(Size(0,nSplitPos)).Height()); 372 373 return 0L; 374 } 375 // ----------------------------------------------------------------------------- 376 void lcl_scroll(Window& _rWindow,const Point& _aDelta) 377 { 378 _rWindow.Scroll(-_aDelta.X(),-_aDelta.Y()/*,SCROLL_CHILDREN*//*|SCROLL_CLIP*/); 379 _rWindow.Invalidate(INVALIDATE_TRANSPARENT); 380 } 381 // ----------------------------------------------------------------------------- 382 void lcl_setOrigin(Window& _rWindow,long _nX, long _nY) 383 { 384 MapMode aMap = _rWindow.GetMapMode(); 385 aMap.SetOrigin( Point(- _nX, - _nY)); 386 _rWindow.SetMapMode( aMap ); 387 } 388 //---------------------------------------------------------------------------- 389 void OSectionWindow::scrollChildren(long _nX) 390 { 391 const Point aDelta( _nX,0 ); 392 393 MapMode aMapMode( m_aReportSection.GetMapMode() ); 394 const Point aOld = aMapMode.GetOrigin(); 395 lcl_setOrigin(m_aReportSection,aDelta.X(), 0); 396 397 aMapMode = m_aReportSection.GetMapMode(); 398 const Point aNew = aMapMode.GetOrigin(); 399 const Point aDiff = aOld - aNew; 400 { 401 //OWindowPositionCorrector aCorrector(&m_aReportSection,-aDelta.Width(),0); 402 lcl_scroll(m_aReportSection,aDiff); 403 } 404 405 //lcl_setOrigin(m_aEndMarker,_nDeltaX, 0); 406 lcl_scroll(m_aEndMarker,m_aEndMarker.PixelToLogic(Point(_nX,0))); 407 408 lcl_setOrigin(m_aSplitter,_nX, 0); 409 lcl_scroll(m_aSplitter,aDiff); 410 } 411 //============================================================================== 412 } // rptui 413 //============================================================================== 414 415