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